From 7c6c6d3df72ff04fd2f88552847fcc67370ead71 Mon Sep 17 00:00:00 2001 From: Tropical <42101043+tropicaaal@users.noreply.github.com> Date: Wed, 25 Mar 2026 16:22:02 -0500 Subject: [PATCH 001/170] refactor: replace winapi TLS functions in Vec3 and AABB --- Minecraft.World/Util/AABB.cpp | 23 ++++++++++------------- Minecraft.World/Util/AABB.h | 4 ++-- Minecraft.World/Util/Vec3.cpp | 22 ++++++++++------------ Minecraft.World/Util/Vec3.h | 5 +++-- 4 files changed, 25 insertions(+), 29 deletions(-) diff --git a/Minecraft.World/Util/AABB.cpp b/Minecraft.World/Util/AABB.cpp index c4a8bff2e..3dff9c23d 100644 --- a/Minecraft.World/Util/AABB.cpp +++ b/Minecraft.World/Util/AABB.cpp @@ -7,8 +7,8 @@ #include "AABB.h" #include "HitResult.h" -unsigned int AABB::tlsIdx = 0; -AABB::ThreadStorage* AABB::tlsDefault = NULL; +thread_local AABB::ThreadStorage* AABB::m_tlsPool = nullptr; +AABB::ThreadStorage* AABB::m_tlsPoolDefault = nullptr; AABB::ThreadStorage::ThreadStorage() { pool = new AABB[POOL_SIZE]; // 4jcraft, needs to be deleted with delete[] @@ -21,21 +21,18 @@ AABB::ThreadStorage::~ThreadStorage() { void AABB::CreateNewThreadStorage() { ThreadStorage* tls = new ThreadStorage(); - if (tlsDefault == NULL) { - tlsIdx = TlsAlloc(); - tlsDefault = tls; + if (m_tlsPoolDefault == nullptr) { + m_tlsPoolDefault = tls; } - - TlsSetValue(tlsIdx, tls); + m_tlsPool = m_tlsPoolDefault; } -void AABB::UseDefaultThreadStorage() { TlsSetValue(tlsIdx, tlsDefault); } +void AABB::UseDefaultThreadStorage() { m_tlsPool = m_tlsPoolDefault; } void AABB::ReleaseThreadStorage() { - ThreadStorage* tls = (ThreadStorage*)TlsGetValue(tlsIdx); - if (tls == tlsDefault) return; - - delete tls; + if (m_tlsPool != m_tlsPoolDefault) { + delete m_tlsPool; + } } AABB* AABB::newPermanent(double x0, double y0, double z0, double x1, double y1, @@ -49,7 +46,7 @@ void AABB::resetPool() {} AABB* AABB::newTemp(double x0, double y0, double z0, double x1, double y1, double z1) { - ThreadStorage* tls = (ThreadStorage*)TlsGetValue(tlsIdx); + ThreadStorage* tls = m_tlsPool; AABB* thisAABB = &tls->pool[tls->poolPointer]; thisAABB->set(x0, y0, z0, x1, y1, z1); tls->poolPointer = (tls->poolPointer + 1) % ThreadStorage::POOL_SIZE; diff --git a/Minecraft.World/Util/AABB.h b/Minecraft.World/Util/AABB.h index bcd941f39..205d5ac98 100644 --- a/Minecraft.World/Util/AABB.h +++ b/Minecraft.World/Util/AABB.h @@ -15,8 +15,8 @@ class AABB { ThreadStorage(); ~ThreadStorage(); }; - static unsigned int tlsIdx; - static ThreadStorage* tlsDefault; + static thread_local ThreadStorage* m_tlsPool; + static ThreadStorage* m_tlsPoolDefault; public: // Each new thread that needs to use Vec3 pools will need to call one of the diff --git a/Minecraft.World/Util/Vec3.cpp b/Minecraft.World/Util/Vec3.cpp index 4e42b99a3..7796aba16 100644 --- a/Minecraft.World/Util/Vec3.cpp +++ b/Minecraft.World/Util/Vec3.cpp @@ -2,8 +2,8 @@ #include "Vec3.h" #include "AABB.h" -unsigned int Vec3::tlsIdx = 0; -Vec3::ThreadStorage* Vec3::tlsDefault = NULL; +thread_local Vec3::ThreadStorage* Vec3::m_tlsPool = nullptr; +Vec3::ThreadStorage* Vec3::m_tlsPoolDefault = nullptr; Vec3::ThreadStorage::ThreadStorage() { pool = new Vec3[POOL_SIZE]; @@ -14,20 +14,18 @@ Vec3::ThreadStorage::~ThreadStorage() { delete[] pool; } void Vec3::CreateNewThreadStorage() { ThreadStorage* tls = new ThreadStorage(); - if (tlsDefault == NULL) { - tlsIdx = TlsAlloc(); - tlsDefault = tls; + if (m_tlsPoolDefault == nullptr) { + m_tlsPoolDefault = tls; } - TlsSetValue(tlsIdx, tls); + m_tlsPool = m_tlsPoolDefault; } -void Vec3::UseDefaultThreadStorage() { TlsSetValue(tlsIdx, tlsDefault); } +void Vec3::UseDefaultThreadStorage() { m_tlsPool = m_tlsPoolDefault; } void Vec3::ReleaseThreadStorage() { - ThreadStorage* tls = (ThreadStorage*)TlsGetValue(tlsIdx); - if (tls == tlsDefault) return; - - delete tls; + if (m_tlsPool != m_tlsPoolDefault) { + delete m_tlsPool; + } } Vec3* Vec3::newPermanent(double x, double y, double z) { @@ -39,7 +37,7 @@ void Vec3::clearPool() {} void Vec3::resetPool() {} Vec3* Vec3::newTemp(double x, double y, double z) { - ThreadStorage* tls = (ThreadStorage*)TlsGetValue(tlsIdx); + ThreadStorage* tls = m_tlsPool; Vec3* thisVec = &tls->pool[tls->poolPointer]; thisVec->set(x, y, z); tls->poolPointer = (tls->poolPointer + 1) % ThreadStorage::POOL_SIZE; diff --git a/Minecraft.World/Util/Vec3.h b/Minecraft.World/Util/Vec3.h index bc1239d81..da9fcc73b 100644 --- a/Minecraft.World/Util/Vec3.h +++ b/Minecraft.World/Util/Vec3.h @@ -12,8 +12,9 @@ class Vec3 { ThreadStorage(); ~ThreadStorage(); }; - static unsigned int tlsIdx; - static ThreadStorage* tlsDefault; + + static thread_local ThreadStorage* m_tlsPool; + static ThreadStorage* m_tlsPoolDefault; public: // Each new thread that needs to use Vec3 pools will need to call one of the From 7b18641f7006984ccf26e406f36862a501ab1e0f Mon Sep 17 00:00:00 2001 From: Tropical <42101043+tropicaaal@users.noreply.github.com> Date: Wed, 25 Mar 2026 16:24:45 -0500 Subject: [PATCH 002/170] chore: clean up unused code from Linux_Minecraft.cpp --- Minecraft.Client/Platform/Linux/Linux_Minecraft.cpp | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/Minecraft.Client/Platform/Linux/Linux_Minecraft.cpp b/Minecraft.Client/Platform/Linux/Linux_Minecraft.cpp index 852dbb58c..4daca7e16 100644 --- a/Minecraft.Client/Platform/Linux/Linux_Minecraft.cpp +++ b/Minecraft.Client/Platform/Linux/Linux_Minecraft.cpp @@ -5,7 +5,6 @@ #include // #include -#include #if defined(__linux__) && defined(__GLIBC__) #include #include @@ -710,16 +709,6 @@ void CleanupDevice() { } #endif -int StartMinecraftThreadProc(void* lpParameter) { - Vec3::UseDefaultThreadStorage(); - AABB::UseDefaultThreadStorage(); - Tesselator::CreateNewThreadStorage(1024 * 1024); - RenderManager.InitialiseContext(); - Minecraft::start(std::wstring(), std::wstring()); - delete Tesselator::getInstance(); - return 0; -} - int main(int argc, const char* argv[]) { #if defined(__linux__) && defined(__GLIBC__) struct sigaction sa; @@ -1202,7 +1191,7 @@ void FreeRichPresenceStrings() { vRichPresenceStrings.clear(); } -#ifdef MEMORY_TRACKING +#if 0 // #ifdef MEMORY_TRACKING int totalAllocGen = 0; std::unordered_map allocCounts; From 9fec342554f3c8d7dc9d418071d9b0951352c81b Mon Sep 17 00:00:00 2001 From: Tropical <42101043+tropicaaal@users.noreply.github.com> Date: Wed, 25 Mar 2026 16:32:06 -0500 Subject: [PATCH 003/170] remove TlsAlloc, TlsFree, TlsGetValue, TlsSetValue --- .../Platform/Linux/Stubs/winapi_stubs.h | 22 ------------------- 1 file changed, 22 deletions(-) diff --git a/Minecraft.Client/Platform/Linux/Stubs/winapi_stubs.h b/Minecraft.Client/Platform/Linux/Stubs/winapi_stubs.h index 452562fad..78fe936b2 100644 --- a/Minecraft.Client/Platform/Linux/Stubs/winapi_stubs.h +++ b/Minecraft.Client/Platform/Linux/Stubs/winapi_stubs.h @@ -306,28 +306,6 @@ static inline ULONG TryEnterCriticalSection( return pthread_mutex_trylock(CriticalSection) == 0; } -// https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-tlsalloc -static inline DWORD TlsAlloc(VOID) { - pthread_key_t key; - if (pthread_key_create(&key, NULL) == 0) return key; - return TLS_OUT_OF_INDEXES; -} - -// https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-tlsfree -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 -static inline LPVOID TlsGetValue(DWORD dwTlsIndex) { - return pthread_getspecific(dwTlsIndex); -} - -// https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-tlssetvalue -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 static inline VOID GlobalMemoryStatus(LPMEMORYSTATUS lpBuffer) { // TODO: Parse /proc/meminfo and set lpBuffer based on that. Probably will From 06a4096cf6a904f822ee0456cbe813b33f570422 Mon Sep 17 00:00:00 2001 From: Tropical <42101043+tropicaaal@users.noreply.github.com> Date: Wed, 25 Mar 2026 18:43:10 -0500 Subject: [PATCH 004/170] fix: properly assign new pool to m_tlsPool --- Minecraft.World/Util/AABB.cpp | 2 +- Minecraft.World/Util/Vec3.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Minecraft.World/Util/AABB.cpp b/Minecraft.World/Util/AABB.cpp index 3dff9c23d..f09dbc6f0 100644 --- a/Minecraft.World/Util/AABB.cpp +++ b/Minecraft.World/Util/AABB.cpp @@ -24,7 +24,7 @@ void AABB::CreateNewThreadStorage() { if (m_tlsPoolDefault == nullptr) { m_tlsPoolDefault = tls; } - m_tlsPool = m_tlsPoolDefault; + m_tlsPool = tls; } void AABB::UseDefaultThreadStorage() { m_tlsPool = m_tlsPoolDefault; } diff --git a/Minecraft.World/Util/Vec3.cpp b/Minecraft.World/Util/Vec3.cpp index 7796aba16..fcc922af2 100644 --- a/Minecraft.World/Util/Vec3.cpp +++ b/Minecraft.World/Util/Vec3.cpp @@ -17,7 +17,7 @@ void Vec3::CreateNewThreadStorage() { if (m_tlsPoolDefault == nullptr) { m_tlsPoolDefault = tls; } - m_tlsPool = m_tlsPoolDefault; + m_tlsPool = tls; } void Vec3::UseDefaultThreadStorage() { m_tlsPool = m_tlsPoolDefault; } From 8e94b763a718379fccaae5c9640ee9c0d0c44455 Mon Sep 17 00:00:00 2001 From: Tropical <42101043+tropicaaal@users.noreply.github.com> Date: Wed, 25 Mar 2026 19:12:11 -0500 Subject: [PATCH 005/170] refactor: remove usage of win32 `Sleep` function for `this_thread::sleep_for` --- Minecraft.Client/Level/ServerLevel.cpp | 5 ++- Minecraft.Client/Minecraft.cpp | 12 ++++--- Minecraft.Client/MinecraftServer.cpp | 14 ++++---- Minecraft.Client/Network/ServerChunkCache.cpp | 5 ++- .../Platform/Common/Consoles_App.cpp | 16 +++++---- .../Leaderboards/SonyLeaderboardManager.cpp | 7 ++-- .../Common/Network/GameNetworkManager.cpp | 33 ++++++++++--------- .../Common/Network/Sony/SonyCommerce.cpp | 8 +++-- .../Common/Network/Sony/SonyRemoteStorage.cpp | 5 +-- .../Platform/Common/UI/IUIScene_PauseMenu.cpp | 9 +++-- .../Common/UI/UIScene_LoadOrJoinMenu.cpp | 23 +++++++------ .../Platform/Common/XUI/XUI_Death.cpp | 7 ++-- .../Platform/Common/XUI/XUI_Leaderboards.cpp | 5 ++- .../Common/XUI/XUI_MultiGameJoinLoad.cpp | 4 ++- .../Platform/Common/XUI/XUI_PauseMenu.cpp | 8 +++-- .../Common/XUI/XUI_TransferToXboxOne.cpp | 10 +++--- Minecraft.Client/Rendering/LevelRenderer.cpp | 5 ++- .../IO/Files/ConsoleSaveFileOriginal.cpp | 5 ++- .../IO/Files/ConsoleSaveFileSplit.cpp | 5 ++- .../Level/Storage/McRegionChunkStorage.cpp | 14 +++++--- Minecraft.World/Network/Connection.cpp | 7 ++-- Minecraft.World/Network/Socket.cpp | 11 ++++--- Minecraft.World/Util/C4JThread.cpp | 4 ++- 23 files changed, 144 insertions(+), 78 deletions(-) diff --git a/Minecraft.Client/Level/ServerLevel.cpp b/Minecraft.Client/Level/ServerLevel.cpp index 025190b7f..ece03b701 100644 --- a/Minecraft.Client/Level/ServerLevel.cpp +++ b/Minecraft.Client/Level/ServerLevel.cpp @@ -1,3 +1,6 @@ +#include +#include + #include "../Platform/stdafx.h" #include "ServerLevel.h" #include "../MinecraftServer.h" @@ -1570,7 +1573,7 @@ int ServerLevel::runUpdate(void* lpParam) { } PIXEndNamedEvent(); #ifdef __PS3__ - Sleep(10); + std::this_thread::sleep_for(std::chrono::milliseconds(10)); #endif //__PS3__ } diff --git a/Minecraft.Client/Minecraft.cpp b/Minecraft.Client/Minecraft.cpp index 1e9a1c954..76aab6c96 100644 --- a/Minecraft.Client/Minecraft.cpp +++ b/Minecraft.Client/Minecraft.cpp @@ -1,3 +1,6 @@ +#include +#include + #include "Platform/stdafx.h" #include "Minecraft.h" #include "GameState/GameMode.h" @@ -781,7 +784,7 @@ void Minecraft::run() { this->toggleFullScreen(); } - Sleep(10); + std::this_thread::sleep_for(std::chrono::milliseconds(10)); } */ @@ -796,7 +799,7 @@ void Minecraft::run() achievementPopup->render(); - Sleep(0); // 4J - was Thread.yield() + std::this_thread::sleep_for(std::chrono::milliseconds(0)); // 4J - was Thread.yield()) // if (Keyboard::isKeyDown(Keyboard::KEY_F7)) Display.update(); // 4J - removed condition Display::update(); @@ -2112,7 +2115,7 @@ void Minecraft::run_middle() { { this->toggleFullScreen(); } - Sleep(10); + std::this_thread::sleep_for(std::chrono::milliseconds(10)); } */ @@ -2141,7 +2144,8 @@ void Minecraft::run_middle() { achievementPopup->render(); PIXBeginNamedEvent(0, "Sleeping"); - Sleep(0); // 4J - was Thread.yield() + std::this_thread::sleep_for( + std::chrono::milliseconds(0)); // 4J - was Thread.yield()) PIXEndNamedEvent(); // if (Keyboard::isKeyDown(Keyboard::KEY_F7)) diff --git a/Minecraft.Client/MinecraftServer.cpp b/Minecraft.Client/MinecraftServer.cpp index a08f48ac9..d92e75bd0 100644 --- a/Minecraft.Client/MinecraftServer.cpp +++ b/Minecraft.Client/MinecraftServer.cpp @@ -2,6 +2,8 @@ // #include "Minecraft.h" #include +#include +#include #include "Input/ConsoleInput.h" #include "Level/DerivedServerLevel.h" @@ -229,7 +231,7 @@ bool MinecraftServer::initServer(__int64 seed, NetworkGameInitData* initData, // 4J-JEV: Need to wait for levelGenerationOptions to load. while (app.getLevelGenerationOptions() != NULL && !app.getLevelGenerationOptions()->hasLoadedData()) - Sleep(1); + std::this_thread::sleep_for(std::chrono::milliseconds(1)); if (app.getLevelGenerationOptions() != NULL && !app.getLevelGenerationOptions()->ready()) { @@ -336,7 +338,7 @@ int MinecraftServer::runPostUpdate(void* lpParam) { } else { LeaveCriticalSection(&server->m_postProcessCS); } - Sleep(1); + std::this_thread::sleep_for(std::chrono::milliseconds(1)); } while (!server->m_postUpdateTerminate && ShutdownManager::ShouldRun(ShutdownManager::ePostProcessThread)); // #ifndef __PS3__ @@ -357,7 +359,7 @@ int MinecraftServer::runPostUpdate(void* lpParam) { printf("processing request %00d\n", server->m_postProcessRequests.size()); #endif - Sleep(1); + std::this_thread::sleep_for(std::chrono::milliseconds(1)); #endif EnterCriticalSection(&server->m_postProcessCS); } @@ -1080,7 +1082,7 @@ void MinecraftServer::stopServer(bool didInit) { // files have completed saving. #if defined(_DURANGO) || defined(__ORBIS__) || defined(__PSVITA__) while (StorageManager.GetSaveState() != C4JStorage::ESaveGame_Idle) { - Sleep(10); + std::this_thread::sleep_for(std::chrono::milliseconds(10)); } #endif @@ -1582,7 +1584,7 @@ void MinecraftServer::run(int64_t seed, void* lpParameter) { app.SetXuiServerAction(i, eXuiServerAction_Idle); } - Sleep(1); + std::this_thread::sleep_for(std::chrono::milliseconds(1)); } } // else @@ -1590,7 +1592,7 @@ void MinecraftServer::run(int64_t seed, void* lpParameter) { // while (running) // { // handleConsoleInputs(); - // Sleep(10); + // std::this_thread::sleep_for(std::chrono::milliseconds(10)); // } // } #if 0 diff --git a/Minecraft.Client/Network/ServerChunkCache.cpp b/Minecraft.Client/Network/ServerChunkCache.cpp index a8b5b78c0..68c701155 100644 --- a/Minecraft.Client/Network/ServerChunkCache.cpp +++ b/Minecraft.Client/Network/ServerChunkCache.cpp @@ -1,3 +1,6 @@ +#include +#include + #include "../Platform/stdafx.h" #include "ServerChunkCache.h" #include "../Level/ServerLevel.h" @@ -277,7 +280,7 @@ LevelChunk* ServerChunkCache::create( } #ifdef __PS3__ - Sleep(1); + std::this_thread::sleep_for(std::chrono::milliseconds(1)); #endif // __PS3__ return chunk; } diff --git a/Minecraft.Client/Platform/Common/Consoles_App.cpp b/Minecraft.Client/Platform/Common/Consoles_App.cpp index f85d56632..830578af0 100644 --- a/Minecraft.Client/Platform/Common/Consoles_App.cpp +++ b/Minecraft.Client/Platform/Common/Consoles_App.cpp @@ -1,5 +1,4 @@ - -#include "../Minecraft.World/Platform/stdafx.h" +#include "../Minecraft.World/Platform/stdafx.h" #include "../Minecraft.World/Recipes/Recipy.h" #include "../Minecraft.Client/GameState/Options.h" @@ -69,6 +68,9 @@ #include #endif +#include +#include + #include "Leaderboards/LeaderboardManager.h" // CMinecraftApp app; @@ -4832,7 +4834,7 @@ int CMinecraftApp::SignoutExitWorldThreadProc(void* lpParameter) { // We can't start/join a new game until the session is destroyed, so wait // for it to be idle again while (g_NetworkManager.IsInSession()) { - Sleep(1); + std::this_thread::sleep_for(std::chrono::milliseconds(1)); } return S_OK; @@ -7726,7 +7728,7 @@ int CMinecraftApp::RemoteSaveThreadProc(void* lpParameter) { eAppAction_WaitRemoteServerSaveComplete) { // Tick all the games connections pMinecraft->tickAllConnections(); - Sleep(100); + std::this_thread::sleep_for(std::chrono::milliseconds(100)); } if (app.GetXuiAction(ProfileManager.GetPrimaryPad()) != @@ -9229,7 +9231,8 @@ bool CMinecraftApp::RetrieveNextTMSPPContent() { C4JStorage::ETMSStatus_Fail_ReadInProgress) { app.DebugPrintf( "TMSPP_ReadFile failed - read in progress\n"); - Sleep(50); + std::this_thread::sleep_for( + std::chrono::milliseconds(50)); LeaveCriticalSection(&csTMSPPDownloadQueue); return false; } @@ -9268,7 +9271,8 @@ bool CMinecraftApp::RetrieveNextTMSPPContent() { app.DebugPrintf( "@@@@@@@@@@@@@@@@@ TMSPP_ReadFile failed - busy " "(probably reading already)\n"); - Sleep(50); + std::this_thread::sleep_for( + std::chrono::milliseconds(50)); LeaveCriticalSection(&csTMSPPDownloadQueue); return false; } diff --git a/Minecraft.Client/Platform/Common/Leaderboards/SonyLeaderboardManager.cpp b/Minecraft.Client/Platform/Common/Leaderboards/SonyLeaderboardManager.cpp index 88a4077d9..8153ac650 100644 --- a/Minecraft.Client/Platform/Common/Leaderboards/SonyLeaderboardManager.cpp +++ b/Minecraft.Client/Platform/Common/Leaderboards/SonyLeaderboardManager.cpp @@ -1,5 +1,7 @@ #include "../../stdafx.h" +#include +#include #include #include // #include @@ -54,7 +56,7 @@ SonyLeaderboardManager::~SonyLeaderboardManager() { // 4J-JEV: Wait for thread to stop and hope it doesn't take too long. long long startShutdown = System::currentTimeMillis(); while (m_threadScoreboard->isRunning()) { - Sleep(1); + std::this_thread::sleep_for(std::chrono::milliseconds(1)); assert((System::currentTimeMillis() - startShutdown) < 16); } @@ -87,7 +89,8 @@ int SonyLeaderboardManager::scoreboardThreadEntry(LPVOID lpParam) { } if ((!needsWriting) && (self->m_eStatsState != eStatsState_Getting)) { - Sleep(50); // 4J-JEV: When we're not reading or writing. + std::this_thread::sleep_for(std::chrono::milliseconds( + 50)); // 4J-JEV: When we're not reading or writing. } } while ((self->m_running || self->m_eStatsState == eStatsState_Getting || diff --git a/Minecraft.Client/Platform/Common/Network/GameNetworkManager.cpp b/Minecraft.Client/Platform/Common/Network/GameNetworkManager.cpp index a26addc80..863e864f9 100644 --- a/Minecraft.Client/Platform/Common/Network/GameNetworkManager.cpp +++ b/Minecraft.Client/Platform/Common/Network/GameNetworkManager.cpp @@ -1,3 +1,6 @@ +#include +#include + #include "../../Minecraft.World/Platform/stdafx.h" #include "../../Minecraft.World/Util/StringHelpers.h" #include "../../Minecraft.World/Util/AABB.h" @@ -344,7 +347,7 @@ bool CGameNetworkManager::StartNetworkGame(Minecraft* minecraft, // message I could find pMinecraft->progressRenderer->progressStagePercentage( g_NetworkManager.GetJoiningReadyPercentage()); - Sleep(10); + std::this_thread::sleep_for(std::chrono::milliseconds(10)); } if (changedMessage) { pMinecraft->progressRenderer->progressStagePercentage(100); @@ -367,7 +370,7 @@ bool CGameNetworkManager::StartNetworkGame(Minecraft* minecraft, // this while (!app.DLCInstallProcessCompleted() && app.DLCInstallPending() && !g_NetworkManager.IsLeavingGame()) { - Sleep(10); + std::this_thread::sleep_for(std::chrono::milliseconds(10)); } if (g_NetworkManager.IsLeavingGame()) { MinecraftServer::HaltServer(); @@ -448,7 +451,7 @@ bool CGameNetworkManager::StartNetworkGame(Minecraft* minecraft, // 4J Stu - We were ticking this way too fast which could cause the // connection to time out The connections should tick at 20 per second - Sleep(50); + std::this_thread::sleep_for(std::chrono::milliseconds(50)); } while ((IsInSession() && !connection->isStarted() && !connection->isClosed() && !g_NetworkManager.IsLeavingGame()) || tPack->isLoadingData() || @@ -548,7 +551,7 @@ bool CGameNetworkManager::StartNetworkGame(Minecraft* minecraft, // 4J Stu - We were ticking this way too fast which could cause // the connection to time out The connections should tick at 20 // per second - Sleep(50); + std::this_thread::sleep_for(std::chrono::milliseconds(50)); app.DebugPrintf("<***> %d %d %d %d %d\n", IsInSession(), !connection->isStarted(), !connection->isClosed(), @@ -960,7 +963,7 @@ int CGameNetworkManager::RunNetworkGameThreadProc(void* lpParameter) { while (tPack->isLoadingData() || (Minecraft::GetInstance()->skins->needsUIUpdate() || ui.IsReloadingSkin())) { - Sleep(1); + std::this_thread::sleep_for(std::chrono::milliseconds(1)); } ui.CleanUpSkinReload(); if (app.GetDisconnectReason() == DisconnectPacket::eDisconnect_None) { @@ -978,7 +981,7 @@ int CGameNetworkManager::RunNetworkGameThreadProc(void* lpParameter) { #ifdef __PSVITA__ // 4J-JEV: Wait for the loading/saving to finish. while (StorageManager.GetSaveState() != C4JStorage::ESaveGame_Idle) - Sleep(10); + std::this_thread::sleep_for(std::chrono::milliseconds(10)); #endif Tile::ReleaseThreadStorage(); @@ -1000,7 +1003,7 @@ int CGameNetworkManager::ServerThreadProc(void* lpParameter) { param->texturePackId)) { while ((Minecraft::GetInstance()->skins->needsUIUpdate() || ui.IsReloadingSkin())) { - Sleep(1); + std::this_thread::sleep_for(std::chrono::milliseconds(1)); } param->levelGen->loadBaseSaveData(); } @@ -1041,7 +1044,7 @@ int CGameNetworkManager::ExitAndJoinFromInviteThreadProc(void* lpParam) { UIScene_PauseMenu::_ExitWorld(NULL); while (g_NetworkManager.IsInSession()) { - Sleep(1); + std::this_thread::sleep_for(std::chrono::milliseconds(1)); } // Xbox should always be online when receiving invites - on PS3 we need to @@ -1247,7 +1250,7 @@ int CGameNetworkManager::ChangeSessionTypeThreadProc(void* lpParam) { while (app.GetXuiServerAction(ProfileManager.GetPrimaryPad()) != eXuiServerAction_Idle && !MinecraftServer::serverHalted()) { - Sleep(10); + std::this_thread::sleep_for(std::chrono::milliseconds(10)); } app.SetXuiServerAction(ProfileManager.GetPrimaryPad(), eXuiServerAction_PauseServer, (void*)TRUE); @@ -1287,7 +1290,7 @@ int CGameNetworkManager::ChangeSessionTypeThreadProc(void* lpParam) { // if we don't do this then there's an async thread running doing this, // which could then finish at any inappropriate time later while (s_pPlatformNetworkManager->IsAddingPlayer()) { - Sleep(1); + std::this_thread::sleep_for(std::chrono::milliseconds(1)); } #endif @@ -1318,7 +1321,7 @@ int CGameNetworkManager::ChangeSessionTypeThreadProc(void* lpParam) { // wait for the current session to end while (g_NetworkManager.IsInSession()) { - Sleep(1); + std::this_thread::sleep_for(std::chrono::milliseconds(1)); } // Reset this flag as the we don't need to know that we only lost the room @@ -1348,7 +1351,7 @@ int CGameNetworkManager::ChangeSessionTypeThreadProc(void* lpParam) { // Wait for all the local players to rejoin the session while (g_NetworkManager.GetPlayerCount() < numLocalPlayers) { - Sleep(1); + std::this_thread::sleep_for(std::chrono::milliseconds(1)); } // Restore the network player of all the server players that are local @@ -1398,7 +1401,7 @@ int CGameNetworkManager::ChangeSessionTypeThreadProc(void* lpParam) { // Make sure that we have transitioned through any joining/creating stages // so we're actually ready to set to play while (!s_pPlatformNetworkManager->IsReadyToPlayOrIdle()) { - Sleep(10); + std::this_thread::sleep_for(std::chrono::milliseconds(10)); } #endif @@ -1407,7 +1410,7 @@ int CGameNetworkManager::ChangeSessionTypeThreadProc(void* lpParam) { #ifndef _XBOX // Wait until the message box has been closed while (ui.IsSceneInStack(XUSER_INDEX_ANY, eUIScene_MessageBox)) { - Sleep(10); + std::this_thread::sleep_for(std::chrono::milliseconds(10)); } #endif @@ -1957,7 +1960,7 @@ void CGameNetworkManager::HandleInviteWhenInMenus( #if 0 while( waitHere ) { - Sleep(1); + std::this_thread::sleep_for(std::chrono::milliseconds(1)); } #endif diff --git a/Minecraft.Client/Platform/Common/Network/Sony/SonyCommerce.cpp b/Minecraft.Client/Platform/Common/Network/Sony/SonyCommerce.cpp index 3ce5ec6e0..d6bcd9b2f 100644 --- a/Minecraft.Client/Platform/Common/Network/Sony/SonyCommerce.cpp +++ b/Minecraft.Client/Platform/Common/Network/Sony/SonyCommerce.cpp @@ -1,8 +1,11 @@ +#include +#include +#include + #include "../../../Minecraft.World/Platform/stdafx.h" #include "SonyCommerce.h" #include "../../../../Platform/PS3/PS3Extras/ShutdownManager.h" -#include bool SonyCommerce::m_bCommerceInitialised = false; SceNpCommerce2SessionInfo SonyCommerce::m_sessionInfo; @@ -122,7 +125,8 @@ int SonyCommerce::TickLoop(void* lpParam) { ShutdownManager::ShouldRun(ShutdownManager::eCommerceThread)) { processEvent(); processMessage(); - Sleep(16); // sleep for a frame + std::this_thread::sleep_for( + std::chrono::milliseconds(16)); // sleep for a frame } ShutdownManager::HasFinished(ShutdownManager::eCommerceThread); diff --git a/Minecraft.Client/Platform/Common/Network/Sony/SonyRemoteStorage.cpp b/Minecraft.Client/Platform/Common/Network/Sony/SonyRemoteStorage.cpp index 132c17034..817763b78 100644 --- a/Minecraft.Client/Platform/Common/Network/Sony/SonyRemoteStorage.cpp +++ b/Minecraft.Client/Platform/Common/Network/Sony/SonyRemoteStorage.cpp @@ -1,4 +1,5 @@ - +#include +#include #include "../../../Minecraft.World/Platform/stdafx.h" #include "SonyRemoteStorage.h" @@ -286,7 +287,7 @@ bool SonyRemoteStorage::shutdown() { void SonyRemoteStorage::waitForStorageManagerIdle() { C4JStorage::ESaveGameState storageState = StorageManager.GetSaveState(); while (storageState != C4JStorage::ESaveGame_Idle) { - Sleep(10); + std::this_thread::sleep_for(std::chrono::milliseconds(10)); // app.DebugPrintf(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> // >>>>> storageState = %d\n", storageState); storageState = StorageManager.GetSaveState(); diff --git a/Minecraft.Client/Platform/Common/UI/IUIScene_PauseMenu.cpp b/Minecraft.Client/Platform/Common/UI/IUIScene_PauseMenu.cpp index 65d52d39a..e387901c7 100644 --- a/Minecraft.Client/Platform/Common/UI/IUIScene_PauseMenu.cpp +++ b/Minecraft.Client/Platform/Common/UI/IUIScene_PauseMenu.cpp @@ -1,3 +1,6 @@ +#include +#include + #include "../../Minecraft.World/Platform/stdafx.h" #include "IUIScene_PauseMenu.h" #include "UIScene.h" @@ -394,7 +397,7 @@ int IUIScene_PauseMenu::SaveWorldThreadProc(void* lpParameter) { while (app.GetXuiServerAction(ProfileManager.GetPrimaryPad()) != eXuiServerAction_Idle && !MinecraftServer::serverHalted()) { - Sleep(10); + std::this_thread::sleep_for(std::chrono::milliseconds(10)); } if (!MinecraftServer::serverHalted() && !app.GetChangingSessionType()) @@ -663,7 +666,7 @@ void IUIScene_PauseMenu::_ExitWorld(void* lpParameter) { // multiplayer client if host of the game will exit during the clients // loading to created world. while (g_NetworkManager.IsNetworkThreadRunning()) { - Sleep(1); + std::this_thread::sleep_for(std::chrono::milliseconds(1)); } pMinecraft->setLevel(NULL, exitReasonStringId, nullptr, saveStats); @@ -683,7 +686,7 @@ void IUIScene_PauseMenu::_ExitWorld(void* lpParameter) { // loads saved data We can't start/join a new game until the session is // destroyed, so wait for it to be idle again while (g_NetworkManager.IsInSession()) { - Sleep(1); + std::this_thread::sleep_for(std::chrono::milliseconds(1)); } app.SetChangingSessionType(false); diff --git a/Minecraft.Client/Platform/Common/UI/UIScene_LoadOrJoinMenu.cpp b/Minecraft.Client/Platform/Common/UI/UIScene_LoadOrJoinMenu.cpp index 563124002..31e09f0fb 100644 --- a/Minecraft.Client/Platform/Common/UI/UIScene_LoadOrJoinMenu.cpp +++ b/Minecraft.Client/Platform/Common/UI/UIScene_LoadOrJoinMenu.cpp @@ -1,3 +1,6 @@ +#include +#include + #include "../../Minecraft.World/Platform/stdafx.h" #include "UI.h" #include "UIScene_LoadOrJoinMenu.h" @@ -2229,7 +2232,7 @@ int UIScene_LoadOrJoinMenu::MustSignInReturnedTexturePack(void* pParam, while (commerceState != CConsoleMinecraftApp::eCommerce_State_Offline && commerceState != CConsoleMinecraftApp::eCommerce_State_Online && commerceState != CConsoleMinecraftApp::eCommerce_State_Error) { - Sleep(10); + std::this_thread::sleep_for(std::chrono::milliseconds(10)); commerceState = app.GetCommerceState(); } @@ -2852,7 +2855,7 @@ int UIScene_LoadOrJoinMenu::DownloadSonyCrossSaveThreadProc(void* lpParameter) { #if defined(_DURANGO) || defined(__ORBIS__) while (StorageManager.GetSaveState() != C4JStorage::ESaveGame_Idle) { - Sleep(10); + std::this_thread::sleep_for(std::chrono::milliseconds(10)); StorageManager.Tick(); } #endif @@ -2999,7 +3002,7 @@ int UIScene_LoadOrJoinMenu::DownloadSonyCrossSaveThreadProc(void* lpParameter) { // waiting to dismiss the dialog break; } - Sleep(50); + std::this_thread::sleep_for(std::chrono::milliseconds(50)); } m_bSaveTransferRunning = false; #ifdef __PS3__ @@ -3151,7 +3154,7 @@ int UIScene_LoadOrJoinMenu::UploadSonyCrossSaveThreadProc(void* lpParameter) { // waiting for dialog to be dismissed break; } - Sleep(50); + std::this_thread::sleep_for(std::chrono::milliseconds(50)); } return 0; @@ -3247,7 +3250,7 @@ int UIScene_LoadOrJoinMenu::DownloadXbox360SaveThreadProc(void* lpParameter) { while (StorageManager.SaveTransferClearState() != C4JStorage::eSaveTransfer_Idle) { - Sleep(5); + std::this_thread::sleep_for(std::chrono::milliseconds(5)); } pStateContainer->m_bSaveTransferInProgress = true; @@ -3432,7 +3435,7 @@ int UIScene_LoadOrJoinMenu::DownloadXbox360SaveThreadProc(void* lpParameter) { while (StorageManager.GetSaveState() != C4JStorage::ESaveGame_Idle) { - Sleep(10); + std::this_thread::sleep_for(std::chrono::milliseconds(10)); // 4J Stu - DO NOT tick this here. The main thread should be // the only place ticking the StorageManager. You WILL get @@ -3470,7 +3473,7 @@ int UIScene_LoadOrJoinMenu::DownloadXbox360SaveThreadProc(void* lpParameter) { break; } - Sleep(50); + std::this_thread::sleep_for(std::chrono::milliseconds(50)); } if (pStateContainer->m_bSaveTransferCancelled) { @@ -3517,7 +3520,7 @@ void UIScene_LoadOrJoinMenu::RequestFileSize(SaveTransferStateContainer* pClass, IDS_SAVETRANSFER_TITLE_GET); pMinecraft->progressRenderer->progressStage( IDS_SAVETRANSFER_STAGE_GET_DETAILS); - Sleep(1); + std::this_thread::sleep_for(std::chrono::milliseconds(1)); pClass->m_eSaveTransferState = StorageManager.SaveTransferGetDetails( pClass->m_iPad, C4JStorage::eGlobalStorage_TitleUser, @@ -3573,7 +3576,7 @@ void UIScene_LoadOrJoinMenu::RequestFileData(SaveTransferStateContainer* pClass, pMinecraft->progressRenderer->progressStart( IDS_SAVETRANSFER_TITLE_GET); pMinecraft->progressRenderer->progressStage(-1); - Sleep(1); + std::this_thread::sleep_for(std::chrono::milliseconds(1)); pClass->m_eSaveTransferState = StorageManager.SaveTransferGetData( pClass->m_iPad, C4JStorage::eGlobalStorage_TitleUser, filename, &UIScene_LoadOrJoinMenu::SaveTransferReturned, @@ -3740,7 +3743,7 @@ int UIScene_LoadOrJoinMenu::CopySaveThreadProc(void* lpParameter) { bool bContinue = true; do { - Sleep(100); + std::this_thread::sleep_for(std::chrono::milliseconds(100)); ui.EnterCallbackIdCriticalSection(); pClass = (UIScene_LoadOrJoinMenu*)ui.GetSceneFromCallbackId( (size_t)lpParameter); diff --git a/Minecraft.Client/Platform/Common/XUI/XUI_Death.cpp b/Minecraft.Client/Platform/Common/XUI/XUI_Death.cpp index 7902b427a..45d6f58a7 100644 --- a/Minecraft.Client/Platform/Common/XUI/XUI_Death.cpp +++ b/Minecraft.Client/Platform/Common/XUI/XUI_Death.cpp @@ -1,9 +1,12 @@ // Minecraft.cpp : Defines the entry point for the application. // +#include +#include +#include + #include "../../Minecraft.World/Platform/stdafx.h" #include "XUI_Death.h" -#include #include "../../Minecraft.World/Util/AABB.h" #include "../../Minecraft.World/Util/Vec3.h" #include "../../Minecraft.World/Headers/net.minecraft.stats.h" @@ -235,7 +238,7 @@ int CScene_Death::RespawnThreadProc(void* lpParameter) { // If we are offline, this should release straight away // WaitForSingleObject( pMinecraft->m_hPlayerRespawned, INFINITE ); while (pMinecraft->localplayers[iPad]->GetPlayerRespawned() == false) { - Sleep(50); + std::this_thread::sleep_for(std::chrono::milliseconds(50)); } return S_OK; diff --git a/Minecraft.Client/Platform/Common/XUI/XUI_Leaderboards.cpp b/Minecraft.Client/Platform/Common/XUI/XUI_Leaderboards.cpp index 193ea0a01..978ca2335 100644 --- a/Minecraft.Client/Platform/Common/XUI/XUI_Leaderboards.cpp +++ b/Minecraft.Client/Platform/Common/XUI/XUI_Leaderboards.cpp @@ -7,6 +7,9 @@ #include "XUI_Ctrl_CraftIngredientSlot.h" #include "XUI_XZP_Icons.h" +#include +#include + LPCWSTR CScene_Leaderboards::m_TitleIconNameA[7] = { L"XuiHSlot1", L"XuiHSlot2", L"XuiHSlot3", L"XuiHSlot4", L"XuiHSlot5", L"XuiHSlot6", L"XuiHSlot7", @@ -283,7 +286,7 @@ HRESULT CScene_Leaderboards::OnDestroy() { app.SetLiveLinkRequired(false); while (m_isProcessingStatsRead) { - Sleep(10); + std::this_thread::sleep_for(std::chrono::milliseconds(10)); } if (m_friends != NULL) delete[] m_friends; diff --git a/Minecraft.Client/Platform/Common/XUI/XUI_MultiGameJoinLoad.cpp b/Minecraft.Client/Platform/Common/XUI/XUI_MultiGameJoinLoad.cpp index 2e07152e6..d9fb16f46 100644 --- a/Minecraft.Client/Platform/Common/XUI/XUI_MultiGameJoinLoad.cpp +++ b/Minecraft.Client/Platform/Common/XUI/XUI_MultiGameJoinLoad.cpp @@ -1,6 +1,8 @@ #include "../../Minecraft.World/Platform/stdafx.h" #include #include +#include +#include #include #include "../../Minecraft.World/Util/StringHelpers.h" #include "../Tutorial/TutorialMode.h" @@ -2174,7 +2176,7 @@ bool CScene_MultiGameJoinLoad::WaitForTransferComplete( // cancelled return false; } - Sleep(50); + std::this_thread::sleep_for(std::chrono::milliseconds(50)); // update the progress pMinecraft->progressRenderer->progressStagePercentage( (unsigned int)(pClass->m_fProgress * 100.0f)); diff --git a/Minecraft.Client/Platform/Common/XUI/XUI_PauseMenu.cpp b/Minecraft.Client/Platform/Common/XUI/XUI_PauseMenu.cpp index d77644991..edfb1ce3c 100644 --- a/Minecraft.Client/Platform/Common/XUI/XUI_PauseMenu.cpp +++ b/Minecraft.Client/Platform/Common/XUI/XUI_PauseMenu.cpp @@ -4,6 +4,8 @@ #include "../../Minecraft.World/Platform/stdafx.h" #include +#include +#include #include "../../Minecraft.World/Util/AABB.h" #include "../../Minecraft.World/Util/Vec3.h" #include "../../Minecraft.World/Headers/net.minecraft.stats.h" @@ -1087,7 +1089,7 @@ int UIScene_PauseMenu::SaveWorldThreadProc(LPVOID lpParameter) { while (app.GetXuiServerAction(ProfileManager.GetPrimaryPad()) != eXuiServerAction_Idle && !MinecraftServer::serverHalted()) { - Sleep(10); + std::this_thread::sleep_for(std::chrono::milliseconds(10)); } if (!MinecraftServer::serverHalted() && !app.GetChangingSessionType()) @@ -1297,7 +1299,7 @@ void UIScene_PauseMenu::_ExitWorld(LPVOID lpParameter) { // multiplayer client if host of the game will exit during the clients // loading to created world. while (g_NetworkManager.IsNetworkThreadRunning()) { - Sleep(1); + std::this_thread::sleep_for(std::chrono::milliseconds(1)); } pMinecraft->setLevel(NULL, exitReasonStringId, nullptr, saveStats); @@ -1317,7 +1319,7 @@ void UIScene_PauseMenu::_ExitWorld(LPVOID lpParameter) { // loads saved data We can't start/join a new game until the session is // destroyed, so wait for it to be idle again while (g_NetworkManager.IsInSession()) { - Sleep(1); + std::this_thread::sleep_for(std::chrono::milliseconds(1)); } app.SetChangingSessionType(false); diff --git a/Minecraft.Client/Platform/Common/XUI/XUI_TransferToXboxOne.cpp b/Minecraft.Client/Platform/Common/XUI/XUI_TransferToXboxOne.cpp index 178c3607f..1dd0cc64d 100644 --- a/Minecraft.Client/Platform/Common/XUI/XUI_TransferToXboxOne.cpp +++ b/Minecraft.Client/Platform/Common/XUI/XUI_TransferToXboxOne.cpp @@ -2,6 +2,8 @@ #include #include #include +#include +#include #include "XUI_Ctrl_4JList.h" #include "XUI_Ctrl_4JIcon.h" @@ -363,7 +365,7 @@ int CScene_TransferToXboxOne::UploadSaveForXboxOneThreadProc( // loop waiting for the write to complete uiComplete = 0; while (pClass->m_bWaitingForWrite && (hr == S_OK)) { - Sleep(50); + std::this_thread::sleep_for(std::chrono::milliseconds(50)); uiComplete++; if (uiComplete > 100) uiComplete = 100; @@ -380,7 +382,7 @@ int CScene_TransferToXboxOne::UploadSaveForXboxOneThreadProc( // finish the bar for (int i = uiComplete; i < 100; i++) { - Sleep(5); + std::this_thread::sleep_for(std::chrono::milliseconds(5)); pMinecraft->progressRenderer->progressStagePercentage(i); } @@ -396,7 +398,7 @@ int CScene_TransferToXboxOne::UploadSaveForXboxOneThreadProc( // sleep until we have the data while (pClass->m_bSaveDataReceived == false) { - Sleep(50); + std::this_thread::sleep_for(std::chrono::milliseconds(50)); } // write the save to user TMS @@ -443,7 +445,7 @@ int CScene_TransferToXboxOne::UploadSaveForXboxOneThreadProc( } else { // loop waiting for the write to complete while (pClass->m_bWaitingForWrite && (hr == S_OK)) { - Sleep(50); + std::this_thread::sleep_for(std::chrono::milliseconds(50)); } uiComplete += uiPercentageChunk; if (uiComplete > 100) uiComplete = 100; diff --git a/Minecraft.Client/Rendering/LevelRenderer.cpp b/Minecraft.Client/Rendering/LevelRenderer.cpp index 313922573..eeb04049e 100644 --- a/Minecraft.Client/Rendering/LevelRenderer.cpp +++ b/Minecraft.Client/Rendering/LevelRenderer.cpp @@ -1,3 +1,6 @@ +#include +#include + #include "../Platform/stdafx.h" #include "LevelRenderer.h" #include "../Textures/Textures.h" @@ -2321,7 +2324,7 @@ bool LevelRenderer::updateDirtyChunks() { } LeaveCriticalSection(&m_csDirtyChunks); #ifdef __PS3__ - Sleep(5); + std::this_thread::sleep_for(std::chrono::milliseconds(5)); #endif // __PS3__ return false; } diff --git a/Minecraft.World/IO/Files/ConsoleSaveFileOriginal.cpp b/Minecraft.World/IO/Files/ConsoleSaveFileOriginal.cpp index bc54c3e07..a24829c80 100644 --- a/Minecraft.World/IO/Files/ConsoleSaveFileOriginal.cpp +++ b/Minecraft.World/IO/Files/ConsoleSaveFileOriginal.cpp @@ -1,3 +1,6 @@ +#include +#include + #include "../../Platform/stdafx.h" #include "../../Util/StringHelpers.h" #include "../../Util/PortableFileIO.h" @@ -664,7 +667,7 @@ void ConsoleSaveFileOriginal::Flush(bool autosave, bool updateThumbnail) { // save/save-exiting so seems prudent to wait for idle while (StorageManager.GetSaveState() != C4JStorage::ESaveGame_Idle) { app.DebugPrintf("Flush wait\n"); - Sleep(10); + std::this_thread::sleep_for(std::chrono::milliseconds(10)); } #endif diff --git a/Minecraft.World/IO/Files/ConsoleSaveFileSplit.cpp b/Minecraft.World/IO/Files/ConsoleSaveFileSplit.cpp index 00690c559..9ee5cc552 100644 --- a/Minecraft.World/IO/Files/ConsoleSaveFileSplit.cpp +++ b/Minecraft.World/IO/Files/ConsoleSaveFileSplit.cpp @@ -1,3 +1,6 @@ +#include +#include + #include "../../Platform/stdafx.h" #include "../../Util/StringHelpers.h" #include "../../Util/PortableFileIO.h" @@ -1298,7 +1301,7 @@ void ConsoleSaveFileSplit::Flush(bool autosave, bool updateThumbnail) { #endif app.DebugPrintf("Flush wait\n"); - Sleep(10); + std::this_thread::sleep_for(std::chrono::milliseconds(10)); } finalizeWrite(); diff --git a/Minecraft.World/Level/Storage/McRegionChunkStorage.cpp b/Minecraft.World/Level/Storage/McRegionChunkStorage.cpp index cef015625..a0bc150e5 100644 --- a/Minecraft.World/Level/Storage/McRegionChunkStorage.cpp +++ b/Minecraft.World/Level/Storage/McRegionChunkStorage.cpp @@ -1,3 +1,6 @@ +#include +#include + #include "../../Platform/stdafx.h" #include "../../Headers/net.minecraft.world.level.h" #include "../../IO/Files/ConsoleSaveFileIO.h" @@ -388,9 +391,10 @@ int McRegionChunkStorage::runSaveThreadProc(void* lpParam) { // If there was more than one thing in the queue last time we checked, // then we want to spin round again soon Otherwise wait a bit longer if ((lastQueueSize - 1) > 0) - Sleep(1); // Sleep 1 to yield + std::this_thread::sleep_for( + std::chrono::milliseconds(1)); // Sleep 1 to yield else - Sleep(100); + std::this_thread::sleep_for(std::chrono::milliseconds(100)); } Compression::ReleaseThreadStorage(); @@ -410,7 +414,7 @@ void McRegionChunkStorage::WaitForAllSaves() { LeaveCriticalSection(&cs_memory); while (queueSize > 0) { - Sleep(10); + std::this_thread::sleep_for(std::chrono::milliseconds(10)); EnterCriticalSection(&cs_memory); queueSize = s_chunkDataQueue.size(); @@ -424,7 +428,7 @@ void McRegionChunkStorage::WaitForAllSaves() { LeaveCriticalSection(&cs_memory); while (runningThreadCount > 0) { - Sleep(10); + std::this_thread::sleep_for(std::chrono::milliseconds(10)); EnterCriticalSection(&cs_memory); runningThreadCount = s_runningThreadCount; @@ -444,7 +448,7 @@ void McRegionChunkStorage::WaitForSaves() { if (queueSize > MAX_QUEUE_SIZE) { while (queueSize > DESIRED_QUEUE_SIZE) { - Sleep(10); + std::this_thread::sleep_for(std::chrono::milliseconds(10)); EnterCriticalSection(&cs_memory); queueSize = s_chunkDataQueue.size(); diff --git a/Minecraft.World/Network/Connection.cpp b/Minecraft.World/Network/Connection.cpp index 942634ed9..66ba0998f 100644 --- a/Minecraft.World/Network/Connection.cpp +++ b/Minecraft.World/Network/Connection.cpp @@ -1,3 +1,6 @@ +#include +#include + #include "../Platform/stdafx.h" #include "../IO/Streams/InputOutputStream.h" #include "Socket.h" @@ -577,7 +580,7 @@ int Connection::runRead(void* lpParam) { while (con->readTick()); // try { - // Sleep(100L); + // std::this_thread::sleep_for(std::chrono::milliseconds(100L)); // TODO - 4J Stu - 1.8.2 changes these sleeps to 2L, but not sure // whether we should do that as well con->m_hWakeReadThread->WaitForSignal(100L); @@ -626,7 +629,7 @@ int Connection::runWrite(void* lpParam) { ShutdownManager::ShouldRun(ShutdownManager::eConnectionWriteThreads)) { while (con->writeTick()); - // Sleep(100L); + // std::this_thread::sleep_for(std::chrono::milliseconds(100L)); // TODO - 4J Stu - 1.8.2 changes these sleeps to 2L, but not sure // whether we should do that as well waitResult = con->m_hWakeWriteThread->WaitForSignal(100L); diff --git a/Minecraft.World/Network/Socket.cpp b/Minecraft.World/Network/Socket.cpp index 0d032886c..6606dda77 100644 --- a/Minecraft.World/Network/Socket.cpp +++ b/Minecraft.World/Network/Socket.cpp @@ -1,3 +1,6 @@ +#include +#include + #include "../Platform/stdafx.h" #include "../IO/Streams/InputOutputStream.h" #include "SocketAddress.h" @@ -250,7 +253,7 @@ int Socket::SocketInputStreamLocal::read() { } LeaveCriticalSection(&s_hostQueueLock[m_queueIdx]); } - Sleep(1); + std::this_thread::sleep_for(std::chrono::milliseconds(1)); } return -1; } @@ -277,7 +280,7 @@ int Socket::SocketInputStreamLocal::read(byteArray b, unsigned int offset, } LeaveCriticalSection(&s_hostQueueLock[m_queueIdx]); } - Sleep(1); + std::this_thread::sleep_for(std::chrono::milliseconds(1)); } return -1; } @@ -356,7 +359,7 @@ int Socket::SocketInputStreamNetwork::read() { } LeaveCriticalSection(&m_socket->m_queueLockNetwork[m_queueIdx]); } - Sleep(1); + std::this_thread::sleep_for(std::chrono::milliseconds(1)); } return -1; } @@ -385,7 +388,7 @@ int Socket::SocketInputStreamNetwork::read(byteArray b, unsigned int offset, } LeaveCriticalSection(&m_socket->m_queueLockNetwork[m_queueIdx]); } - Sleep(1); + std::this_thread::sleep_for(std::chrono::milliseconds(1)); } return -1; } diff --git a/Minecraft.World/Util/C4JThread.cpp b/Minecraft.World/Util/C4JThread.cpp index ace672d19..eccfdfcaa 100644 --- a/Minecraft.World/Util/C4JThread.cpp +++ b/Minecraft.World/Util/C4JThread.cpp @@ -1,6 +1,8 @@ #include "../Platform/stdafx.h" #include "C4JThread.h" +#include +#include #ifdef __PSVITA__ #include "../../Minecraft.Client/Platform/PSVita/PSVitaExtras/ShutdownManager.h" #include "../../Minecraft.Client/Platform/PSVita/PSVitaExtras/PSVitaTLSStorage.h" @@ -443,7 +445,7 @@ void C4JThread::Sleep(int millisecs) { // 4J Stu - 0 is an error, so add a tiny sleep when we just want to yield sceKernelDelayThread(millisecs * 1000 + 1); #else - ::Sleep(millisecs); + std::this_thread::sleep_for(std::chrono::milliseconds(millisecs)); #endif // __PS3__ } From d9f03fdddf5cdf426f6d1ca80177177313462b9e Mon Sep 17 00:00:00 2001 From: Tropical <42101043+tropicaaal@users.noreply.github.com> Date: Wed, 25 Mar 2026 19:13:12 -0500 Subject: [PATCH 006/170] refactor: replace 0ms sleep with a proper yield --- Minecraft.Client/Minecraft.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Minecraft.Client/Minecraft.cpp b/Minecraft.Client/Minecraft.cpp index 76aab6c96..dfd39cd8e 100644 --- a/Minecraft.Client/Minecraft.cpp +++ b/Minecraft.Client/Minecraft.cpp @@ -2144,8 +2144,10 @@ void Minecraft::run_middle() { achievementPopup->render(); PIXBeginNamedEvent(0, "Sleeping"); - std::this_thread::sleep_for( - std::chrono::milliseconds(0)); // 4J - was Thread.yield()) + std::this_thread::yield_now(); // 4jcraft added now that we have + // portable thread yield. + // std::this_thread::sleep_for( + // std::chrono::milliseconds(0)); // 4J - was Thread.yield()) PIXEndNamedEvent(); // if (Keyboard::isKeyDown(Keyboard::KEY_F7)) From caf7128d5889999e75cbe314f66b314afd0939e9 Mon Sep 17 00:00:00 2001 From: Tropical <42101043+tropicaaal@users.noreply.github.com> Date: Wed, 25 Mar 2026 19:14:53 -0500 Subject: [PATCH 007/170] refactor: remove `Sleep` from winapi_stubs --- Minecraft.Client/Platform/Linux/Stubs/winapi_stubs.h | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/Minecraft.Client/Platform/Linux/Stubs/winapi_stubs.h b/Minecraft.Client/Platform/Linux/Stubs/winapi_stubs.h index 452562fad..a2f76c701 100644 --- a/Minecraft.Client/Platform/Linux/Stubs/winapi_stubs.h +++ b/Minecraft.Client/Platform/Linux/Stubs/winapi_stubs.h @@ -336,17 +336,6 @@ static inline VOID GlobalMemoryStatus(LPMEMORYSTATUS lpBuffer) { static inline DWORD GetLastError(VOID) { return errno; } -static inline 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); -} - static inline LONG64 InterlockedCompareExchangeRelease64( LONG64 volatile* Destination, LONG64 Exchange, LONG64 Comperand) { LONG64 expected = Comperand; From b598aa9232c11939e2a5b18681976be0b9385015 Mon Sep 17 00:00:00 2001 From: Tropical <42101043+tropicaaal@users.noreply.github.com> Date: Wed, 25 Mar 2026 19:20:18 -0500 Subject: [PATCH 008/170] fix: only use `InterlockedCompareExchangeRelease64` on LP64 systems --- Minecraft.Client/Platform/Linux/Stubs/winapi_stubs.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/Minecraft.Client/Platform/Linux/Stubs/winapi_stubs.h b/Minecraft.Client/Platform/Linux/Stubs/winapi_stubs.h index a2f76c701..5aea5dc23 100644 --- a/Minecraft.Client/Platform/Linux/Stubs/winapi_stubs.h +++ b/Minecraft.Client/Platform/Linux/Stubs/winapi_stubs.h @@ -336,6 +336,7 @@ static inline VOID GlobalMemoryStatus(LPMEMORYSTATUS lpBuffer) { static inline DWORD GetLastError(VOID) { return errno; } +#ifdef __LP64__ static inline LONG64 InterlockedCompareExchangeRelease64( LONG64 volatile* Destination, LONG64 Exchange, LONG64 Comperand) { LONG64 expected = Comperand; @@ -343,6 +344,15 @@ static inline LONG64 InterlockedCompareExchangeRelease64( __ATOMIC_RELEASE, __ATOMIC_RELAXED); return expected; } +#else +static inline LONG64 InterlockedCompareExchangeRelease( + LONG volatile* Destination, LONG Exchange, LONG Comperand) { + LONG expected = Comperand; + __atomic_compare_exchange_n(Destination, &expected, Exchange, false, + __ATOMIC_RELEASE, __ATOMIC_RELAXED); + return expected; +} +#endif // internal helper: convert time_t to FILETIME (100ns intervals since // 1601-01-01) From cbca0280b4baf31e8b48ebb51f8911e218097b3b Mon Sep 17 00:00:00 2001 From: Tropical <42101043+tropicaaal@users.noreply.github.com> Date: Wed, 25 Mar 2026 19:21:36 -0500 Subject: [PATCH 009/170] rust brainrot --- Minecraft.Client/Minecraft.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Minecraft.Client/Minecraft.cpp b/Minecraft.Client/Minecraft.cpp index dfd39cd8e..c1dcecf01 100644 --- a/Minecraft.Client/Minecraft.cpp +++ b/Minecraft.Client/Minecraft.cpp @@ -2144,8 +2144,8 @@ void Minecraft::run_middle() { achievementPopup->render(); PIXBeginNamedEvent(0, "Sleeping"); - std::this_thread::yield_now(); // 4jcraft added now that we have - // portable thread yield. + std::this_thread::yield(); // 4jcraft added now that we have + // portable thread yield. // std::this_thread::sleep_for( // std::chrono::milliseconds(0)); // 4J - was Thread.yield()) PIXEndNamedEvent(); From 7b021bc99daceee61633b14d7d36100e0471ffb3 Mon Sep 17 00:00:00 2001 From: orng Date: Thu, 26 Mar 2026 01:10:27 -0500 Subject: [PATCH 010/170] wip: removing vec3 tls --- Minecraft.Client/Minecraft.cpp | 4 +- Minecraft.Client/Network/PlayerConnection.cpp | 3 +- .../spirit/home/lex/lexer/lexertl/lexer.hpp | 658 +++++++------- .../PS3/SPU_Tasks/ChunkUpdate/Tile_SPU.cpp | 802 +++++++++--------- Minecraft.Client/Player/LocalPlayer.cpp | 2 +- .../Rendering/Culling/DirtyChunkSorter.cpp | 2 +- .../EntityRenderers/LivingEntityRenderer.cpp | 2 +- .../EntityRenderers/MinecartRenderer.cpp | 7 +- Minecraft.Client/Rendering/GameRenderer.cpp | 9 +- Minecraft.Client/Rendering/Lighting.cpp | 8 +- Minecraft.Client/Rendering/Polygon.cpp | 12 +- Minecraft.World/AI/Goals/AvoidPlayerGoal.cpp | 2 +- Minecraft.World/AI/Goals/BegGoal.cpp | 2 +- Minecraft.World/AI/Goals/FollowOwnerGoal.cpp | 2 +- Minecraft.World/AI/Goals/LeapAtTargetGoal.cpp | 2 +- Minecraft.World/AI/Goals/LookAtPlayerGoal.cpp | 2 +- Minecraft.World/AI/Goals/MoveIndoorsGoal.cpp | 2 +- .../AI/Goals/MoveTowardsTargetGoal.cpp | 2 +- .../AI/Goals/NearestAttackableTargetGoal.cpp | 2 +- Minecraft.World/AI/Goals/OcelotAttackGoal.cpp | 2 +- Minecraft.World/AI/Goals/SitGoal.cpp | 2 +- Minecraft.World/AI/Goals/TakeFlowerGoal.cpp | 2 +- Minecraft.World/AI/Goals/TargetGoal.cpp | 2 +- Minecraft.World/AI/Goals/TemptGoal.cpp | 2 +- .../AI/Goals/TradeWithPlayerGoal.cpp | 2 +- Minecraft.World/AI/Navigation/PathFinder.cpp | 2 +- .../AI/Navigation/PathNavigation.cpp | 6 +- Minecraft.World/Blocks/LiquidTile.cpp | 10 +- Minecraft.World/Blocks/StairTile.cpp | 2 +- Minecraft.World/Blocks/Tile.cpp | 82 +- .../Containers/HorseInventoryMenu.cpp | 2 +- Minecraft.World/Entities/Entity.cpp | 2 +- Minecraft.World/Entities/Entity.h | 1 + Minecraft.World/Entities/LivingEntity.cpp | 6 +- .../Entities/MinecartContainer.cpp | 2 +- Minecraft.World/Entities/Mobs/Arrow.cpp | 8 +- .../Entities/Mobs/DragonFireball.cpp | 2 +- Minecraft.World/Entities/Mobs/EnderDragon.cpp | 47 +- Minecraft.World/Entities/Mobs/EnderMan.cpp | 12 +- .../Entities/Mobs/ExperienceOrb.cpp | 2 +- Minecraft.World/Entities/Mobs/Fireball.cpp | 4 +- Minecraft.World/Entities/Mobs/FishingHook.cpp | 4 +- Minecraft.World/Entities/Mobs/Ghast.cpp | 2 +- Minecraft.World/Entities/Mobs/Minecart.cpp | 37 +- Minecraft.World/Entities/Mobs/Ocelot.cpp | 2 +- Minecraft.World/Entities/Mobs/Slime.cpp | 2 +- .../Entities/Mobs/ThrownPotion.cpp | 2 +- Minecraft.World/Entities/Mobs/Witch.cpp | 2 +- Minecraft.World/Entities/Mobs/WitherBoss.cpp | 2 +- Minecraft.World/Entities/PathfinderMob.cpp | 2 +- Minecraft.World/Entities/Throwable.cpp | 4 +- Minecraft.World/Items/BoatItem.cpp | 9 +- Minecraft.World/Items/Item.cpp | 4 +- Minecraft.World/Level/ChunkPos.h | 2 +- Minecraft.World/Level/Level.cpp | 2 +- Minecraft.World/Level/RandomLevelSource.cpp | 8 +- Minecraft.World/Player/Player.cpp | 4 +- Minecraft.World/Util/AABB.cpp | 89 +- Minecraft.World/Util/HitResult.cpp | 14 +- Minecraft.World/Util/HitResult.h | 6 +- Minecraft.World/Util/Vec3.cpp | 146 ++-- Minecraft.World/Util/Vec3.h | 45 +- 62 files changed, 1070 insertions(+), 1045 deletions(-) diff --git a/Minecraft.Client/Minecraft.cpp b/Minecraft.Client/Minecraft.cpp index 1e9a1c954..c8d90e7db 100644 --- a/Minecraft.Client/Minecraft.cpp +++ b/Minecraft.Client/Minecraft.cpp @@ -2750,7 +2750,7 @@ void Minecraft::tick(bool bFirst, bool bUpdateTextures) { // 4J-PB - Call the useItemOn with the TestOnly flag set bool bUseItemOn = gameMode->useItemOn( player, level, itemInstance, x, y, z, face, - hitResult->pos, true); + &hitResult->pos, true); /* 4J-Jev: * Moved this here so we have item tooltips to @@ -3900,7 +3900,7 @@ void Minecraft::tick(bool bFirst, bool bUpdateTextures) { bool usedItem = false; gameMode->useItemOn(player, level, nullptr, hitResult->x, hitResult->y, hitResult->z, 0, - hitResult->pos, false, &usedItem); + &hitResult->pos, false, &usedItem); } else { ui.PlayUISFX(eSFX_Press); app.LoadCrafting2x2Menu(iPad, player); diff --git a/Minecraft.Client/Network/PlayerConnection.cpp b/Minecraft.Client/Network/PlayerConnection.cpp index 0e5038d86..9f5e861e8 100644 --- a/Minecraft.Client/Network/PlayerConnection.cpp +++ b/Minecraft.Client/Network/PlayerConnection.cpp @@ -1551,7 +1551,8 @@ void PlayerConnection::handlePlayerAbilities( // StringBuilder result = new StringBuilder(); // for (String candidate : server.getAutoCompletions(player, -//packet.getMessage())) { if (result.length() > 0) result.append("\0"); +// packet.getMessage())) { if (result.length() > 0) +// result.append("\0"); // result.append(candidate); // } diff --git a/Minecraft.Client/Platform/PS3/PS3Extras/boost_1_53_0/boost/spirit/home/lex/lexer/lexertl/lexer.hpp b/Minecraft.Client/Platform/PS3/PS3Extras/boost_1_53_0/boost/spirit/home/lex/lexer/lexertl/lexer.hpp index 0f8af55d0..f73cb4e09 100644 --- a/Minecraft.Client/Platform/PS3/PS3Extras/boost_1_53_0/boost/spirit/home/lex/lexer/lexertl/lexer.hpp +++ b/Minecraft.Client/Platform/PS3/PS3Extras/boost_1_53_0/boost/spirit/home/lex/lexer/lexertl/lexer.hpp @@ -27,373 +27,359 @@ #include -namespace boost { namespace spirit { namespace lex { namespace lexertl -{ - /////////////////////////////////////////////////////////////////////////// - namespace detail - { - /////////////////////////////////////////////////////////////////////// - // The must_escape function checks if the given character value needs - // to be preceded by a backslash character to disable its special - // meaning in the context of a regular expression - /////////////////////////////////////////////////////////////////////// - template - inline bool must_escape(Char c) - { - // FIXME: more needed? - switch (c) { - case '+': case '/': case '*': case '?': - case '|': - case '(': case ')': - case '[': case ']': - case '{': case '}': - case '.': - case '^': case '$': - case '\\': - case '"': - return true; +namespace boost { +namespace spirit { +namespace lex { +namespace lexertl { +/////////////////////////////////////////////////////////////////////////// +namespace detail { +/////////////////////////////////////////////////////////////////////// +// The must_escape function checks if the given character value needs +// to be preceded by a backslash character to disable its special +// meaning in the context of a regular expression +/////////////////////////////////////////////////////////////////////// +template +inline bool must_escape(Char c) { + // FIXME: more needed? + switch (c) { + case '+': + case '/': + case '*': + case '?': + case '|': + case '(': + case ')': + case '[': + case ']': + case '{': + case '}': + case '.': + case '^': + case '$': + case '\\': + case '"': + return true; - default: - break; - } - return false; - } + default: + break; + } + return false; +} - /////////////////////////////////////////////////////////////////////// - // The escape function returns the string representation of the given - // character value, possibly escaped with a backslash character, to - // allow it being safely used in a regular expression definition. - /////////////////////////////////////////////////////////////////////// - template - inline std::basic_string escape(Char ch) - { - std::basic_string result(1, ch); - if (detail::must_escape(ch)) - { - typedef typename std::basic_string::size_type size_type; - result.insert((size_type)0, 1, '\\'); - } - return result; - } +/////////////////////////////////////////////////////////////////////// +// The escape function returns the string representation of the given +// character value, possibly escaped with a backslash character, to +// allow it being safely used in a regular expression definition. +/////////////////////////////////////////////////////////////////////// +template +inline std::basic_string escape(Char ch) { + std::basic_string result(1, ch); + if (detail::must_escape(ch)) { + typedef typename std::basic_string::size_type size_type; + result.insert((size_type)0, 1, '\\'); + } + return result; +} - /////////////////////////////////////////////////////////////////////// - // - /////////////////////////////////////////////////////////////////////// - inline boost::lexer::regex_flags map_flags(unsigned int flags) - { - unsigned int retval = boost::lexer::none; - if (flags & match_flags::match_not_dot_newline) - retval |= boost::lexer::dot_not_newline; - if (flags & match_flags::match_icase) - retval |= boost::lexer::icase; +/////////////////////////////////////////////////////////////////////// +// +/////////////////////////////////////////////////////////////////////// +inline boost::lexer::regex_flags map_flags(unsigned int flags) { + unsigned int retval = boost::lexer::none; + if (flags & match_flags::match_not_dot_newline) + retval |= boost::lexer::dot_not_newline; + if (flags & match_flags::match_icase) retval |= boost::lexer::icase; - return boost::lexer::regex_flags(retval); - } + return boost::lexer::regex_flags(retval); +} +} // namespace detail + +/////////////////////////////////////////////////////////////////////////// +template +bool generate_static(Lexer const&, + std::basic_ostream&, + typename Lexer::char_type const*, F); + +/////////////////////////////////////////////////////////////////////////// +// +// Every lexer type to be used as a lexer for Spirit has to conform to +// the following public interface: +// +// typedefs: +// iterator_type The type of the iterator exposed by this lexer. +// token_type The type of the tokens returned from the exposed +// iterators. +// +// functions: +// default constructor +// Since lexers are instantiated as base classes +// only it might be a good idea to make this +// constructor protected. +// begin, end Return a pair of iterators, when dereferenced +// returning the sequence of tokens recognized in +// the input stream given as the parameters to the +// begin() function. +// add_token Should add the definition of a token to be +// recognized by this lexer. +// clear Should delete all current token definitions +// associated with the given state of this lexer +// object. +// +// template parameters: +// Iterator The type of the iterator used to access the +// underlying character stream. +// Token The type of the tokens to be returned from the +// exposed token iterator. +// Functor The type of the InputPolicy to use to instantiate +// the multi_pass iterator type to be used as the +// token iterator (returned from begin()/end()). +// +/////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////// +// +// The lexer class is a implementation of a Spirit.Lex lexer on +// top of Ben Hanson's lexertl library as outlined above (For more +// information about lexertl go here: http://www.benhanson.net/lexertl.html). +// +// This class is supposed to be used as the first and only template +// parameter while instantiating instances of a lex::lexer class. +// +/////////////////////////////////////////////////////////////////////////// +template , + typename Iterator = typename Token::iterator_type, + typename Functor = functor > +class lexer { +private: + struct dummy { + void true_() {} + }; + typedef void (dummy::*safe_bool)(); + + static std::size_t const all_states_id = static_cast(-2); + +public: + operator safe_bool() const { return initialized_dfa_ ? &dummy::true_ : 0; } + + typedef + typename boost::detail::iterator_traits::value_type char_type; + typedef std::basic_string string_type; + + typedef boost::lexer::basic_rules basic_rules_type; + + // Every lexer type to be used as a lexer for Spirit has to conform to + // a public interface . + typedef Token token_type; + typedef typename Token::id_type id_type; + typedef iterator iterator_type; + +private: + // this type is purely used for the iterator_type construction below + struct iterator_data_type { + typedef typename Functor::semantic_actions_type semantic_actions_type; + + iterator_data_type( + boost::lexer::basic_state_machine const& sm, + boost::lexer::basic_rules const& rules, + semantic_actions_type const& actions) + : state_machine_(sm), rules_(rules), actions_(actions) {} + + boost::lexer::basic_state_machine const& state_machine_; + boost::lexer::basic_rules const& rules_; + semantic_actions_type const& actions_; + + private: + // silence MSVC warning C4512: assignment operator could not be + // generated + iterator_data_type& operator=(iterator_data_type const&); + }; + +public: + // Return the start iterator usable for iterating over the generated + // tokens. + iterator_type begin(Iterator& first, Iterator const& last, + char_type const* initial_state = 0) const { + if (!init_dfa()) // never minimize DFA for dynamic lexers + return iterator_type(); + + iterator_data_type iterator_data(state_machine_, rules_, actions_); + return iterator_type(iterator_data, first, last, initial_state); } - /////////////////////////////////////////////////////////////////////////// - template - bool generate_static(Lexer const& - , std::basic_ostream& - , typename Lexer::char_type const*, F); + // Return the end iterator usable to stop iterating over the generated + // tokens. + iterator_type end() const { return iterator_type(); } - /////////////////////////////////////////////////////////////////////////// - // - // Every lexer type to be used as a lexer for Spirit has to conform to - // the following public interface: - // - // typedefs: - // iterator_type The type of the iterator exposed by this lexer. - // token_type The type of the tokens returned from the exposed - // iterators. - // - // functions: - // default constructor - // Since lexers are instantiated as base classes - // only it might be a good idea to make this - // constructor protected. - // begin, end Return a pair of iterators, when dereferenced - // returning the sequence of tokens recognized in - // the input stream given as the parameters to the - // begin() function. - // add_token Should add the definition of a token to be - // recognized by this lexer. - // clear Should delete all current token definitions - // associated with the given state of this lexer - // object. - // - // template parameters: - // Iterator The type of the iterator used to access the - // underlying character stream. - // Token The type of the tokens to be returned from the - // exposed token iterator. - // Functor The type of the InputPolicy to use to instantiate - // the multi_pass iterator type to be used as the - // token iterator (returned from begin()/end()). - // - /////////////////////////////////////////////////////////////////////////// +protected: + // Lexer instances can be created by means of a derived class only. + lexer(unsigned int flags) + : flags_(detail::map_flags(flags)), + rules_(flags_), + initialized_dfa_(false) {} - /////////////////////////////////////////////////////////////////////////// - // - // The lexer class is a implementation of a Spirit.Lex lexer on - // top of Ben Hanson's lexertl library as outlined above (For more - // information about lexertl go here: http://www.benhanson.net/lexertl.html). - // - // This class is supposed to be used as the first and only template - // parameter while instantiating instances of a lex::lexer class. - // - /////////////////////////////////////////////////////////////////////////// - template - , typename Iterator = typename Token::iterator_type - , typename Functor = functor > - class lexer - { - private: - struct dummy { void true_() {} }; - typedef void (dummy::*safe_bool)(); +public: + // interface for token definition management + std::size_t add_token(char_type const* state, char_type tokendef, + std::size_t token_id, char_type const* targetstate) { + add_state(state); + initialized_dfa_ = false; + if (state == all_states()) + return rules_.add(state, detail::escape(tokendef), token_id, + rules_.dot()); - static std::size_t const all_states_id = static_cast(-2); + if (0 == targetstate) + targetstate = state; + else + add_state(targetstate); + return rules_.add(state, detail::escape(tokendef), token_id, + targetstate); + } + std::size_t add_token(char_type const* state, string_type const& tokendef, + std::size_t token_id, char_type const* targetstate) { + add_state(state); + initialized_dfa_ = false; + if (state == all_states()) + return rules_.add(state, tokendef, token_id, rules_.dot()); - public: - operator safe_bool() const - { return initialized_dfa_ ? &dummy::true_ : 0; } + if (0 == targetstate) + targetstate = state; + else + add_state(targetstate); + return rules_.add(state, tokendef, token_id, targetstate); + } - typedef typename boost::detail::iterator_traits::value_type - char_type; - typedef std::basic_string string_type; + // interface for pattern definition management + void add_pattern(char_type const* state, string_type const& name, + string_type const& patterndef) { + add_state(state); + rules_.add_macro(name.c_str(), patterndef); + initialized_dfa_ = false; + } - typedef boost::lexer::basic_rules basic_rules_type; + boost::lexer::rules const& get_rules() const { return rules_; } - // Every lexer type to be used as a lexer for Spirit has to conform to - // a public interface . - typedef Token token_type; - typedef typename Token::id_type id_type; - typedef iterator iterator_type; + void clear(char_type const* state) { + std::size_t s = rules_.state(state); + if (boost::lexer::npos != s) rules_.clear(state); + initialized_dfa_ = false; + } + std::size_t add_state(char_type const* state) { + if (state == all_states()) return all_states_id; - private: - // this type is purely used for the iterator_type construction below - struct iterator_data_type - { - typedef typename Functor::semantic_actions_type semantic_actions_type; - - iterator_data_type( - boost::lexer::basic_state_machine const& sm - , boost::lexer::basic_rules const& rules - , semantic_actions_type const& actions) - : state_machine_(sm), rules_(rules), actions_(actions) - {} - - boost::lexer::basic_state_machine const& state_machine_; - boost::lexer::basic_rules const& rules_; - semantic_actions_type const& actions_; - - private: - // silence MSVC warning C4512: assignment operator could not be generated - iterator_data_type& operator= (iterator_data_type const&); - }; - - public: - // Return the start iterator usable for iterating over the generated - // tokens. - iterator_type begin(Iterator& first, Iterator const& last - , char_type const* initial_state = 0) const - { - if (!init_dfa()) // never minimize DFA for dynamic lexers - return iterator_type(); - - iterator_data_type iterator_data(state_machine_, rules_, actions_); - return iterator_type(iterator_data, first, last, initial_state); - } - - // Return the end iterator usable to stop iterating over the generated - // tokens. - iterator_type end() const - { - return iterator_type(); - } - - protected: - // Lexer instances can be created by means of a derived class only. - lexer(unsigned int flags) - : flags_(detail::map_flags(flags)) - , rules_(flags_) - , initialized_dfa_(false) - {} - - public: - // interface for token definition management - std::size_t add_token(char_type const* state, char_type tokendef, - std::size_t token_id, char_type const* targetstate) - { - add_state(state); - initialized_dfa_ = false; - if (state == all_states()) - return rules_.add(state, detail::escape(tokendef), token_id, rules_.dot()); - - if (0 == targetstate) - targetstate = state; - else - add_state(targetstate); - return rules_.add(state, detail::escape(tokendef), token_id, targetstate); - } - std::size_t add_token(char_type const* state, string_type const& tokendef, - std::size_t token_id, char_type const* targetstate) - { - add_state(state); - initialized_dfa_ = false; - if (state == all_states()) - return rules_.add(state, tokendef, token_id, rules_.dot()); - - if (0 == targetstate) - targetstate = state; - else - add_state(targetstate); - return rules_.add(state, tokendef, token_id, targetstate); - } - - // interface for pattern definition management - void add_pattern (char_type const* state, string_type const& name, - string_type const& patterndef) - { - add_state(state); - rules_.add_macro(name.c_str(), patterndef); + std::size_t stateid = rules_.state(state); + if (boost::lexer::npos == stateid) { + stateid = rules_.add_state(state); initialized_dfa_ = false; } + return stateid; + } + string_type initial_state() const { return string_type(rules_.initial()); } + string_type all_states() const { return string_type(rules_.all_states()); } - boost::lexer::rules const& get_rules() const { return rules_; } - - void clear(char_type const* state) - { - std::size_t s = rules_.state(state); - if (boost::lexer::npos != s) - rules_.clear(state); - initialized_dfa_ = false; - } - std::size_t add_state(char_type const* state) - { - if (state == all_states()) - return all_states_id; - - std::size_t stateid = rules_.state(state); - if (boost::lexer::npos == stateid) { - stateid = rules_.add_state(state); - initialized_dfa_ = false; - } - return stateid; - } - string_type initial_state() const - { - return string_type(rules_.initial()); - } - string_type all_states() const - { - return string_type(rules_.all_states()); - } - - // Register a semantic action with the given id - template - void add_action(std::size_t unique_id, std::size_t state, F act) - { - // If you see an error here stating add_action is not a member of - // fusion::unused_type then you are probably having semantic actions - // attached to at least one token in the lexer definition without - // using the lex::lexertl::actor_lexer<> as its base class. - typedef typename Functor::wrap_action_type wrapper_type; - if (state == all_states_id) { - // add the action to all known states - typedef typename - basic_rules_type::string_size_t_map::value_type + // Register a semantic action with the given id + template + void add_action(std::size_t unique_id, std::size_t state, F act) { + // If you see an error here stating add_action is not a member of + // fusion::unused_type then you are probably having semantic actions + // attached to at least one token in the lexer definition without + // using the lex::lexertl::actor_lexer<> as its base class. + typedef typename Functor::wrap_action_type wrapper_type; + if (state == all_states_id) { + // add the action to all known states + typedef typename basic_rules_type::string_size_t_map::value_type state_type; - std::size_t states = rules_.statemap().size(); - BOOST_FOREACH(state_type const& s, rules_.statemap()) { - for (std::size_t j = 0; j < states; ++j) - actions_.add_action(unique_id + j, s.second, wrapper_type::call(act)); - } - } - else { - actions_.add_action(unique_id, state, wrapper_type::call(act)); + std::size_t states = rules_.statemap().size(); + BOOST_FOREACH (state_type const& s, rules_.statemap()) { + for (std::size_t j = 0; j < states; ++j) + actions_.add_action(unique_id + j, s.second, + wrapper_type::call(act)); } + } else { + actions_.add_action(unique_id, state, wrapper_type::call(act)); } -// template -// void add_action(std::size_t unique_id, char_type const* state, F act) -// { -// typedef typename Functor::wrap_action_type wrapper_type; -// actions_.add_action(unique_id, add_state(state), wrapper_type::call(act)); -// } + } + // template + // void add_action(std::size_t unique_id, char_type const* state, F + // act) + // { + // typedef typename Functor::wrap_action_type wrapper_type; + // actions_.add_action(unique_id, add_state(state), + // wrapper_type::call(act)); + // } - // We do not minimize the state machine by default anymore because - // Ben said: "If you can afford to generate a lexer at runtime, there - // is little point in calling minimise." - // Go figure. - bool init_dfa(bool minimize = false) const - { - if (!initialized_dfa_) { - state_machine_.clear(); - typedef boost::lexer::basic_generator generator; - generator::build (rules_, state_machine_); - if (minimize) - generator::minimise (state_machine_); + // We do not minimize the state machine by default anymore because + // Ben said: "If you can afford to generate a lexer at runtime, there + // is little point in calling minimise." + // Go figure. + bool init_dfa(bool minimize = false) const { + if (!initialized_dfa_) { + state_machine_.clear(); + typedef boost::lexer::basic_generator generator; + generator::build(rules_, state_machine_); + if (minimize) generator::minimise(state_machine_); #if defined(BOOST_SPIRIT_LEXERTL_DEBUG) - boost::lexer::debug::dump(state_machine_, std::cerr); + boost::lexer::debug::dump(state_machine_, std::cerr); #endif - initialized_dfa_ = true; + initialized_dfa_ = true; -// // release memory held by rules description -// basic_rules_type rules; -// rules.init_state_info(rules_); // preserve states -// std::swap(rules, rules_); - } - return true; + // // release memory held by rules description + // basic_rules_type rules; + // rules.init_state_info(rules_); // preserve + // states std::swap(rules, rules_); } + return true; + } - private: - // lexertl specific data - mutable boost::lexer::basic_state_machine state_machine_; - boost::lexer::regex_flags flags_; - /*mutable*/ basic_rules_type rules_; +private: + // lexertl specific data + mutable boost::lexer::basic_state_machine state_machine_; + boost::lexer::regex_flags flags_; + /*mutable*/ basic_rules_type rules_; - typename Functor::semantic_actions_type actions_; - mutable bool initialized_dfa_; + typename Functor::semantic_actions_type actions_; + mutable bool initialized_dfa_; - // generator functions must be able to access members directly - template - friend bool generate_static(Lexer const& - , std::basic_ostream& - , typename Lexer::char_type const*, F); - }; + // generator functions must be able to access members directly + template + friend bool generate_static(Lexer const&, + std::basic_ostream&, + typename Lexer::char_type const*, F); +}; - /////////////////////////////////////////////////////////////////////////// - // - // The actor_lexer class is another implementation of a Spirit.Lex - // lexer on top of Ben Hanson's lexertl library as outlined above (For - // more information about lexertl go here: - // http://www.benhanson.net/lexertl.html). - // - // The only difference to the lexer class above is that token_def - // definitions may have semantic (lexer) actions attached while being - // defined: - // - // int w; - // token_def word = "[^ \t\n]+"; - // self = word[++ref(w)]; // see example: word_count_lexer - // - // This class is supposed to be used as the first and only template - // parameter while instantiating instances of a lex::lexer class. - // - /////////////////////////////////////////////////////////////////////////// - template - , typename Iterator = typename Token::iterator_type - , typename Functor = functor > - class actor_lexer : public lexer - { - protected: - // Lexer instances can be created by means of a derived class only. - actor_lexer(unsigned int flags) - : lexer(flags) {} - }; +/////////////////////////////////////////////////////////////////////////// +// +// The actor_lexer class is another implementation of a Spirit.Lex +// lexer on top of Ben Hanson's lexertl library as outlined above (For +// more information about lexertl go here: +// http://www.benhanson.net/lexertl.html). +// +// The only difference to the lexer class above is that token_def +// definitions may have semantic (lexer) actions attached while being +// defined: +// +// int w; +// token_def word = "[^ \t\n]+"; +// self = word[++ref(w)]; // see example: word_count_lexer +// +// This class is supposed to be used as the first and only template +// parameter while instantiating instances of a lex::lexer class. +// +/////////////////////////////////////////////////////////////////////////// +template , + typename Iterator = typename Token::iterator_type, + typename Functor = + functor > +class actor_lexer : public lexer { +protected: + // Lexer instances can be created by means of a derived class only. + actor_lexer(unsigned int flags) : lexer(flags) {} +}; -}}}} +} // namespace lexertl +} // namespace lex +} // namespace spirit +} // namespace boost #endif diff --git a/Minecraft.Client/Platform/PS3/SPU_Tasks/ChunkUpdate/Tile_SPU.cpp b/Minecraft.Client/Platform/PS3/SPU_Tasks/ChunkUpdate/Tile_SPU.cpp index eb768ac4c..9da02ae9f 100644 --- a/Minecraft.Client/Platform/PS3/SPU_Tasks/ChunkUpdate/Tile_SPU.cpp +++ b/Minecraft.Client/Platform/PS3/SPU_Tasks/ChunkUpdate/Tile_SPU.cpp @@ -96,36 +96,28 @@ TileData_SPU* Tile_SPU::ms_pTileData = NULL; Tile_SPU Tile_SPU::m_tiles[256]; +int Tile_SPU::getRenderShape() { return SHAPE_BLOCK; } - -int Tile_SPU::getRenderShape() -{ - return SHAPE_BLOCK; +void Tile_SPU::setShape(float x0, float y0, float z0, float x1, float y1, + float z1) { + ms_pTileData->xx0[id] = x0; + ms_pTileData->yy0[id] = y0; + ms_pTileData->zz0[id] = z0; + ms_pTileData->xx1[id] = x1; + ms_pTileData->yy1[id] = y1; + ms_pTileData->zz1[id] = z1; } - -void Tile_SPU::setShape(float x0, float y0, float z0, float x1, float y1, float z1) -{ - ms_pTileData->xx0[id] = x0; - ms_pTileData->yy0[id] = y0; - ms_pTileData->zz0[id] = z0; - ms_pTileData->xx1[id] = x1; - ms_pTileData->yy1[id] = y1; - ms_pTileData->zz1[id] = z1; +float Tile_SPU::getBrightness(ChunkRebuildData* level, int x, int y, int z) { + return level->getBrightness(x, y, z, ms_pTileData->lightEmission[id]); } - -float Tile_SPU::getBrightness(ChunkRebuildData *level, int x, int y, int z) -{ - return level->getBrightness(x, y, z, ms_pTileData->lightEmission[id]); -} -// +// // // 4J - brought forward from 1.8.2 -int Tile_SPU::getLightColor(ChunkRebuildData *level, int x, int y, int z) -{ - int tileID = level->getTile(x, y, z); - return level->getLightColor(x, y, z, ms_pTileData->lightEmission[tileID]); +int Tile_SPU::getLightColor(ChunkRebuildData* level, int x, int y, int z) { + int tileID = level->getTile(x, y, z); + return level->getLightColor(x, y, z, ms_pTileData->lightEmission[tileID]); } -// +// // bool Tile_SPU::isFaceVisible(Level *level, int x, int y, int z, int f) // { // if (f == 0) y--; @@ -136,197 +128,198 @@ int Tile_SPU::getLightColor(ChunkRebuildData *level, int x, int y, int z) // if (f == 5) x++; // return !level->isSolidRenderTile(x, y, z); // } -// -bool Tile_SPU::shouldRenderFace(ChunkRebuildData *level, int x, int y, int z, int face) -{ - if (face == 0 && getShapeY0() > 0) return true; - if (face == 1 && getShapeY1() < 1) return true; - if (face == 2 && getShapeZ0() > 0) return true; - if (face == 3 && getShapeZ1() < 1) return true; - if (face == 4 && getShapeX0() > 0) return true; - if (face == 5 && getShapeX1() < 1) return true; - return (!level->isSolidRenderTile(x, y, z)); +// +bool Tile_SPU::shouldRenderFace(ChunkRebuildData* level, int x, int y, int z, + int face) { + if (face == 0 && getShapeY0() > 0) return true; + if (face == 1 && getShapeY1() < 1) return true; + if (face == 2 && getShapeZ0() > 0) return true; + if (face == 3 && getShapeZ1() < 1) return true; + if (face == 4 && getShapeX0() > 0) return true; + if (face == 5 && getShapeX1() < 1) return true; + return (!level->isSolidRenderTile(x, y, z)); } -// -bool Tile_SPU::isSolidFace(ChunkRebuildData *level, int x, int y, int z, int face) -{ - return (level->getMaterial(x, y, z)->isSolid()); +// +bool Tile_SPU::isSolidFace(ChunkRebuildData* level, int x, int y, int z, + int face) { + return (level->getMaterial(x, y, z)->isSolid()); } -Icon_SPU *Tile_SPU::getTexture(ChunkRebuildData *level, int x, int y, int z, int face) -{ - // 4J - addition here to make rendering big blocks of leaves more efficient. Normally leaves never consider themselves as solid, so - // blocks of leaves will have all sides of each block completely visible. Changing to consider as solid if this block is surrounded by - // other leaves. This is paired with another change in Level::isSolidRenderTile/Region::isSolidRenderTile which makes things solid - // code-wise (ie for determining visible sides of neighbouring blocks). This change just makes the texture a solid one (tex + 1) which - // we already have in the texture map for doing non-fancy graphics. Note: this tile-specific code is here rather than making some new virtual - // method in the tiles, for the sake of efficiency - I don't imagine we'll be doing much more of this sort of thing +Icon_SPU* Tile_SPU::getTexture(ChunkRebuildData* level, int x, int y, int z, + int face) { + // 4J - addition here to make rendering big blocks of leaves more efficient. + // Normally leaves never consider themselves as solid, so blocks of leaves + // will have all sides of each block completely visible. Changing to + // consider as solid if this block is surrounded by other leaves. This is + // paired with another change in + // Level::isSolidRenderTile/Region::isSolidRenderTile which makes things + // solid code-wise (ie for determining visible sides of neighbouring + // blocks). This change just makes the texture a solid one (tex + 1) which + // we already have in the texture map for doing non-fancy graphics. Note: + // this tile-specific code is here rather than making some new virtual + // method in the tiles, for the sake of efficiency - I don't imagine we'll + // be doing much more of this sort of thing - int tileId = level->getTile(x, y, z); - int tileData = level->getData(x, y, z); + int tileId = level->getTile(x, y, z); + int tileData = level->getData(x, y, z); - if( tileId == Tile_SPU::leaves_Id ) - { - bool opaque = true; - int axo[6] = { 1,-1, 0, 0, 0, 0}; - int ayo[6] = { 0, 0, 1,-1, 0, 0}; - int azo[6] = { 0, 0, 0, 0, 1,-1}; - for( int i = 0; (i < 6) && opaque; i++ ) - { - int t = level->getTile(x + axo[i], y + ayo[i] , z + azo[i]); - if( ( t != Tile_SPU::leaves_Id ) && ( ( Tile_SPU::m_tiles[t].id == -1) || !Tile_SPU::m_tiles[t].isSolidRender() ) ) - { - opaque = false; - } - } + if (tileId == Tile_SPU::leaves_Id) { + bool opaque = true; + int axo[6] = {1, -1, 0, 0, 0, 0}; + int ayo[6] = {0, 0, 1, -1, 0, 0}; + int azo[6] = {0, 0, 0, 0, 1, -1}; + for (int i = 0; (i < 6) && opaque; i++) { + int t = level->getTile(x + axo[i], y + ayo[i], z + azo[i]); + if ((t != Tile_SPU::leaves_Id) && + ((Tile_SPU::m_tiles[t].id == -1) || + !Tile_SPU::m_tiles[t].isSolidRender())) { + opaque = false; + } + } - - Icon_SPU *icon = NULL; - if(opaque) - { - LeafTile_SPU::setFancy(false); - icon = getTexture(face, tileData); - LeafTile_SPU::setFancy(true); - } - else - { - icon = getTexture(face, tileData); - } - return icon; - } - return getTexture(face, tileData); + Icon_SPU* icon = NULL; + if (opaque) { + LeafTile_SPU::setFancy(false); + icon = getTexture(face, tileData); + LeafTile_SPU::setFancy(true); + } else { + icon = getTexture(face, tileData); + } + return icon; + } + return getTexture(face, tileData); } -// -Icon_SPU *Tile_SPU::getTexture(int face, int data) -{ - return &ms_pTileData->iconData[id]; +// +Icon_SPU* Tile_SPU::getTexture(int face, int data) { + return &ms_pTileData->iconData[id]; } -// -Icon_SPU *Tile_SPU::getTexture(int face) -{ - return getTexture(face, 0); -} -// +// +Icon_SPU* Tile_SPU::getTexture(int face) { return getTexture(face, 0); } +// // AABB *Tile_SPU::getTileAABB(Level *level, int x, int y, int z) // { -// return AABB::newTemp(x + xx0, y + yy0, z + zz0, x + xx1, y + yy1, z + zz1); +// return AABB::newTemp(x + xx0, y + yy0, z + zz0, x + xx1, y + yy1, z + +// zz1); // } -// -// void Tile_SPU::addAABBs(Level *level, int x, int y, int z, AABB *box, AABBList *boxes, Entity *source) +// +// void Tile_SPU::addAABBs(Level *level, int x, int y, int z, AABB *box, +// AABBList *boxes, Entity *source) // { // AABB *aabb = getAABB(level, x, y, z); // if (aabb != NULL && box->intersects(aabb)) boxes->push_back(aabb); // } -// -// void Tile_SPU::addAABBs(Level *level, int x, int y, int z, AABB *box, AABBList *boxes) +// +// void Tile_SPU::addAABBs(Level *level, int x, int y, int z, AABB *box, +// AABBList *boxes) // { // AABB *aabb = getAABB(level, x, y, z); // if (aabb != NULL && box->intersects(aabb)) boxes->push_back(aabb); // } -// +// // AABB *Tile_SPU::getAABB(Level *level, int x, int y, int z) // { -// return AABB::newTemp(x + xx0, y + yy0, z + zz0, x + xx1, y + yy1, z + zz1); +// return AABB::newTemp(x + xx0, y + yy0, z + zz0, x + xx1, y + yy1, z + +// zz1); // } -// - bool Tile_SPU::isSolidRender(bool isServerLevel) - { - return true; - } - +// +bool Tile_SPU::isSolidRender(bool isServerLevel) { return true; } // bool Tile_SPU::mayPick(int data, bool liquid) // { // return mayPick(); // } -// +// // bool Tile_SPU::mayPick() // { // return true; // } -// +// // void Tile_SPU::tick(Level *level, int x, int y, int z, Random *random) // { // } -// +// // void Tile_SPU::animateTick(Level *level, int x, int y, int z, Random *random) // { // } -// +// // void Tile_SPU::destroy(Level *level, int x, int y, int z, int data) // { // } -// +// // void Tile_SPU::neighborChanged(Level *level, int x, int y, int z, int type) // { // } -// +// // void Tile_SPU::addLights(Level *level, int x, int y, int z) // { // } -// +// // int Tile_SPU::getTickDelay() // { // return 10; // } -// +// // void Tile_SPU::onPlace(Level *level, int x, int y, int z) // { // } -// +// // void Tile_SPU::onRemove(Level *level, int x, int y, int z) // { // } -// +// // int Tile_SPU::getResourceCount(Random *random) // { // return 1; // } -// +// // int Tile_SPU::getResource(int data, Random *random, int playerBonusLevel) // { // return id; // } -// +// // float Tile_SPU::getDestroyProgress(std::shared_ptr player) // { // if (destroySpeed < 0) return 0; // if (!player->canDestroy(this)) return 1 / destroySpeed / 100.0f; // return (player->getDestroySpeed(this) / destroySpeed) / 30; // } -// -// void Tile_SPU::spawnResources(Level *level, int x, int y, int z, int data, int playerBonusLevel) +// +// void Tile_SPU::spawnResources(Level *level, int x, int y, int z, int data, +// int playerBonusLevel) // { // spawnResources(level, x, y, z, data, 1, playerBonusLevel); // } -// -// void Tile_SPU::spawnResources(Level *level, int x, int y, int z, int data, float odds, int playerBonusLevel) +// +// void Tile_SPU::spawnResources(Level *level, int x, int y, int z, int data, +// float odds, int playerBonusLevel) // { // if (level->isClientSide) return; -// int count = getResourceCountForLootBonus(playerBonusLevel, level->random); -// for (int i = 0; i < count; i++) +// int count = getResourceCountForLootBonus(playerBonusLevel, +// level->random); for (int i = 0; i < count; i++) // { // if (level->random->nextFloat() > odds) continue; // int type = getResource(data, level->random, playerBonusLevel); // if (type <= 0) continue; -// -// popResource(level, x, y, z, std::shared_ptr( new ItemInstance(type, 1, getSpawnResourcesAuxValue(data) ) ) ); +// +// popResource(level, x, y, z, std::shared_ptr( new +// ItemInstance(type, 1, getSpawnResourcesAuxValue(data) ) ) ); // } // } -// -// void Tile_SPU::popResource(Level *level, int x, int y, int z, std::shared_ptr itemInstance) +// +// void Tile_SPU::popResource(Level *level, int x, int y, int z, +// std::shared_ptr itemInstance) // { // if( level->isClientSide ) return; -// +// // float s = 0.7f; // double xo = level->random->nextFloat() * s + (1 - s) * 0.5; // double yo = level->random->nextFloat() * s + (1 - s) * 0.5; // double zo = level->random->nextFloat() * s + (1 - s) * 0.5; -// std::shared_ptr item = std::shared_ptr( new ItemEntity(level, x + xo, y + yo, z + zo, itemInstance ) ); -// item->throwTime = 10; -// level->addEntity(item); +// std::shared_ptr item = std::shared_ptr( new +// ItemEntity(level, x + xo, y + yo, z + zo, itemInstance ) ); item->throwTime = +// 10; level->addEntity(item); // } -// +// // // Brought forward for TU7 // void Tile_SPU::popExperience(Level *level, int x, int y, int z, int amount) // { @@ -334,184 +327,192 @@ Icon_SPU *Tile_SPU::getTexture(int face) // { // while (amount > 0) // { -// int newCount = ExperienceOrb::getExperienceValue(amount); -// amount -= newCount; -// level->addEntity(std::shared_ptr( new ExperienceOrb(level, x + .5, y + .5, z + .5, newCount))); +// int newCount = +// ExperienceOrb::getExperienceValue(amount); amount -= newCount; +// level->addEntity(std::shared_ptr( new +// ExperienceOrb(level, x + .5, y + .5, z + .5, newCount))); // } // } // } -// +// // int Tile_SPU::getSpawnResourcesAuxValue(int data) // { // return 0; // } -// +// // float Tile_SPU::getExplosionResistance(std::shared_ptr source) // { // return explosionResistance / 5.0f; // } -// -// HitResult *Tile_SPU::clip(Level *level, int xt, int yt, int zt, Vec3 *a, Vec3 *b) +// +// HitResult *Tile_SPU::clip(Level *level, int xt, int yt, int zt, Vec3 *a, Vec3 +// *b) // { // EnterCriticalSection(&m_csShape); // updateShape(level, xt, yt, zt); -// +// // a = a->add(-xt, -yt, -zt); // b = b->add(-xt, -yt, -zt); -// +// // Vec3 *xh0 = a->clipX(b, xx0); // Vec3 *xh1 = a->clipX(b, xx1); -// +// // Vec3 *yh0 = a->clipY(b, yy0); // Vec3 *yh1 = a->clipY(b, yy1); -// +// // Vec3 *zh0 = a->clipZ(b, zz0); // Vec3 *zh1 = a->clipZ(b, zz1); -// +// // Vec3 *closest = NULL; -// -// if (containsX(xh0) && (closest == NULL || a->distanceTo(xh0) < a->distanceTo(closest))) closest = xh0; -// if (containsX(xh1) && (closest == NULL || a->distanceTo(xh1) < a->distanceTo(closest))) closest = xh1; -// if (containsY(yh0) && (closest == NULL || a->distanceTo(yh0) < a->distanceTo(closest))) closest = yh0; -// if (containsY(yh1) && (closest == NULL || a->distanceTo(yh1) < a->distanceTo(closest))) closest = yh1; -// if (containsZ(zh0) && (closest == NULL || a->distanceTo(zh0) < a->distanceTo(closest))) closest = zh0; -// if (containsZ(zh1) && (closest == NULL || a->distanceTo(zh1) < a->distanceTo(closest))) closest = zh1; -// +// +// if (containsX(xh0) && (closest == NULL || a->distanceTo(xh0) < +// a->distanceTo(closest))) closest = xh0; if (containsX(xh1) && (closest == +// NULL || a->distanceTo(xh1) < a->distanceTo(closest))) closest = xh1; if +// (containsY(yh0) && (closest == NULL || a->distanceTo(yh0) < +// a->distanceTo(closest))) closest = yh0; if (containsY(yh1) && (closest == +// NULL || a->distanceTo(yh1) < a->distanceTo(closest))) closest = yh1; if +// (containsZ(zh0) && (closest == NULL || a->distanceTo(zh0) < +// a->distanceTo(closest))) closest = zh0; if (containsZ(zh1) && (closest == +// NULL || a->distanceTo(zh1) < a->distanceTo(closest))) closest = zh1; +// // LeaveCriticalSection(&m_csShape); -// +// // if (closest == NULL) return NULL; -// +// // int face = -1; -// +// // if (closest == xh0) face = 4; // if (closest == xh1) face = 5; // if (closest == yh0) face = 0; // if (closest == yh1) face = 1; // if (closest == zh0) face = 2; // if (closest == zh1) face = 3; -// +// // return new HitResult(xt, yt, zt, face, closest->add(xt, yt, zt)); // } -// +// // bool Tile_SPU::containsX(Vec3 *v) // { // if( v == NULL) return false; // return v->y >= yy0 && v->y <= yy1 && v->z >= zz0 && v->z <= zz1; // } -// +// // bool Tile_SPU::containsY(Vec3 *v) // { // if( v == NULL) return false; // return v->x >= xx0 && v->x <= xx1 && v->z >= zz0 && v->z <= zz1; // } -// +// // bool Tile_SPU::containsZ(Vec3 *v) // { // if( v == NULL) return false; // return v->x >= xx0 && v->x <= xx1 && v->y >= yy0 && v->y <= yy1; // } -// +// // void Tile_SPU::wasExploded(Level *level, int x, int y, int z) // { // } -// -int Tile_SPU::getRenderLayer() -{ - return 0; -} -// +// +int Tile_SPU::getRenderLayer() { return 0; } +// // bool Tile_SPU::mayPlace(Level *level, int x, int y, int z, int face) // { // return mayPlace(level, x, y, z); // } -// +// // bool Tile_SPU::mayPlace(Level *level, int x, int y, int z) // { // int t = level->getTile(x, y, z); // return t == 0 || Tile_SPU::tiles[t]->material->isReplaceable(); // } -// +// // // 4J-PB - Adding a TestUse for tooltip display // bool Tile_SPU::TestUse() // { // return false; // } -// -// bool Tile_SPU::TestUse(Level *level, int x, int y, int z, std::shared_ptr player) +// +// bool Tile_SPU::TestUse(Level *level, int x, int y, int z, +// std::shared_ptr player) // { // return false; // } -// -// bool Tile_SPU::use(Level *level, int x, int y, int z, std::shared_ptr player, int clickedFace, float clickX, float clickY, float clickZ, bool soundOnly/*=false*/) // 4J added soundOnly param +// +// bool Tile_SPU::use(Level *level, int x, int y, int z, std::shared_ptr +// player, int clickedFace, float clickX, float clickY, float clickZ, bool +// soundOnly/*=false*/) // 4J added soundOnly param // { // return false; // } -// -// void Tile_SPU::stepOn(Level *level, int x, int y, int z, std::shared_ptr entity) +// +// void Tile_SPU::stepOn(Level *level, int x, int y, int z, +// std::shared_ptr entity) // { // } -// +// // void Tile_SPU::setPlacedOnFace(Level *level, int x, int y, int z, int face) // { // } -// +// // void Tile_SPU::prepareRender(Level *level, int x, int y, int z) // { // } -// -// void Tile_SPU::attack(Level *level, int x, int y, int z, std::shared_ptr player) +// +// void Tile_SPU::attack(Level *level, int x, int y, int z, +// std::shared_ptr player) // { // } -// -// void Tile_SPU::handleEntityInside(Level *level, int x, int y, int z, std::shared_ptr e, Vec3 *current) +// +// void Tile_SPU::handleEntityInside(Level *level, int x, int y, int z, +// std::shared_ptr e, Vec3 *current) // { // } -// -void Tile_SPU::updateShape(ChunkRebuildData *level, int x, int y, int z, int forceData, TileEntity* forceEntity) // 4J added forceData, forceEntity param -{ -} -// +// +void Tile_SPU::updateShape( + ChunkRebuildData* level, int x, int y, int z, int forceData, + TileEntity* forceEntity) // 4J added forceData, forceEntity param +{} +// -int Tile_SPU::getColor(ChunkRebuildData *level, int x, int y, int z) -{ - return 0xffffff; +int Tile_SPU::getColor(ChunkRebuildData* level, int x, int y, int z) { + return 0xffffff; } -// +// // int Tile_SPU::getColor(LevelSource *level, int x, int y, int z, int data) // { // return 0xffffff; // } -// +// // bool Tile_SPU::getSignal(LevelSource *level, int x, int y, int z) // { // return false; // } -// +// // bool Tile_SPU::getSignal(LevelSource *level, int x, int y, int z, int dir) // { // return false; // } -// +// // bool Tile_SPU::isSignalSource() // { // return false; // } -// -// void Tile_SPU::entityInside(Level *level, int x, int y, int z, std::shared_ptr entity) +// +// void Tile_SPU::entityInside(Level *level, int x, int y, int z, +// std::shared_ptr entity) // { // } -// +// // bool Tile_SPU::getDirectSignal(Level *level, int x, int y, int z, int dir) // { // return false; // } -// -void Tile_SPU::updateDefaultShape() -{ -} -// -// void Tile_SPU::playerDestroy(Level *level, std::shared_ptr player, int x, int y, int z, int data) +// +void Tile_SPU::updateDefaultShape() {} +// +// void Tile_SPU::playerDestroy(Level *level, std::shared_ptr player, +// int x, int y, int z, int data) // { // // 4J Stu - Special case - only record a crop destroy if is fully grown // if(id==Tile_SPU::crops_Id) @@ -523,14 +524,15 @@ void Tile_SPU::updateDefaultShape() // { // player->awardStat(Stats::blocksMined[id], 1); // } -// player->awardStat(Stats::totalBlocksMined, 1); // 4J : WESTY : Added for other award. -// player->causeFoodExhaustion(FoodConstants::EXHAUSTION_MINE); -// +// player->awardStat(Stats::totalBlocksMined, 1); // 4J : WESTY : Added +// for other award. player->causeFoodExhaustion(FoodConstants::EXHAUSTION_MINE); +// // if( id == Tile_SPU::treeTrunk_Id ) // player->awardStat(Achievements::mineWood); -// -// -// if (isCubeShaped() && !isEntityTile[id] && EnchantmentHelper::hasSilkTouch(player->inventory)) +// +// +// if (isCubeShaped() && !isEntityTile[id] && +// EnchantmentHelper::hasSilkTouch(player->inventory)) // { // std::shared_ptr item = getSilkTouchItemInstance(data); // if (item != NULL) @@ -540,360 +542,354 @@ void Tile_SPU::updateDefaultShape() // } // else // { -// int playerBonusLevel = EnchantmentHelper::getDiggingLootBonus(player->inventory); +// int playerBonusLevel = +// EnchantmentHelper::getDiggingLootBonus(player->inventory); // spawnResources(level, x, y, z, data, playerBonusLevel); // } // } -// +// // std::shared_ptr Tile_SPU::getSilkTouchItemInstance(int data) // { // int popData = 0; -// if (id >= 0 && id < Item::items.length && Item::items[id]->isStackedByData()) +// if (id >= 0 && id < Item::items.length && +// Item::items[id]->isStackedByData()) // { // popData = data; // } // return std::shared_ptr(new ItemInstance(id, 1, popData)); // } -// +// // int Tile_SPU::getResourceCountForLootBonus(int bonusLevel, Random *random) // { // return getResourceCount(random); // } -// +// // bool Tile_SPU::canSurvive(Level *level, int x, int y, int z) // { // return true; // } -// -// void Tile_SPU::setPlacedBy(Level *level, int x, int y, int z, std::shared_ptr by) +// +// void Tile_SPU::setPlacedBy(Level *level, int x, int y, int z, +// std::shared_ptr by) // { // } -// +// // Tile *Tile_SPU::setDescriptionId(unsigned int id) // { // this->descriptionId = id; // return this; // } -// +// // std::wstring Tile_SPU::getName() // { // return I18n::get(getDescriptionId() + L".name"); // } -// +// // unsigned int Tile_SPU::getDescriptionId(int iData /*= -1*/) // { // return descriptionId; // } -// +// // Tile *Tile_SPU::setUseDescriptionId(unsigned int id) // { // this->useDescriptionId = id; // return this; // } -// +// // unsigned int Tile_SPU::getUseDescriptionId() // { // return useDescriptionId; // } -// -// void Tile_SPU::triggerEvent(Level *level, int x, int y, int z, int b0, int b1) +// +// void Tile_SPU::triggerEvent(Level *level, int x, int y, int z, int b0, int +// b1) // { // } -// +// // bool Tile_SPU::isCollectStatistics() // { // return collectStatistics; // } -// +// // Tile *Tile_SPU::setNotCollectStatistics() // { // collectStatistics = false; // return this; // } -// +// // int Tile_SPU::getPistonPushReaction() // { // return material->getPushReaction(); // } -// +// // // 4J - brought forward from 1.8.2 -float Tile_SPU::getShadeBrightness(ChunkRebuildData *level, int x, int y, int z) -{ - return level->isSolidBlockingTile(x, y, z) ? 0.2f : 1.0f; +float Tile_SPU::getShadeBrightness(ChunkRebuildData* level, int x, int y, + int z) { + return level->isSolidBlockingTile(x, y, z) ? 0.2f : 1.0f; } -Tile_SPU* Tile_SPU::createFromID( int tileID ) -{ - if(tileID == 0) - return NULL; +Tile_SPU* Tile_SPU::createFromID(int tileID) { + if (tileID == 0) return NULL; + + if (m_tiles[tileID].id != -1) return &m_tiles[tileID]; - if(m_tiles[tileID].id != -1) - return &m_tiles[tileID]; - #ifndef SN_TARGET_PS3_SPU - app.DebugPrintf("missing tile ID %d\n", tileID); + app.DebugPrintf("missing tile ID %d\n", tileID); #else - spu_print("missing tile ID %d\n", tileID); -#endif - return &m_tiles[1]; - + spu_print("missing tile ID %d\n", tileID); +#endif + return &m_tiles[1]; } -Material_SPU* Tile_SPU::getMaterial() -{ - int matID = ms_pTileData->materialIDs[id]; - return &ms_pTileData->materials[matID]; +Material_SPU* Tile_SPU::getMaterial() { + int matID = ms_pTileData->materialIDs[id]; + return &ms_pTileData->materials[matID]; } -// -// void Tile_SPU::fallOn(Level *level, int x, int y, int z, std::shared_ptr entity, float fallDistance) +// +// void Tile_SPU::fallOn(Level *level, int x, int y, int z, +// std::shared_ptr entity, float fallDistance) // { // } -// +// // void Tile_SPU::registerIcons(IconRegister *iconRegister) // { // icon = iconRegister->registerIcon(m_textureName); // } -// +// // std::wstring Tile_SPU::getTileItemIconName() // { // return L""; // } -// +// // Tile *Tile_SPU::setTextureName(const std::wstring &name) // { // m_textureName = name; // return this; // } +void Tile_SPU::initTilePointers() { +#define CREATE_TILE_TYPE(index, className) \ + new (&m_tiles[index]) className(index); + CREATE_TILE_TYPE(grass_Id, GrassTile_SPU); + CREATE_TILE_TYPE(stoneSlab_Id, StoneSlabTile_SPU); + CREATE_TILE_TYPE(stoneSlabHalf_Id, StoneSlabTile_SPU); + CREATE_TILE_TYPE(woodSlab_Id, WoodSlabTile_SPU); + CREATE_TILE_TYPE(woodSlabHalf_Id, WoodSlabTile_SPU); -void Tile_SPU::initTilePointers() -{ + CREATE_TILE_TYPE(chest_Id, ChestTile_SPU); -#define CREATE_TILE_TYPE(index, className) new (&m_tiles[index]) className(index); + CREATE_TILE_TYPE(ironFence_Id, ThinFenceTile_SPU); + CREATE_TILE_TYPE(thinGlass_Id, ThinFenceTile_SPU); + CREATE_TILE_TYPE(fence_Id, FenceTile_SPU); + CREATE_TILE_TYPE(netherFence_Id, FenceTile_SPU); - CREATE_TILE_TYPE(grass_Id, GrassTile_SPU); - CREATE_TILE_TYPE(stoneSlab_Id, StoneSlabTile_SPU); - CREATE_TILE_TYPE(stoneSlabHalf_Id, StoneSlabTile_SPU); - CREATE_TILE_TYPE(woodSlab_Id, WoodSlabTile_SPU); - CREATE_TILE_TYPE(woodSlabHalf_Id, WoodSlabTile_SPU); + CREATE_TILE_TYPE(stairs_wood_Id, StairTile_SPU); + CREATE_TILE_TYPE(stairs_stone_Id, StairTile_SPU); + CREATE_TILE_TYPE(stairs_bricks_Id, StairTile_SPU); + CREATE_TILE_TYPE(stairs_stoneBrickSmooth_Id, StairTile_SPU); + CREATE_TILE_TYPE(stairs_netherBricks_Id, StairTile_SPU); + CREATE_TILE_TYPE(stairs_sandstone_Id, StairTile_SPU); + CREATE_TILE_TYPE(stairs_sprucewood_Id, StairTile_SPU); + CREATE_TILE_TYPE(stairs_birchwood_Id, StairTile_SPU); + CREATE_TILE_TYPE(stairs_junglewood_Id, StairTile_SPU); - CREATE_TILE_TYPE(chest_Id, ChestTile_SPU); + CREATE_TILE_TYPE(dirt_Id, DirtTile_SPU); - CREATE_TILE_TYPE(ironFence_Id, ThinFenceTile_SPU); - CREATE_TILE_TYPE(thinGlass_Id, ThinFenceTile_SPU); + CREATE_TILE_TYPE(door_iron_Id, DoorTile_SPU); + CREATE_TILE_TYPE(door_wood_Id, DoorTile_SPU); - CREATE_TILE_TYPE(fence_Id, FenceTile_SPU); - CREATE_TILE_TYPE(netherFence_Id, FenceTile_SPU); + CREATE_TILE_TYPE(pressurePlate_stone_Id, PressurePlateTile_SPU); + CREATE_TILE_TYPE(pressurePlate_wood_Id, PressurePlateTile_SPU); - CREATE_TILE_TYPE(stairs_wood_Id, StairTile_SPU); - CREATE_TILE_TYPE(stairs_stone_Id, StairTile_SPU); - CREATE_TILE_TYPE(stairs_bricks_Id, StairTile_SPU); - CREATE_TILE_TYPE(stairs_stoneBrickSmooth_Id, StairTile_SPU); - CREATE_TILE_TYPE(stairs_netherBricks_Id, StairTile_SPU); - CREATE_TILE_TYPE(stairs_sandstone_Id, StairTile_SPU); - CREATE_TILE_TYPE(stairs_sprucewood_Id, StairTile_SPU); - CREATE_TILE_TYPE(stairs_birchwood_Id, StairTile_SPU); - CREATE_TILE_TYPE(stairs_junglewood_Id, StairTile_SPU); + CREATE_TILE_TYPE(farmland_Id, FarmTile_SPU); - CREATE_TILE_TYPE(dirt_Id, DirtTile_SPU); + CREATE_TILE_TYPE(flower_Id, Bush_SPU); + CREATE_TILE_TYPE(rose_Id, Bush_SPU); + CREATE_TILE_TYPE(deadBush_Id, Bush_SPU); // DeadBushTile - CREATE_TILE_TYPE(door_iron_Id, DoorTile_SPU); - CREATE_TILE_TYPE(door_wood_Id, DoorTile_SPU); + CREATE_TILE_TYPE(tallgrass_Id, TallGrass_SPU); - CREATE_TILE_TYPE(pressurePlate_stone_Id, PressurePlateTile_SPU); - CREATE_TILE_TYPE(pressurePlate_wood_Id, PressurePlateTile_SPU); + CREATE_TILE_TYPE(sandStone_Id, SandStoneTile_SPU); - CREATE_TILE_TYPE(farmland_Id, FarmTile_SPU); + CREATE_TILE_TYPE(wood_Id, WoodTile_SPU); - CREATE_TILE_TYPE(flower_Id, Bush_SPU); - CREATE_TILE_TYPE(rose_Id, Bush_SPU); - CREATE_TILE_TYPE(deadBush_Id, Bush_SPU); // DeadBushTile + CREATE_TILE_TYPE(treeTrunk_Id, TreeTile_SPU); - CREATE_TILE_TYPE(tallgrass_Id, TallGrass_SPU); + CREATE_TILE_TYPE(leaves_Id, LeafTile_SPU); - CREATE_TILE_TYPE(sandStone_Id, SandStoneTile_SPU); + CREATE_TILE_TYPE(crops_Id, CropTile_SPU); - CREATE_TILE_TYPE(wood_Id, WoodTile_SPU); + CREATE_TILE_TYPE(reeds_Id, ReedTile_SPU); - CREATE_TILE_TYPE(treeTrunk_Id, TreeTile_SPU); + CREATE_TILE_TYPE(torch_Id, TorchTile_SPU); + CREATE_TILE_TYPE(notGate_off_Id, TorchTile_SPU); // TorchTile->NotGateTile + CREATE_TILE_TYPE(notGate_on_Id, TorchTile_SPU); // TorchTile->NotGateTile - CREATE_TILE_TYPE(leaves_Id, LeafTile_SPU); + CREATE_TILE_TYPE(mushroom1_Id, Mushroom_SPU); + CREATE_TILE_TYPE(mushroom2_Id, Mushroom_SPU); - CREATE_TILE_TYPE(crops_Id, CropTile_SPU); + CREATE_TILE_TYPE(mobSpawner_Id, MobSpawnerTile_SPU); + CREATE_TILE_TYPE(musicBlock_Id, EntityTile_SPU); // MusicTile->EntityTile - CREATE_TILE_TYPE(reeds_Id, ReedTile_SPU); + CREATE_TILE_TYPE(furnace_Id, FurnaceTile_SPU); + CREATE_TILE_TYPE(furnace_lit_Id, FurnaceTile_SPU); - CREATE_TILE_TYPE(torch_Id, TorchTile_SPU); - CREATE_TILE_TYPE(notGate_off_Id, TorchTile_SPU); // TorchTile->NotGateTile - CREATE_TILE_TYPE(notGate_on_Id, TorchTile_SPU); // TorchTile->NotGateTile + CREATE_TILE_TYPE(web_Id, WebTile_SPU); - CREATE_TILE_TYPE(mushroom1_Id, Mushroom_SPU); - CREATE_TILE_TYPE(mushroom2_Id, Mushroom_SPU); + CREATE_TILE_TYPE(water_Id, LiquidTile_SPU); + CREATE_TILE_TYPE(lava_Id, LiquidTile_SPU); + CREATE_TILE_TYPE(calmLava_Id, LiquidTile_SPU); // LiquidTileStatic + CREATE_TILE_TYPE(calmWater_Id, LiquidTile_SPU); // LiquidTileStatic - CREATE_TILE_TYPE(mobSpawner_Id, MobSpawnerTile_SPU); - CREATE_TILE_TYPE(musicBlock_Id, EntityTile_SPU); // MusicTile->EntityTile + CREATE_TILE_TYPE(fire_Id, FireTile_SPU); - CREATE_TILE_TYPE(furnace_Id, FurnaceTile_SPU); - CREATE_TILE_TYPE(furnace_lit_Id, FurnaceTile_SPU); + CREATE_TILE_TYPE(sapling_Id, Sapling_SPU); - CREATE_TILE_TYPE(web_Id, WebTile_SPU); + CREATE_TILE_TYPE(glass_Id, GlassTile_SPU); - CREATE_TILE_TYPE(water_Id, LiquidTile_SPU); - CREATE_TILE_TYPE(lava_Id, LiquidTile_SPU); - CREATE_TILE_TYPE(calmLava_Id, LiquidTile_SPU); // LiquidTileStatic - CREATE_TILE_TYPE(calmWater_Id, LiquidTile_SPU); // LiquidTileStatic + CREATE_TILE_TYPE(ice_Id, IceTile_SPU); - CREATE_TILE_TYPE(fire_Id, FireTile_SPU); + CREATE_TILE_TYPE(portalTile_Id, PortalTile_SPU); - CREATE_TILE_TYPE(sapling_Id, Sapling_SPU); + CREATE_TILE_TYPE(dispenser_Id, DispenserTile_SPU); - CREATE_TILE_TYPE(glass_Id, GlassTile_SPU); + CREATE_TILE_TYPE(rail_Id, RailTile_SPU); + CREATE_TILE_TYPE(goldenRail_Id, RailTile_SPU); - CREATE_TILE_TYPE(ice_Id, IceTile_SPU); + CREATE_TILE_TYPE(detectorRail_Id, DetectorRailTile_SPU); - CREATE_TILE_TYPE(portalTile_Id, PortalTile_SPU); + CREATE_TILE_TYPE(tnt_Id, TntTile_SPU); - CREATE_TILE_TYPE(dispenser_Id, DispenserTile_SPU); + CREATE_TILE_TYPE(bookshelf_Id, BookshelfTile_SPU); - CREATE_TILE_TYPE(rail_Id, RailTile_SPU); - CREATE_TILE_TYPE(goldenRail_Id, RailTile_SPU); + CREATE_TILE_TYPE(workBench_Id, WorkbenchTile_SPU); - CREATE_TILE_TYPE(detectorRail_Id, DetectorRailTile_SPU); + CREATE_TILE_TYPE(sign_Id, SignTile_SPU); + CREATE_TILE_TYPE(wallSign_Id, SignTile_SPU); - CREATE_TILE_TYPE(tnt_Id, TntTile_SPU); + CREATE_TILE_TYPE(ladder_Id, LadderTile_SPU); - CREATE_TILE_TYPE(bookshelf_Id, BookshelfTile_SPU); + CREATE_TILE_TYPE(button_stone_Id, ButtonTile_SPU); + CREATE_TILE_TYPE(button_wood_Id, ButtonTile_SPU); - CREATE_TILE_TYPE(workBench_Id, WorkbenchTile_SPU); + CREATE_TILE_TYPE(topSnow_Id, TopSnowTile_SPU); - CREATE_TILE_TYPE(sign_Id, SignTile_SPU); - CREATE_TILE_TYPE(wallSign_Id, SignTile_SPU); + CREATE_TILE_TYPE(cactus_Id, CactusTile_SPU); - CREATE_TILE_TYPE(ladder_Id, LadderTile_SPU); + CREATE_TILE_TYPE(recordPlayer_Id, RecordPlayerTile_SPU); - CREATE_TILE_TYPE(button_stone_Id, ButtonTile_SPU); - CREATE_TILE_TYPE(button_wood_Id, ButtonTile_SPU); + CREATE_TILE_TYPE(pumpkin_Id, PumpkinTile_SPU); + CREATE_TILE_TYPE(litPumpkin_Id, PumpkinTile_SPU); - CREATE_TILE_TYPE(topSnow_Id, TopSnowTile_SPU); + CREATE_TILE_TYPE(cake_Id, CakeTile_SPU); - CREATE_TILE_TYPE(cactus_Id, CactusTile_SPU); + CREATE_TILE_TYPE(trapdoor_Id, TrapDoorTile_SPU); - CREATE_TILE_TYPE(recordPlayer_Id, RecordPlayerTile_SPU); + CREATE_TILE_TYPE(monsterStoneEgg_Id, StoneMonsterTile_SPU); - CREATE_TILE_TYPE(pumpkin_Id, PumpkinTile_SPU); - CREATE_TILE_TYPE(litPumpkin_Id, PumpkinTile_SPU); + CREATE_TILE_TYPE(stoneBrickSmooth_Id, SmoothStoneBrickTile_SPU); - CREATE_TILE_TYPE(cake_Id, CakeTile_SPU); + CREATE_TILE_TYPE(hugeMushroom1_Id, HugeMushroomTile_SPU); + CREATE_TILE_TYPE(hugeMushroom2_Id, HugeMushroomTile_SPU); - CREATE_TILE_TYPE(trapdoor_Id, TrapDoorTile_SPU); + CREATE_TILE_TYPE(melon_Id, MelonTile_SPU); - CREATE_TILE_TYPE(monsterStoneEgg_Id, StoneMonsterTile_SPU); + CREATE_TILE_TYPE(melonStem_Id, StemTile_SPU); + CREATE_TILE_TYPE(pumpkinStem_Id, StemTile_SPU); - CREATE_TILE_TYPE(stoneBrickSmooth_Id, SmoothStoneBrickTile_SPU); + CREATE_TILE_TYPE(vine_Id, VineTile_SPU); - CREATE_TILE_TYPE(hugeMushroom1_Id, HugeMushroomTile_SPU); - CREATE_TILE_TYPE(hugeMushroom2_Id, HugeMushroomTile_SPU); + CREATE_TILE_TYPE(mycel_Id, MycelTile_SPU); - CREATE_TILE_TYPE(melon_Id, MelonTile_SPU); + CREATE_TILE_TYPE(waterLily_Id, WaterlilyTile_SPU); - CREATE_TILE_TYPE(melonStem_Id, StemTile_SPU); - CREATE_TILE_TYPE(pumpkinStem_Id, StemTile_SPU); + CREATE_TILE_TYPE(netherStalk_Id, NetherStalkTile_SPU); - CREATE_TILE_TYPE(vine_Id, VineTile_SPU); + CREATE_TILE_TYPE(enchantTable_Id, EnchantmentTableTile_SPU); - CREATE_TILE_TYPE(mycel_Id, MycelTile_SPU); + CREATE_TILE_TYPE(brewingStand_Id, BrewingStandTile_SPU); - CREATE_TILE_TYPE(waterLily_Id, WaterlilyTile_SPU); + CREATE_TILE_TYPE(diode_on_Id, DiodeTile_SPU); + CREATE_TILE_TYPE(diode_off_Id, DiodeTile_SPU); - CREATE_TILE_TYPE(netherStalk_Id, NetherStalkTile_SPU); + CREATE_TILE_TYPE(redStoneDust_Id, RedStoneDustTile_SPU); - CREATE_TILE_TYPE(enchantTable_Id, EnchantmentTableTile_SPU); + CREATE_TILE_TYPE(fenceGate_Id, FenceGateTile_SPU); - CREATE_TILE_TYPE(brewingStand_Id, BrewingStandTile_SPU); + CREATE_TILE_TYPE(bed_Id, BedTile_SPU); - CREATE_TILE_TYPE(diode_on_Id, DiodeTile_SPU); - CREATE_TILE_TYPE(diode_off_Id, DiodeTile_SPU); + CREATE_TILE_TYPE(pistonBase_Id, PistonBaseTile_SPU); + CREATE_TILE_TYPE(pistonStickyBase_Id, PistonBaseTile_SPU); - CREATE_TILE_TYPE(redStoneDust_Id, RedStoneDustTile_SPU); + CREATE_TILE_TYPE(pistonExtensionPiece_Id, PistonExtensionTile_SPU); - CREATE_TILE_TYPE(fenceGate_Id, FenceGateTile_SPU); + CREATE_TILE_TYPE(pistonMovingPiece_Id, PistonMovingPiece_SPU); - CREATE_TILE_TYPE(bed_Id, BedTile_SPU); + CREATE_TILE_TYPE(lever_Id, LeverTile_SPU); - CREATE_TILE_TYPE(pistonBase_Id, PistonBaseTile_SPU); - CREATE_TILE_TYPE(pistonStickyBase_Id, PistonBaseTile_SPU); + CREATE_TILE_TYPE(cauldron_Id, CauldronTile_SPU); - CREATE_TILE_TYPE(pistonExtensionPiece_Id, PistonExtensionTile_SPU); + CREATE_TILE_TYPE(endPortalTile_Id, TheEndPortal_SPU); - CREATE_TILE_TYPE(pistonMovingPiece_Id, PistonMovingPiece_SPU); + CREATE_TILE_TYPE(endPortalFrameTile_Id, TheEndPortalFrameTile_SPU); - CREATE_TILE_TYPE(lever_Id, LeverTile_SPU); + CREATE_TILE_TYPE(dragonEgg_Id, EggTile_SPU); - CREATE_TILE_TYPE(cauldron_Id, CauldronTile_SPU); + CREATE_TILE_TYPE(cocoa_Id, CocoaTile_SPU); - CREATE_TILE_TYPE(endPortalTile_Id, TheEndPortal_SPU); + CREATE_TILE_TYPE(redstoneLight_Id, RedlightTile_SPU); + CREATE_TILE_TYPE(redstoneLight_lit_Id, RedlightTile_SPU); - CREATE_TILE_TYPE(endPortalFrameTile_Id, TheEndPortalFrameTile_SPU); + CREATE_TILE_TYPE(skull_Id, SkullTile_SPU); - CREATE_TILE_TYPE(dragonEgg_Id, EggTile_SPU); + // these tile types don't have any additional code that we need. + CREATE_TILE_TYPE(stoneBrick_Id, Tile_SPU); // Tile + CREATE_TILE_TYPE(lapisBlock_Id, Tile_SPU); + CREATE_TILE_TYPE(redBrick_Id, Tile_SPU); + CREATE_TILE_TYPE(mossStone_Id, Tile_SPU); + CREATE_TILE_TYPE(netherBrick_Id, Tile_SPU); + CREATE_TILE_TYPE(whiteStone_Id, Tile_SPU); + CREATE_TILE_TYPE(unbreakable_Id, Tile_SPU); + CREATE_TILE_TYPE(sponge_Id, Tile_SPU); + CREATE_TILE_TYPE(rock_Id, Tile_SPU); // StoneTile + CREATE_TILE_TYPE(obsidian_Id, Tile_SPU); // StoneTile->ObsidianTile + CREATE_TILE_TYPE(sand_Id, Tile_SPU); // HeavyTile + CREATE_TILE_TYPE(gravel_Id, Tile_SPU); // GravelTile + CREATE_TILE_TYPE(goldOre_Id, Tile_SPU); // OreTile + CREATE_TILE_TYPE(ironOre_Id, Tile_SPU); // OreTile + CREATE_TILE_TYPE(coalOre_Id, Tile_SPU); // OreTile + CREATE_TILE_TYPE(lapisOre_Id, Tile_SPU); // OreTile + CREATE_TILE_TYPE(diamondOre_Id, Tile_SPU); // OreTile + CREATE_TILE_TYPE(clay_Id, Tile_SPU); // ClayTile + CREATE_TILE_TYPE(redStoneOre_Id, Tile_SPU); // RedStoneOreTile + CREATE_TILE_TYPE(redStoneOre_lit_Id, Tile_SPU); // RedStoneOreTile + CREATE_TILE_TYPE(goldBlock_Id, Tile_SPU); // MetalTile + CREATE_TILE_TYPE(ironBlock_Id, Tile_SPU); // MetalTile + CREATE_TILE_TYPE(diamondBlock_Id, Tile_SPU); // MetalTile + CREATE_TILE_TYPE(snow_Id, Tile_SPU); // SnowTile + CREATE_TILE_TYPE(hellRock_Id, Tile_SPU); // HellStoneTile + CREATE_TILE_TYPE(hellSand_Id, Tile_SPU); // HellSandTile + CREATE_TILE_TYPE(lightGem_Id, Tile_SPU); // LightGemTile + CREATE_TILE_TYPE(aprilFoolsJoke_Id, Tile_SPU); // LockedChestTile - CREATE_TILE_TYPE(cocoa_Id, CocoaTile_SPU); + CREATE_TILE_TYPE(cloth_Id, ClothTile_SPU); // wool - CREATE_TILE_TYPE(redstoneLight_Id, RedlightTile_SPU); - CREATE_TILE_TYPE(redstoneLight_lit_Id, RedlightTile_SPU); - - CREATE_TILE_TYPE(skull_Id, SkullTile_SPU); - - // these tile types don't have any additional code that we need. - CREATE_TILE_TYPE(stoneBrick_Id, Tile_SPU); // Tile - CREATE_TILE_TYPE(lapisBlock_Id, Tile_SPU); - CREATE_TILE_TYPE(redBrick_Id, Tile_SPU); - CREATE_TILE_TYPE(mossStone_Id, Tile_SPU); - CREATE_TILE_TYPE(netherBrick_Id, Tile_SPU); - CREATE_TILE_TYPE(whiteStone_Id, Tile_SPU); - CREATE_TILE_TYPE(unbreakable_Id, Tile_SPU); - CREATE_TILE_TYPE(sponge_Id, Tile_SPU); - CREATE_TILE_TYPE(rock_Id, Tile_SPU); // StoneTile - CREATE_TILE_TYPE(obsidian_Id, Tile_SPU); // StoneTile->ObsidianTile - CREATE_TILE_TYPE(sand_Id, Tile_SPU); // HeavyTile - CREATE_TILE_TYPE(gravel_Id, Tile_SPU); // GravelTile - CREATE_TILE_TYPE(goldOre_Id, Tile_SPU); // OreTile - CREATE_TILE_TYPE(ironOre_Id, Tile_SPU); // OreTile - CREATE_TILE_TYPE(coalOre_Id, Tile_SPU); // OreTile - CREATE_TILE_TYPE(lapisOre_Id, Tile_SPU); // OreTile - CREATE_TILE_TYPE(diamondOre_Id, Tile_SPU); // OreTile - CREATE_TILE_TYPE(clay_Id, Tile_SPU); // ClayTile - CREATE_TILE_TYPE(redStoneOre_Id, Tile_SPU); // RedStoneOreTile - CREATE_TILE_TYPE(redStoneOre_lit_Id, Tile_SPU); // RedStoneOreTile - CREATE_TILE_TYPE(goldBlock_Id, Tile_SPU); // MetalTile - CREATE_TILE_TYPE(ironBlock_Id, Tile_SPU); // MetalTile - CREATE_TILE_TYPE(diamondBlock_Id, Tile_SPU); // MetalTile - CREATE_TILE_TYPE(snow_Id, Tile_SPU); // SnowTile - CREATE_TILE_TYPE(hellRock_Id, Tile_SPU); // HellStoneTile - CREATE_TILE_TYPE(hellSand_Id, Tile_SPU); // HellSandTile - CREATE_TILE_TYPE(lightGem_Id, Tile_SPU); // LightGemTile - CREATE_TILE_TYPE(aprilFoolsJoke_Id, Tile_SPU); // LockedChestTile - - CREATE_TILE_TYPE(cloth_Id, ClothTile_SPU); // wool - - - CREATE_TILE_TYPE(emeraldOre_Id, Tile_SPU); // OreTile - CREATE_TILE_TYPE(enderChest_Id, EnderChestTile_SPU); - CREATE_TILE_TYPE(tripWireSource_Id, TripWireSourceTile_SPU); - CREATE_TILE_TYPE(tripWire_Id, TripWireTile_SPU); -// - CREATE_TILE_TYPE(emeraldBlock_Id, Tile_SPU); // MetalTile - CREATE_TILE_TYPE(cobbleWall_Id, WallTile_SPU); - CREATE_TILE_TYPE(flowerPot_Id, FlowerPotTile_SPU); - CREATE_TILE_TYPE(carrots_Id, CarrotTile_SPU); - CREATE_TILE_TYPE(potatoes_Id, PotatoTile_SPU); - CREATE_TILE_TYPE(anvil_Id, AnvilTile_SPU); - CREATE_TILE_TYPE(netherQuartz_Id, Tile_SPU); // OreTile - CREATE_TILE_TYPE(quartzBlock_Id, QuartzBlockTile_SPU); - CREATE_TILE_TYPE(stairs_quartz_Id, StairTile_SPU); - CREATE_TILE_TYPE(woolCarpet_Id, WoolCarpetTile_SPU); - -}; \ No newline at end of file + CREATE_TILE_TYPE(emeraldOre_Id, Tile_SPU); // OreTile + CREATE_TILE_TYPE(enderChest_Id, EnderChestTile_SPU); + CREATE_TILE_TYPE(tripWireSource_Id, TripWireSourceTile_SPU); + CREATE_TILE_TYPE(tripWire_Id, TripWireTile_SPU); + // + CREATE_TILE_TYPE(emeraldBlock_Id, Tile_SPU); // MetalTile + CREATE_TILE_TYPE(cobbleWall_Id, WallTile_SPU); + CREATE_TILE_TYPE(flowerPot_Id, FlowerPotTile_SPU); + CREATE_TILE_TYPE(carrots_Id, CarrotTile_SPU); + CREATE_TILE_TYPE(potatoes_Id, PotatoTile_SPU); + CREATE_TILE_TYPE(anvil_Id, AnvilTile_SPU); + CREATE_TILE_TYPE(netherQuartz_Id, Tile_SPU); // OreTile + CREATE_TILE_TYPE(quartzBlock_Id, QuartzBlockTile_SPU); + CREATE_TILE_TYPE(stairs_quartz_Id, StairTile_SPU); + CREATE_TILE_TYPE(woolCarpet_Id, WoolCarpetTile_SPU); +}; diff --git a/Minecraft.Client/Player/LocalPlayer.cpp b/Minecraft.Client/Player/LocalPlayer.cpp index dbb47eaf1..f264a55af 100644 --- a/Minecraft.Client/Player/LocalPlayer.cpp +++ b/Minecraft.Client/Player/LocalPlayer.cpp @@ -1506,7 +1506,7 @@ bool LocalPlayer::handleMouseClick(int button) { bool usedItem = false; if (minecraft->gameMode->useItemOn( minecraft->localplayers[GetXboxPad()], level, item, x, y, z, - face, minecraft->hitResult->pos, false, &usedItem)) { + face, &minecraft->hitResult->pos, false, &usedItem)) { // Presume that if we actually used the held item, then we've // placed it if (usedItem) { diff --git a/Minecraft.Client/Rendering/Culling/DirtyChunkSorter.cpp b/Minecraft.Client/Rendering/Culling/DirtyChunkSorter.cpp index 9901135a6..ed12da6ef 100644 --- a/Minecraft.Client/Rendering/Culling/DirtyChunkSorter.cpp +++ b/Minecraft.Client/Rendering/Culling/DirtyChunkSorter.cpp @@ -23,4 +23,4 @@ bool DirtyChunkSorter::operator()(const Chunk* c0, const Chunk* c1) const { if (d0 > d1) return true; return c0->id >= c1->id; // 4J - was c0.id < c1.id ? 1 : -1 -} \ No newline at end of file +} diff --git a/Minecraft.Client/Rendering/EntityRenderers/LivingEntityRenderer.cpp b/Minecraft.Client/Rendering/EntityRenderers/LivingEntityRenderer.cpp index d2183890e..6be119c1b 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/LivingEntityRenderer.cpp +++ b/Minecraft.Client/Rendering/EntityRenderers/LivingEntityRenderer.cpp @@ -613,4 +613,4 @@ void LivingEntityRenderer::renderNameTag(std::shared_ptr mob, glDisable(GL_BLEND); glColor4f(1, 1, 1, 1); glPopMatrix(); -} \ No newline at end of file +} diff --git a/Minecraft.Client/Rendering/EntityRenderers/MinecartRenderer.cpp b/Minecraft.Client/Rendering/EntityRenderers/MinecartRenderer.cpp index f1d7cd569..83f81f10a 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/MinecartRenderer.cpp +++ b/Minecraft.Client/Rendering/EntityRenderers/MinecartRenderer.cpp @@ -54,10 +54,11 @@ void MinecartRenderer::render(std::shared_ptr _cart, double x, double y, y += (p0->y + p1->y) / 2 - yy; z += p->z - zz; - Vec3* dir = p1->add(-p0->x, -p0->y, -p0->z); + Vec3* dir = Vec3::newTemp(-p0->x, -p0->y, -p0->z); + *dir = dir->add(p1->x, p1->y, p1->z); if (dir->length() == 0) { } else { - dir = dir->normalize(); + *dir = dir->normalize(); rot = (float)(atan2(dir->z, dir->x) * 180 / PI); xRot = (float)(atan(dir->y) * 73); } @@ -146,4 +147,4 @@ void MinecartRenderer::renderMinecartContents(std::shared_ptr cart, glPushMatrix(); renderer->renderTile(tile, tileData, brightness); glPopMatrix(); -} \ No newline at end of file +} diff --git a/Minecraft.Client/Rendering/GameRenderer.cpp b/Minecraft.Client/Rendering/GameRenderer.cpp index 9455cc252..0946c50b9 100644 --- a/Minecraft.Client/Rendering/GameRenderer.cpp +++ b/Minecraft.Client/Rendering/GameRenderer.cpp @@ -301,11 +301,12 @@ void GameRenderer::pick(float a) { } if (mc->hitResult != NULL) { - dist = mc->hitResult->pos->distanceTo(from); + dist = mc->hitResult->pos.distanceTo(*from); } Vec3* b = mc->cameraTargetPlayer->getViewVector(a); - Vec3* to = from->add(b->x * range, b->y * range, b->z * range); + Vec3* to = Vec3::newTemp(b->x * range, b->y * range, b->z * range); + *to = to->add(from->x, from->y, from->z); hovered = nullptr; float overlap = 1; std::vector >* objects = mc->level->getEntities( @@ -527,7 +528,7 @@ void GameRenderer::moveCameraToPlayer(float a) { Vec3::newTemp(x + xo, y + yo, z + zo), Vec3::newTemp(x - xd + xo, y - yd + yo, z - zd + zo)); if (hr != NULL) { - double dist = hr->pos->distanceTo(Vec3::newTemp(x, y, z)); + double dist = hr->pos.distanceTo(*Vec3::newTemp(x, y, z)); if (dist < cameraDist) cameraDist = dist; delete hr; } @@ -1867,7 +1868,7 @@ void GameRenderer::setupClearColor(float a) { Vec3* sunAngle = Mth::sin(level->getSunAngle(a)) > 0 ? Vec3::newTemp(-1, 0, 0) : Vec3::newTemp(1, 0, 0); - float d = (float)player->getViewVector(a)->dot(sunAngle); + float d = (float)player->getViewVector(a)->dot(*sunAngle); if (d < 0) d = 0; if (d > 0) { float* c = diff --git a/Minecraft.Client/Rendering/Lighting.cpp b/Minecraft.Client/Rendering/Lighting.cpp index c0eb8e562..73e700837 100644 --- a/Minecraft.Client/Rendering/Lighting.cpp +++ b/Minecraft.Client/Rendering/Lighting.cpp @@ -22,13 +22,15 @@ void Lighting::turnOn() { float d = 0.6f; float s = 0.0f; - Vec3* l = Vec3::newTemp(0.2f, 1.0f, -0.7f)->normalize(); + Vec3* l = Vec3::newTemp(0.2f, 1.0f, -0.7f); + *l = l->normalize(); glLight(GL_LIGHT0, GL_POSITION, getBuffer(l->x, l->y, l->z, 0)); glLight(GL_LIGHT0, GL_DIFFUSE, getBuffer(d, d, d, 1)); glLight(GL_LIGHT0, GL_AMBIENT, getBuffer(0.0f, 0.0f, 0.0f, 1.0f)); glLight(GL_LIGHT0, GL_SPECULAR, getBuffer(s, s, s, 1.0f)); - l = Vec3::newTemp(-0.2f, 1.0f, 0.7f)->normalize(); + l = Vec3::newTemp(-0.2f, 1.0f, 0.7f); + *l = l->normalize(); glLight(GL_LIGHT1, GL_POSITION, getBuffer(l->x, l->y, l->z, 0)); glLight(GL_LIGHT1, GL_DIFFUSE, getBuffer(d, d, d, 1)); glLight(GL_LIGHT1, GL_AMBIENT, getBuffer(0.0f, 0.0f, 0.0f, 1.0f)); @@ -55,4 +57,4 @@ void Lighting::turnOnGui() { glRotatef(165, 1, 0, 0); turnOn(); glPopMatrix(); -} \ No newline at end of file +} diff --git a/Minecraft.Client/Rendering/Polygon.cpp b/Minecraft.Client/Rendering/Polygon.cpp index 28c37260e..6e5dd3d5f 100644 --- a/Minecraft.Client/Rendering/Polygon.cpp +++ b/Minecraft.Client/Rendering/Polygon.cpp @@ -45,15 +45,15 @@ void _Polygon::mirror() { } void _Polygon::render(Tesselator* t, float scale) { - Vec3* v0 = vertices[1]->pos->vectorTo(vertices[0]->pos); - Vec3* v1 = vertices[1]->pos->vectorTo(vertices[2]->pos); - Vec3* n = v1->cross(v0)->normalize(); + Vec3 v0 = vertices[1]->pos->vectorTo(*vertices[0]->pos); + Vec3 v1 = vertices[1]->pos->vectorTo(*vertices[2]->pos); + Vec3 n = v1.cross(v0).normalize(); t->begin(); if (_flipNormal) { - t->normal(-(float)n->x, -(float)n->y, -(float)n->z); + t->normal(-(float)n.x, -(float)n.y, -(float)n.z); } else { - t->normal((float)n->x, (float)n->y, (float)n->z); + t->normal((float)n.x, (float)n.y, (float)n.z); } for (int i = 0; i < 4; i++) { @@ -67,4 +67,4 @@ void _Polygon::render(Tesselator* t, float scale) { _Polygon* _Polygon::flipNormal() { _flipNormal = true; return this; -} \ No newline at end of file +} diff --git a/Minecraft.World/AI/Goals/AvoidPlayerGoal.cpp b/Minecraft.World/AI/Goals/AvoidPlayerGoal.cpp index 1e2d3cb1d..59a6e84f4 100644 --- a/Minecraft.World/AI/Goals/AvoidPlayerGoal.cpp +++ b/Minecraft.World/AI/Goals/AvoidPlayerGoal.cpp @@ -95,4 +95,4 @@ void AvoidPlayerGoal::tick() { mob->getNavigation()->setSpeedModifier(sprintSpeedModifier); else mob->getNavigation()->setSpeedModifier(walkSpeedModifier); -} \ No newline at end of file +} diff --git a/Minecraft.World/AI/Goals/BegGoal.cpp b/Minecraft.World/AI/Goals/BegGoal.cpp index de7992e6a..4c8c2bd28 100644 --- a/Minecraft.World/AI/Goals/BegGoal.cpp +++ b/Minecraft.World/AI/Goals/BegGoal.cpp @@ -54,4 +54,4 @@ bool BegGoal::playerHoldingInteresting(std::shared_ptr player) { if (item == NULL) return false; if (!wolf->isTame() && item->id == Item::bone_Id) return true; return wolf->isFood(item); -} \ No newline at end of file +} diff --git a/Minecraft.World/AI/Goals/FollowOwnerGoal.cpp b/Minecraft.World/AI/Goals/FollowOwnerGoal.cpp index 928f7e8ef..a0ddb3ccb 100644 --- a/Minecraft.World/AI/Goals/FollowOwnerGoal.cpp +++ b/Minecraft.World/AI/Goals/FollowOwnerGoal.cpp @@ -85,4 +85,4 @@ void FollowOwnerGoal::tick() { } } } -} \ No newline at end of file +} diff --git a/Minecraft.World/AI/Goals/LeapAtTargetGoal.cpp b/Minecraft.World/AI/Goals/LeapAtTargetGoal.cpp index 9779984dd..fc59fda1f 100644 --- a/Minecraft.World/AI/Goals/LeapAtTargetGoal.cpp +++ b/Minecraft.World/AI/Goals/LeapAtTargetGoal.cpp @@ -34,4 +34,4 @@ void LeapAtTargetGoal::start() { mob->xd += (xdd / dd * 0.5f) * 0.8f + mob->xd * 0.2f; mob->zd += (zdd / dd * 0.5f) * 0.8f + mob->zd * 0.2f; mob->yd = yd; -} \ No newline at end of file +} diff --git a/Minecraft.World/AI/Goals/LookAtPlayerGoal.cpp b/Minecraft.World/AI/Goals/LookAtPlayerGoal.cpp index 631362809..32cd4d1d6 100644 --- a/Minecraft.World/AI/Goals/LookAtPlayerGoal.cpp +++ b/Minecraft.World/AI/Goals/LookAtPlayerGoal.cpp @@ -62,4 +62,4 @@ void LookAtPlayerGoal::tick() { lookAt.lock()->x, lookAt.lock()->y + lookAt.lock()->getHeadHeight(), lookAt.lock()->z, 10, mob->getMaxHeadXRot()); --lookTime; -} \ No newline at end of file +} diff --git a/Minecraft.World/AI/Goals/MoveIndoorsGoal.cpp b/Minecraft.World/AI/Goals/MoveIndoorsGoal.cpp index db570665d..01b7b6cba 100644 --- a/Minecraft.World/AI/Goals/MoveIndoorsGoal.cpp +++ b/Minecraft.World/AI/Goals/MoveIndoorsGoal.cpp @@ -68,4 +68,4 @@ void MoveIndoorsGoal::stop() { insideX = _doorInfo->getIndoorX(); insideZ = _doorInfo->getIndoorZ(); doorInfo = std::weak_ptr(); -} \ No newline at end of file +} diff --git a/Minecraft.World/AI/Goals/MoveTowardsTargetGoal.cpp b/Minecraft.World/AI/Goals/MoveTowardsTargetGoal.cpp index d00147b38..a218b78f3 100644 --- a/Minecraft.World/AI/Goals/MoveTowardsTargetGoal.cpp +++ b/Minecraft.World/AI/Goals/MoveTowardsTargetGoal.cpp @@ -41,4 +41,4 @@ void MoveTowardsTargetGoal::stop() { target = std::weak_ptr(); } void MoveTowardsTargetGoal::start() { mob->getNavigation()->moveTo(wantedX, wantedY, wantedZ, speedModifier); -} \ No newline at end of file +} diff --git a/Minecraft.World/AI/Goals/NearestAttackableTargetGoal.cpp b/Minecraft.World/AI/Goals/NearestAttackableTargetGoal.cpp index bdb2d72e2..a67f91cf9 100644 --- a/Minecraft.World/AI/Goals/NearestAttackableTargetGoal.cpp +++ b/Minecraft.World/AI/Goals/NearestAttackableTargetGoal.cpp @@ -74,4 +74,4 @@ bool NearestAttackableTargetGoal::canUse() { void NearestAttackableTargetGoal::start() { mob->setTarget(target.lock()); TargetGoal::start(); -} \ No newline at end of file +} diff --git a/Minecraft.World/AI/Goals/OcelotAttackGoal.cpp b/Minecraft.World/AI/Goals/OcelotAttackGoal.cpp index 5f56a3712..d14d3bc9d 100644 --- a/Minecraft.World/AI/Goals/OcelotAttackGoal.cpp +++ b/Minecraft.World/AI/Goals/OcelotAttackGoal.cpp @@ -57,4 +57,4 @@ void OcelotAttackGoal::tick() { if (attackTime > 0) return; attackTime = 20; mob->doHurtTarget(target.lock()); -} \ No newline at end of file +} diff --git a/Minecraft.World/AI/Goals/SitGoal.cpp b/Minecraft.World/AI/Goals/SitGoal.cpp index 6a7a3fa14..2ec85aff7 100644 --- a/Minecraft.World/AI/Goals/SitGoal.cpp +++ b/Minecraft.World/AI/Goals/SitGoal.cpp @@ -38,4 +38,4 @@ void SitGoal::start() { void SitGoal::stop() { mob->setSitting(false); } -void SitGoal::wantToSit(bool _wantToSit) { this->_wantToSit = _wantToSit; } \ No newline at end of file +void SitGoal::wantToSit(bool _wantToSit) { this->_wantToSit = _wantToSit; } diff --git a/Minecraft.World/AI/Goals/TakeFlowerGoal.cpp b/Minecraft.World/AI/Goals/TakeFlowerGoal.cpp index 455c84c8b..e7c5410c4 100644 --- a/Minecraft.World/AI/Goals/TakeFlowerGoal.cpp +++ b/Minecraft.World/AI/Goals/TakeFlowerGoal.cpp @@ -72,4 +72,4 @@ void TakeFlowerGoal::tick() { villager->getNavigation()->stop(); } } -} \ No newline at end of file +} diff --git a/Minecraft.World/AI/Goals/TargetGoal.cpp b/Minecraft.World/AI/Goals/TargetGoal.cpp index 4c424e03e..5d7751ee7 100644 --- a/Minecraft.World/AI/Goals/TargetGoal.cpp +++ b/Minecraft.World/AI/Goals/TargetGoal.cpp @@ -115,4 +115,4 @@ bool TargetGoal::canReach(std::shared_ptr target) { int zz = last->z - Mth::floor(target->z); delete path; return xx * xx + zz * zz <= 1.5 * 1.5; -} \ No newline at end of file +} diff --git a/Minecraft.World/AI/Goals/TemptGoal.cpp b/Minecraft.World/AI/Goals/TemptGoal.cpp index 82738d257..c0b06eb93 100644 --- a/Minecraft.World/AI/Goals/TemptGoal.cpp +++ b/Minecraft.World/AI/Goals/TemptGoal.cpp @@ -84,4 +84,4 @@ void TemptGoal::tick() { mob->getNavigation()->moveTo(player.lock(), speedModifier); } -bool TemptGoal::isRunning() { return _isRunning; } \ No newline at end of file +bool TemptGoal::isRunning() { return _isRunning; } diff --git a/Minecraft.World/AI/Goals/TradeWithPlayerGoal.cpp b/Minecraft.World/AI/Goals/TradeWithPlayerGoal.cpp index cfb14d6e0..61219b4d5 100644 --- a/Minecraft.World/AI/Goals/TradeWithPlayerGoal.cpp +++ b/Minecraft.World/AI/Goals/TradeWithPlayerGoal.cpp @@ -38,4 +38,4 @@ bool TradeWithPlayerGoal::canUse() { void TradeWithPlayerGoal::start() { mob->getNavigation()->stop(); } -void TradeWithPlayerGoal::stop() { mob->setTradingPlayer(nullptr); } \ No newline at end of file +void TradeWithPlayerGoal::stop() { mob->setTradingPlayer(nullptr); } diff --git a/Minecraft.World/AI/Navigation/PathFinder.cpp b/Minecraft.World/AI/Navigation/PathFinder.cpp index 0fe650e3b..20a730c4a 100644 --- a/Minecraft.World/AI/Navigation/PathFinder.cpp +++ b/Minecraft.World/AI/Navigation/PathFinder.cpp @@ -283,4 +283,4 @@ Path* PathFinder::reconstruct_path(Node* from, Node* to) { Path* ret = new Path(nodes); delete[] nodes.data; return ret; -} \ No newline at end of file +} diff --git a/Minecraft.World/AI/Navigation/PathNavigation.cpp b/Minecraft.World/AI/Navigation/PathNavigation.cpp index a80e4d4ef..0160d92f0 100644 --- a/Minecraft.World/AI/Navigation/PathNavigation.cpp +++ b/Minecraft.World/AI/Navigation/PathNavigation.cpp @@ -151,7 +151,7 @@ void PathNavigation::updatePath() { float waypointRadiusSqr = mob->bbWidth * mob->bbWidth; for (int i = path->getIndex(); i < firstElevation; ++i) { Vec3* pathPos = path->getPos(mob->shared_from_this(), i); - if (mobPos->distanceToSqr(pathPos) < waypointRadiusSqr) { + if (mobPos->distanceToSqr(*pathPos) < waypointRadiusSqr) { path->setIndex(i + 1); } } @@ -170,7 +170,7 @@ void PathNavigation::updatePath() { // stuck detection (probably pushed off path) if (_tick - lastStuckCheck > 100) { - if (mobPos->distanceToSqr(lastStuckCheckPos) < 1.5 * 1.5) stop(); + if (mobPos->distanceToSqr(*lastStuckCheckPos) < 1.5 * 1.5) stop(); lastStuckCheck = _tick; lastStuckCheckPos->x = mobPos->x; lastStuckCheckPos->y = mobPos->y; @@ -329,4 +329,4 @@ bool PathNavigation::canWalkAbove(int startX, int startY, int startZ, int sx, return true; } -void PathNavigation::setLevel(Level* level) { this->level = level; } \ No newline at end of file +void PathNavigation::setLevel(Level* level) { this->level = level; } diff --git a/Minecraft.World/Blocks/LiquidTile.cpp b/Minecraft.World/Blocks/LiquidTile.cpp index e307e2125..348982c5f 100644 --- a/Minecraft.World/Blocks/LiquidTile.cpp +++ b/Minecraft.World/Blocks/LiquidTile.cpp @@ -135,14 +135,14 @@ Vec3* LiquidTile::getFlow(LevelSource* level, int x, int y, int z) { t = getRenderedDepth(level, xt, yt - 1, zt); if (t >= 0) { int dir = t - (mid - 8); - flow = flow->add((xt - x) * dir, (yt - y) * dir, - (zt - z) * dir); + *flow = flow->add((xt - x) * dir, (yt - y) * dir, + (zt - z) * dir); } } } else { if (t >= 0) { int dir = t - mid; - flow = + *flow = flow->add((xt - x) * dir, (yt - y) * dir, (zt - z) * dir); } } @@ -157,9 +157,9 @@ Vec3* LiquidTile::getFlow(LevelSource* level, int x, int y, int z) { if (ok || isSolidFace(level, x, y + 1, z + 1, 3)) ok = true; if (ok || isSolidFace(level, x - 1, y + 1, z, 4)) ok = true; if (ok || isSolidFace(level, x + 1, y + 1, z, 5)) ok = true; - if (ok) flow = flow->normalize()->add(0, -6, 0); + if (ok) *flow = flow->normalize().add(0, -6, 0); } - flow = flow->normalize(); + *flow = flow->normalize(); return flow; } diff --git a/Minecraft.World/Blocks/StairTile.cpp b/Minecraft.World/Blocks/StairTile.cpp index f03aa9a08..2990ada14 100644 --- a/Minecraft.World/Blocks/StairTile.cpp +++ b/Minecraft.World/Blocks/StairTile.cpp @@ -443,7 +443,7 @@ HitResult* StairTile::clip(Level* level, int xt, int yt, int zt, Vec3* a, for (unsigned int i = 0; i < 8; ++i) { HitResult* result = results[i]; if (result != NULL) { - double dist = result->pos->distanceToSqr(b); + double dist = result->pos.distanceToSqr(*b); if (dist > closestDist) { closest = result; diff --git a/Minecraft.World/Blocks/Tile.cpp b/Minecraft.World/Blocks/Tile.cpp index 73dc4a523..67457536c 100644 --- a/Minecraft.World/Blocks/Tile.cpp +++ b/Minecraft.World/Blocks/Tile.cpp @@ -15,6 +15,7 @@ #include "../Headers/net.minecraft.world.food.h" #include "../Headers/net.minecraft.world.h" #include "../Headers/net.minecraft.h" +#include "Util/Vec3.h" #include "Tile.h" std::wstring Tile::TILE_DESCRIPTION_PREFIX = L"Tile."; @@ -2120,52 +2121,65 @@ float Tile::getExplosionResistance(std::shared_ptr source) { HitResult* Tile::clip(Level* level, int xt, int yt, int zt, Vec3* a, Vec3* b) { updateShape(level, xt, yt, zt); - a = a->add(-xt, -yt, -zt); - b = b->add(-xt, -yt, -zt); + *a = a->add(-xt, -yt, -zt); + *b = b->add(-xt, -yt, -zt); ThreadStorage* tls = m_tlsShape; - Vec3* xh0 = a->clipX(b, tls->xx0); - Vec3* xh1 = a->clipX(b, tls->xx1); + auto xh0 = a->clipX(*b, tls->xx0); + auto xh1 = a->clipX(*b, tls->xx1); - Vec3* yh0 = a->clipY(b, tls->yy0); - Vec3* yh1 = a->clipY(b, tls->yy1); + auto yh0 = a->clipY(*b, tls->yy0); + auto yh1 = a->clipY(*b, tls->yy1); - Vec3* zh0 = a->clipZ(b, tls->zz0); - Vec3* zh1 = a->clipZ(b, tls->zz1); + auto zh0 = a->clipZ(*b, tls->zz0); + auto zh1 = a->clipZ(*b, tls->zz1); - Vec3* closest = NULL; + Vec3* closest = nullptr; - if (containsX(xh0) && - (closest == NULL || a->distanceToSqr(xh0) < a->distanceToSqr(closest))) - closest = xh0; - if (containsX(xh1) && - (closest == NULL || a->distanceToSqr(xh1) < a->distanceToSqr(closest))) - closest = xh1; - if (containsY(yh0) && - (closest == NULL || a->distanceToSqr(yh0) < a->distanceToSqr(closest))) - closest = yh0; - if (containsY(yh1) && - (closest == NULL || a->distanceToSqr(yh1) < a->distanceToSqr(closest))) - closest = yh1; - if (containsZ(zh0) && - (closest == NULL || a->distanceToSqr(zh0) < a->distanceToSqr(closest))) - closest = zh0; - if (containsZ(zh1) && - (closest == NULL || a->distanceToSqr(zh1) < a->distanceToSqr(closest))) - closest = zh1; + if (xh0.has_value() and containsX(&*xh0) and + (closest == nullptr or + a->distanceToSqr(*xh0) < a->distanceToSqr(*closest))) + *closest = *xh0; + + if (xh1.has_value() and containsX(&*xh1) and + (closest == nullptr or + a->distanceToSqr(*xh1) < a->distanceToSqr(*closest))) + *closest = *xh1; + + if (yh0.has_value() and containsY(&*yh0) and + (closest == nullptr or + a->distanceToSqr(*yh0) < a->distanceToSqr(*closest))) + *closest = *yh0; + + if (yh1.has_value() and containsY(&*yh1) and + (closest == nullptr or + a->distanceToSqr(*yh1) < a->distanceToSqr(*closest))) + *closest = *yh1; + + if (zh0.has_value() and containsZ(&*zh0) and + (closest == nullptr or + a->distanceToSqr(*zh0) < a->distanceToSqr(*closest))) + *closest = *zh0; + + if (zh1.has_value() and containsZ(&*zh1) and + (closest == nullptr or + a->distanceToSqr(*zh1) < a->distanceToSqr(*closest))) + *closest = *zh1; if (closest == NULL) return NULL; int face = -1; - if (closest == xh0) face = Facing::WEST; - if (closest == xh1) face = Facing::EAST; - if (closest == yh0) face = Facing::DOWN; - if (closest == yh1) face = Facing::UP; - if (closest == zh0) face = Facing::NORTH; - if (closest == zh1) face = Facing::SOUTH; + if (*closest == xh0) face = Facing::WEST; + if (*closest == xh1) face = Facing::EAST; + if (*closest == yh0) face = Facing::DOWN; + if (*closest == yh1) face = Facing::UP; + if (*closest == zh0) face = Facing::NORTH; + if (*closest == zh1) face = Facing::SOUTH; - return new HitResult(xt, yt, zt, face, closest->add(xt, yt, zt)); + *closest = closest->add(xt, yt, zt); + + return new HitResult(xt, yt, zt, face, *closest); } bool Tile::containsX(Vec3* v) { diff --git a/Minecraft.World/Containers/HorseInventoryMenu.cpp b/Minecraft.World/Containers/HorseInventoryMenu.cpp index e4766aaef..a492bb442 100644 --- a/Minecraft.World/Containers/HorseInventoryMenu.cpp +++ b/Minecraft.World/Containers/HorseInventoryMenu.cpp @@ -113,4 +113,4 @@ void HorseInventoryMenu::removed(std::shared_ptr player) { std::shared_ptr HorseInventoryMenu::getContainer() { return horseContainer; -} \ No newline at end of file +} diff --git a/Minecraft.World/Entities/Entity.cpp b/Minecraft.World/Entities/Entity.cpp index 1c4170040..dc3ee4dd7 100644 --- a/Minecraft.World/Entities/Entity.cpp +++ b/Minecraft.World/Entities/Entity.cpp @@ -1874,4 +1874,4 @@ unsigned int Entity::getAnimOverrideBitmask() { } return m_uiAnimOverrideBitmask; -} \ No newline at end of file +} diff --git a/Minecraft.World/Entities/Entity.h b/Minecraft.World/Entities/Entity.h index ea827e28f..bc7d0a4dc 100644 --- a/Minecraft.World/Entities/Entity.h +++ b/Minecraft.World/Entities/Entity.h @@ -424,6 +424,7 @@ private: static int extraWanderTicks; static thread_local bool m_tlsUseSmallIds; + public: static void tickExtraWandering(); static void countFlagsForPIX(); diff --git a/Minecraft.World/Entities/LivingEntity.cpp b/Minecraft.World/Entities/LivingEntity.cpp index e795f18cf..571f69273 100644 --- a/Minecraft.World/Entities/LivingEntity.cpp +++ b/Minecraft.World/Entities/LivingEntity.cpp @@ -31,6 +31,7 @@ #include "../Util/ParticleTypes.h" #include "../Stats/GenericStats.h" #include "ItemEntity.h" +#include "Util/Vec3.h" const double LivingEntity::MIN_MOVEMENT_DISTANCE = 0.005; @@ -800,7 +801,7 @@ void LivingEntity::breakItem(std::shared_ptr itemInstance) { -random->nextFloat() * 0.6 - 0.3, 0.6); p->xRot(-xRot * PI / 180); p->yRot(-yRot * PI / 180); - p = p->add(x, y + getHeadHeight(), z); + *p = p->add(x, y + getHeadHeight(), z); level->addParticle(PARTICLE_ICONCRACK(itemInstance->getItem()->id, 0), p->x, p->y, p->z, d->x, d->y + 0.05, d->z); } @@ -1691,7 +1692,8 @@ Vec3* LivingEntity::getPos(float a) { HitResult* LivingEntity::pick(double range, float a) { Vec3* from = getPos(a); Vec3* b = getViewVector(a); - Vec3* to = from->add(b->x * range, b->y * range, b->z * range); + Vec3* to = Vec3::newTemp(b->x * range, b->y * range, b->z * range); + *to = to->add(from->x, from->y, from->z); return level->clip(from, to); } diff --git a/Minecraft.World/Entities/MinecartContainer.cpp b/Minecraft.World/Entities/MinecartContainer.cpp index 63364c434..ca25f81df 100644 --- a/Minecraft.World/Entities/MinecartContainer.cpp +++ b/Minecraft.World/Entities/MinecartContainer.cpp @@ -210,4 +210,4 @@ void MinecartContainer::applyNaturalSlowdown() { xd *= keep; yd *= 0; zd *= keep; -} \ No newline at end of file +} diff --git a/Minecraft.World/Entities/Mobs/Arrow.cpp b/Minecraft.World/Entities/Mobs/Arrow.cpp index fc6562f26..1a5db2c82 100644 --- a/Minecraft.World/Entities/Mobs/Arrow.cpp +++ b/Minecraft.World/Entities/Mobs/Arrow.cpp @@ -224,7 +224,7 @@ void Arrow::tick() { from = Vec3::newTemp(x, y, z); to = Vec3::newTemp(x + xd, y + yd, z + zd); if (res != NULL) { - to = Vec3::newTemp(res->pos->x, res->pos->y, res->pos->z); + to = Vec3::newTemp(res->pos.x, res->pos.y, res->pos.z); } std::shared_ptr hitEntity = nullptr; std::vector >* objects = level->getEntities( @@ -359,9 +359,9 @@ void Arrow::tick() { zTile = res->z; lastTile = level->getTile(xTile, yTile, zTile); lastData = level->getData(xTile, yTile, zTile); - xd = (float)(res->pos->x - x); - yd = (float)(res->pos->y - y); - zd = (float)(res->pos->z - z); + xd = (float)(res->pos.x - x); + yd = (float)(res->pos.y - y); + zd = (float)(res->pos.z - z); float dd = (float)sqrt(xd * xd + yd * yd + zd * zd); // 4J added check - zero dd here was creating NaNs if (dd > 0.0001f) { diff --git a/Minecraft.World/Entities/Mobs/DragonFireball.cpp b/Minecraft.World/Entities/Mobs/DragonFireball.cpp index 29fa582d0..62f4a067c 100644 --- a/Minecraft.World/Entities/Mobs/DragonFireball.cpp +++ b/Minecraft.World/Entities/Mobs/DragonFireball.cpp @@ -67,4 +67,4 @@ ePARTICLE_TYPE DragonFireball::getTrailParticleType() { return eParticleType_dragonbreath; } -bool DragonFireball::shouldBurn() { return false; } \ No newline at end of file +bool DragonFireball::shouldBurn() { return false; } diff --git a/Minecraft.World/Entities/Mobs/EnderDragon.cpp b/Minecraft.World/Entities/Mobs/EnderDragon.cpp index 582bda987..b2726950b 100644 --- a/Minecraft.World/Entities/Mobs/EnderDragon.cpp +++ b/Minecraft.World/Entities/Mobs/EnderDragon.cpp @@ -314,7 +314,8 @@ void EnderDragon::aiStep() { // v->y, v->z, lSteps); unsigned int d = 0; for(unsigned int d = 1; // d < 3; ++d) { - Vec3* vN = v->normalize(); + Vec3* vN = Vec3::newTemp(v->x, v->y, v->z); + *vN = v->normalize(); vN->yRot(-PI / 4); for (unsigned int i = 0; i < 8; ++i) { if (getSynchedAction() == e_EnderdragonAction_Landing) { @@ -478,12 +479,14 @@ void EnderDragon::aiStep() { } else if (getSynchedAction() == e_EnderdragonAction_Sitting_Scanning) { if (attackTarget != NULL) { Vec3* aim = Vec3::newTemp((attackTarget->x - x), 0, - (attackTarget->z - z)) - ->normalize(); + (attackTarget->z - z)); + *aim = aim->normalize(); + Vec3* dir = Vec3::newTemp(sin(yRot * PI / 180), 0, - -cos(yRot * PI / 180)) - ->normalize(); - float dot = (float)dir->dot(aim); + -cos(yRot * PI / 180)); + + *dir = dir->normalize(); + float dot = (float)dir->dot(*aim); float angleDegs = acos(dot) * 180 / PI; angleDegs = angleDegs + 0.5f; @@ -562,12 +565,13 @@ void EnderDragon::aiStep() { if (yRotD < -50) yRotD = -50; Vec3* aim = - Vec3::newTemp((xTarget - x), (yTarget - y), (zTarget - z)) - ->normalize(); + Vec3::newTemp((xTarget - x), (yTarget - y), (zTarget - z)); + *aim = aim->normalize(); + Vec3* dir = - Vec3::newTemp(sin(yRot * PI / 180), yd, -cos(yRot * PI / 180)) - ->normalize(); - float dot = (float)(dir->dot(aim) + 0.5f) / 1.5f; + Vec3::newTemp(sin(yRot * PI / 180), yd, -cos(yRot * PI / 180)); + *dir = dir->normalize(); + float dot = (float)(dir->dot(*aim) + 0.5f) / 1.5f; if (dot < 0) dot = 0; yRotA *= 0.80f; @@ -591,8 +595,9 @@ void EnderDragon::aiStep() { move(xd, yd, zd); } - Vec3* actual = Vec3::newTemp(xd, yd, zd)->normalize(); - float slide = (float)(actual->dot(dir) + 1) / 2.0f; + Vec3* actual = Vec3::newTemp(xd, yd, zd); + *actual = actual->normalize(); + float slide = (float)(actual->dot(*dir) + 1) / 2.0f; slide = 0.8f + 0.15f * slide; xd *= slide; @@ -734,12 +739,14 @@ void EnderDragon::aiStep() { if (this->canSee(attackTarget)) { m_fireballCharge++; Vec3* aim = Vec3::newTemp((attackTarget->x - x), 0, - (attackTarget->z - z)) - ->normalize(); + (attackTarget->z - z)); + *aim = aim->normalize(); + Vec3* dir = Vec3::newTemp(sin(yRot * PI / 180), 0, - -cos(yRot * PI / 180)) - ->normalize(); - float dot = (float)dir->dot(aim); + -cos(yRot * PI / 180)); + *dir = dir->normalize(); + + float dot = (float)dir->dot(*aim); float angleDegs = acos(dot) * 180 / PI; angleDegs = angleDegs + 0.5f; @@ -979,8 +986,8 @@ void EnderDragon::findNewTarget() { int targetNodeIndex = 0; if (playerNearestToEgg != NULL) { Vec3* aim = Vec3::newTemp(playerNearestToEgg->x, 0, - playerNearestToEgg->z) - ->normalize(); + playerNearestToEgg->z); + *aim = aim->normalize(); // app.DebugPrintf("Final marker node near (%f,%d,%f)\n", // -aim->x*40,105,-aim->z*40 ); targetNodeIndex = diff --git a/Minecraft.World/Entities/Mobs/EnderMan.cpp b/Minecraft.World/Entities/Mobs/EnderMan.cpp index 986143ab9..3e2586874 100644 --- a/Minecraft.World/Entities/Mobs/EnderMan.cpp +++ b/Minecraft.World/Entities/Mobs/EnderMan.cpp @@ -114,14 +114,16 @@ bool EnderMan::isLookingAtMe(std::shared_ptr player) { std::shared_ptr helmet = player->inventory->armor[3]; if (helmet != NULL && helmet->id == Tile::pumpkin_Id) return false; - Vec3* look = player->getViewVector(1)->normalize(); + Vec3* look = player->getViewVector(1); + *look = look->normalize(); + Vec3* dir = Vec3::newTemp( x - player->x, (bb->y0 + bbHeight / 2) - (player->y + player->getHeadHeight()), z - player->z); double dist = dir->length(); - dir = dir->normalize(); - double dot = look->dot(dir); + *dir = dir->normalize(); + double dot = look->dot(*dir); if (dot > 1 - 0.025 / dist) { return player->canSee(shared_from_this()); } @@ -251,7 +253,7 @@ bool EnderMan::teleport() { bool EnderMan::teleportTowards(std::shared_ptr e) { Vec3* dir = Vec3::newTemp( x - e->x, bb->y0 + bbHeight / 2 - e->y + e->getHeadHeight(), z - e->z); - dir = dir->normalize(); + *dir = dir->normalize(); double d = 16; double xx = x + (random->nextDouble() - 0.5) * 8 - dir->x * d; double yy = y + (random->nextInt(16) - 8) - dir->y * d; @@ -378,4 +380,4 @@ bool EnderMan::isCreepy() { return entityData->getByte(DATA_CREEPY) > 0; } void EnderMan::setCreepy(bool creepy) { entityData->set(DATA_CREEPY, (uint8_t)(creepy ? 1 : 0)); -} \ No newline at end of file +} diff --git a/Minecraft.World/Entities/Mobs/ExperienceOrb.cpp b/Minecraft.World/Entities/Mobs/ExperienceOrb.cpp index 83aa925af..26418c28e 100644 --- a/Minecraft.World/Entities/Mobs/ExperienceOrb.cpp +++ b/Minecraft.World/Entities/Mobs/ExperienceOrb.cpp @@ -265,4 +265,4 @@ bool ExperienceOrb::shouldRender(Vec3* c) { if (distance < 4) return false; return Entity::shouldRender(c); -} \ No newline at end of file +} diff --git a/Minecraft.World/Entities/Mobs/Fireball.cpp b/Minecraft.World/Entities/Mobs/Fireball.cpp index 1bf7bf6df..c7e1a805d 100644 --- a/Minecraft.World/Entities/Mobs/Fireball.cpp +++ b/Minecraft.World/Entities/Mobs/Fireball.cpp @@ -173,7 +173,7 @@ void Fireball::tick() { from = Vec3::newTemp(x, y, z); to = Vec3::newTemp(x + xd, y + yd, z + zd); if (res != NULL) { - to = Vec3::newTemp(res->pos->x, res->pos->y, res->pos->z); + *to = Vec3{res->pos.x, res->pos.y, res->pos.z}; } std::shared_ptr hitEntity = nullptr; std::vector >* objects = level->getEntities( @@ -326,4 +326,4 @@ int Fireball::getLightColor(float a) { return 15 << 20 | 15 << 4; } ePARTICLE_TYPE Fireball::getTrailParticleType() { return eParticleType_smoke; } -bool Fireball::shouldBurn() { return true; } \ No newline at end of file +bool Fireball::shouldBurn() { return true; } diff --git a/Minecraft.World/Entities/Mobs/FishingHook.cpp b/Minecraft.World/Entities/Mobs/FishingHook.cpp index f5bbb74d7..74351cc06 100644 --- a/Minecraft.World/Entities/Mobs/FishingHook.cpp +++ b/Minecraft.World/Entities/Mobs/FishingHook.cpp @@ -210,7 +210,7 @@ void FishingHook::tick() { from = Vec3::newTemp(x, y, z); to = Vec3::newTemp(x + xd, y + yd, z + zd); if (res != NULL) { - to = Vec3::newTemp(res->pos->x, res->pos->y, res->pos->z); + to = Vec3::newTemp(res->pos.x, res->pos.y, res->pos.z); } std::shared_ptr hitEntity = nullptr; std::vector >* objects = level->getEntities( @@ -412,4 +412,4 @@ int FishingHook::retrieve() { void FishingHook::remove() { Entity::remove(); if (owner != NULL) owner->fishing = nullptr; -} \ No newline at end of file +} diff --git a/Minecraft.World/Entities/Mobs/Ghast.cpp b/Minecraft.World/Entities/Mobs/Ghast.cpp index c170a0f66..a44e29e60 100644 --- a/Minecraft.World/Entities/Mobs/Ghast.cpp +++ b/Minecraft.World/Entities/Mobs/Ghast.cpp @@ -217,4 +217,4 @@ void Ghast::readAdditionalSaveData(CompoundTag* tag) { FlyingMob::readAdditionalSaveData(tag); if (tag->contains(L"ExplosionPower")) explosionPower = tag->getInt(L"ExplosionPower"); -} \ No newline at end of file +} diff --git a/Minecraft.World/Entities/Mobs/Minecart.cpp b/Minecraft.World/Entities/Mobs/Minecart.cpp index 4351c4ad8..182a7c5dd 100644 --- a/Minecraft.World/Entities/Mobs/Minecart.cpp +++ b/Minecraft.World/Entities/Mobs/Minecart.cpp @@ -129,10 +129,9 @@ bool Minecart::hurt(DamageSource* source, float hurtDamage) { if (dynamic_cast(source) != NULL) { std::shared_ptr attacker = source->getDirectEntity(); - if (attacker->instanceof - (eTYPE_PLAYER) && - !std::dynamic_pointer_cast(attacker) - ->isAllowedToHurtEntity(shared_from_this())) { + if (attacker->instanceof(eTYPE_PLAYER) && + !std::dynamic_pointer_cast(attacker)->isAllowedToHurtEntity( + shared_from_this())) { return false; } } @@ -149,9 +148,9 @@ bool Minecart::hurt(DamageSource* source, float hurtDamage) { if (rider.lock() != NULL && rider.lock() == source->getEntity()) hurtDamage += 1; - bool creativePlayer = - source->getEntity() != NULL && source->getEntity()->instanceof - (eTYPE_PLAYER) && std::dynamic_pointer_cast(source->getEntity()) + bool creativePlayer = source->getEntity() != NULL && + source->getEntity()->instanceof(eTYPE_PLAYER) && + std::dynamic_pointer_cast(source->getEntity()) ->abilities.instabuild; if (creativePlayer || getDamage() > 20 * 2) { @@ -310,8 +309,8 @@ void Minecart::tick() { AUTO_VAR(itEnd, entities->end()); for (AUTO_VAR(it, entities->begin()); it != itEnd; it++) { std::shared_ptr e = (*it); // entities->at(i); - if (e != rider.lock() && e->isPushable() && e->instanceof - (eTYPE_MINECART)) { + if (e != rider.lock() && e->isPushable() && + e->instanceof(eTYPE_MINECART)) { std::shared_ptr cart = std::dynamic_pointer_cast(e); cart->m_bHasPushedCartThisTick = false; @@ -405,7 +404,7 @@ void Minecart::moveAlongTrack(int xt, int yt, int zt, double maxSpeed, xd = pow * xD / dd; zd = pow * zD / dd; - if (rider.lock() != NULL && rider.lock()->instanceof (eTYPE_LIVINGENTITY)) { + if (rider.lock() != NULL && rider.lock()->instanceof(eTYPE_LIVINGENTITY)) { std::shared_ptr living = std::dynamic_pointer_cast(rider.lock()); @@ -689,10 +688,9 @@ void Minecart::push(std::shared_ptr e) { if (level->isClientSide) return; if (e == rider.lock()) return; - if (e->instanceof (eTYPE_LIVINGENTITY) && !e->instanceof - (eTYPE_PLAYER) && !e->instanceof - (eTYPE_VILLAGERGOLEM) && (getType() == TYPE_RIDEABLE) && - (xd * xd + zd * zd > 0.01)) { + if (e->instanceof(eTYPE_LIVINGENTITY) && !e->instanceof(eTYPE_PLAYER) && + !e->instanceof(eTYPE_VILLAGERGOLEM) && (getType() == TYPE_RIDEABLE) && + (xd * xd + zd * zd > 0.01)) { if ((rider.lock() == NULL) && (e->riding == NULL)) { e->ride(shared_from_this()); } @@ -718,7 +716,7 @@ void Minecart::push(std::shared_ptr e) { xa *= 0.5; za *= 0.5; - if (e->instanceof (eTYPE_MINECART)) { + if (e->instanceof(eTYPE_MINECART)) { double xo = e->x - x; double zo = e->z - z; @@ -726,12 +724,13 @@ void Minecart::push(std::shared_ptr e) { // other // Fix for #38882 - TU5: Gameplay: Minecart with furnace is not // able to move another minecart on the rail. - Vec3* dir = Vec3::newTemp(xo, 0, zo)->normalize(); + Vec3* dir = Vec3::newTemp(xo, 0, zo); + *dir = dir->normalize(); Vec3* facing = - Vec3::newTemp(cos(yRot * PI / 180), 0, sin(yRot * PI / 180)) - ->normalize(); + Vec3::newTemp(cos(yRot * PI / 180), 0, sin(yRot * PI / 180)); + *facing = facing->normalize(); - double dot = abs(dir->dot(facing)); + double dot = abs(dir->dot(*facing)); if (dot < 0.8f) { return; diff --git a/Minecraft.World/Entities/Mobs/Ocelot.cpp b/Minecraft.World/Entities/Mobs/Ocelot.cpp index f9a0e1bdc..b31798af2 100644 --- a/Minecraft.World/Entities/Mobs/Ocelot.cpp +++ b/Minecraft.World/Entities/Mobs/Ocelot.cpp @@ -305,4 +305,4 @@ void Ocelot::setSittingOnTile(bool val) { bool Ocelot::isSittingOnTile() { uint8_t current = entityData->getByte(DATA_FLAGS_ID); return (current & 0x02) > 0; -} \ No newline at end of file +} diff --git a/Minecraft.World/Entities/Mobs/Slime.cpp b/Minecraft.World/Entities/Mobs/Slime.cpp index a504db841..6db5e5c4b 100644 --- a/Minecraft.World/Entities/Mobs/Slime.cpp +++ b/Minecraft.World/Entities/Mobs/Slime.cpp @@ -248,4 +248,4 @@ int Slime::getMaxHeadXRot() { return 0; } bool Slime::doPlayJumpSound() { return getSize() > 0; } -bool Slime::doPlayLandSound() { return getSize() > 2; } \ No newline at end of file +bool Slime::doPlayLandSound() { return getSize() > 2; } diff --git a/Minecraft.World/Entities/Mobs/ThrownPotion.cpp b/Minecraft.World/Entities/Mobs/ThrownPotion.cpp index 3ed57fa98..7bfc9cf6a 100644 --- a/Minecraft.World/Entities/Mobs/ThrownPotion.cpp +++ b/Minecraft.World/Entities/Mobs/ThrownPotion.cpp @@ -151,4 +151,4 @@ void ThrownPotion::addAdditonalSaveData(CompoundTag* tag) { if (potionItem != NULL) tag->putCompound(L"Potion", potionItem->save(new CompoundTag())); -} \ No newline at end of file +} diff --git a/Minecraft.World/Entities/Mobs/Witch.cpp b/Minecraft.World/Entities/Mobs/Witch.cpp index 4099d1f95..50950d57f 100644 --- a/Minecraft.World/Entities/Mobs/Witch.cpp +++ b/Minecraft.World/Entities/Mobs/Witch.cpp @@ -212,4 +212,4 @@ void Witch::performRangedAttack(std::shared_ptr target, potion->shoot(xd, yd + dist * 0.2f, zd, 0.75f, 8); level->addEntity(potion); -} \ No newline at end of file +} diff --git a/Minecraft.World/Entities/Mobs/WitherBoss.cpp b/Minecraft.World/Entities/Mobs/WitherBoss.cpp index 2c6a0d849..092e810ea 100644 --- a/Minecraft.World/Entities/Mobs/WitherBoss.cpp +++ b/Minecraft.World/Entities/Mobs/WitherBoss.cpp @@ -506,4 +506,4 @@ bool WitherBoss::isPowered() { return getHealth() <= getMaxHealth() / 2; } MobType WitherBoss::getMobType() { return UNDEAD; } -void WitherBoss::ride(std::shared_ptr e) { riding = nullptr; } \ No newline at end of file +void WitherBoss::ride(std::shared_ptr e) { riding = nullptr; } diff --git a/Minecraft.World/Entities/PathfinderMob.cpp b/Minecraft.World/Entities/PathfinderMob.cpp index 8b30f6fb8..6abf6a2ac 100644 --- a/Minecraft.World/Entities/PathfinderMob.cpp +++ b/Minecraft.World/Entities/PathfinderMob.cpp @@ -328,4 +328,4 @@ void PathfinderMob::onLeashDistance(float distanceToLeashHolder) {} bool PathfinderMob::couldWander() { return (noActionTime < SharedConstants::TICKS_PER_SECOND * 5) || (isExtraWanderingEnabled()); -} \ No newline at end of file +} diff --git a/Minecraft.World/Entities/Throwable.cpp b/Minecraft.World/Entities/Throwable.cpp index 5e0165b8e..316b08313 100644 --- a/Minecraft.World/Entities/Throwable.cpp +++ b/Minecraft.World/Entities/Throwable.cpp @@ -142,7 +142,7 @@ void Throwable::tick() { from = Vec3::newTemp(x, y, z); to = Vec3::newTemp(x + xd, y + yd, z + zd); if (res != NULL) { - to = Vec3::newTemp(res->pos->x, res->pos->y, res->pos->z); + to = Vec3::newTemp(res->pos.x, res->pos.y, res->pos.z); } if (!level->isClientSide) { @@ -256,4 +256,4 @@ std::shared_ptr Throwable::getOwner() { owner = level->getPlayerByName(ownerName); } return owner; -} \ No newline at end of file +} diff --git a/Minecraft.World/Items/BoatItem.cpp b/Minecraft.World/Items/BoatItem.cpp index 90f9b7f32..b7ed93864 100644 --- a/Minecraft.World/Items/BoatItem.cpp +++ b/Minecraft.World/Items/BoatItem.cpp @@ -5,6 +5,7 @@ #include "../Headers/net.minecraft.world.level.tile.h" #include "../Headers/net.minecraft.world.phys.h" #include "ItemInstance.h" +#include "Util/Vec3.h" #include "BoatItem.h" BoatItem::BoatItem(int id) : Item(id) { maxStackSize = 1; } @@ -36,7 +37,8 @@ bool BoatItem::TestUse(std::shared_ptr itemInstance, Level* level, float za = yCos * xCos; double range = 5; - Vec3* to = from->add(xa * range, ya * range, za * range); + Vec3* to = Vec3::newTemp(xa * range, ya * range, za * range); + *to = to->add(from->x, from->y, from->z); HitResult* hr = level->clip(from, to, true); if (hr == NULL) return false; @@ -72,7 +74,8 @@ std::shared_ptr BoatItem::use( float za = yCos * xCos; double range = 5; - Vec3* to = from->add(xa * range, ya * range, za * range); + Vec3* to = Vec3::newTemp(xa * range, ya * range, za * range); + *to = to->add(from->x, from->y, from->z); HitResult* hr = level->clip(from, to, true); if (hr == NULL) return itemInstance; @@ -131,4 +134,4 @@ std::shared_ptr BoatItem::use( delete hr; return itemInstance; -} \ No newline at end of file +} diff --git a/Minecraft.World/Items/Item.cpp b/Minecraft.World/Items/Item.cpp index 401aa4e1e..85124b3fa 100644 --- a/Minecraft.World/Items/Item.cpp +++ b/Minecraft.World/Items/Item.cpp @@ -15,6 +15,7 @@ #include "Item.h" #include "HangingEntityItem.h" #include "../Util/HtmlString.h" +#include "Util/Vec3.h" typedef Item::Tier _Tier; @@ -1614,7 +1615,8 @@ HitResult* Item::getPlayerPOVHitResult(Level* level, float za = yCos * xCos; double range = 5; - Vec3* to = from->add(xa * range, ya * range, za * range); + Vec3* to = Vec3::newTemp(xa * range, ya * range, za * range); + *to = to->add(from->x, from->y, from->z); return level->clip(from, to, alsoPickLiquid, !alsoPickLiquid); } diff --git a/Minecraft.World/Level/ChunkPos.h b/Minecraft.World/Level/ChunkPos.h index 9a2eabca4..e38a551a5 100644 --- a/Minecraft.World/Level/ChunkPos.h +++ b/Minecraft.World/Level/ChunkPos.h @@ -44,4 +44,4 @@ struct ChunkPosKeyEq { bool operator()(const ChunkPos& x, const ChunkPos& y) const { return ChunkPos::eq_test(x, y); } -}; \ No newline at end of file +}; diff --git a/Minecraft.World/Level/Level.cpp b/Minecraft.World/Level/Level.cpp index 4c8862d2d..8e72c6f05 100644 --- a/Minecraft.World/Level/Level.cpp +++ b/Minecraft.World/Level/Level.cpp @@ -2490,7 +2490,7 @@ bool Level::checkAndHandleWater(AABB* box, Material* material, } } if (current->length() > 0 && e->isPushedByWater()) { - current = current->normalize(); + *current = current->normalize(); double pow = 0.014; e->xd += current->x * pow; e->yd += current->y * pow; diff --git a/Minecraft.World/Level/RandomLevelSource.cpp b/Minecraft.World/Level/RandomLevelSource.cpp index 62c72926a..6db10eaea 100644 --- a/Minecraft.World/Level/RandomLevelSource.cpp +++ b/Minecraft.World/Level/RandomLevelSource.cpp @@ -121,9 +121,9 @@ int RandomLevelSource::getMinDistanceToEdge(int xxx, int zzz, int worldSize, (xxx > (max - falloffStart) && xxx < (max + falloffStart))) { Vec3* point = Vec3::newTemp(xxx, 0, zzz); if (xxx > 0) - dist = point->distanceFromLine(topRight, bottomRight); + dist = point->distanceFromLine(*topRight, *bottomRight); else - dist = point->distanceFromLine(topLeft, bottomLeft); + dist = point->distanceFromLine(*topLeft, *bottomLeft); closest = dist; } @@ -132,9 +132,9 @@ int RandomLevelSource::getMinDistanceToEdge(int xxx, int zzz, int worldSize, (zzz > (max - falloffStart) && zzz < (max + falloffStart))) { Vec3* point = Vec3::newTemp(xxx, 0, zzz); if (zzz > 0) - dist = point->distanceFromLine(bottomLeft, bottomRight); + dist = point->distanceFromLine(*bottomLeft, *bottomRight); else - dist = point->distanceFromLine(topLeft, topRight); + dist = point->distanceFromLine(*topLeft, *topRight); if (dist < closest) closest = dist; } diff --git a/Minecraft.World/Player/Player.cpp b/Minecraft.World/Player/Player.cpp index f7b8e9b85..7253d1633 100644 --- a/Minecraft.World/Player/Player.cpp +++ b/Minecraft.World/Player/Player.cpp @@ -435,7 +435,7 @@ void Player::tick() { // minecart. For some reason some of the torches come off so it will also need some fixing along the way. static bool madeTrack = false; if( !madeTrack ) - { + { this->drop( std::shared_ptr( new ItemInstance( Item::minecart, 1 ) ) ); this->drop( std::shared_ptr( new ItemInstance( Tile::goldenRail, 10 ) ) ); this->drop( std::shared_ptr( new ItemInstance( Tile::lever, 10 ) ) ); @@ -537,7 +537,7 @@ void Player::spawnEatParticles(std::shared_ptr useItem, -random->nextFloat() * 0.6 - 0.3, 0.6); p->xRot(-xRot * PI / 180); p->yRot(-yRot * PI / 180); - p = p->add(x, y + getHeadHeight(), z); + *p = p->add(x, y + getHeadHeight(), z); level->addParticle(PARTICLE_ICONCRACK(useItem->getItem()->id, 0), p->x, p->y, p->z, d->x, d->y + 0.05, d->z); diff --git a/Minecraft.World/Util/AABB.cpp b/Minecraft.World/Util/AABB.cpp index c4a8bff2e..b5f98c1a9 100644 --- a/Minecraft.World/Util/AABB.cpp +++ b/Minecraft.World/Util/AABB.cpp @@ -5,7 +5,9 @@ #include "../Platform/stdafx.h" #include "AABB.h" +#include #include "HitResult.h" +#include "Util/Vec3.h" unsigned int AABB::tlsIdx = 0; AABB::ThreadStorage* AABB::tlsDefault = NULL; @@ -238,55 +240,62 @@ AABB* AABB::shrink(double xa, double ya, double za) { AABB* AABB::copy() { return AABB::newTemp(x0, y0, z0, x1, y1, z1); } HitResult* AABB::clip(Vec3* a, Vec3* b) { - Vec3* xh0 = a->clipX(b, x0); - Vec3* xh1 = a->clipX(b, x1); + auto xh0 = a->clipX(*b, x0); + auto xh1 = a->clipX(*b, x1); - Vec3* yh0 = a->clipY(b, y0); - Vec3* yh1 = a->clipY(b, y1); + auto yh0 = a->clipY(*b, y0); + auto yh1 = a->clipY(*b, y1); - Vec3* zh0 = a->clipZ(b, z0); - Vec3* zh1 = a->clipZ(b, z1); + auto zh0 = a->clipZ(*b, z0); + auto zh1 = a->clipZ(*b, z1); - if (!containsX(xh0)) xh0 = NULL; - if (!containsX(xh1)) xh1 = NULL; - if (!containsY(yh0)) yh0 = NULL; - if (!containsY(yh1)) yh1 = NULL; - if (!containsZ(zh0)) zh0 = NULL; - if (!containsZ(zh1)) zh1 = NULL; + if (!(xh0.has_value() and containsX(&*xh0))) xh0 = std::nullopt; + if (!(xh1.has_value() and containsX(&*xh1))) xh1 = std::nullopt; + if (!(yh0.has_value() and containsY(&*yh0))) yh0 = std::nullopt; + if (!(yh1.has_value() and containsY(&*yh1))) yh1 = std::nullopt; + if (!(zh0.has_value() and containsZ(&*zh0))) zh0 = std::nullopt; + if (!(zh1.has_value() and containsZ(&*zh1))) zh1 = std::nullopt; + Vec3* closest = nullptr; - Vec3* closest = NULL; + if (xh0.has_value() and + (closest == nullptr or + a->distanceToSqr(*xh0) < a->distanceToSqr(*closest))) + *closest = *xh0; + if (xh1.has_value() and + (closest == nullptr or + a->distanceToSqr(*xh1) < a->distanceToSqr(*closest))) + *closest = *xh1; + if (yh0.has_value() and + (closest == nullptr or + a->distanceToSqr(*yh0) < a->distanceToSqr(*closest))) + *closest = *yh0; + if (yh1.has_value() and + (closest == nullptr or + a->distanceToSqr(*yh1) < a->distanceToSqr(*closest))) + *closest = *yh1; + if (zh0.has_value() and + (closest == nullptr or + a->distanceToSqr(*zh0) < a->distanceToSqr(*closest))) + *closest = *zh0; + if (zh1.has_value() and + (closest == nullptr or + a->distanceToSqr(*zh1) < a->distanceToSqr(*closest))) + *closest = *zh1; - if (xh0 != NULL && - (closest == NULL || a->distanceToSqr(xh0) < a->distanceToSqr(closest))) - closest = xh0; - if (xh1 != NULL && - (closest == NULL || a->distanceToSqr(xh1) < a->distanceToSqr(closest))) - closest = xh1; - if (yh0 != NULL && - (closest == NULL || a->distanceToSqr(yh0) < a->distanceToSqr(closest))) - closest = yh0; - if (yh1 != NULL && - (closest == NULL || a->distanceToSqr(yh1) < a->distanceToSqr(closest))) - closest = yh1; - if (zh0 != NULL && - (closest == NULL || a->distanceToSqr(zh0) < a->distanceToSqr(closest))) - closest = zh0; - if (zh1 != NULL && - (closest == NULL || a->distanceToSqr(zh1) < a->distanceToSqr(closest))) - closest = zh1; - - if (closest == NULL) return NULL; + if (closest == nullptr) return nullptr; int face = -1; - if (closest == xh0) face = 4; - if (closest == xh1) face = 5; - if (closest == yh0) face = 0; - if (closest == yh1) face = 1; - if (closest == zh0) face = 2; - if (closest == zh1) face = 3; + if (*closest == xh0) face = 4; + if (*closest == xh1) face = 5; + if (*closest == yh0) face = 0; + if (*closest == yh1) face = 1; + if (*closest == zh0) face = 2; + if (*closest == zh1) face = 3; - return new HitResult(0, 0, 0, face, closest); + closest = Vec3::newTemp(closest->x, closest->y, closest->z); + + return new HitResult(0, 0, 0, face, *closest); } bool AABB::containsX(Vec3* v) { diff --git a/Minecraft.World/Util/HitResult.cpp b/Minecraft.World/Util/HitResult.cpp index dfa52bf72..e6f49dbac 100644 --- a/Minecraft.World/Util/HitResult.cpp +++ b/Minecraft.World/Util/HitResult.cpp @@ -3,13 +3,13 @@ #include "../Headers/net.minecraft.world.entity.h" #include "HitResult.h" -HitResult::HitResult(int x, int y, int z, int f, Vec3* pos) { +HitResult::HitResult(int x, int y, int z, int f, const Vec3& pos) { type = TILE; this->x = x; this->y = y; this->z = z; this->f = f; - this->pos = Vec3::newTemp(pos->x, pos->y, pos->z); + this->pos = pos; this->entity = nullptr; } @@ -17,14 +17,14 @@ HitResult::HitResult(int x, int y, int z, int f, Vec3* pos) { HitResult::HitResult(std::shared_ptr entity) { type = ENTITY; this->entity = entity; - pos = Vec3::newTemp(entity->x, entity->y, entity->z); + pos = {entity->x, entity->y, entity->z}; x = y = z = f = 0; } double HitResult::distanceTo(std::shared_ptr e) { - double xd = pos->x - e->x; - double yd = pos->y - e->y; - double zd = pos->z - e->z; + double xd = pos.x - e->x; + double yd = pos.y - e->y; + double zd = pos.z - e->z; return xd * xd + yd * yd + zd * zd; -} \ No newline at end of file +} diff --git a/Minecraft.World/Util/HitResult.h b/Minecraft.World/Util/HitResult.h index ee4121d52..83934fc6f 100644 --- a/Minecraft.World/Util/HitResult.h +++ b/Minecraft.World/Util/HitResult.h @@ -7,12 +7,12 @@ public: Type type; int x, y, z, f; - Vec3* pos; + Vec3 pos; std::shared_ptr entity; - HitResult(int x, int y, int z, int f, Vec3* pos); + HitResult(int x, int y, int z, int f, const Vec3& pos); HitResult(std::shared_ptr entity); double distanceTo(std::shared_ptr e); -}; \ No newline at end of file +}; diff --git a/Minecraft.World/Util/Vec3.cpp b/Minecraft.World/Util/Vec3.cpp index 4e42b99a3..0262d2e17 100644 --- a/Minecraft.World/Util/Vec3.cpp +++ b/Minecraft.World/Util/Vec3.cpp @@ -1,5 +1,7 @@ #include "../Platform/stdafx.h" #include "Vec3.h" +#include +#include #include "AABB.h" unsigned int Vec3::tlsIdx = 0; @@ -62,108 +64,99 @@ Vec3* Vec3::set(double x, double y, double z) { return this; } -Vec3* Vec3::interpolateTo(Vec3* t, double p) { - double xt = x + (t->x - x) * p; - double yt = y + (t->y - y) * p; - double zt = z + (t->z - z) * p; +Vec3 Vec3::vectorTo(const Vec3& p) const { return {p.x - x, p.y - y, p.z - z}; } - return Vec3::newTemp(xt, yt, zt); +Vec3 Vec3::normalize() const { + double dist = std::sqrt(x * x + y * y + z * z); + if (dist < 0.0001) return {0, 0, 0}; + + return {x / dist, y / dist, z / dist}; } -Vec3* Vec3::vectorTo(Vec3* p) { - return Vec3::newTemp(p->x - x, p->y - y, p->z - z); +double Vec3::dot(const Vec3& p) const { return x * p.x + y * p.y + z * p.z; } + +Vec3 Vec3::cross(const Vec3& p) const { + return {y * p.z - z * p.y, z * p.x - x * p.z, x * p.y - y * p.x}; } -Vec3* Vec3::normalize() { - double dist = (double)(sqrt(x * x + y * y + z * z)); - if (dist < 0.0001) return Vec3::newTemp(0, 0, 0); - return Vec3::newTemp(x / dist, y / dist, z / dist); +Vec3 Vec3::add(double x, double y, double z) const { + return {this->x + x, this->y + y, this->z + z}; } -double Vec3::dot(Vec3* p) { return x * p->x + y * p->y + z * p->z; } - -Vec3* Vec3::cross(Vec3* p) { - return Vec3::newTemp(y * p->z - z * p->y, z * p->x - x * p->z, - x * p->y - y * p->x); +double Vec3::distanceTo(const Vec3& p) const { + double xd = p.x - x; + double yd = p.y - y; + double zd = p.z - z; + return std::sqrt(xd * xd + yd * yd + zd * zd); } -Vec3* Vec3::add(double x, double y, double z) { - return Vec3::newTemp(this->x + x, this->y + y, this->z + z); -} - -double Vec3::distanceTo(Vec3* p) { - double xd = p->x - x; - double yd = p->y - y; - double zd = p->z - z; - return (double)sqrt(xd * xd + yd * yd + zd * zd); -} - -double Vec3::distanceToSqr(Vec3* p) { - double xd = p->x - x; - double yd = p->y - y; - double zd = p->z - z; +double Vec3::distanceToSqr(const Vec3& p) { + double xd = p.x - x; + double yd = p.y - y; + double zd = p.z - z; return xd * xd + yd * yd + zd * zd; } -double Vec3::distanceToSqr(double x2, double y2, double z2) { +double Vec3::distanceToSqr(const double x2, const double y2, + const double z2) const { double xd = x2 - x; double yd = y2 - y; double zd = z2 - z; return xd * xd + yd * yd + zd * zd; } -Vec3* Vec3::scale(double l) { return Vec3::newTemp(x * l, y * l, z * l); } +Vec3 Vec3::scale(const double l) const { return {x * l, y * l, z * l}; } -double Vec3::length() { return sqrt(x * x + y * y + z * z); } +double Vec3::length() const { return sqrt(x * x + y * y + z * z); } -Vec3* Vec3::clipX(Vec3* b, double xt) { - double xd = b->x - x; - double yd = b->y - y; - double zd = b->z - z; +std::optional Vec3::clipX(const Vec3& b, const double xt) const { + double xd = b.x - x; + double yd = b.y - y; + double zd = b.z - z; - if (xd * xd < 0.0000001f) return NULL; + if (xd * xd < 0.0000001f) return std::nullopt; double d = (xt - x) / xd; - if (d < 0 || d > 1) return NULL; - return Vec3::newTemp(x + xd * d, y + yd * d, z + zd * d); + if (d < 0 || d > 1) return std::nullopt; + + return Vec3{x + xd * d, y + yd * d, z + zd * d}; } -Vec3* Vec3::clipY(Vec3* b, double yt) { - double xd = b->x - x; - double yd = b->y - y; - double zd = b->z - z; +std::optional Vec3::clipY(const Vec3& b, const double yt) const { + double xd = b.x - x; + double yd = b.y - y; + double zd = b.z - z; - if (yd * yd < 0.0000001f) return NULL; + if (yd * yd < 0.0000001f) return std::nullopt; double d = (yt - y) / yd; - if (d < 0 || d > 1) return NULL; - return Vec3::newTemp(x + xd * d, y + yd * d, z + zd * d); + if (d < 0 || d > 1) return std::nullopt; + + return Vec3{x + xd * d, y + yd * d, z + zd * d}; } -Vec3* Vec3::clipZ(Vec3* b, double zt) { - double xd = b->x - x; - double yd = b->y - y; - double zd = b->z - z; +std::optional Vec3::clipZ(const Vec3& b, const double zt) const { + double xd = b.x - x; + double yd = b.y - y; + double zd = b.z - z; - if (zd * zd < 0.0000001f) return NULL; + if (zd * zd < 0.0000001f) return std::nullopt; double d = (zt - z) / zd; - if (d < 0 || d > 1) return NULL; - return Vec3::newTemp(x + xd * d, y + yd * d, z + zd * d); + if (d < 0 || d > 1) return std::nullopt; + + return Vec3{x + xd * d, y + yd * d, z + zd * d}; } -std::wstring Vec3::toString() { - static wchar_t buf[128]; - swprintf(buf, 128, L"(%f,%f,%f)", x, y, z); - return std::wstring(buf); +std::wstring Vec3::toString() const { + return std::format(L"({},{},{})", x, y, z); } -Vec3* Vec3::lerp(Vec3* v, double a) { - return Vec3::newTemp(x + (v->x - x) * a, y + (v->y - y) * a, - z + (v->z - z) * a); +Vec3 Vec3::lerp(const Vec3& v, const double a) const { + return {x + (v.x - x) * a, y + (v.y - y) * a, z + (v.z - z) * a}; } -void Vec3::xRot(float degs) { +void Vec3::xRot(const float degs) { double _cos = cos(degs); // 4J - cos/sin were floats but seems pointless // wasting precision here double _sin = sin(degs); @@ -177,7 +170,7 @@ void Vec3::xRot(float degs) { z = zz; } -void Vec3::yRot(float degs) { +void Vec3::yRot(const float degs) { double _cos = cos(degs); // 4J - cos/sin were floats but seems pointless // wasting precision here double _sin = sin(degs); @@ -191,7 +184,7 @@ void Vec3::yRot(float degs) { z = zz; } -void Vec3::zRot(float degs) { +void Vec3::zRot(const float degs) { double _cos = cos(degs); // 4J - cos/sin were floats but seems pointless // wasting precision here double _sin = sin(degs); @@ -230,23 +223,24 @@ double Vec3::distanceTo(AABB* box) { return sqrt(xd * xd + yd * yd + zd * zd); } -Vec3* Vec3::closestPointOnLine(Vec3* p1, Vec3* p2) { - Vec3* diff = newTemp(x - p1->x, y - p1->y, z - p1->z); - Vec3* dir = newTemp(p2->x - p1->x, p2->y - p1->y, p2->z - p1->z); - float dot1 = diff->dot(dir); +Vec3 Vec3::closestPointOnLine(const Vec3& p1, const Vec3& p2) const { + Vec3 diff = {x - p1.x, y - p1.y, z - p1.z}; + Vec3 dir = {p2.x - p1.x, p2.y - p1.y, p2.z - p1.z}; + float dot1 = diff.dot(dir); + if (dot1 <= 0.0f) return p1; - float dot2 = dir->dot(dir); + float dot2 = dir.dot(dir); if (dot2 <= dot1) return p2; float t = dot1 / dot2; - return newTemp(p1->x + t * dir->x, p1->y + t * dir->y, p1->z + t * dir->z); + + return {p1.x + t * dir.x, p1.y + t * dir.y, p1.z + t * dir.z}; } -double Vec3::distanceFromLine(Vec3* p1, Vec3* p2) { - Vec3* closestPoint = closestPointOnLine(p1, p2); - Vec3* diff = - newTemp(x - closestPoint->x, y - closestPoint->y, z - closestPoint->z); - return diff->length(); +double Vec3::distanceFromLine(const Vec3& p1, const Vec3& p2) const { + Vec3 closestPoint = closestPointOnLine(p1, p2); + Vec3 diff{x - closestPoint.x, y - closestPoint.y, z - closestPoint.z}; + return diff.length(); } diff --git a/Minecraft.World/Util/Vec3.h b/Minecraft.World/Util/Vec3.h index bc1239d81..9b424305a 100644 --- a/Minecraft.World/Util/Vec3.h +++ b/Minecraft.World/Util/Vec3.h @@ -1,5 +1,6 @@ #pragma once +#include class AABB; class Vec3 { @@ -29,28 +30,28 @@ public: static Vec3* newTemp(double x, double y, double z); double x, y, z; -private: Vec3() {} Vec3(double x, double y, double z); + +private: Vec3* set(double x, double y, double z); public: - Vec3* interpolateTo(Vec3* t, double p); - Vec3* vectorTo(Vec3* p); - Vec3* normalize(); - double dot(Vec3* p); - Vec3* cross(Vec3* p); - Vec3* add(double x, double y, double z); - double distanceTo(Vec3* p); - double distanceToSqr(Vec3* p); - double distanceToSqr(double x2, double y2, double z2); - Vec3* scale(double l); - double length(); - Vec3* clipX(Vec3* b, double xt); - Vec3* clipY(Vec3* b, double yt); - Vec3* clipZ(Vec3* b, double zt); - std::wstring toString(); - Vec3* lerp(Vec3* v, double a); + Vec3 vectorTo(const Vec3& p) const; + Vec3 normalize() const; + double dot(const Vec3& p) const; + Vec3 cross(const Vec3& p) const; + Vec3 add(double x, double y, double z) const; + double distanceTo(const Vec3& p) const; + double distanceToSqr(const Vec3& p); + double distanceToSqr(double x2, double y2, double z2) const; + Vec3 scale(double l) const; + double length() const; + std::optional clipX(const Vec3& b, double xt) const; + std::optional clipY(const Vec3& b, double yt) const; + std::optional clipZ(const Vec3& b, double zt) const; + std::wstring toString() const; + Vec3 lerp(const Vec3& v, double a) const; void xRot(float degs); void yRot(float degs); void zRot(float degs); @@ -58,6 +59,10 @@ public: // 4J Added double distanceTo(AABB* box); - Vec3* closestPointOnLine(Vec3* p1, Vec3* p2); - double distanceFromLine(Vec3* p1, Vec3* p2); -}; \ No newline at end of file + Vec3 closestPointOnLine(const Vec3& p1, const Vec3& p2) const; + double distanceFromLine(const Vec3& p1, const Vec3& p2) const; + + constexpr bool operator==(const Vec3& rhs) const { + return x == rhs.x and y == rhs.y and z == rhs.z; + } +}; From 9405f38f8064b9c4addfba5cc15d3511857b6210 Mon Sep 17 00:00:00 2001 From: orng Date: Thu, 26 Mar 2026 02:56:15 -0500 Subject: [PATCH 011/170] fix: crashing on world join --- Minecraft.World/Blocks/Tile.cpp | 46 +++++++++++----------- Minecraft.World/Util/AABB.cpp | 68 +++++++++++++++++---------------- 2 files changed, 59 insertions(+), 55 deletions(-) diff --git a/Minecraft.World/Blocks/Tile.cpp b/Minecraft.World/Blocks/Tile.cpp index 67457536c..d110d7e8a 100644 --- a/Minecraft.World/Blocks/Tile.cpp +++ b/Minecraft.World/Blocks/Tile.cpp @@ -17,6 +17,7 @@ #include "../Headers/net.minecraft.h" #include "Util/Vec3.h" #include "Tile.h" +#include std::wstring Tile::TILE_DESCRIPTION_PREFIX = L"Tile."; @@ -2134,52 +2135,51 @@ HitResult* Tile::clip(Level* level, int xt, int yt, int zt, Vec3* a, Vec3* b) { auto zh0 = a->clipZ(*b, tls->zz0); auto zh1 = a->clipZ(*b, tls->zz1); - Vec3* closest = nullptr; + std::optional closest = std::nullopt; if (xh0.has_value() and containsX(&*xh0) and - (closest == nullptr or + (!closest.has_value() or a->distanceToSqr(*xh0) < a->distanceToSqr(*closest))) - *closest = *xh0; + closest = xh0; if (xh1.has_value() and containsX(&*xh1) and - (closest == nullptr or + (!closest.has_value() or a->distanceToSqr(*xh1) < a->distanceToSqr(*closest))) - *closest = *xh1; + closest = xh1; if (yh0.has_value() and containsY(&*yh0) and - (closest == nullptr or + (!closest.has_value() or a->distanceToSqr(*yh0) < a->distanceToSqr(*closest))) - *closest = *yh0; + closest = yh0; if (yh1.has_value() and containsY(&*yh1) and - (closest == nullptr or + (!closest.has_value() or a->distanceToSqr(*yh1) < a->distanceToSqr(*closest))) - *closest = *yh1; + closest = yh1; if (zh0.has_value() and containsZ(&*zh0) and - (closest == nullptr or + (!closest.has_value() or a->distanceToSqr(*zh0) < a->distanceToSqr(*closest))) - *closest = *zh0; + closest = zh0; if (zh1.has_value() and containsZ(&*zh1) and - (closest == nullptr or + (!closest.has_value() or a->distanceToSqr(*zh1) < a->distanceToSqr(*closest))) - *closest = *zh1; + closest = zh1; - if (closest == NULL) return NULL; + if (!closest.has_value()) return nullptr; int face = -1; - if (*closest == xh0) face = Facing::WEST; - if (*closest == xh1) face = Facing::EAST; - if (*closest == yh0) face = Facing::DOWN; - if (*closest == yh1) face = Facing::UP; - if (*closest == zh0) face = Facing::NORTH; - if (*closest == zh1) face = Facing::SOUTH; + if (closest == xh0) face = Facing::WEST; + if (closest == xh1) face = Facing::EAST; + if (closest == yh0) face = Facing::DOWN; + if (closest == yh1) face = Facing::UP; + if (closest == zh0) face = Facing::NORTH; + if (closest == zh1) face = Facing::SOUTH; - *closest = closest->add(xt, yt, zt); - - return new HitResult(xt, yt, zt, face, *closest); + Vec3 res = closest->add(xt, yt, zt); + return new HitResult(xt, yt, zt, face, res); } bool Tile::containsX(Vec3* v) { diff --git a/Minecraft.World/Util/AABB.cpp b/Minecraft.World/Util/AABB.cpp index b5f98c1a9..e9252864c 100644 --- a/Minecraft.World/Util/AABB.cpp +++ b/Minecraft.World/Util/AABB.cpp @@ -255,45 +255,49 @@ HitResult* AABB::clip(Vec3* a, Vec3* b) { if (!(yh1.has_value() and containsY(&*yh1))) yh1 = std::nullopt; if (!(zh0.has_value() and containsZ(&*zh0))) zh0 = std::nullopt; if (!(zh1.has_value() and containsZ(&*zh1))) zh1 = std::nullopt; - Vec3* closest = nullptr; + + std::optional closest = std::nullopt; if (xh0.has_value() and - (closest == nullptr or + (!closest.has_value() or a->distanceToSqr(*xh0) < a->distanceToSqr(*closest))) - *closest = *xh0; - if (xh1.has_value() and - (closest == nullptr or - a->distanceToSqr(*xh1) < a->distanceToSqr(*closest))) - *closest = *xh1; - if (yh0.has_value() and - (closest == nullptr or - a->distanceToSqr(*yh0) < a->distanceToSqr(*closest))) - *closest = *yh0; - if (yh1.has_value() and - (closest == nullptr or - a->distanceToSqr(*yh1) < a->distanceToSqr(*closest))) - *closest = *yh1; - if (zh0.has_value() and - (closest == nullptr or - a->distanceToSqr(*zh0) < a->distanceToSqr(*closest))) - *closest = *zh0; - if (zh1.has_value() and - (closest == nullptr or - a->distanceToSqr(*zh1) < a->distanceToSqr(*closest))) - *closest = *zh1; + closest = xh0; - if (closest == nullptr) return nullptr; + if (xh1.has_value() and + (!closest.has_value() or + a->distanceToSqr(*xh1) < a->distanceToSqr(*closest))) + closest = xh1; + + if (yh0.has_value() and + (!closest.has_value() or + a->distanceToSqr(*yh0) < a->distanceToSqr(*closest))) + closest = yh0; + + if (yh1.has_value() and + (!closest.has_value() or + a->distanceToSqr(*yh1) < a->distanceToSqr(*closest))) + closest = yh1; + + if (zh0.has_value() and + (!closest.has_value() or + a->distanceToSqr(*zh0) < a->distanceToSqr(*closest))) + closest = zh0; + + if (zh1.has_value() and + (!closest.has_value() or + a->distanceToSqr(*zh1) < a->distanceToSqr(*closest))) + closest = zh1; + + if (!closest.has_value()) return nullptr; int face = -1; - if (*closest == xh0) face = 4; - if (*closest == xh1) face = 5; - if (*closest == yh0) face = 0; - if (*closest == yh1) face = 1; - if (*closest == zh0) face = 2; - if (*closest == zh1) face = 3; - - closest = Vec3::newTemp(closest->x, closest->y, closest->z); + if (closest == xh0) face = 4; + if (closest == xh1) face = 5; + if (closest == yh0) face = 0; + if (closest == yh1) face = 1; + if (closest == zh0) face = 2; + if (closest == zh1) face = 3; return new HitResult(0, 0, 0, face, *closest); } From bee10e55a898925ef4eb9434ba2c50d30f8a50ba Mon Sep 17 00:00:00 2001 From: orng Date: Thu, 26 Mar 2026 04:19:04 -0500 Subject: [PATCH 012/170] refactor: remove calls to `Vec3::newTemp` when not returned --- .../Platform/Common/Consoles_App.cpp | 8 +- .../ApplySchematicRuleDefinition.cpp | 2 +- .../Common/GameRules/ConsoleSchematicFile.cpp | 13 +- .../Common/Tutorial/AreaConstraint.cpp | 10 +- .../Platform/Common/XUI/XUI_Death.cpp | 2 +- .../Platform/Common/XUI/XUI_PauseMenu.cpp | 2 +- .../ChunkUpdate/TileRenderer_SPU.cpp | 13159 ++++++++-------- Minecraft.Client/Rendering/Camera.cpp | 2 +- .../EntityRenderers/FishingHookRenderer.cpp | 16 +- .../EntityRenderers/MinecartRenderer.cpp | 12 +- .../EntityRenderers/TileRenderer.cpp | 19 +- Minecraft.Client/Rendering/GameRenderer.cpp | 23 +- Minecraft.Client/Rendering/Lighting.cpp | 12 +- Minecraft.Client/Rendering/Vertex.cpp | 2 +- Minecraft.World/AI/Goals/AvoidPlayerGoal.cpp | 4 +- Minecraft.World/AI/Goals/MoveIndoorsGoal.cpp | 7 +- .../AI/Goals/MoveThroughVillageGoal.cpp | 3 +- .../AI/Goals/MoveTowardsRestrictionGoal.cpp | 7 +- .../AI/Goals/MoveTowardsTargetGoal.cpp | 3 +- Minecraft.World/Entities/LivingEntity.cpp | 34 +- Minecraft.World/Entities/Mobs/Arrow.cpp | 21 +- Minecraft.World/Entities/Mobs/EnderDragon.cpp | 69 +- Minecraft.World/Entities/Mobs/EnderMan.cpp | 26 +- Minecraft.World/Entities/Mobs/Fireball.cpp | 16 +- Minecraft.World/Entities/Mobs/FishingHook.cpp | 16 +- Minecraft.World/Entities/Mobs/Minecart.cpp | 12 +- Minecraft.World/Entities/Throwable.cpp | 16 +- Minecraft.World/Items/BoatItem.cpp | 10 +- Minecraft.World/Items/Item.cpp | 8 +- .../Level/Dimensions/TheEndDimension.cpp | 2 +- Minecraft.World/Level/Events/VillageSiege.cpp | 2 +- Minecraft.World/Level/Explosion.cpp | 6 +- Minecraft.World/Level/Level.cpp | 31 +- Minecraft.World/Level/RandomLevelSource.cpp | 22 +- Minecraft.World/Player/Player.cpp | 20 +- Minecraft.World/Util/Vec3.cpp | 3 +- Minecraft.World/Util/Vec3.h | 2 + 37 files changed, 6791 insertions(+), 6831 deletions(-) diff --git a/Minecraft.Client/Platform/Common/Consoles_App.cpp b/Minecraft.Client/Platform/Common/Consoles_App.cpp index f85d56632..7ec88c75b 100644 --- a/Minecraft.Client/Platform/Common/Consoles_App.cpp +++ b/Minecraft.Client/Platform/Common/Consoles_App.cpp @@ -6332,7 +6332,7 @@ int CMinecraftApp::WarningTrialTexturePackReturned( DLCPack *pDLCPack=pDLCTexPack->getDLCInfoParentPack();//tPack->getDLCPack(); const char *pchPackName=wstringtofilename(pDLCPack->getName()); app.DebugPrintf("Texture Pack - %s\n",pchPackName); - SONYDLC *pSONYDLCInfo=app.GetSONYDLCInfo((char *)pchPackName); + SONYDLC *pSONYDLCInfo=app.GetSONYDLCInfo((char *)pchPackName); if(pSONYDLCInfo!=NULL) { @@ -6353,14 +6353,14 @@ int CMinecraftApp::WarningTrialTexturePackReturned( #if defined __ORBIS__ || defined __PSVITA__ || defined __PS3__ if(app.CheckForEmptyStore(iPad)==false) #endif - { + { if(app.DLCAlreadyPurchased(chSkuID)) { app.DownloadAlreadyPurchased(chSkuID); } else { - app.Checkout(chSkuID); + app.Checkout(chSkuID); } } } @@ -10355,4 +10355,4 @@ std::wstring CMinecraftApp::getRootPath(std::uint32_t packId, void CMinecraftApp::SetReachedMainMenu() { m_hasReachedMainMenu = true; } bool CMinecraftApp::HasReachedMainMenu() { return m_hasReachedMainMenu; } -#endif \ No newline at end of file +#endif diff --git a/Minecraft.Client/Platform/Common/GameRules/ApplySchematicRuleDefinition.cpp b/Minecraft.Client/Platform/Common/GameRules/ApplySchematicRuleDefinition.cpp index e7f25cf69..9139bfce7 100644 --- a/Minecraft.Client/Platform/Common/GameRules/ApplySchematicRuleDefinition.cpp +++ b/Minecraft.Client/Platform/Common/GameRules/ApplySchematicRuleDefinition.cpp @@ -251,4 +251,4 @@ void ApplySchematicRuleDefinition::reset() { m_totalBlocksChanged = 0; m_totalBlocksChangedLighting = 0; m_completed = false; -} \ No newline at end of file +} diff --git a/Minecraft.Client/Platform/Common/GameRules/ConsoleSchematicFile.cpp b/Minecraft.Client/Platform/Common/GameRules/ConsoleSchematicFile.cpp index 04d7015c9..62476d8ab 100644 --- a/Minecraft.Client/Platform/Common/GameRules/ConsoleSchematicFile.cpp +++ b/Minecraft.Client/Platform/Common/GameRules/ConsoleSchematicFile.cpp @@ -463,8 +463,8 @@ void ConsoleSchematicFile::applyTileEntities(LevelChunk* chunk, AABB* chunkBox, schematicCoordToChunkCoord(destinationBox, te->x, te->z, rot, targetX, targetZ); - Vec3* pos = Vec3::newTemp(targetX, targetY, targetZ); - if (chunkBox->containsIncludingLowerBound(pos)) { + Vec3 pos(targetX, targetY, targetZ); + if (chunkBox->containsIncludingLowerBound(&pos)) { std::shared_ptr teCopy = chunk->getTileEntity( (int)targetX & 15, (int)targetY & 15, (int)targetZ & 15); @@ -510,9 +510,8 @@ void ConsoleSchematicFile::applyTileEntities(LevelChunk* chunk, AABB* chunkBox, // Add 0.01 as the AABB::contains function returns false if a value is // <= the lower bound - Vec3* pos = - Vec3::newTemp(targetX + 0.01, targetY + 0.01, targetZ + 0.01); - if (!chunkBox->containsIncludingLowerBound(pos)) { + Vec3 pos(targetX + 0.01, targetY + 0.01, targetZ + 0.01); + if (!chunkBox->containsIncludingLowerBound(&pos)) { ++it; continue; } @@ -800,8 +799,8 @@ void ConsoleSchematicFile::getBlocksAndData(LevelChunk* chunk, byteArray* data, // if (xs * ys * zs == LevelChunk::BLOCKS_LENGTH) //{ // byteArray blockData = byteArray(data->data + blocksP, - //Level::CHUNK_TILE_COUNT); chunk->getBlockData(blockData); blocksP += - //blockData.length; + // Level::CHUNK_TILE_COUNT); chunk->getBlockData(blockData); + // blocksP += blockData.length; // byteArray dataData = byteArray(data->data + dataP, 16384); // chunk->getBlockLightData(dataData); diff --git a/Minecraft.Client/Platform/Common/Tutorial/AreaConstraint.cpp b/Minecraft.Client/Platform/Common/Tutorial/AreaConstraint.cpp index ddd57b539..2057080b5 100644 --- a/Minecraft.Client/Platform/Common/Tutorial/AreaConstraint.cpp +++ b/Minecraft.Client/Platform/Common/Tutorial/AreaConstraint.cpp @@ -37,15 +37,15 @@ bool AreaConstraint::canMoveToPosition(double xo, double yo, double zo, double xt, double yt, double zt) { if (!m_restrictsMovement) return true; - Vec3* targetPos = Vec3::newTemp(xt, yt, zt); + Vec3 targetPos(xt, yt, zt); Minecraft* minecraft = Minecraft::GetInstance(); - if (movementArea->contains(targetPos) == contains) { + if (movementArea->contains(&targetPos) == contains) { return true; } - Vec3* origPos = Vec3::newTemp(xo, yo, zo); + Vec3 origPos(xo, yo, zo); - double currDist = origPos->distanceTo(movementArea); - double targetDist = targetPos->distanceTo(movementArea); + double currDist = origPos.distanceTo(movementArea); + double targetDist = targetPos.distanceTo(movementArea); return targetDist < currDist; } diff --git a/Minecraft.Client/Platform/Common/XUI/XUI_Death.cpp b/Minecraft.Client/Platform/Common/XUI/XUI_Death.cpp index 7902b427a..d073d2e98 100644 --- a/Minecraft.Client/Platform/Common/XUI/XUI_Death.cpp +++ b/Minecraft.Client/Platform/Common/XUI/XUI_Death.cpp @@ -246,4 +246,4 @@ HRESULT CScene_Death::OnCustomMessage_Splitscreenplayer(bool bJoining, bHandled = true; return app.AdjustSplitscreenScene_PlayerChanged(m_hObj, &m_OriginalPosition, m_iPad, bJoining); -} \ No newline at end of file +} diff --git a/Minecraft.Client/Platform/Common/XUI/XUI_PauseMenu.cpp b/Minecraft.Client/Platform/Common/XUI/XUI_PauseMenu.cpp index d77644991..7e2d611ea 100644 --- a/Minecraft.Client/Platform/Common/XUI/XUI_PauseMenu.cpp +++ b/Minecraft.Client/Platform/Common/XUI/XUI_PauseMenu.cpp @@ -1326,4 +1326,4 @@ void UIScene_PauseMenu::_ExitWorld(LPVOID lpParameter) { void UIScene_PauseMenu::SetIgnoreInput(bool ignoreInput) { m_bIgnoreInput = ignoreInput; -} \ No newline at end of file +} diff --git a/Minecraft.Client/Platform/PS3/SPU_Tasks/ChunkUpdate/TileRenderer_SPU.cpp b/Minecraft.Client/Platform/PS3/SPU_Tasks/ChunkUpdate/TileRenderer_SPU.cpp index d7d5af1cd..a0193a671 100644 --- a/Minecraft.Client/Platform/PS3/SPU_Tasks/ChunkUpdate/TileRenderer_SPU.cpp +++ b/Minecraft.Client/Platform/PS3/SPU_Tasks/ChunkUpdate/TileRenderer_SPU.cpp @@ -26,7 +26,7 @@ #ifdef SN_TARGET_PS3_SPU #include "../Common/spu_assert.h" -#endif +#endif static const float MATH_PI = 3.141592654f; @@ -35,7 +35,8 @@ static const float MATH_PI = 3.141592654f; // #include "../../../../Textures/Textures.h" // #include "../../../../../Minecraft.World/Headers/net.minecraft.world.level.h" // #include "../../../Minecraft.World/net.minecraft.world.level.tile.h" -// #include "../../../../../Minecraft.World/Headers/net.minecraft.world.level.material.h" +// #include +// "../../../../../Minecraft.World/Headers/net.minecraft.world.level.material.h" // #include "../../../../../Minecraft.World/Headers/net.minecraft.h" // #include "../../../../../Minecraft.World/Headers/net.minecraft.world.h" // #include "../../../Minecraft.World/net.minecraft.world.level.tile.h" @@ -44,7 +45,7 @@ static const float MATH_PI = 3.141592654f; #ifdef SN_TARGET_PS3_SPU #include "Stubs_SPU.h" -#endif // SN_TARGET_PS3_SPU +#endif // SN_TARGET_PS3_SPU // #include "../../../../../Minecraft.World/Util/SharedConstants.h" #include "Facing_SPU.h" @@ -54,629 +55,589 @@ static const float MATH_PI = 3.141592654f; // #define DISABLE_TESS_FUNCS #ifdef SN_TARGET_PS3_SPU -class SharedConstants -{ +class SharedConstants { public: - static const bool TEXTURE_LIGHTING = true; - static const int WORLD_RESOLUTION = 16; + static const bool TEXTURE_LIGHTING = true; + static const int WORLD_RESOLUTION = 16; }; #endif // #define SN_TARGET_PS3_SPU bool TileRenderer_SPU::fancy = true; -bool g_ambientOcclusionMax = false; // minecraft->options->ambientOcclusion >= Options::AO_MAX -const float smallUV = ( 1.0f / 16.0f ); +bool g_ambientOcclusionMax = + false; // minecraft->options->ambientOcclusion >= Options::AO_MAX +const float smallUV = (1.0f / 16.0f); +void TileRenderer_SPU::_init() { + fixedTexture = NULL; + xFlipTexture = false; + noCulling = false; + blsmooth = 1; + applyAmbienceOcclusion = false; + setColor = true; + northFlip = FLIP_NONE; + southFlip = FLIP_NONE; + eastFlip = FLIP_NONE; + westFlip = FLIP_NONE; + upFlip = FLIP_NONE; + downFlip = FLIP_NONE; -void TileRenderer_SPU::_init() -{ - fixedTexture = NULL; - xFlipTexture = false; - noCulling = false; - blsmooth = 1; - applyAmbienceOcclusion = false; - setColor = true; - northFlip = FLIP_NONE; - southFlip = FLIP_NONE; - eastFlip = FLIP_NONE; - westFlip = FLIP_NONE; - upFlip = FLIP_NONE; - downFlip = FLIP_NONE; - - tileShapeX0 = 0.0; - tileShapeX1 = 0.0; - tileShapeY0 = 0.0; - tileShapeY1 = 0.0; - tileShapeZ0 = 0.0; - tileShapeZ1 = 0.0; - fixedShape = false; - smoothShapeLighting = false; -// minecraft = Minecraft::GetInstance(); + tileShapeX0 = 0.0; + tileShapeX1 = 0.0; + tileShapeY0 = 0.0; + tileShapeY1 = 0.0; + tileShapeZ0 = 0.0; + tileShapeZ1 = 0.0; + fixedShape = false; + smoothShapeLighting = false; + // minecraft = Minecraft::GetInstance(); } -TileRenderer_SPU::TileRenderer_SPU( ChunkRebuildData* level ) -{ - this->level = level; - _init(); +TileRenderer_SPU::TileRenderer_SPU(ChunkRebuildData* level) { + this->level = level; + _init(); } -TileRenderer_SPU::TileRenderer_SPU() -{ - this->level = NULL; - _init(); +TileRenderer_SPU::TileRenderer_SPU() { + this->level = NULL; + _init(); } -Tesselator_SPU* TileRenderer_SPU::getTesselator() -{ - Tesselator_SPU* t = &level->m_tesselator; - return t; +Tesselator_SPU* TileRenderer_SPU::getTesselator() { + Tesselator_SPU* t = &level->m_tesselator; + return t; } - - -void TileRenderer_SPU::setFixedTexture( Icon_SPU *fixedTexture ) -{ - this->fixedTexture = fixedTexture; +void TileRenderer_SPU::setFixedTexture(Icon_SPU* fixedTexture) { + this->fixedTexture = fixedTexture; } -void TileRenderer_SPU::clearFixedTexture() -{ - this->fixedTexture = NULL; +void TileRenderer_SPU::clearFixedTexture() { this->fixedTexture = NULL; } + +bool TileRenderer_SPU::hasFixedTexture() { return fixedTexture != NULL; } + +void TileRenderer_SPU::setShape(float x0, float y0, float z0, float x1, + float y1, float z1) { + if (!fixedShape) { + tileShapeX0 = x0; + tileShapeX1 = x1; + tileShapeY0 = y0; + tileShapeY1 = y1; + tileShapeZ0 = z0; + tileShapeZ1 = z1; + smoothShapeLighting = + (tileShapeX0 > 0 || tileShapeX1 < 1 || tileShapeY0 > 0 || + tileShapeY1 < 1 || tileShapeZ0 > 0 || tileShapeZ1 < 1); + } } -bool TileRenderer_SPU::hasFixedTexture() -{ - return fixedTexture != NULL; +void TileRenderer_SPU::setShape(Tile_SPU* tt) { + if (!fixedShape) { + tileShapeX0 = tt->getShapeX0(); + tileShapeX1 = tt->getShapeX1(); + tileShapeY0 = tt->getShapeY0(); + tileShapeY1 = tt->getShapeY1(); + tileShapeZ0 = tt->getShapeZ0(); + tileShapeZ1 = tt->getShapeZ1(); + smoothShapeLighting = + (tileShapeX0 > 0 || tileShapeX1 < 1 || tileShapeY0 > 0 || + tileShapeY1 < 1 || tileShapeZ0 > 0 || tileShapeZ1 < 1); + } } -void TileRenderer_SPU::setShape(float x0, float y0, float z0, float x1, float y1, float z1) -{ - if (!fixedShape) - { - tileShapeX0 = x0; - tileShapeX1 = x1; - tileShapeY0 = y0; - tileShapeY1 = y1; - tileShapeZ0 = z0; - tileShapeZ1 = z1; - smoothShapeLighting = (tileShapeX0 > 0 || tileShapeX1 < 1 || tileShapeY0 > 0 || tileShapeY1 < 1 || tileShapeZ0 > 0 || tileShapeZ1 < 1); - } +void TileRenderer_SPU::setFixedShape(float x0, float y0, float z0, float x1, + float y1, float z1) { + tileShapeX0 = x0; + tileShapeX1 = x1; + tileShapeY0 = y0; + tileShapeY1 = y1; + tileShapeZ0 = z0; + tileShapeZ1 = z1; + fixedShape = true; + + smoothShapeLighting = + (tileShapeX0 > 0 || tileShapeX1 < 1 || tileShapeY0 > 0 || + tileShapeY1 < 1 || tileShapeZ0 > 0 || tileShapeZ1 < 1); } -void TileRenderer_SPU::setShape(Tile_SPU *tt) +void TileRenderer_SPU::clearFixedShape() { fixedShape = false; } + +void TileRenderer_SPU::tesselateInWorldFixedTexture( + Tile_SPU* tile, int x, int y, int z, + Icon_SPU* + fixedTexture) // 4J renamed to differentiate from tesselateInWorld { - if (!fixedShape) - { - tileShapeX0 = tt->getShapeX0(); - tileShapeX1 = tt->getShapeX1(); - tileShapeY0 = tt->getShapeY0(); - tileShapeY1 = tt->getShapeY1(); - tileShapeZ0 = tt->getShapeZ0(); - tileShapeZ1 = tt->getShapeZ1(); - smoothShapeLighting = (tileShapeX0 > 0 || tileShapeX1 < 1 || tileShapeY0 > 0 || tileShapeY1 < 1 || tileShapeZ0 > 0 || tileShapeZ1 < 1); - } + this->setFixedTexture(fixedTexture); + tesselateInWorld(tile, x, y, z); + this->clearFixedTexture(); } -void TileRenderer_SPU::setFixedShape(float x0, float y0, float z0, float x1, float y1, float z1) +void TileRenderer_SPU::tesselateInWorldNoCulling( + Tile_SPU* tile, int x, int y, int z, int forceData, + TileEntity* forceEntity) // 4J added forceData, forceEntity param { - tileShapeX0 = x0; - tileShapeX1 = x1; - tileShapeY0 = y0; - tileShapeY1 = y1; - tileShapeZ0 = z0; - tileShapeZ1 = z1; - fixedShape = true; - - smoothShapeLighting = (tileShapeX0 > 0 || tileShapeX1 < 1 || tileShapeY0 > 0 || tileShapeY1 < 1 || tileShapeZ0 > 0 || tileShapeZ1 < 1); + noCulling = true; + tesselateInWorld(tile, x, y, z, forceData); + noCulling = false; } -void TileRenderer_SPU::clearFixedShape() -{ - fixedShape = false; +bool TileRenderer_SPU::hasRenderer(Tile_SPU* tt) { + int shape = tt->getRenderShape(); + bool retVal = false; + switch (shape) { + case Tile_SPU::SHAPE_BLOCK: + case Tile_SPU::SHAPE_WATER: + case Tile_SPU::SHAPE_CACTUS: + case Tile_SPU::SHAPE_STEM: + case Tile_SPU::SHAPE_LILYPAD: + case Tile_SPU::SHAPE_ROWS: + case Tile_SPU::SHAPE_TORCH: + case Tile_SPU::SHAPE_FIRE: + case Tile_SPU::SHAPE_LADDER: + case Tile_SPU::SHAPE_DOOR: + case Tile_SPU::SHAPE_RAIL: + case Tile_SPU::SHAPE_EGG: + case Tile_SPU::SHAPE_VINE: + case Tile_SPU::SHAPE_BREWING_STAND: + case Tile_SPU::SHAPE_CROSS_TEXTURE: + case Tile_SPU::SHAPE_FENCE: + retVal = true; + break; + + case Tile_SPU::SHAPE_FENCE_GATE: + case Tile_SPU::SHAPE_RED_DUST: + case Tile_SPU::SHAPE_STAIRS: + case Tile_SPU::SHAPE_DIODE: + case Tile_SPU::SHAPE_LEVER: + case Tile_SPU::SHAPE_BED: + case Tile_SPU::SHAPE_PISTON_BASE: + case Tile_SPU::SHAPE_PISTON_EXTENSION: + case Tile_SPU::SHAPE_IRON_FENCE: + case Tile_SPU::SHAPE_CAULDRON: + case Tile_SPU::SHAPE_PORTAL_FRAME: + retVal = false; + break; + } + + return retVal; } -void TileRenderer_SPU::tesselateInWorldFixedTexture( Tile_SPU* tile, int x, int y, int z, Icon_SPU *fixedTexture ) // 4J renamed to differentiate from tesselateInWorld +bool TileRenderer_SPU::tesselateInWorld( + Tile_SPU* tt, int x, int y, int z, int forceData, + TileEntity* forceEntity) // 4J added forceData, forceEntity param { - this->setFixedTexture(fixedTexture); - tesselateInWorld( tile, x, y, z ); - this->clearFixedTexture(); + Tesselator_SPU* t = getTesselator(); + + int shape = tt->getRenderShape(); + tt->updateShape(level, x, y, z, forceData, forceEntity); + setShape(tt); + t->setMipmapEnable(level->m_tileData.mipmapEnable[tt->id]); // 4J added + + bool retVal = false; + switch (shape) { + case Tile_SPU::SHAPE_BLOCK: + retVal = tesselateBlockInWorld(tt, x, y, z); + break; + case Tile_SPU::SHAPE_TREE: + retVal = tesselateTreeInWorld(tt, x, y, z); + break; + case Tile_SPU::SHAPE_QUARTZ: + retVal = tesselateQuartzInWorld(tt, x, y, z); + break; + case Tile_SPU::SHAPE_WATER: + retVal = tesselateWaterInWorld(tt, x, y, z); + break; + case Tile_SPU::SHAPE_CACTUS: + retVal = tesselateCactusInWorld(tt, x, y, z); + break; + case Tile_SPU::SHAPE_CROSS_TEXTURE: + retVal = tesselateCrossInWorld(tt, x, y, z); + break; + case Tile_SPU::SHAPE_STEM: + retVal = tesselateStemInWorld(tt, x, y, z); + break; + case Tile_SPU::SHAPE_LILYPAD: + retVal = tesselateLilypadInWorld((WaterlilyTile_SPU*)tt, x, y, z); + break; + case Tile_SPU::SHAPE_ROWS: + retVal = tesselateRowInWorld(tt, x, y, z); + break; + case Tile_SPU::SHAPE_TORCH: + retVal = tesselateTorchInWorld(tt, x, y, z); + break; + case Tile_SPU::SHAPE_FIRE: + retVal = tesselateFireInWorld((FireTile_SPU*)tt, x, y, z); + break; + case Tile_SPU::SHAPE_RED_DUST: + retVal = tesselateDustInWorld(tt, x, y, z); + break; + case Tile_SPU::SHAPE_LADDER: + retVal = tesselateLadderInWorld(tt, x, y, z); + break; + case Tile_SPU::SHAPE_DOOR: + retVal = tesselateDoorInWorld(tt, x, y, z); + break; + case Tile_SPU::SHAPE_RAIL: + retVal = tesselateRailInWorld((RailTile_SPU*)tt, x, y, z); + break; + case Tile_SPU::SHAPE_STAIRS: + retVal = tesselateStairsInWorld((StairTile_SPU*)tt, x, y, z); + break; + case Tile_SPU::SHAPE_EGG: + retVal = tesselateEggInWorld((EggTile_SPU*)tt, x, y, z); + break; + case Tile_SPU::SHAPE_FENCE: + retVal = tesselateFenceInWorld((FenceTile_SPU*)tt, x, y, z); + break; + case Tile_SPU::SHAPE_WALL: + retVal = tesselateWallInWorld((WallTile_SPU*)tt, x, y, z); + break; + case Tile_SPU::SHAPE_LEVER: + retVal = tesselateLeverInWorld(tt, x, y, z); + break; + case Tile_SPU::SHAPE_TRIPWIRE_SOURCE: + retVal = tesselateTripwireSourceInWorld(tt, x, y, z); + break; + case Tile_SPU::SHAPE_TRIPWIRE: + retVal = tesselateTripwireInWorld(tt, x, y, z); + break; + case Tile_SPU::SHAPE_BED: + retVal = tesselateBedInWorld(tt, x, y, z); + break; + case Tile_SPU::SHAPE_DIODE: + retVal = tesselateDiodeInWorld((DiodeTile_SPU*)tt, x, y, z); + break; + case Tile_SPU::SHAPE_PISTON_BASE: + retVal = tesselatePistonBaseInWorld(tt, x, y, z, false, forceData); + break; + case Tile_SPU::SHAPE_PISTON_EXTENSION: + retVal = + tesselatePistonExtensionInWorld(tt, x, y, z, true, forceData); + break; + case Tile_SPU::SHAPE_IRON_FENCE: + retVal = tesselateThinFenceInWorld((ThinFenceTile*)tt, x, y, z); + break; + case Tile_SPU::SHAPE_VINE: + retVal = tesselateVineInWorld(tt, x, y, z); + break; + case Tile_SPU::SHAPE_FENCE_GATE: + retVal = tesselateFenceGateInWorld((FenceGateTile_SPU*)tt, x, y, z); + break; + case Tile_SPU::SHAPE_CAULDRON: + retVal = tesselateCauldronInWorld((CauldronTile_SPU*)tt, x, y, z); + break; + case Tile_SPU::SHAPE_FLOWER_POT: + retVal = tesselateFlowerPotInWorld((FlowerPotTile_SPU*)tt, x, y, z); + break; + case Tile_SPU::SHAPE_ANVIL: + retVal = tesselateAnvilInWorld((AnvilTile_SPU*)tt, x, y, z); + break; + case Tile_SPU::SHAPE_BREWING_STAND: + retVal = tesselateBrewingStandInWorld((BrewingStandTile_SPU*)tt, x, + y, z); + break; + case Tile_SPU::SHAPE_PORTAL_FRAME: + retVal = tesselateAirPortalFrameInWorld((TheEndPortalFrameTile*)tt, + x, y, z); + break; + case Tile_SPU::SHAPE_COCOA: + retVal = tesselateCocoaInWorld((CocoaTile_SPU*)tt, x, y, z); + break; + }; + + t->setMipmapEnable(true); // 4J added + return retVal; } -void TileRenderer_SPU::tesselateInWorldNoCulling( Tile_SPU* tile, int x, int y, int z, int forceData, - TileEntity* forceEntity ) // 4J added forceData, forceEntity param -{ - noCulling = true; - tesselateInWorld( tile, x, y, z, forceData ); - noCulling = false; -} - -bool TileRenderer_SPU::hasRenderer(Tile_SPU* tt) -{ - int shape = tt->getRenderShape(); - bool retVal = false; - switch(shape) - { - case Tile_SPU::SHAPE_BLOCK: - case Tile_SPU::SHAPE_WATER: - case Tile_SPU::SHAPE_CACTUS: - case Tile_SPU::SHAPE_STEM: - case Tile_SPU::SHAPE_LILYPAD: - case Tile_SPU::SHAPE_ROWS: - case Tile_SPU::SHAPE_TORCH: - case Tile_SPU::SHAPE_FIRE: - case Tile_SPU::SHAPE_LADDER: - case Tile_SPU::SHAPE_DOOR: - case Tile_SPU::SHAPE_RAIL: - case Tile_SPU::SHAPE_EGG: - case Tile_SPU::SHAPE_VINE: - case Tile_SPU::SHAPE_BREWING_STAND: - case Tile_SPU::SHAPE_CROSS_TEXTURE: - case Tile_SPU::SHAPE_FENCE: - retVal = true; - break; - - case Tile_SPU::SHAPE_FENCE_GATE: - case Tile_SPU::SHAPE_RED_DUST: - case Tile_SPU::SHAPE_STAIRS: - case Tile_SPU::SHAPE_DIODE: - case Tile_SPU::SHAPE_LEVER: - case Tile_SPU::SHAPE_BED: - case Tile_SPU::SHAPE_PISTON_BASE: - case Tile_SPU::SHAPE_PISTON_EXTENSION: - case Tile_SPU::SHAPE_IRON_FENCE: - case Tile_SPU::SHAPE_CAULDRON: - case Tile_SPU::SHAPE_PORTAL_FRAME: - retVal = false; - break; - } - - return retVal; -} - - -bool TileRenderer_SPU::tesselateInWorld( Tile_SPU* tt, int x, int y, int z, int forceData, - TileEntity* forceEntity ) // 4J added forceData, forceEntity param -{ - Tesselator_SPU* t = getTesselator(); - - int shape = tt->getRenderShape(); - tt->updateShape( level, x, y, z, forceData, forceEntity ); - setShape(tt); - t->setMipmapEnable( level->m_tileData.mipmapEnable[tt->id] ); // 4J added - - bool retVal = false; - switch(shape) - { - case Tile_SPU::SHAPE_BLOCK: - retVal = tesselateBlockInWorld( tt, x, y, z ); - break; - case Tile_SPU::SHAPE_TREE: - retVal = tesselateTreeInWorld(tt, x, y, z); - break; - case Tile_SPU::SHAPE_QUARTZ: - retVal = tesselateQuartzInWorld(tt, x, y, z); - break; - case Tile_SPU::SHAPE_WATER: - retVal = tesselateWaterInWorld( tt, x, y, z ); - break; - case Tile_SPU::SHAPE_CACTUS: - retVal = tesselateCactusInWorld( tt, x, y, z ); - break; - case Tile_SPU::SHAPE_CROSS_TEXTURE: - retVal = tesselateCrossInWorld( tt, x, y, z ); - break; - case Tile_SPU::SHAPE_STEM: - retVal = tesselateStemInWorld( tt, x, y, z ); - break; - case Tile_SPU::SHAPE_LILYPAD: - retVal = tesselateLilypadInWorld( (WaterlilyTile_SPU*)tt, x, y, z ); - break; - case Tile_SPU::SHAPE_ROWS: - retVal = tesselateRowInWorld( tt, x, y, z ); - break; - case Tile_SPU::SHAPE_TORCH: - retVal = tesselateTorchInWorld( tt, x, y, z ); - break; - case Tile_SPU::SHAPE_FIRE: - retVal = tesselateFireInWorld( (FireTile_SPU *)tt, x, y, z ); - break; - case Tile_SPU::SHAPE_RED_DUST: - retVal = tesselateDustInWorld( tt, x, y, z ); - break; - case Tile_SPU::SHAPE_LADDER: - retVal = tesselateLadderInWorld( tt, x, y, z ); - break; - case Tile_SPU::SHAPE_DOOR: - retVal = tesselateDoorInWorld( tt, x, y, z ); - break; - case Tile_SPU::SHAPE_RAIL: - retVal = tesselateRailInWorld( ( RailTile_SPU* )tt, x, y, z ); - break; - case Tile_SPU::SHAPE_STAIRS: - retVal = tesselateStairsInWorld( (StairTile_SPU *)tt, x, y, z ); - break; - case Tile_SPU::SHAPE_EGG: - retVal = tesselateEggInWorld((EggTile_SPU*) tt, x, y, z); - break; - case Tile_SPU::SHAPE_FENCE: - retVal = tesselateFenceInWorld( ( FenceTile_SPU* )tt, x, y, z ); - break; - case Tile_SPU::SHAPE_WALL: - retVal = tesselateWallInWorld( (WallTile_SPU *) tt, x, y, z); - break; - case Tile_SPU::SHAPE_LEVER: - retVal = tesselateLeverInWorld( tt, x, y, z ); - break; - case Tile_SPU::SHAPE_TRIPWIRE_SOURCE: - retVal = tesselateTripwireSourceInWorld(tt, x, y, z); - break; - case Tile_SPU::SHAPE_TRIPWIRE: - retVal = tesselateTripwireInWorld(tt, x, y, z); - break; - case Tile_SPU::SHAPE_BED: - retVal = tesselateBedInWorld( tt, x, y, z ); - break; - case Tile_SPU::SHAPE_DIODE: - retVal = tesselateDiodeInWorld( (DiodeTile_SPU *)tt, x, y, z ); - break; - case Tile_SPU::SHAPE_PISTON_BASE: - retVal = tesselatePistonBaseInWorld( tt, x, y, z, false, forceData ); - break; - case Tile_SPU::SHAPE_PISTON_EXTENSION: - retVal = tesselatePistonExtensionInWorld( tt, x, y, z, true, forceData ); - break; - case Tile_SPU::SHAPE_IRON_FENCE: - retVal = tesselateThinFenceInWorld( ( ThinFenceTile* )tt, x, y, z ); - break; - case Tile_SPU::SHAPE_VINE: - retVal = tesselateVineInWorld( tt, x, y, z ); - break; - case Tile_SPU::SHAPE_FENCE_GATE: - retVal = tesselateFenceGateInWorld( ( FenceGateTile_SPU* )tt, x, y, z ); - break; - case Tile_SPU::SHAPE_CAULDRON: - retVal = tesselateCauldronInWorld((CauldronTile_SPU* ) tt, x, y, z); - break; - case Tile_SPU::SHAPE_FLOWER_POT: - retVal = tesselateFlowerPotInWorld((FlowerPotTile_SPU *) tt, x, y, z); - break; - case Tile_SPU::SHAPE_ANVIL: - retVal = tesselateAnvilInWorld((AnvilTile_SPU *) tt, x, y, z); - break; - case Tile_SPU::SHAPE_BREWING_STAND: - retVal = tesselateBrewingStandInWorld((BrewingStandTile_SPU* ) tt, x, y, z); - break; - case Tile_SPU::SHAPE_PORTAL_FRAME: - retVal = tesselateAirPortalFrameInWorld((TheEndPortalFrameTile *)tt, x, y, z); - break; - case Tile_SPU::SHAPE_COCOA: - retVal = tesselateCocoaInWorld((CocoaTile_SPU *) tt, x, y, z); - break; - - }; - - - t->setMipmapEnable( true ); // 4J added - return retVal; - -} - -bool TileRenderer_SPU::tesselateAirPortalFrameInWorld(TheEndPortalFrameTile *tt, int x, int y, int z) -{ +bool TileRenderer_SPU::tesselateAirPortalFrameInWorld(TheEndPortalFrameTile* tt, + int x, int y, int z) { #ifdef DISABLE_TESS_FUNCS int data = level->getData(x, y, z); int direction = data & 3; - if (direction == Direction::SOUTH) - { + if (direction == Direction::SOUTH) { upFlip = FLIP_180; - } - else if (direction == Direction::EAST) - { + } else if (direction == Direction::EAST) { upFlip = FLIP_CW; - } - else if (direction == Direction::WEST) - { + } else if (direction == Direction::WEST) { upFlip = FLIP_CCW; } - if (!TheEndPortalFrameTile::hasEye(data)) - { -// EnterCriticalSection( &Tile_SPU::m_csShape ); + if (!TheEndPortalFrameTile::hasEye(data)) { + // EnterCriticalSection( &Tile_SPU::m_csShape ); setShape(0, 0, 0, 1, 13.0f / 16.0f, 1); tesselateBlockInWorld(tt, x, y, z); -// LeaveCriticalSection( &Tile_SPU::m_csShape ); + // LeaveCriticalSection( &Tile_SPU::m_csShape ); upFlip = FLIP_NONE; return true; } -// EnterCriticalSection( &Tile_SPU::m_csShape ); - noCulling = true; + // EnterCriticalSection( &Tile_SPU::m_csShape ); + noCulling = true; setShape(0, 0, 0, 1, 13.0f / 16.0f, 1); tesselateBlockInWorld(tt, x, y, z); setFixedTexture(tt->getEye()); - setShape(4.0f / 16.0f, 13.0f / 16.0f, 4.0f / 16.0f, 12.0f / 16.0f, 1, 12.0f / 16.0f); + setShape(4.0f / 16.0f, 13.0f / 16.0f, 4.0f / 16.0f, 12.0f / 16.0f, 1, + 12.0f / 16.0f); tesselateBlockInWorld(tt, x, y, z); - noCulling = false; + noCulling = false; clearFixedTexture(); -// LeaveCriticalSection( &Tile_SPU::m_csShape ); + // LeaveCriticalSection( &Tile_SPU::m_csShape ); upFlip = FLIP_NONE; -#endif // DISABLE_TESS_FUNCS +#endif // DISABLE_TESS_FUNCS return true; } -bool TileRenderer_SPU::tesselateBedInWorld( Tile_SPU* tt, int x, int y, int z ) -{ +bool TileRenderer_SPU::tesselateBedInWorld(Tile_SPU* tt, int x, int y, int z) { #ifdef DISABLE_TESS_FUNCS - Tesselator_SPU* t = getTesselator(); + Tesselator_SPU* t = getTesselator(); - int data = level->getData( x, y, z ); - int direction = BedTile::getDirection( data ); - bool isHead = BedTile::isHeadPiece( data ); + int data = level->getData(x, y, z); + int direction = BedTile::getDirection(data); + bool isHead = BedTile::isHeadPiece(data); - float c10 = 0.5f; - float c11 = 1.0f; - float c2 = 0.8f; - float c3 = 0.6f; + float c10 = 0.5f; + float c11 = 1.0f; + float c2 = 0.8f; + float c3 = 0.6f; - float r11 = c11; - float g11 = c11; - float b11 = c11; + float r11 = c11; + float g11 = c11; + float b11 = c11; - float r10 = c10; - float r2 = c2; - float r3 = c3; + float r10 = c10; + float r2 = c2; + float r3 = c3; - float g10 = c10; - float g2 = c2; - float g3 = c3; + float g10 = c10; + float g2 = c2; + float g3 = c3; - float b10 = c10; - float b2 = c2; - float b3 = c3; + float b10 = c10; + float b2 = c2; + float b3 = c3; - // 4J - change brought forward from 1.8.2 - int centerColor; - float centerBrightness; - if ( SharedConstants::TEXTURE_LIGHTING ) - { - centerColor = tt->getLightColor( level, x, y, z ); - } - else - { - centerBrightness = tt->getBrightness( level, x, y, z ); - } + // 4J - change brought forward from 1.8.2 + int centerColor; + float centerBrightness; + if (SharedConstants::TEXTURE_LIGHTING) { + centerColor = tt->getLightColor(level, x, y, z); + } else { + centerBrightness = tt->getBrightness(level, x, y, z); + } - // render wooden underside - { - // 4J - change brought forward from 1.8.2 - if ( SharedConstants::TEXTURE_LIGHTING ) - { - t->tex2( centerColor ); - t->color( r10, g10, b10 ); - } - else - { - t->color( r10 * centerBrightness, g10 * centerBrightness, b10 * centerBrightness ); - } + // render wooden underside + { + // 4J - change brought forward from 1.8.2 + if (SharedConstants::TEXTURE_LIGHTING) { + t->tex2(centerColor); + t->color(r10, g10, b10); + } else { + t->color(r10 * centerBrightness, g10 * centerBrightness, + b10 * centerBrightness); + } - Icon_SPU *tex = getTexture( tt, level, x, y, z, Facing::DOWN ); + Icon_SPU* tex = getTexture(tt, level, x, y, z, Facing::DOWN); - float u0 = tex->getU0(); - float u1 = tex->getU1(); - float v0 = tex->getV0(); - float v1 = tex->getV1(); + float u0 = tex->getU0(); + float u1 = tex->getU1(); + float v0 = tex->getV0(); + float v1 = tex->getV1(); - float x0 = x + tileShapeX0; - float x1 = x + tileShapeX1; - float y0 = y + tileShapeY0 + 3.0 / 16.0; - float z0 = z + tileShapeZ0; - float z1 = z + tileShapeZ1; + float x0 = x + tileShapeX0; + float x1 = x + tileShapeX1; + float y0 = y + tileShapeY0 + 3.0 / 16.0; + float z0 = z + tileShapeZ0; + float z1 = z + tileShapeZ1; - t->vertexUV( x0 , y0 , z1 , u0 , v1 ); - t->vertexUV( x0 , y0 , z0 , u0 , v0 ); - t->vertexUV( x1 , y0 , z0 , u1 , v0 ); - t->vertexUV( x1 , y0 , z1 , u1 , v1 ); - } + t->vertexUV(x0, y0, z1, u0, v1); + t->vertexUV(x0, y0, z0, u0, v0); + t->vertexUV(x1, y0, z0, u1, v0); + t->vertexUV(x1, y0, z1, u1, v1); + } - // render bed top - // 4J - change brought forward from 1.8.2 - if ( SharedConstants::TEXTURE_LIGHTING ) - { - t->tex2( tt->getLightColor( level, x, y + 1, z ) ); - t->color( r11, g11, b11 ); - } - else - { - float brightness = tt->getBrightness( level, x, y + 1, z ); - t->color( r11 * brightness, g11 * brightness, b11 * brightness ); - } + // render bed top + // 4J - change brought forward from 1.8.2 + if (SharedConstants::TEXTURE_LIGHTING) { + t->tex2(tt->getLightColor(level, x, y + 1, z)); + t->color(r11, g11, b11); + } else { + float brightness = tt->getBrightness(level, x, y + 1, z); + t->color(r11 * brightness, g11 * brightness, b11 * brightness); + } - Icon_SPU *tex = getTexture( tt, level, x, y, z, Facing::UP ); + Icon_SPU* tex = getTexture(tt, level, x, y, z, Facing::UP); - float u0 = tex->getU0(); - float u1 = tex->getU1(); - float v0 = tex->getV0(); - float v1 = tex->getV1(); + float u0 = tex->getU0(); + float u1 = tex->getU1(); + float v0 = tex->getV0(); + float v1 = tex->getV1(); - float topLeftU = u0; - float topRightU = u1; - float topLeftV = v0; - float topRightV = v0; - float bottomLeftU = u0; - float bottomRightU = u1; - float bottomLeftV = v1; - float bottomRightV = v1; + float topLeftU = u0; + float topRightU = u1; + float topLeftV = v0; + float topRightV = v0; + float bottomLeftU = u0; + float bottomRightU = u1; + float bottomLeftV = v1; + float bottomRightV = v1; - if ( direction == Direction::SOUTH ) - { - // rotate 90 degrees clockwise - topRightU = u0; - topLeftV = v1; - bottomLeftU = u1; - bottomRightV = v0; - } - else if ( direction == Direction::NORTH ) - { - // rotate 90 degrees counter-clockwise - topLeftU = u1; - topRightV = v1; - bottomRightU = u0; - bottomLeftV = v0; - } - else if ( direction == Direction::EAST ) - { - // rotate 180 degrees - topLeftU = u1; - topRightV = v1; - bottomRightU = u0; - bottomLeftV = v0; - topRightU = u0; - topLeftV = v1; - bottomLeftU = u1; - bottomRightV = v0; - } + if (direction == Direction::SOUTH) { + // rotate 90 degrees clockwise + topRightU = u0; + topLeftV = v1; + bottomLeftU = u1; + bottomRightV = v0; + } else if (direction == Direction::NORTH) { + // rotate 90 degrees counter-clockwise + topLeftU = u1; + topRightV = v1; + bottomRightU = u0; + bottomLeftV = v0; + } else if (direction == Direction::EAST) { + // rotate 180 degrees + topLeftU = u1; + topRightV = v1; + bottomRightU = u0; + bottomLeftV = v0; + topRightU = u0; + topLeftV = v1; + bottomLeftU = u1; + bottomRightV = v0; + } - float x0 = x + tileShapeX0; - float x1 = x + tileShapeX1; - float y1 = y + tileShapeY1; - float z0 = z + tileShapeZ0; - float z1 = z + tileShapeZ1; + float x0 = x + tileShapeX0; + float x1 = x + tileShapeX1; + float y1 = y + tileShapeY1; + float z0 = z + tileShapeZ0; + float z1 = z + tileShapeZ1; - t->vertexUV( x1 , y1 , z1 , bottomLeftU ,bottomLeftV ); - t->vertexUV( x1 , y1 , z0 , topLeftU , topLeftV ); - t->vertexUV( x0 , y1 , z0 , topRightU ,topRightV ); - t->vertexUV( x0 , y1 , z1 , bottomRightU ,bottomRightV ); + t->vertexUV(x1, y1, z1, bottomLeftU, bottomLeftV); + t->vertexUV(x1, y1, z0, topLeftU, topLeftV); + t->vertexUV(x0, y1, z0, topRightU, topRightV); + t->vertexUV(x0, y1, z1, bottomRightU, bottomRightV); - // determine which edge to skip (the one between foot and head piece) - int skipEdge = Direction::DIRECTION_FACING[direction]; - if ( isHead ) - { - skipEdge = Direction::DIRECTION_FACING[Direction::DIRECTION_OPPOSITE[direction]]; - } - // and which edge to x-flip - int flipEdge = Facing::WEST; - switch ( direction ) - { - case Direction::NORTH: - break; - case Direction::SOUTH: - flipEdge = Facing::EAST; - break; - case Direction::EAST: - flipEdge = Facing::NORTH; - break; - case Direction::WEST: - flipEdge = Facing::SOUTH; - break; - } + // determine which edge to skip (the one between foot and head piece) + int skipEdge = Direction::DIRECTION_FACING[direction]; + if (isHead) { + skipEdge = Direction::DIRECTION_FACING + [Direction::DIRECTION_OPPOSITE[direction]]; + } + // and which edge to x-flip + int flipEdge = Facing::WEST; + switch (direction) { + case Direction::NORTH: + break; + case Direction::SOUTH: + flipEdge = Facing::EAST; + break; + case Direction::EAST: + flipEdge = Facing::NORTH; + break; + case Direction::WEST: + flipEdge = Facing::SOUTH; + break; + } - if ( ( skipEdge != Facing::NORTH ) && ( noCulling || tt->shouldRenderFace( level, x, y, z - 1, Facing::NORTH ) ) ) - { - if ( SharedConstants::TEXTURE_LIGHTING ) - { - t->tex2( tileShapeZ0 > 0 ? centerColor : tt->getLightColor( level, x, y, z - 1 ) ); - t->color( r2, g2, b2 ); - } - else - { - float br = tt->getBrightness( level, x, y, z - 1 ); - if ( tileShapeZ0 > 0 ) br = centerBrightness; - t->color( r2 * br, g2 * br, b2 * br ); - } - xFlipTexture = flipEdge == Facing::NORTH; - renderNorth( tt, x, y, z, getTexture( tt, level, x, y, z, 2 ) ); - } + if ((skipEdge != Facing::NORTH) && + (noCulling || + tt->shouldRenderFace(level, x, y, z - 1, Facing::NORTH))) { + if (SharedConstants::TEXTURE_LIGHTING) { + t->tex2(tileShapeZ0 > 0 ? centerColor + : tt->getLightColor(level, x, y, z - 1)); + t->color(r2, g2, b2); + } else { + float br = tt->getBrightness(level, x, y, z - 1); + if (tileShapeZ0 > 0) br = centerBrightness; + t->color(r2 * br, g2 * br, b2 * br); + } + xFlipTexture = flipEdge == Facing::NORTH; + renderNorth(tt, x, y, z, getTexture(tt, level, x, y, z, 2)); + } - if ( ( skipEdge != Facing::SOUTH ) && ( noCulling || tt->shouldRenderFace( level, x, y, z + 1, Facing::SOUTH ) ) ) - { - if ( SharedConstants::TEXTURE_LIGHTING ) - { - t->tex2( tileShapeZ1 < 1 ? centerColor : tt->getLightColor( level, x, y, z + 1 ) ); - t->color( r2, g2, b2 ); - } - else - { - float br = tt->getBrightness( level, x, y, z + 1 ); - if ( tileShapeZ1 < 1 ) br = centerBrightness; - t->color( r2 * br, g2 * br, b2 * br ); - } + if ((skipEdge != Facing::SOUTH) && + (noCulling || + tt->shouldRenderFace(level, x, y, z + 1, Facing::SOUTH))) { + if (SharedConstants::TEXTURE_LIGHTING) { + t->tex2(tileShapeZ1 < 1 ? centerColor + : tt->getLightColor(level, x, y, z + 1)); + t->color(r2, g2, b2); + } else { + float br = tt->getBrightness(level, x, y, z + 1); + if (tileShapeZ1 < 1) br = centerBrightness; + t->color(r2 * br, g2 * br, b2 * br); + } - xFlipTexture = flipEdge == Facing::SOUTH; - renderSouth( tt, x, y, z, getTexture( tt, level, x, y, z, 3 ) ); - } + xFlipTexture = flipEdge == Facing::SOUTH; + renderSouth(tt, x, y, z, getTexture(tt, level, x, y, z, 3)); + } - if ( ( skipEdge != Facing::WEST ) && ( noCulling || tt->shouldRenderFace( level, x - 1, y, z, Facing::WEST ) ) ) - { - if ( SharedConstants::TEXTURE_LIGHTING ) - { - t->tex2( tileShapeZ0 > 0 ? centerColor : tt->getLightColor( level, x - 1, y, z ) ); - t->color( r3, g3, b3 ); - } - else - { - float br = tt->getBrightness( level, x - 1, y, z ); - if ( tileShapeX0 > 0 ) br = centerBrightness; - t->color( r3 * br, g3 * br, b3 * br ); - } - xFlipTexture = flipEdge == Facing::WEST; - renderWest( tt, x, y, z, getTexture( tt, level, x, y, z, 4 ) ); - } + if ((skipEdge != Facing::WEST) && + (noCulling || tt->shouldRenderFace(level, x - 1, y, z, Facing::WEST))) { + if (SharedConstants::TEXTURE_LIGHTING) { + t->tex2(tileShapeZ0 > 0 ? centerColor + : tt->getLightColor(level, x - 1, y, z)); + t->color(r3, g3, b3); + } else { + float br = tt->getBrightness(level, x - 1, y, z); + if (tileShapeX0 > 0) br = centerBrightness; + t->color(r3 * br, g3 * br, b3 * br); + } + xFlipTexture = flipEdge == Facing::WEST; + renderWest(tt, x, y, z, getTexture(tt, level, x, y, z, 4)); + } - if ( ( skipEdge != Facing::EAST ) && ( noCulling || tt->shouldRenderFace( level, x + 1, y, z, Facing::EAST ) ) ) - { - if ( SharedConstants::TEXTURE_LIGHTING ) - { - t->tex2( tileShapeZ1 < 1 ? centerColor : tt->getLightColor( level, x + 1, y, z ) ); - t->color( r3, g3, b3 ); - } - else - { - float br = tt->getBrightness( level, x + 1, y, z ); - if ( tileShapeX1 < 1 ) br = centerBrightness; - t->color( r3 * br, g3 * br, b3 * br ); - } - xFlipTexture = flipEdge == Facing::EAST; - renderEast( tt, x, y, z, getTexture( tt, level, x, y, z, 5 ) ); - } - xFlipTexture = false; -#endif // DISABLE_TESS_FUNCS - - return true; + if ((skipEdge != Facing::EAST) && + (noCulling || tt->shouldRenderFace(level, x + 1, y, z, Facing::EAST))) { + if (SharedConstants::TEXTURE_LIGHTING) { + t->tex2(tileShapeZ1 < 1 ? centerColor + : tt->getLightColor(level, x + 1, y, z)); + t->color(r3, g3, b3); + } else { + float br = tt->getBrightness(level, x + 1, y, z); + if (tileShapeX1 < 1) br = centerBrightness; + t->color(r3 * br, g3 * br, b3 * br); + } + xFlipTexture = flipEdge == Facing::EAST; + renderEast(tt, x, y, z, getTexture(tt, level, x, y, z, 5)); + } + xFlipTexture = false; +#endif // DISABLE_TESS_FUNCS + return true; } -bool TileRenderer_SPU::tesselateBrewingStandInWorld(BrewingStandTile_SPU *tt, int x, int y, int z) -{ - -// EnterCriticalSection( &Tile_SPU::m_csShape ); +bool TileRenderer_SPU::tesselateBrewingStandInWorld(BrewingStandTile_SPU* tt, + int x, int y, int z) { + // EnterCriticalSection( &Tile_SPU::m_csShape ); // bounding box first - setShape(7.0f / 16.0f, 0.0f, 7.0f / 16.0f, 9.0f / 16.0f, 14.0f / 16.0f, 9.0f / 16.0f); + setShape(7.0f / 16.0f, 0.0f, 7.0f / 16.0f, 9.0f / 16.0f, 14.0f / 16.0f, + 9.0f / 16.0f); tesselateBlockInWorld(tt, x, y, z); setFixedTexture(tt->getBaseTexture()); - setShape(9.0f / 16.0f, 0.0f, 5.0f / 16.0f, 15.0f / 16.0f, 2 / 16.0f, 11.0f / 16.0f); + setShape(9.0f / 16.0f, 0.0f, 5.0f / 16.0f, 15.0f / 16.0f, 2 / 16.0f, + 11.0f / 16.0f); tesselateBlockInWorld(tt, x, y, z); - setShape(2.0f / 16.0f, 0.0f, 1.0f / 16.0f, 8.0f / 16.0f, 2 / 16.0f, 7.0f / 16.0f); + setShape(2.0f / 16.0f, 0.0f, 1.0f / 16.0f, 8.0f / 16.0f, 2 / 16.0f, + 7.0f / 16.0f); tesselateBlockInWorld(tt, x, y, z); - setShape(2.0f / 16.0f, 0.0f, 9.0f / 16.0f, 8.0f / 16.0f, 2 / 16.0f, 15.0f / 16.0f); + setShape(2.0f / 16.0f, 0.0f, 9.0f / 16.0f, 8.0f / 16.0f, 2 / 16.0f, + 15.0f / 16.0f); tesselateBlockInWorld(tt, x, y, z); clearFixedTexture(); - Tesselator_SPU* t = getTesselator(); + Tesselator_SPU* t = getTesselator(); float br; - if (SharedConstants::TEXTURE_LIGHTING) - { + if (SharedConstants::TEXTURE_LIGHTING) { t->tex2(tt->getLightColor(level, x, y, z)); br = 1; - } - else - { + } else { br = tt->getBrightness(level, x, y, z); } int col = tt->getColor(level, x, y, z); @@ -686,31 +647,29 @@ bool TileRenderer_SPU::tesselateBrewingStandInWorld(BrewingStandTile_SPU *tt, in t->color(br * r, br * g, br * b); - Icon_SPU *tex = getTexture(tt, 0, 0); + Icon_SPU* tex = getTexture(tt, 0, 0); - if (hasFixedTexture()) tex = fixedTexture; - float v0 = tex->getV0(); - float v1 = tex->getV1(); + if (hasFixedTexture()) tex = fixedTexture; + float v0 = tex->getV0(); + float v1 = tex->getV1(); int data = level->getData(x, y, z); - for (int arm = 0; arm < 3; arm++) - { - + for (int arm = 0; arm < 3; arm++) { float angle = arm * MATH_PI * 2.0f / 3.0f + MATH_PI * 0.5f; - float u0 = tex->getU(8); - float u1 = tex->getU1(); -// if (brewEntity != null && brewEntity.getItem(arm) != null) { - if ((data & (1 << arm)) != 0) - { + float u0 = tex->getU(8); + float u1 = tex->getU1(); + // if (brewEntity != null && brewEntity.getItem(arm) != null) + // { + if ((data & (1 << arm)) != 0) { u1 = tex->getU0(); } - float x0 = x + 8.0f / 16.0f; - float x1 = x + 8.0f / 16.0f + sin(angle) * 8.0f / 16.0f; - float z0 = z + 8.0f / 16.0f; - float z1 = z + 8.0f / 16.0f + cos(angle) * 8.0f / 16.0f; + float x0 = x + 8.0f / 16.0f; + float x1 = x + 8.0f / 16.0f + sin(angle) * 8.0f / 16.0f; + float z0 = z + 8.0f / 16.0f; + float z1 = z + 8.0f / 16.0f + cos(angle) * 8.0f / 16.0f; t->vertexUV(x0, y + 1.0f, z0, u0, v0); t->vertexUV(x0, y + 0.0f, z0, u0, v1); @@ -725,27 +684,24 @@ bool TileRenderer_SPU::tesselateBrewingStandInWorld(BrewingStandTile_SPU *tt, in tt->updateDefaultShape(); -// LeaveCriticalSection( &Tile_SPU::m_csShape ); + // LeaveCriticalSection( &Tile_SPU::m_csShape ); return true; } -bool TileRenderer_SPU::tesselateCauldronInWorld(CauldronTile_SPU *tt, int x, int y, int z) -{ +bool TileRenderer_SPU::tesselateCauldronInWorld(CauldronTile_SPU* tt, int x, + int y, int z) { #ifdef DISABLE_TESS_FUNCS // bounding box first tesselateBlockInWorld(tt, x, y, z); - Tesselator_SPU* t = getTesselator(); + Tesselator_SPU* t = getTesselator(); float br; - if (SharedConstants::TEXTURE_LIGHTING) - { + if (SharedConstants::TEXTURE_LIGHTING) { t->tex2(tt->getLightColor(level, x, y, z)); br = 1; - } - else - { + } else { br = tt->getBrightness(level, x, y, z); } int col = tt->getColor(level, x, y, z); @@ -756,3058 +712,3045 @@ bool TileRenderer_SPU::tesselateCauldronInWorld(CauldronTile_SPU *tt, int x, int t->color(br * r, br * g, br * b); // render inside - Icon_SPU *insideTex = tt->getTexture(Facing::NORTH); - const float cWidth = ( 2.0f / 16.0f ) - ( 1.0f / 128.0f ); // 4J - Moved by 1/128th (smallest movement possible with our vertex storage) to remove gap at edge of cauldron + Icon_SPU* insideTex = tt->getTexture(Facing::NORTH); + const float cWidth = + (2.0f / 16.0f) - + (1.0f / + 128.0f); // 4J - Moved by 1/128th (smallest movement possible with our + // vertex storage) to remove gap at edge of cauldron renderEast(tt, x - 1.0f + cWidth, y, z, insideTex); renderWest(tt, x + 1.0f - cWidth, y, z, insideTex); renderSouth(tt, x, y, z - 1.0f + cWidth, insideTex); renderNorth(tt, x, y, z + 1.0f - cWidth, insideTex); - Icon_SPU *bottomTex = CauldronTile::getTexture(CauldronTile::TEXTURE_INSIDE); + Icon_SPU* bottomTex = + CauldronTile::getTexture(CauldronTile::TEXTURE_INSIDE); renderFaceUp(tt, x, y - 1.0f + 4.0f / 16.0f, z, bottomTex); renderFaceDown(tt, x, y + 1.0f - 12.0f / 16.0f, z, bottomTex); int waterLevel = level->getData(x, y, z); - if (waterLevel > 0) - { - Icon_SPU *liquidTex = LiquidTile_SPU::getTexture(LiquidTile_SPU::TEXTURE_WATER_STILL); + if (waterLevel > 0) { + Icon_SPU* liquidTex = + LiquidTile_SPU::getTexture(LiquidTile_SPU::TEXTURE_WATER_STILL); - if (waterLevel > 3) - { + if (waterLevel > 3) { waterLevel = 3; } - renderFaceUp(tt, x, y - 1.0f + (6.0f + waterLevel * 3.0f) / 16.0f, z, liquidTex); + renderFaceUp(tt, x, y - 1.0f + (6.0f + waterLevel * 3.0f) / 16.0f, z, + liquidTex); } -#endif // DISABLE_TESS_FUNCS +#endif // DISABLE_TESS_FUNCS return true; - } -bool TileRenderer_SPU::tesselateFlowerPotInWorld(FlowerPotTile_SPU *tt, int x, int y, int z) -{ +bool TileRenderer_SPU::tesselateFlowerPotInWorld(FlowerPotTile_SPU* tt, int x, + int y, int z) { #ifdef DISABLE_TESS_FUNCS - // bounding box first - tesselateBlockInWorld(tt, x, y, z); + // bounding box first + tesselateBlockInWorld(tt, x, y, z); - Tesselator *t = Tesselator::getInstance(); + Tesselator* t = Tesselator::getInstance(); - float br; - if (SharedConstants::TEXTURE_LIGHTING) - { - t->tex2(tt->getLightColor(level, x, y, z)); - br = 1; - } - else - { - br = tt->getBrightness(level, x, y, z); - } - int col = tt->getColor(level, x, y, z); - Icon *tex = getTexture(tt, 0); - float r = ((col >> 16) & 0xff) / 255.0f; - float g = ((col >> 8) & 0xff) / 255.0f; - float b = ((col) & 0xff) / 255.0f; + float br; + if (SharedConstants::TEXTURE_LIGHTING) { + t->tex2(tt->getLightColor(level, x, y, z)); + br = 1; + } else { + br = tt->getBrightness(level, x, y, z); + } + int col = tt->getColor(level, x, y, z); + Icon* tex = getTexture(tt, 0); + float r = ((col >> 16) & 0xff) / 255.0f; + float g = ((col >> 8) & 0xff) / 255.0f; + float b = ((col) & 0xff) / 255.0f; - if (GameRenderer::anaglyph3d) - { - float cr = (r * 30 + g * 59 + b * 11) / 100; - float cg = (r * 30 + g * 70) / (100); - float cb = (r * 30 + b * 70) / (100); + if (GameRenderer::anaglyph3d) { + float cr = (r * 30 + g * 59 + b * 11) / 100; + float cg = (r * 30 + g * 70) / (100); + float cb = (r * 30 + b * 70) / (100); - r = cr; - g = cg; - b = cb; - } - t->color(br * r, br * g, br * b); + r = cr; + g = cg; + b = cb; + } + t->color(br * r, br * g, br * b); - // render inside + // render inside - float halfWidth = (6.0f / 16.0f) / 2 - 0.001f; - renderEast(tt, x - 0.5f + halfWidth, y, z, tex); - renderWest(tt, x + 0.5f - halfWidth, y, z, tex); - renderSouth(tt, x, y, z - 0.5f + halfWidth, tex); - renderNorth(tt, x, y, z + 0.5f - halfWidth, tex); + float halfWidth = (6.0f / 16.0f) / 2 - 0.001f; + renderEast(tt, x - 0.5f + halfWidth, y, z, tex); + renderWest(tt, x + 0.5f - halfWidth, y, z, tex); + renderSouth(tt, x, y, z - 0.5f + halfWidth, tex); + renderNorth(tt, x, y, z + 0.5f - halfWidth, tex); - renderFaceUp(tt, x, y - 0.5f + halfWidth + 3.0f / 16.0f, z, getTexture(Tile::dirt)); + renderFaceUp(tt, x, y - 0.5f + halfWidth + 3.0f / 16.0f, z, + getTexture(Tile::dirt)); - int type = level->getData(x, y, z); + int type = level->getData(x, y, z); - if (type != 0) - { - float xOff = 0; - float yOff = 4; - float zOff = 0; - Tile *plant = NULL; + if (type != 0) { + float xOff = 0; + float yOff = 4; + float zOff = 0; + Tile* plant = NULL; - switch (type) - { - case FlowerPotTile::TYPE_FLOWER_RED: - plant = Tile::rose; - break; - case FlowerPotTile::TYPE_FLOWER_YELLOW: - plant = Tile::flower; - break; - case FlowerPotTile::TYPE_MUSHROOM_BROWN: - plant = Tile::mushroom1; - break; - case FlowerPotTile::TYPE_MUSHROOM_RED: - plant = Tile::mushroom2; - break; - } + switch (type) { + case FlowerPotTile::TYPE_FLOWER_RED: + plant = Tile::rose; + break; + case FlowerPotTile::TYPE_FLOWER_YELLOW: + plant = Tile::flower; + break; + case FlowerPotTile::TYPE_MUSHROOM_BROWN: + plant = Tile::mushroom1; + break; + case FlowerPotTile::TYPE_MUSHROOM_RED: + plant = Tile::mushroom2; + break; + } - t->addOffset(xOff / 16.0f, yOff / 16.0f, zOff / 16.0f); + t->addOffset(xOff / 16.0f, yOff / 16.0f, zOff / 16.0f); - if (plant != NULL) - { - tesselateInWorld(plant, x, y, z); - } - else - { - if (type == FlowerPotTile::TYPE_CACTUS) - { + if (plant != NULL) { + tesselateInWorld(plant, x, y, z); + } else { + if (type == FlowerPotTile::TYPE_CACTUS) { + // Force drawing of all faces else the cactus misses faces + // when a block is adjacent + noCulling = true; - // Force drawing of all faces else the cactus misses faces - // when a block is adjacent - noCulling = true; + float halfSize = 0.25f / 2; + setShape(0.5f - halfSize, 0.0f, 0.5f - halfSize, + 0.5f + halfSize, 0.25f, 0.5f + halfSize); + tesselateBlockInWorld(Tile::cactus, x, y, z); + setShape(0.5f - halfSize, 0.25f, 0.5f - halfSize, + 0.5f + halfSize, 0.5f, 0.5f + halfSize); + tesselateBlockInWorld(Tile::cactus, x, y, z); + setShape(0.5f - halfSize, 0.5f, 0.5f - halfSize, + 0.5f + halfSize, 0.75f, 0.5f + halfSize); + tesselateBlockInWorld(Tile::cactus, x, y, z); - float halfSize = 0.25f / 2; - setShape(0.5f - halfSize, 0.0f, 0.5f - halfSize, 0.5f + halfSize, 0.25f, 0.5f + halfSize); - tesselateBlockInWorld(Tile::cactus, x, y, z); - setShape(0.5f - halfSize, 0.25f, 0.5f - halfSize, 0.5f + halfSize, 0.5f, 0.5f + halfSize); - tesselateBlockInWorld(Tile::cactus, x, y, z); - setShape(0.5f - halfSize, 0.5f, 0.5f - halfSize, 0.5f + halfSize, 0.75f, 0.5f + halfSize); - tesselateBlockInWorld(Tile::cactus, x, y, z); + noCulling = false; - noCulling = false; + setShape(0, 0, 0, 1, 1, 1); + } else if (type == FlowerPotTile::TYPE_SAPLING_DEFAULT) { + tesselateCrossTexture(Tile::sapling, Sapling::TYPE_DEFAULT, x, + y, z, 0.75f); + } else if (type == FlowerPotTile::TYPE_SAPLING_BIRCH) { + tesselateCrossTexture(Tile::sapling, Sapling::TYPE_BIRCH, x, y, + z, 0.75f); + } else if (type == FlowerPotTile::TYPE_SAPLING_EVERGREEN) { + tesselateCrossTexture(Tile::sapling, Sapling::TYPE_EVERGREEN, x, + y, z, 0.75f); + } else if (type == FlowerPotTile::TYPE_SAPLING_JUNGLE) { + tesselateCrossTexture(Tile::sapling, Sapling::TYPE_JUNGLE, x, y, + z, 0.75f); + } else if (type == FlowerPotTile::TYPE_FERN) { + col = Tile::tallgrass->getColor(level, x, y, z); + r = ((col >> 16) & 0xff) / 255.0f; + g = ((col >> 8) & 0xff) / 255.0f; + b = ((col) & 0xff) / 255.0f; + t->color(br * r, br * g, br * b); + tesselateCrossTexture(Tile::tallgrass, TallGrass::FERN, x, y, z, + 0.75f); + } else if (type == FlowerPotTile::TYPE_DEAD_BUSH) { + tesselateCrossTexture(Tile::deadBush, TallGrass::FERN, x, y, z, + 0.75f); + } + } - setShape(0, 0, 0, 1, 1, 1); - } - else if (type == FlowerPotTile::TYPE_SAPLING_DEFAULT) - { - tesselateCrossTexture(Tile::sapling, Sapling::TYPE_DEFAULT, x, y, z, 0.75f); - } - else if (type == FlowerPotTile::TYPE_SAPLING_BIRCH) - { - tesselateCrossTexture(Tile::sapling, Sapling::TYPE_BIRCH, x, y, z, 0.75f); - } - else if (type == FlowerPotTile::TYPE_SAPLING_EVERGREEN) - { - tesselateCrossTexture(Tile::sapling, Sapling::TYPE_EVERGREEN, x, y, z, 0.75f); - } - else if (type == FlowerPotTile::TYPE_SAPLING_JUNGLE) - { - tesselateCrossTexture(Tile::sapling, Sapling::TYPE_JUNGLE, x, y, z, 0.75f); - } - else if (type == FlowerPotTile::TYPE_FERN) - { - col = Tile::tallgrass->getColor(level, x, y, z); - r = ((col >> 16) & 0xff) / 255.0f; - g = ((col >> 8) & 0xff) / 255.0f; - b = ((col) & 0xff) / 255.0f; - t->color(br * r, br * g, br * b); - tesselateCrossTexture(Tile::tallgrass, TallGrass::FERN, x, y, z, 0.75f); - } - else if (type == FlowerPotTile::TYPE_DEAD_BUSH) - { - tesselateCrossTexture(Tile::deadBush, TallGrass::FERN, x, y, z, 0.75f); - } - } + t->addOffset(-xOff / 16.0f, -yOff / 16.0f, -zOff / 16.0f); + } +#endif // DISABLE_TESS_FUNCS - t->addOffset(-xOff / 16.0f, -yOff / 16.0f, -zOff / 16.0f); - } -#endif //DISABLE_TESS_FUNCS - - return true; + return true; } -bool TileRenderer_SPU::tesselateAnvilInWorld(AnvilTile_SPU *tt, int x, int y, int z) -{ - return tesselateAnvilInWorld(tt, x, y, z, level->getData(x, y, z)); - +bool TileRenderer_SPU::tesselateAnvilInWorld(AnvilTile_SPU* tt, int x, int y, + int z) { + return tesselateAnvilInWorld(tt, x, y, z, level->getData(x, y, z)); } -bool TileRenderer_SPU::tesselateAnvilInWorld(AnvilTile_SPU *tt, int x, int y, int z, int data) -{ +bool TileRenderer_SPU::tesselateAnvilInWorld(AnvilTile_SPU* tt, int x, int y, + int z, int data) { #ifdef DISABLE_TESS_FUNCS - Tesselator *t = Tesselator::getInstance(); + Tesselator* t = Tesselator::getInstance(); - float br; - if (SharedConstants::TEXTURE_LIGHTING) - { - t->tex2(tt->getLightColor(level, x, y, z)); - br = 1; - } - else - { - br = tt->getBrightness(level, x, y, z); - } - int col = tt->getColor(level, x, y, z); - float r = ((col >> 16) & 0xff) / 255.0f; - float g = ((col >> 8) & 0xff) / 255.0f; - float b = ((col) & 0xff) / 255.0f; + float br; + if (SharedConstants::TEXTURE_LIGHTING) { + t->tex2(tt->getLightColor(level, x, y, z)); + br = 1; + } else { + br = tt->getBrightness(level, x, y, z); + } + int col = tt->getColor(level, x, y, z); + float r = ((col >> 16) & 0xff) / 255.0f; + float g = ((col >> 8) & 0xff) / 255.0f; + float b = ((col) & 0xff) / 255.0f; - if (GameRenderer::anaglyph3d) - { - float cr = (r * 30 + g * 59 + b * 11) / 100; - float cg = (r * 30 + g * 70) / (100); - float cb = (r * 30 + b * 70) / (100); + if (GameRenderer::anaglyph3d) { + float cr = (r * 30 + g * 59 + b * 11) / 100; + float cg = (r * 30 + g * 70) / (100); + float cb = (r * 30 + b * 70) / (100); - r = cr; - g = cg; - b = cb; - } - t->color(br * r, br * g, br * b); -#endif // DISABLE_TESS_FUNCS + r = cr; + g = cg; + b = cb; + } + t->color(br * r, br * g, br * b); +#endif // DISABLE_TESS_FUNCS - - return tesselateAnvilInWorld(tt, x, y, z, data, false); + return tesselateAnvilInWorld(tt, x, y, z, data, false); } -bool TileRenderer_SPU::tesselateAnvilInWorld(AnvilTile_SPU *tt, int x, int y, int z, int data, bool render) -{ +bool TileRenderer_SPU::tesselateAnvilInWorld(AnvilTile_SPU* tt, int x, int y, + int z, int data, bool render) { #ifdef DISABLE_TESS_FUNCS - int facing = render ? 0 : data & 3; - boolean rotate = false; - float bottom = 0; + int facing = render ? 0 : data & 3; + boolean rotate = false; + float bottom = 0; - switch (facing) - { - case Direction::NORTH: - eastFlip = FLIP_CW; - westFlip = FLIP_CCW; - break; - case Direction::SOUTH: - eastFlip = FLIP_CCW; - westFlip = FLIP_CW; - upFlip = FLIP_180; - downFlip = FLIP_180; - break; - case Direction::WEST: - northFlip = FLIP_CW; - southFlip = FLIP_CCW; - upFlip = FLIP_CCW; - downFlip = FLIP_CW; - rotate = true; - break; - case Direction::EAST: - northFlip = FLIP_CCW; - southFlip = FLIP_CW; - upFlip = FLIP_CW; - downFlip = FLIP_CCW; - rotate = true; - break; - } + switch (facing) { + case Direction::NORTH: + eastFlip = FLIP_CW; + westFlip = FLIP_CCW; + break; + case Direction::SOUTH: + eastFlip = FLIP_CCW; + westFlip = FLIP_CW; + upFlip = FLIP_180; + downFlip = FLIP_180; + break; + case Direction::WEST: + northFlip = FLIP_CW; + southFlip = FLIP_CCW; + upFlip = FLIP_CCW; + downFlip = FLIP_CW; + rotate = true; + break; + case Direction::EAST: + northFlip = FLIP_CCW; + southFlip = FLIP_CW; + upFlip = FLIP_CW; + downFlip = FLIP_CCW; + rotate = true; + break; + } - bottom = tesselateAnvilPiece(tt, x, y, z, AnvilTile::PART_BASE, bottom, 12.0f / 16.0f, 4.0f / 16.0f, 12.0f / 16.0f, rotate, render, data); - bottom = tesselateAnvilPiece(tt, x, y, z, AnvilTile::PART_JOINT, bottom, 8.0f / 16.0f, 1.0f / 16.0f, 10.0f / 16.0f, rotate, render, data); - bottom = tesselateAnvilPiece(tt, x, y, z, AnvilTile::PART_COLUMN, bottom, 4.0f / 16.0f, 5.0f / 16.0f, 8.0f / 16.0f, rotate, render, data); - bottom = tesselateAnvilPiece(tt, x, y, z, AnvilTile::PART_TOP, bottom, 10.0f / 16.0f, 6.0f / 16.0f, 16.0f / 16.0f, rotate, render, data); + bottom = tesselateAnvilPiece(tt, x, y, z, AnvilTile::PART_BASE, bottom, + 12.0f / 16.0f, 4.0f / 16.0f, 12.0f / 16.0f, + rotate, render, data); + bottom = tesselateAnvilPiece(tt, x, y, z, AnvilTile::PART_JOINT, bottom, + 8.0f / 16.0f, 1.0f / 16.0f, 10.0f / 16.0f, + rotate, render, data); + bottom = tesselateAnvilPiece(tt, x, y, z, AnvilTile::PART_COLUMN, bottom, + 4.0f / 16.0f, 5.0f / 16.0f, 8.0f / 16.0f, + rotate, render, data); + bottom = tesselateAnvilPiece(tt, x, y, z, AnvilTile::PART_TOP, bottom, + 10.0f / 16.0f, 6.0f / 16.0f, 16.0f / 16.0f, + rotate, render, data); - setShape(0, 0, 0, 1, 1, 1); - northFlip = FLIP_NONE; - southFlip = FLIP_NONE; - eastFlip = FLIP_NONE; - westFlip = FLIP_NONE; - upFlip = FLIP_NONE; - downFlip = FLIP_NONE; -#endif // DISABLE_TESS_FUNCS + setShape(0, 0, 0, 1, 1, 1); + northFlip = FLIP_NONE; + southFlip = FLIP_NONE; + eastFlip = FLIP_NONE; + westFlip = FLIP_NONE; + upFlip = FLIP_NONE; + downFlip = FLIP_NONE; +#endif // DISABLE_TESS_FUNCS - return true; + return true; } -float TileRenderer_SPU::tesselateAnvilPiece(AnvilTile_SPU *tt, int x, int y, int z, int part, float bottom, float width, float height, float length, bool rotate, bool render, int data) +float TileRenderer_SPU::tesselateAnvilPiece(AnvilTile_SPU* tt, int x, int y, + int z, int part, float bottom, + float width, float height, + float length, bool rotate, + bool render, int data) { +#ifdef DISABLE_TESS_FUNCS + if (rotate) { + float swap = width; + width = length; + length = swap; + } + + width /= 2; + length /= 2; + + ms_pTileData->anvilPart = part; + setShape(0.5f - width, bottom, 0.5f - length, 0.5f + width, bottom + height, + 0.5f + length); + + if (render) { + Tesselator* t = Tesselator::getInstance(); + t->begin(); + t->normal(0, -1, 0); + renderFaceDown(tt, 0, 0, 0, getTexture(tt, 0, data)); + t->end(); + + t->begin(); + t->normal(0, 1, 0); + renderFaceUp(tt, 0, 0, 0, getTexture(tt, 1, data)); + t->end(); + + t->begin(); + t->normal(0, 0, -1); + renderNorth(tt, 0, 0, 0, getTexture(tt, 2, data)); + t->end(); + + t->begin(); + t->normal(0, 0, 1); + renderSouth(tt, 0, 0, 0, getTexture(tt, 3, data)); + t->end(); + + t->begin(); + t->normal(-1, 0, 0); + renderWest(tt, 0, 0, 0, getTexture(tt, 4, data)); + t->end(); + + t->begin(); + t->normal(1, 0, 0); + renderEast(tt, 0, 0, 0, getTexture(tt, 5, data)); + t->end(); + } else { + tesselateBlockInWorld(tt, x, y, z); + } +#endif // DISABLE_TESS_FUNCS + + return bottom + height; +} + +bool TileRenderer_SPU::tesselateTorchInWorld(Tile_SPU* tt, int x, int y, + int z) { + int dir = level->getData(x, y, z); + + Tesselator_SPU* t = getTesselator(); + + if (SharedConstants::TEXTURE_LIGHTING) { + t->tex2(tt->getLightColor(level, x, y, z)); + t->color(1.0f, 1.0f, 1.0f); + } else { + float br = tt->getBrightness(level, x, y, z); + if (level->m_tileData.lightEmission[tt->id] > 0) br = 1.0f; + t->color(br, br, br); + } + + float r = 0.40f; + float r2 = 0.5f - r; + float h = 0.20f; + if (dir == 1) { + tesselateTorch(tt, (float)x - r2, (float)y + h, (float)z, -r, 0.0f, 0); + } else if (dir == 2) { + tesselateTorch(tt, (float)x + r2, (float)y + h, (float)z, +r, 0.0f, 0); + } else if (dir == 3) { + tesselateTorch(tt, (float)x, (float)y + h, z - r2, 0.0f, -r, 0); + } else if (dir == 4) { + tesselateTorch(tt, (float)x, (float)y + h, (float)z + r2, 0.0f, +r, 0); + } else { + tesselateTorch(tt, (float)x, (float)y, (float)z, 0.0f, 0.0f, 0); + } + return true; +} + +bool TileRenderer_SPU::tesselateDiodeInWorld(DiodeTile_SPU* tt, int x, int y, + int z) { +#ifdef DISABLE_TESS_FUNCS + Tesselator_SPU* t = getTesselator(); + + tesselateDiodeInWorld( + tt, x, y, z, level->getData(x, y, z) & DiodeTile_SPU::DIRECTION_MASK); + return true; +#endif // #ifdef DISABLE_TESS_FUNCS + return false; +} + +void TileRenderer_SPU::tesselateDiodeInWorld(DiodeTile_SPU* tt, int x, int y, + int z, int dir) { +#ifdef DISABLE_TESS_FUNCS + // render half-block edges + tesselateBlockInWorld(tt, x, y, z); + + Tesselator_SPU* t = getTesselator(); + + if (SharedConstants::TEXTURE_LIGHTING) { + t->tex2(tt->getLightColor(level, x, y, z)); + t->color(1.0f, 1.0f, 1.0f); + } else { + float br = tt->getBrightness(level, x, y, z); + if (level->m_tileData.lightEmission[tt->id] > 0) br = 1.0f; + t->color(br, br, br); + } + + int data = level->getData(x, y, z); + + // 4J Stu - This block gets moved in a later version, but we don't need that + // yet BEGIN TORCH SECTION + { + int dir = data & DiodeTile_SPU::DIRECTION_MASK; + int delay = + (data & DiodeTile_SPU::DELAY_MASK) >> DiodeTile_SPU::DELAY_SHIFT; + float h = -3.0f / 16.0f; + float transmitterX = 0.0f; + float transmitterZ = 0.0f; + float receiverX = 0.0f; + float receiverZ = 0.0f; + + switch (dir) { + case Direction::SOUTH: + receiverZ = -5.0f / 16.0f; + transmitterZ = DiodeTile_SPU::DELAY_RENDER_OFFSETS[delay]; + break; + case Direction::NORTH: + receiverZ = 5.0f / 16.0f; + transmitterZ = -DiodeTile_SPU::DELAY_RENDER_OFFSETS[delay]; + break; + case Direction::EAST: + receiverX = -5.0f / 16.0f; + transmitterX = DiodeTile_SPU::DELAY_RENDER_OFFSETS[delay]; + break; + case Direction::WEST: + receiverX = 5.0f / 16.0f; + transmitterX = -DiodeTile_SPU::DELAY_RENDER_OFFSETS[delay]; + break; + } + + // render transmitter + tesselateTorch(tt, x + transmitterX, y + h, z + transmitterZ, 0.0f, + 0.0f, 0); + // render receiver + tesselateTorch(tt, x + receiverX, y + h, z + receiverZ, 0.0f, 0.0f, 0); + } + // END TORCH SECTION + + Icon_SPU* tex = getTexture(tt, Facing::UP, data); + float u0 = tex->getU0(); + float u1 = tex->getU1(); + float v0 = tex->getV0(); + float v1 = tex->getV1(); + + float r = 2.0f / 16.0f; + + float x0 = (float)(x + 1.0f); + float x1 = (float)(x + 1.0f); + float x2 = (float)(x + 0.0f); + float x3 = (float)(x + 0.0f); + + float z0 = (float)(z + 0.0f); + float z1 = (float)(z + 1.0f); + float z2 = (float)(z + 1.0f); + float z3 = (float)(z + 0.0f); + + float y0 = (float)(y + r); + + if (dir == Direction::NORTH) { + // rotate 180 degrees + x0 = x1 = (float)(x + 0.0f); + x2 = x3 = (float)(x + 1.0f); + z0 = z3 = (float)(z + 1.0f); + z1 = z2 = (float)(z + 0.0f); + } else if (dir == Direction::EAST) { + // rotate 90 degrees counter-clockwise + x0 = x3 = (float)(x + 0.0f); + x1 = x2 = (float)(x + 1.0f); + z0 = z1 = (float)(z + 0.0f); + z2 = z3 = (float)(z + 1.0f); + } else if (dir == Direction::WEST) { + // rotate 90 degrees clockwise + x0 = x3 = (float)(x + 1.0f); + x1 = x2 = (float)(x + 0.0f); + z0 = z1 = (float)(z + 1.0f); + z2 = z3 = (float)(z + 0.0f); + } + + t->vertexUV(x3, y0, z3, u0, v0); + t->vertexUV(x2, y0, z2, u0, v1); + t->vertexUV(x1, y0, z1, u1, v1); + t->vertexUV(x0, y0, z0, u1, v0); +#endif // #ifdef DISABLE_TESS_FUNCS +} + +void TileRenderer_SPU::tesselatePistonBaseForceExtended( + Tile_SPU* tile, int x, int y, int z, + int forceData) // 4J added forceData param { #ifdef DISABLE_TESS_FUNCS - if (rotate) - { - float swap = width; - width = length; - length = swap; - } - - width /= 2; - length /= 2; - - ms_pTileData->anvilPart = part; - setShape(0.5f - width, bottom, 0.5f - length, 0.5f + width, bottom + height, 0.5f + length); - - if (render) - { - Tesselator *t = Tesselator::getInstance(); - t->begin(); - t->normal(0, -1, 0); - renderFaceDown(tt, 0, 0, 0, getTexture(tt, 0, data)); - t->end(); - - t->begin(); - t->normal(0, 1, 0); - renderFaceUp(tt, 0, 0, 0, getTexture(tt, 1, data)); - t->end(); - - t->begin(); - t->normal(0, 0, -1); - renderNorth(tt, 0, 0, 0, getTexture(tt, 2, data)); - t->end(); - - t->begin(); - t->normal(0, 0, 1); - renderSouth(tt, 0, 0, 0, getTexture(tt, 3, data)); - t->end(); - - t->begin(); - t->normal(-1, 0, 0); - renderWest(tt, 0, 0, 0, getTexture(tt, 4, data)); - t->end(); - - t->begin(); - t->normal(1, 0, 0); - renderEast(tt, 0, 0, 0, getTexture(tt, 5, data)); - t->end(); - } - else - { - tesselateBlockInWorld(tt, x, y, z); - } -#endif // DISABLE_TESS_FUNCS - - return bottom + height; + noCulling = true; + tesselatePistonBaseInWorld(tile, x, y, z, true, forceData); + noCulling = false; +#endif // DISABLE_TESS_FUNCS } - -bool TileRenderer_SPU::tesselateTorchInWorld( Tile_SPU* tt, int x, int y, int z ) -{ - int dir = level->getData( x, y, z ); - - Tesselator_SPU* t = getTesselator(); - - if ( SharedConstants::TEXTURE_LIGHTING ) - { - t->tex2( tt->getLightColor( level, x, y, z ) ); - t->color( 1.0f, 1.0f, 1.0f ); - } - else - { - float br = tt->getBrightness( level, x, y, z ); - if ( level->m_tileData.lightEmission[tt->id] > 0 ) br = 1.0f; - t->color( br, br, br ); - } - - float r = 0.40f; - float r2 = 0.5f - r; - float h = 0.20f; - if ( dir == 1 ) - { - tesselateTorch( tt, (float)x - r2, (float)y + h, (float)z, -r, 0.0f, 0 ); - } - else if ( dir == 2 ) - { - tesselateTorch( tt, (float)x + r2, (float)y + h, (float)z, +r, 0.0f, 0 ); - } - else if ( dir == 3 ) - { - tesselateTorch( tt, (float)x, (float)y + h, z - r2, 0.0f, -r, 0 ); - } - else if ( dir == 4 ) - { - tesselateTorch( tt, (float)x, (float)y + h, (float)z + r2, 0.0f, +r, 0 ); - } - else - { - tesselateTorch( tt, (float)x, (float)y, (float)z, 0.0f, 0.0f, 0 ); - } - return true; - -} - -bool TileRenderer_SPU::tesselateDiodeInWorld(DiodeTile_SPU *tt, int x, int y, int z) +bool TileRenderer_SPU::tesselatePistonBaseInWorld( + Tile_SPU* tt, int x, int y, int z, bool forceExtended, + int forceData) // 4J added forceData param { #ifdef DISABLE_TESS_FUNCS - Tesselator_SPU* t = getTesselator(); + int data = (forceData == -1) ? level->getData(x, y, z) : forceData; + bool extended = forceExtended || (data & PistonBaseTile::EXTENDED_BIT) != 0; + int facing = PistonBaseTile::getFacing(data); - tesselateDiodeInWorld(tt, x, y, z, level->getData(x, y, z) & DiodeTile_SPU::DIRECTION_MASK); - return true; -#endif // #ifdef DISABLE_TESS_FUNCS - return false; -} + const float thickness = PistonBaseTile::PLATFORM_THICKNESS / 16.0f; -void TileRenderer_SPU::tesselateDiodeInWorld( DiodeTile_SPU* tt, int x, int y, int z, int dir ) -{ -#ifdef DISABLE_TESS_FUNCS - // render half-block edges - tesselateBlockInWorld( tt, x, y, z ); - - Tesselator_SPU* t = getTesselator(); - - if ( SharedConstants::TEXTURE_LIGHTING ) - { - t->tex2( tt->getLightColor( level, x, y, z ) ); - t->color( 1.0f, 1.0f, 1.0f ); - } - else - { - float br = tt->getBrightness( level, x, y, z ); - if ( level->m_tileData.lightEmission[tt->id] > 0 ) br = 1.0f; - t->color( br, br, br ); - } - - int data = level->getData(x, y, z); - - // 4J Stu - This block gets moved in a later version, but we don't need that yet - // BEGIN TORCH SECTION - { - int dir = data & DiodeTile_SPU::DIRECTION_MASK; - int delay = ( data & DiodeTile_SPU::DELAY_MASK ) >> DiodeTile_SPU::DELAY_SHIFT; - float h = -3.0f / 16.0f; - float transmitterX = 0.0f; - float transmitterZ = 0.0f; - float receiverX = 0.0f; - float receiverZ = 0.0f; - - switch ( dir ) - { - case Direction::SOUTH: - receiverZ = -5.0f / 16.0f; - transmitterZ = DiodeTile_SPU::DELAY_RENDER_OFFSETS[delay]; - break; - case Direction::NORTH: - receiverZ = 5.0f / 16.0f; - transmitterZ = -DiodeTile_SPU::DELAY_RENDER_OFFSETS[delay]; - break; - case Direction::EAST: - receiverX = -5.0f / 16.0f; - transmitterX = DiodeTile_SPU::DELAY_RENDER_OFFSETS[delay]; - break; - case Direction::WEST: - receiverX = 5.0f / 16.0f; - transmitterX = -DiodeTile_SPU::DELAY_RENDER_OFFSETS[delay]; - break; - } - - // render transmitter - tesselateTorch( tt, x + transmitterX, y + h, z + transmitterZ, 0.0f, 0.0f, 0 ); - // render receiver - tesselateTorch( tt, x + receiverX, y + h, z + receiverZ, 0.0f, 0.0f, 0 ); - } - // END TORCH SECTION - - Icon_SPU *tex = getTexture(tt, Facing::UP, data); - float u0 = tex->getU0(); - float u1 = tex->getU1(); - float v0 = tex->getV0(); - float v1 = tex->getV1(); - - float r = 2.0f / 16.0f; - - float x0 = ( float )( x + 1.0f ); - float x1 = ( float )( x + 1.0f ); - float x2 = ( float )( x + 0.0f ); - float x3 = ( float )( x + 0.0f ); - - float z0 = ( float )( z + 0.0f ); - float z1 = ( float )( z + 1.0f ); - float z2 = ( float )( z + 1.0f ); - float z3 = ( float )( z + 0.0f ); - - float y0 = ( float )( y + r ); - - if ( dir == Direction::NORTH ) - { - // rotate 180 degrees - x0 = x1 = ( float )( x + 0.0f ); - x2 = x3 = ( float )( x + 1.0f ); - z0 = z3 = ( float )( z + 1.0f ); - z1 = z2 = ( float )( z + 0.0f ); - } - else if ( dir == Direction::EAST ) - { - // rotate 90 degrees counter-clockwise - x0 = x3 = ( float )( x + 0.0f ); - x1 = x2 = ( float )( x + 1.0f ); - z0 = z1 = ( float )( z + 0.0f ); - z2 = z3 = ( float )( z + 1.0f ); - } - else if ( dir == Direction::WEST ) - { - // rotate 90 degrees clockwise - x0 = x3 = ( float )( x + 1.0f ); - x1 = x2 = ( float )( x + 0.0f ); - z0 = z1 = ( float )( z + 1.0f ); - z2 = z3 = ( float )( z + 0.0f ); - } - - t->vertexUV( x3 , y0 , z3 , u0 , v0 ); - t->vertexUV( x2 , y0 , z2 , u0 , v1 ); - t->vertexUV( x1 , y0 , z1 , u1 , v1 ); - t->vertexUV( x0 , y0 , z0 , u1 , v0 ); -#endif // #ifdef DISABLE_TESS_FUNCS -} - -void TileRenderer_SPU::tesselatePistonBaseForceExtended( Tile_SPU* tile, int x, int y, int z, int forceData ) // 4J added forceData param -{ -#ifdef DISABLE_TESS_FUNCS - noCulling = true; - tesselatePistonBaseInWorld( tile, x, y, z, true, forceData ); - noCulling = false; -#endif // DISABLE_TESS_FUNCS - -} - -bool TileRenderer_SPU::tesselatePistonBaseInWorld( Tile_SPU* tt, int x, int y, int z, bool forceExtended, int forceData ) // 4J added forceData param -{ -#ifdef DISABLE_TESS_FUNCS - int data = ( forceData == -1 ) ? level->getData( x, y, z ) : forceData; - bool extended = forceExtended || ( data & PistonBaseTile::EXTENDED_BIT ) != 0; - int facing = PistonBaseTile::getFacing( data ); - - const float thickness = PistonBaseTile::PLATFORM_THICKNESS / 16.0f; - -// EnterCriticalSection( &Tile_SPU::m_csShape ); - if ( extended ) - { - switch ( facing ) - { - case Facing::DOWN: - northFlip = FLIP_180; - southFlip = FLIP_180; - eastFlip = FLIP_180; - westFlip = FLIP_180; - setShape( 0.0f, thickness, 0.0f, 1.0f, 1.0f, 1.0f ); - break; - case Facing::UP: - setShape( 0.0f, 0.0f, 0.0f, 1.0f, 1.0f - thickness, 1.0f ); - break; - case Facing::NORTH: - eastFlip = FLIP_CW; - westFlip = FLIP_CCW; - setShape( 0.0f, 0.0f, thickness, 1.0f, 1.0f, 1.0f ); - break; - case Facing::SOUTH: - eastFlip = FLIP_CCW; - westFlip = FLIP_CW; - upFlip = FLIP_180; - downFlip = FLIP_180; - setShape( 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f - thickness ); - break; - case Facing::WEST: - northFlip = FLIP_CW; - southFlip = FLIP_CCW; - upFlip = FLIP_CCW; - downFlip = FLIP_CW; - setShape( thickness, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f ); - break; - case Facing::EAST: - northFlip = FLIP_CCW; - southFlip = FLIP_CW; - upFlip = FLIP_CW; - downFlip = FLIP_CCW; - setShape( 0.0f, 0.0f, 0.0f, 1.0f - thickness, 1.0f, 1.0f ); - break; - } - // weird way of telling the piston to use the - // "inside" texture for the forward-facing edge - ((PistonBaseTile *) tt)->updateShape((float) tileShapeX0, (float) tileShapeY0, (float) tileShapeZ0, (float) tileShapeX1, (float) tileShapeY1, (float) tileShapeZ1); - tesselateBlockInWorld( tt, x, y, z ); - northFlip = FLIP_NONE; - southFlip = FLIP_NONE; - eastFlip = FLIP_NONE; - westFlip = FLIP_NONE; - upFlip = FLIP_NONE; - downFlip = FLIP_NONE; - ((PistonBaseTile *) tt)->updateShape((float) tileShapeX0, (float) tileShapeY0, (float) tileShapeZ0, (float) tileShapeX1, (float) tileShapeY1, (float) tileShapeZ1); - } - else - { - switch ( facing ) - { - case Facing::DOWN: - northFlip = FLIP_180; - southFlip = FLIP_180; - eastFlip = FLIP_180; - westFlip = FLIP_180; - break; - case Facing::UP: - break; - case Facing::NORTH: - eastFlip = FLIP_CW; - westFlip = FLIP_CCW; - break; - case Facing::SOUTH: - eastFlip = FLIP_CCW; - westFlip = FLIP_CW; - upFlip = FLIP_180; - downFlip = FLIP_180; - break; - case Facing::WEST: - northFlip = FLIP_CW; - southFlip = FLIP_CCW; - upFlip = FLIP_CCW; - downFlip = FLIP_CW; - break; - case Facing::EAST: - northFlip = FLIP_CCW; - southFlip = FLIP_CW; - upFlip = FLIP_CW; - downFlip = FLIP_CCW; - break; - } - tesselateBlockInWorld( tt, x, y, z ); - northFlip = FLIP_NONE; - southFlip = FLIP_NONE; - eastFlip = FLIP_NONE; - westFlip = FLIP_NONE; - upFlip = FLIP_NONE; - downFlip = FLIP_NONE; - } + // EnterCriticalSection( &Tile_SPU::m_csShape ); + if (extended) { + switch (facing) { + case Facing::DOWN: + northFlip = FLIP_180; + southFlip = FLIP_180; + eastFlip = FLIP_180; + westFlip = FLIP_180; + setShape(0.0f, thickness, 0.0f, 1.0f, 1.0f, 1.0f); + break; + case Facing::UP: + setShape(0.0f, 0.0f, 0.0f, 1.0f, 1.0f - thickness, 1.0f); + break; + case Facing::NORTH: + eastFlip = FLIP_CW; + westFlip = FLIP_CCW; + setShape(0.0f, 0.0f, thickness, 1.0f, 1.0f, 1.0f); + break; + case Facing::SOUTH: + eastFlip = FLIP_CCW; + westFlip = FLIP_CW; + upFlip = FLIP_180; + downFlip = FLIP_180; + setShape(0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f - thickness); + break; + case Facing::WEST: + northFlip = FLIP_CW; + southFlip = FLIP_CCW; + upFlip = FLIP_CCW; + downFlip = FLIP_CW; + setShape(thickness, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f); + break; + case Facing::EAST: + northFlip = FLIP_CCW; + southFlip = FLIP_CW; + upFlip = FLIP_CW; + downFlip = FLIP_CCW; + setShape(0.0f, 0.0f, 0.0f, 1.0f - thickness, 1.0f, 1.0f); + break; + } + // weird way of telling the piston to use the + // "inside" texture for the forward-facing edge + ((PistonBaseTile*)tt) + ->updateShape((float)tileShapeX0, (float)tileShapeY0, + (float)tileShapeZ0, (float)tileShapeX1, + (float)tileShapeY1, (float)tileShapeZ1); + tesselateBlockInWorld(tt, x, y, z); + northFlip = FLIP_NONE; + southFlip = FLIP_NONE; + eastFlip = FLIP_NONE; + westFlip = FLIP_NONE; + upFlip = FLIP_NONE; + downFlip = FLIP_NONE; + ((PistonBaseTile*)tt) + ->updateShape((float)tileShapeX0, (float)tileShapeY0, + (float)tileShapeZ0, (float)tileShapeX1, + (float)tileShapeY1, (float)tileShapeZ1); + } else { + switch (facing) { + case Facing::DOWN: + northFlip = FLIP_180; + southFlip = FLIP_180; + eastFlip = FLIP_180; + westFlip = FLIP_180; + break; + case Facing::UP: + break; + case Facing::NORTH: + eastFlip = FLIP_CW; + westFlip = FLIP_CCW; + break; + case Facing::SOUTH: + eastFlip = FLIP_CCW; + westFlip = FLIP_CW; + upFlip = FLIP_180; + downFlip = FLIP_180; + break; + case Facing::WEST: + northFlip = FLIP_CW; + southFlip = FLIP_CCW; + upFlip = FLIP_CCW; + downFlip = FLIP_CW; + break; + case Facing::EAST: + northFlip = FLIP_CCW; + southFlip = FLIP_CW; + upFlip = FLIP_CW; + downFlip = FLIP_CCW; + break; + } + tesselateBlockInWorld(tt, x, y, z); + northFlip = FLIP_NONE; + southFlip = FLIP_NONE; + eastFlip = FLIP_NONE; + westFlip = FLIP_NONE; + upFlip = FLIP_NONE; + downFlip = FLIP_NONE; + } // LeaveCriticalSection( &Tile_SPU::m_csShape ); -#endif // DISABLE_TESS_FUNCS - - return true; +#endif // DISABLE_TESS_FUNCS + return true; } -void TileRenderer_SPU::renderPistonArmUpDown( float x0, float x1, float y0, float y1, float z0, float z1, float br, - float armLengthPixels ) -{ +void TileRenderer_SPU::renderPistonArmUpDown(float x0, float x1, float y0, + float y1, float z0, float z1, + float br, float armLengthPixels) { #ifdef DISABLE_TESS_FUNCS - Icon_SPU *armTex = PistonBaseTile::getTexture(PistonBaseTile::EDGE_TEX); - if (hasFixedTexture()) armTex = fixedTexture; + Icon_SPU* armTex = PistonBaseTile::getTexture(PistonBaseTile::EDGE_TEX); + if (hasFixedTexture()) armTex = fixedTexture; - Tesselator_SPU* t = getTesselator(); + Tesselator_SPU* t = getTesselator(); - // upwards arm - float u00 = armTex->getU0(); - float v00 = armTex->getV0(); - float u11 = armTex->getU(armLengthPixels); - float v11 = armTex->getV(PistonBaseTile::PLATFORM_THICKNESS); + // upwards arm + float u00 = armTex->getU0(); + float v00 = armTex->getV0(); + float u11 = armTex->getU(armLengthPixels); + float v11 = armTex->getV(PistonBaseTile::PLATFORM_THICKNESS); - t->color( br, br, br ); - - t->vertexUV( x0, y1, z0, u11, v00 ); - t->vertexUV( x0, y0, z0, u00, v00 ); - t->vertexUV( x1, y0, z1, u00, v11 ); - t->vertexUV( x1, y1, z1, u11, v11 ); -#endif // DISABLE_TESS_FUNCS + t->color(br, br, br); + t->vertexUV(x0, y1, z0, u11, v00); + t->vertexUV(x0, y0, z0, u00, v00); + t->vertexUV(x1, y0, z1, u00, v11); + t->vertexUV(x1, y1, z1, u11, v11); +#endif // DISABLE_TESS_FUNCS } -void TileRenderer_SPU::renderPistonArmNorthSouth( float x0, float x1, float y0, float y1, float z0, float z1, - float br, float armLengthPixels ) -{ +void TileRenderer_SPU::renderPistonArmNorthSouth(float x0, float x1, float y0, + float y1, float z0, float z1, + float br, + float armLengthPixels) { #ifdef DISABLE_TESS_FUNCS - Icon_SPU *armTex = PistonBaseTile::getTexture(PistonBaseTile::EDGE_TEX); - if (hasFixedTexture()) armTex = fixedTexture; + Icon_SPU* armTex = PistonBaseTile::getTexture(PistonBaseTile::EDGE_TEX); + if (hasFixedTexture()) armTex = fixedTexture; - Tesselator_SPU* t = getTesselator(); + Tesselator_SPU* t = getTesselator(); - // upwards arm - float u00 = armTex->getU0(); - float v00 = armTex->getV0(); - float u11 = armTex->getU(armLengthPixels); - float v11 = armTex->getV(PistonBaseTile::PLATFORM_THICKNESS); + // upwards arm + float u00 = armTex->getU0(); + float v00 = armTex->getV0(); + float u11 = armTex->getU(armLengthPixels); + float v11 = armTex->getV(PistonBaseTile::PLATFORM_THICKNESS); - t->color( br, br, br ); + t->color(br, br, br); - t->vertexUV( x0, y0, z1, u11, v00 ); - t->vertexUV( x0, y0, z0, u00, v00 ); - t->vertexUV( x1, y1, z0, u00, v11 ); - t->vertexUV( x1, y1, z1, u11, v11 ); -#endif // DISABLE_TESS_FUNCS + t->vertexUV(x0, y0, z1, u11, v00); + t->vertexUV(x0, y0, z0, u00, v00); + t->vertexUV(x1, y1, z0, u00, v11); + t->vertexUV(x1, y1, z1, u11, v11); +#endif // DISABLE_TESS_FUNCS } -void TileRenderer_SPU::renderPistonArmEastWest( float x0, float x1, float y0, float y1, float z0, float z1, float br, - float armLengthPixels ) -{ +void TileRenderer_SPU::renderPistonArmEastWest(float x0, float x1, float y0, + float y1, float z0, float z1, + float br, + float armLengthPixels) { #ifdef DISABLE_TESS_FUNCS - Icon_SPU *armTex = PistonBaseTile::getTexture(PistonBaseTile::EDGE_TEX); - if (hasFixedTexture()) armTex = fixedTexture; + Icon_SPU* armTex = PistonBaseTile::getTexture(PistonBaseTile::EDGE_TEX); + if (hasFixedTexture()) armTex = fixedTexture; - Tesselator_SPU* t = getTesselator(); + Tesselator_SPU* t = getTesselator(); - // upwards arm - float u00 = armTex->getU0(); - float v00 = armTex->getV0(); - float u11 = armTex->getU(armLengthPixels); - float v11 = armTex->getV(PistonBaseTile::PLATFORM_THICKNESS); + // upwards arm + float u00 = armTex->getU0(); + float v00 = armTex->getV0(); + float u11 = armTex->getU(armLengthPixels); + float v11 = armTex->getV(PistonBaseTile::PLATFORM_THICKNESS); - t->color( br, br, br ); + t->color(br, br, br); - t->vertexUV( x1, y0, z0, u11, v00 ); - t->vertexUV( x0, y0, z0, u00, v00 ); - t->vertexUV( x0, y1, z1, u00, v11 ); - t->vertexUV( x1, y1, z1, u11, v11 ); -#endif // DISABLE_TESS_FUNCS + t->vertexUV(x1, y0, z0, u11, v00); + t->vertexUV(x0, y0, z0, u00, v00); + t->vertexUV(x0, y1, z1, u00, v11); + t->vertexUV(x1, y1, z1, u11, v11); +#endif // DISABLE_TESS_FUNCS } -void TileRenderer_SPU::tesselatePistonArmNoCulling( Tile_SPU* tile, int x, int y, int z, bool fullArm, int forceData ) // 4J added forceData param +void TileRenderer_SPU::tesselatePistonArmNoCulling( + Tile_SPU* tile, int x, int y, int z, bool fullArm, + int forceData) // 4J added forceData param { #ifdef DISABLE_TESS_FUNCS - noCulling = true; - tesselatePistonExtensionInWorld( tile, x, y, z, fullArm ); - noCulling = false; -#endif // DISABLE_TESS_FUNCS + noCulling = true; + tesselatePistonExtensionInWorld(tile, x, y, z, fullArm); + noCulling = false; +#endif // DISABLE_TESS_FUNCS } -bool TileRenderer_SPU::tesselatePistonExtensionInWorld( Tile_SPU* tt, int x, int y, int z, bool fullArm, int forceData ) // 4J added forceData param +bool TileRenderer_SPU::tesselatePistonExtensionInWorld( + Tile_SPU* tt, int x, int y, int z, bool fullArm, + int forceData) // 4J added forceData param { #ifdef DISABLE_TESS_FUNCS - int data = ( forceData == -1 ) ? level->getData( x, y, z ) : forceData; - int facing = PistonExtensionTile::getFacing( data ); + int data = (forceData == -1) ? level->getData(x, y, z) : forceData; + int facing = PistonExtensionTile::getFacing(data); - const float thickness = PistonBaseTile::PLATFORM_THICKNESS / 16.0f; - const float leftEdge = ( 8.0f - ( PistonBaseTile::PLATFORM_THICKNESS / 2.0f ) ) / 16.0f; - const float rightEdge = ( 8.0f + ( PistonBaseTile::PLATFORM_THICKNESS / 2.0f ) ) / 16.0f; - const float br = tt->getBrightness( level, x, y, z ); - const float armLength = fullArm ? 1.0f : 0.5f; - const float armLengthPixels = fullArm ? 16.0f : 8.0f; + const float thickness = PistonBaseTile::PLATFORM_THICKNESS / 16.0f; + const float leftEdge = + (8.0f - (PistonBaseTile::PLATFORM_THICKNESS / 2.0f)) / 16.0f; + const float rightEdge = + (8.0f + (PistonBaseTile::PLATFORM_THICKNESS / 2.0f)) / 16.0f; + const float br = tt->getBrightness(level, x, y, z); + const float armLength = fullArm ? 1.0f : 0.5f; + const float armLengthPixels = fullArm ? 16.0f : 8.0f; -// EnterCriticalSection( &Tile_SPU::m_csShape ); - Tesselator_SPU* t = getTesselator(); + // EnterCriticalSection( &Tile_SPU::m_csShape ); + Tesselator_SPU* t = getTesselator(); - switch ( facing ) - { - case Facing::DOWN: - northFlip = FLIP_180; - southFlip = FLIP_180; - eastFlip = FLIP_180; - westFlip = FLIP_180; - setShape( 0.0f, 0.0f, 0.0f, 1.0f, thickness, 1.0f ); - tesselateBlockInWorld( tt, x, y, z ); + switch (facing) { + case Facing::DOWN: + northFlip = FLIP_180; + southFlip = FLIP_180; + eastFlip = FLIP_180; + westFlip = FLIP_180; + setShape(0.0f, 0.0f, 0.0f, 1.0f, thickness, 1.0f); + tesselateBlockInWorld(tt, x, y, z); - t->tex2( getLightColor(tt, level, x, y , z ) ); // 4J added - renderPistonArmDown doesn't set its own tex2 so just inherited from previous tesselateBlockInWorld - renderPistonArmUpDown( x + leftEdge, x + rightEdge, y + thickness, y + thickness + armLength, - z + rightEdge, z + rightEdge, br * 0.8f, armLengthPixels ); - renderPistonArmUpDown( x + rightEdge, x + leftEdge, y + thickness, y + thickness + armLength, z + leftEdge, - z + leftEdge, br * 0.8f, armLengthPixels ); - renderPistonArmUpDown( x + leftEdge, x + leftEdge, y + thickness, y + thickness + armLength, z + leftEdge, - z + rightEdge, br * 0.6f, armLengthPixels ); - renderPistonArmUpDown( x + rightEdge, x + rightEdge, y + thickness, y + thickness + armLength, - z + rightEdge, z + leftEdge, br * 0.6f, armLengthPixels ); + t->tex2(getLightColor( + tt, level, x, y, + z)); // 4J added - renderPistonArmDown doesn't set its own tex2 + // so just inherited from previous tesselateBlockInWorld + renderPistonArmUpDown(x + leftEdge, x + rightEdge, y + thickness, + y + thickness + armLength, z + rightEdge, + z + rightEdge, br * 0.8f, armLengthPixels); + renderPistonArmUpDown(x + rightEdge, x + leftEdge, y + thickness, + y + thickness + armLength, z + leftEdge, + z + leftEdge, br * 0.8f, armLengthPixels); + renderPistonArmUpDown(x + leftEdge, x + leftEdge, y + thickness, + y + thickness + armLength, z + leftEdge, + z + rightEdge, br * 0.6f, armLengthPixels); + renderPistonArmUpDown(x + rightEdge, x + rightEdge, y + thickness, + y + thickness + armLength, z + rightEdge, + z + leftEdge, br * 0.6f, armLengthPixels); - break; - case Facing::UP: - setShape( 0.0f, 1.0f - thickness, 0.0f, 1.0f, 1.0f, 1.0f ); - tesselateBlockInWorld( tt, x, y, z ); + break; + case Facing::UP: + setShape(0.0f, 1.0f - thickness, 0.0f, 1.0f, 1.0f, 1.0f); + tesselateBlockInWorld(tt, x, y, z); - t->tex2( getLightColor(tt, level, x, y , z ) ); // 4J added - renderPistonArmDown doesn't set its own tex2 so just inherited from previous tesselateBlockInWorld - renderPistonArmUpDown( x + leftEdge, x + rightEdge, y - thickness + 1.0f - armLength, y - thickness + 1.0f, - z + rightEdge, z + rightEdge, br * 0.8f, armLengthPixels ); - renderPistonArmUpDown( x + rightEdge, x + leftEdge, y - thickness + 1.0f - armLength, y - thickness + 1.0f, - z + leftEdge, z + leftEdge, br * 0.8f, armLengthPixels ); - renderPistonArmUpDown( x + leftEdge, x + leftEdge, y - thickness + 1.0f - armLength, y - thickness + 1.0f, - z + leftEdge, z + rightEdge, br * 0.6f, armLengthPixels ); - renderPistonArmUpDown( x + rightEdge, x + rightEdge, y - thickness + 1.0f - armLength, - y - thickness + 1.0f, z + rightEdge, z + leftEdge, br * 0.6f, armLengthPixels ); - break; - case Facing::NORTH: - eastFlip = FLIP_CW; - westFlip = FLIP_CCW; - setShape( 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, thickness ); - tesselateBlockInWorld( tt, x, y, z ); + t->tex2(getLightColor( + tt, level, x, y, + z)); // 4J added - renderPistonArmDown doesn't set its own tex2 + // so just inherited from previous tesselateBlockInWorld + renderPistonArmUpDown(x + leftEdge, x + rightEdge, + y - thickness + 1.0f - armLength, + y - thickness + 1.0f, z + rightEdge, + z + rightEdge, br * 0.8f, armLengthPixels); + renderPistonArmUpDown(x + rightEdge, x + leftEdge, + y - thickness + 1.0f - armLength, + y - thickness + 1.0f, z + leftEdge, + z + leftEdge, br * 0.8f, armLengthPixels); + renderPistonArmUpDown(x + leftEdge, x + leftEdge, + y - thickness + 1.0f - armLength, + y - thickness + 1.0f, z + leftEdge, + z + rightEdge, br * 0.6f, armLengthPixels); + renderPistonArmUpDown(x + rightEdge, x + rightEdge, + y - thickness + 1.0f - armLength, + y - thickness + 1.0f, z + rightEdge, + z + leftEdge, br * 0.6f, armLengthPixels); + break; + case Facing::NORTH: + eastFlip = FLIP_CW; + westFlip = FLIP_CCW; + setShape(0.0f, 0.0f, 0.0f, 1.0f, 1.0f, thickness); + tesselateBlockInWorld(tt, x, y, z); - t->tex2( getLightColor(tt, level, x, y , z ) ); // 4J added - renderPistonArmDown doesn't set its own tex2 so just inherited from previous tesselateBlockInWorld - renderPistonArmNorthSouth( x + leftEdge, x + leftEdge, y + rightEdge, y + leftEdge, z + thickness, - z + thickness + armLength, br * 0.6f, armLengthPixels ); - renderPistonArmNorthSouth( x + rightEdge, x + rightEdge, y + leftEdge, y + rightEdge, z + thickness, - z + thickness + armLength, br * 0.6f, armLengthPixels ); - renderPistonArmNorthSouth( x + leftEdge, x + rightEdge, y + leftEdge, y + leftEdge, z + thickness, - z + thickness + armLength, br * 0.5f, armLengthPixels ); - renderPistonArmNorthSouth( x + rightEdge, x + leftEdge, y + rightEdge, y + rightEdge, z + thickness, - z + thickness + armLength, br, armLengthPixels ); - break; - case Facing::SOUTH: - eastFlip = FLIP_CCW; - westFlip = FLIP_CW; - upFlip = FLIP_180; - downFlip = FLIP_180; - setShape( 0.0f, 0.0f, 1.0f - thickness, 1.0f, 1.0f, 1.0f ); - tesselateBlockInWorld( tt, x, y, z ); + t->tex2(getLightColor( + tt, level, x, y, + z)); // 4J added - renderPistonArmDown doesn't set its own tex2 + // so just inherited from previous tesselateBlockInWorld + renderPistonArmNorthSouth(x + leftEdge, x + leftEdge, y + rightEdge, + y + leftEdge, z + thickness, + z + thickness + armLength, br * 0.6f, + armLengthPixels); + renderPistonArmNorthSouth(x + rightEdge, x + rightEdge, + y + leftEdge, y + rightEdge, + z + thickness, z + thickness + armLength, + br * 0.6f, armLengthPixels); + renderPistonArmNorthSouth(x + leftEdge, x + rightEdge, y + leftEdge, + y + leftEdge, z + thickness, + z + thickness + armLength, br * 0.5f, + armLengthPixels); + renderPistonArmNorthSouth( + x + rightEdge, x + leftEdge, y + rightEdge, y + rightEdge, + z + thickness, z + thickness + armLength, br, armLengthPixels); + break; + case Facing::SOUTH: + eastFlip = FLIP_CCW; + westFlip = FLIP_CW; + upFlip = FLIP_180; + downFlip = FLIP_180; + setShape(0.0f, 0.0f, 1.0f - thickness, 1.0f, 1.0f, 1.0f); + tesselateBlockInWorld(tt, x, y, z); - t->tex2( getLightColor(tt, level, x, y , z ) ); // 4J added - renderPistonArmDown doesn't set its own tex2 so just inherited from previous tesselateBlockInWorld - renderPistonArmNorthSouth( x + leftEdge, x + leftEdge, y + rightEdge, y + leftEdge, - z - thickness + 1.0f - armLength, z - thickness + 1.0f, br * 0.6f, - armLengthPixels ); - renderPistonArmNorthSouth( x + rightEdge, x + rightEdge, y + leftEdge, y + rightEdge, - z - thickness + 1.0f - armLength, z - thickness + 1.0f, br * 0.6f, - armLengthPixels ); - renderPistonArmNorthSouth( x + leftEdge, x + rightEdge, y + leftEdge, y + leftEdge, - z - thickness + 1.0f - armLength, z - thickness + 1.0f, br * 0.5f, - armLengthPixels ); - renderPistonArmNorthSouth( x + rightEdge, x + leftEdge, y + rightEdge, y + rightEdge, - z - thickness + 1.0f - armLength, z - thickness + 1.0f, br, armLengthPixels ); - break; - case Facing::WEST: - northFlip = FLIP_CW; - southFlip = FLIP_CCW; - upFlip = FLIP_CCW; - downFlip = FLIP_CW; - setShape( 0.0f, 0.0f, 0.0f, thickness, 1.0f, 1.0f ); - tesselateBlockInWorld( tt, x, y, z ); // 4J added - renderPistonArmDown doesn't set its own tex2 so just inherited from previous tesselateBlockInWorld + t->tex2(getLightColor( + tt, level, x, y, + z)); // 4J added - renderPistonArmDown doesn't set its own tex2 + // so just inherited from previous tesselateBlockInWorld + renderPistonArmNorthSouth( + x + leftEdge, x + leftEdge, y + rightEdge, y + leftEdge, + z - thickness + 1.0f - armLength, z - thickness + 1.0f, + br * 0.6f, armLengthPixels); + renderPistonArmNorthSouth( + x + rightEdge, x + rightEdge, y + leftEdge, y + rightEdge, + z - thickness + 1.0f - armLength, z - thickness + 1.0f, + br * 0.6f, armLengthPixels); + renderPistonArmNorthSouth( + x + leftEdge, x + rightEdge, y + leftEdge, y + leftEdge, + z - thickness + 1.0f - armLength, z - thickness + 1.0f, + br * 0.5f, armLengthPixels); + renderPistonArmNorthSouth( + x + rightEdge, x + leftEdge, y + rightEdge, y + rightEdge, + z - thickness + 1.0f - armLength, z - thickness + 1.0f, br, + armLengthPixels); + break; + case Facing::WEST: + northFlip = FLIP_CW; + southFlip = FLIP_CCW; + upFlip = FLIP_CCW; + downFlip = FLIP_CW; + setShape(0.0f, 0.0f, 0.0f, thickness, 1.0f, 1.0f); + tesselateBlockInWorld( + tt, x, y, + z); // 4J added - renderPistonArmDown doesn't set its own tex2 + // so just inherited from previous tesselateBlockInWorld - t->tex2( getLightColor(tt, level, x, y , z ) ); - renderPistonArmEastWest( x + thickness, x + thickness + armLength, y + leftEdge, y + leftEdge, - z + rightEdge, z + leftEdge, br * 0.5f, armLengthPixels ); - renderPistonArmEastWest( x + thickness, x + thickness + armLength, y + rightEdge, y + rightEdge, - z + leftEdge, z + rightEdge, br, armLengthPixels ); - renderPistonArmEastWest( x + thickness, x + thickness + armLength, y + leftEdge, y + rightEdge, - z + leftEdge, z + leftEdge, br * 0.6f, armLengthPixels ); - renderPistonArmEastWest( x + thickness, x + thickness + armLength, y + rightEdge, y + leftEdge, - z + rightEdge, z + rightEdge, br * 0.6f, armLengthPixels ); - break; - case Facing::EAST: - northFlip = FLIP_CCW; - southFlip = FLIP_CW; - upFlip = FLIP_CW; - downFlip = FLIP_CCW; - setShape( 1.0f - thickness, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f ); - tesselateBlockInWorld( tt, x, y, z ); + t->tex2(getLightColor(tt, level, x, y, z)); + renderPistonArmEastWest(x + thickness, x + thickness + armLength, + y + leftEdge, y + leftEdge, z + rightEdge, + z + leftEdge, br * 0.5f, armLengthPixels); + renderPistonArmEastWest(x + thickness, x + thickness + armLength, + y + rightEdge, y + rightEdge, z + leftEdge, + z + rightEdge, br, armLengthPixels); + renderPistonArmEastWest(x + thickness, x + thickness + armLength, + y + leftEdge, y + rightEdge, z + leftEdge, + z + leftEdge, br * 0.6f, armLengthPixels); + renderPistonArmEastWest(x + thickness, x + thickness + armLength, + y + rightEdge, y + leftEdge, z + rightEdge, + z + rightEdge, br * 0.6f, armLengthPixels); + break; + case Facing::EAST: + northFlip = FLIP_CCW; + southFlip = FLIP_CW; + upFlip = FLIP_CW; + downFlip = FLIP_CCW; + setShape(1.0f - thickness, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f); + tesselateBlockInWorld(tt, x, y, z); - t->tex2( getLightColor(tt, level, x, y , z ) ); // 4J added - renderPistonArmDown doesn't set its own tex2 so just inherited from previous tesselateBlockInWorld - renderPistonArmEastWest( x - thickness + 1.0f - armLength, x - thickness + 1.0f, y + leftEdge, - y + leftEdge, z + rightEdge, z + leftEdge, br * 0.5f, armLengthPixels ); - renderPistonArmEastWest( x - thickness + 1.0f - armLength, x - thickness + 1.0f, y + rightEdge, - y + rightEdge, z + leftEdge, z + rightEdge, br, armLengthPixels ); - renderPistonArmEastWest( x - thickness + 1.0f - armLength, x - thickness + 1.0f, y + leftEdge, - y + rightEdge, z + leftEdge, z + leftEdge, br * 0.6f, armLengthPixels ); - renderPistonArmEastWest( x - thickness + 1.0f - armLength, x - thickness + 1.0f, y + rightEdge, - y + leftEdge, z + rightEdge, z + rightEdge, br * 0.6f, armLengthPixels ); - break; - } - northFlip = FLIP_NONE; - southFlip = FLIP_NONE; - eastFlip = FLIP_NONE; - westFlip = FLIP_NONE; - upFlip = FLIP_NONE; - downFlip = FLIP_NONE; - setShape( 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f ); + t->tex2(getLightColor( + tt, level, x, y, + z)); // 4J added - renderPistonArmDown doesn't set its own tex2 + // so just inherited from previous tesselateBlockInWorld + renderPistonArmEastWest(x - thickness + 1.0f - armLength, + x - thickness + 1.0f, y + leftEdge, + y + leftEdge, z + rightEdge, z + leftEdge, + br * 0.5f, armLengthPixels); + renderPistonArmEastWest(x - thickness + 1.0f - armLength, + x - thickness + 1.0f, y + rightEdge, + y + rightEdge, z + leftEdge, z + rightEdge, + br, armLengthPixels); + renderPistonArmEastWest(x - thickness + 1.0f - armLength, + x - thickness + 1.0f, y + leftEdge, + y + rightEdge, z + leftEdge, z + leftEdge, + br * 0.6f, armLengthPixels); + renderPistonArmEastWest(x - thickness + 1.0f - armLength, + x - thickness + 1.0f, y + rightEdge, + y + leftEdge, z + rightEdge, z + rightEdge, + br * 0.6f, armLengthPixels); + break; + } + northFlip = FLIP_NONE; + southFlip = FLIP_NONE; + eastFlip = FLIP_NONE; + westFlip = FLIP_NONE; + upFlip = FLIP_NONE; + downFlip = FLIP_NONE; + setShape(0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f); // LeaveCriticalSection( &Tile_SPU::m_csShape ); -#endif // DISABLE_TESS_FUNCS - - return true; +#endif // DISABLE_TESS_FUNCS + return true; } -bool TileRenderer_SPU::tesselateLeverInWorld( Tile_SPU* tt, int x, int y, int z ) -{ +bool TileRenderer_SPU::tesselateLeverInWorld(Tile_SPU* tt, int x, int y, + int z) { #ifdef DISABLE_TESS_FUNCS - int data = level->getData( x, y, z ); + int data = level->getData(x, y, z); - int dir = data & 7; - bool flipped = ( data & 8 ) > 0; + int dir = data & 7; + bool flipped = (data & 8) > 0; - Tesselator_SPU* t = getTesselator(); + Tesselator_SPU* t = getTesselator(); - bool hadFixed = hasFixedTexture(); - if (!hadFixed) this->setFixedTexture(getTexture(Tile_SPU::stoneBrick)); - float w1 = 4.0f / 16.0f; - float w2 = 3.0f / 16.0f; - float h = 3.0f / 16.0f; -// EnterCriticalSection( &Tile_SPU::m_csShape ); - if ( dir == 5 ) - { - setShape( 0.5f - w2, 0.0f, 0.5f - w1, 0.5f + w2, h, 0.5f + w1 ); - } - else if ( dir == 6 ) - { - setShape( 0.5f - w1, 0.0f, 0.5f - w2, 0.5f + w1, h, 0.5f + w2 ); - } - else if ( dir == 4 ) - { - setShape( 0.5f - w2, 0.5f - w1, 1.0f - h, 0.5f + w2, 0.5f + w1, 1.0f ); - } - else if ( dir == 3 ) - { - setShape( 0.5f - w2, 0.5f - w1, 0, 0.5f + w2, 0.5f + w1, h ); - } - else if ( dir == 2 ) - { - setShape( 1.0f - h, 0.5f - w1, 0.5f - w2, 1.0f, 0.5f + w1, 0.5f + w2 ); - } - else if ( dir == 1 ) - { - setShape( 0, 0.5f - w1, 0.5f - w2, h, 0.5f + w1, 0.5f + w2 ); - } - else if (dir == 0) - { - setShape(0.5f - w1, 1 - h, 0.5f - w2, 0.5f + w1, 1, 0.5f + w2); - } - else if (dir == 7) - { - setShape(0.5f - w2, 1 - h, 0.5f - w1, 0.5f + w2, 1, 0.5f + w1); - } - this->tesselateBlockInWorld( tt, x, y, z ); -// LeaveCriticalSection( &Tile_SPU::m_csShape ); - if ( !hadFixed ) this->clearFixedTexture(); + bool hadFixed = hasFixedTexture(); + if (!hadFixed) this->setFixedTexture(getTexture(Tile_SPU::stoneBrick)); + float w1 = 4.0f / 16.0f; + float w2 = 3.0f / 16.0f; + float h = 3.0f / 16.0f; + // EnterCriticalSection( &Tile_SPU::m_csShape ); + if (dir == 5) { + setShape(0.5f - w2, 0.0f, 0.5f - w1, 0.5f + w2, h, 0.5f + w1); + } else if (dir == 6) { + setShape(0.5f - w1, 0.0f, 0.5f - w2, 0.5f + w1, h, 0.5f + w2); + } else if (dir == 4) { + setShape(0.5f - w2, 0.5f - w1, 1.0f - h, 0.5f + w2, 0.5f + w1, 1.0f); + } else if (dir == 3) { + setShape(0.5f - w2, 0.5f - w1, 0, 0.5f + w2, 0.5f + w1, h); + } else if (dir == 2) { + setShape(1.0f - h, 0.5f - w1, 0.5f - w2, 1.0f, 0.5f + w1, 0.5f + w2); + } else if (dir == 1) { + setShape(0, 0.5f - w1, 0.5f - w2, h, 0.5f + w1, 0.5f + w2); + } else if (dir == 0) { + setShape(0.5f - w1, 1 - h, 0.5f - w2, 0.5f + w1, 1, 0.5f + w2); + } else if (dir == 7) { + setShape(0.5f - w2, 1 - h, 0.5f - w1, 0.5f + w2, 1, 0.5f + w1); + } + this->tesselateBlockInWorld(tt, x, y, z); + // LeaveCriticalSection( &Tile_SPU::m_csShape ); + if (!hadFixed) this->clearFixedTexture(); - float br; - if ( SharedConstants::TEXTURE_LIGHTING ) - { - t->tex2( tt->getLightColor( level, x, y, z ) ); - br = 1; - } - else - { - br = tt->getBrightness( level, x, y, z ); - } - if ( Tile_SPU::lightEmission[tt->id] > 0 ) br = 1.0f; - t->color( br, br, br ); - Icon_SPU *tex = getTexture(tt, 0); + float br; + if (SharedConstants::TEXTURE_LIGHTING) { + t->tex2(tt->getLightColor(level, x, y, z)); + br = 1; + } else { + br = tt->getBrightness(level, x, y, z); + } + if (Tile_SPU::lightEmission[tt->id] > 0) br = 1.0f; + t->color(br, br, br); + Icon_SPU* tex = getTexture(tt, 0); - if (hasFixedTexture()) tex = fixedTexture; - float u0 = tex->getU0(); - float v0 = tex->getV0(); - float u1 = tex->getU1(); - float v1 = tex->getV1(); + if (hasFixedTexture()) tex = fixedTexture; + float u0 = tex->getU0(); + float v0 = tex->getV0(); + float u1 = tex->getU1(); + float v1 = tex->getV1(); - Vec3* corners[8]; - float xv = 1.0f / 16.0f; - float zv = 1.0f / 16.0f; - float yv = 10.0f / 16.0f; - corners[0] = Vec3::newTemp( -xv, -0, -zv ); - corners[1] = Vec3::newTemp( +xv, -0, -zv ); - corners[2] = Vec3::newTemp( +xv, -0, +zv ); - corners[3] = Vec3::newTemp( -xv, -0, +zv ); - corners[4] = Vec3::newTemp( -xv, +yv, -zv ); - corners[5] = Vec3::newTemp( +xv, +yv, -zv ); - corners[6] = Vec3::newTemp( +xv, +yv, +zv ); - corners[7] = Vec3::newTemp( -xv, +yv, +zv ); + Vec3* corners[8]; + float xv = 1.0f / 16.0f; + float zv = 1.0f / 16.0f; + float yv = 10.0f / 16.0f; + corners[0] = Vec3::newTemp(-xv, -0, -zv); + corners[1] = Vec3::newTemp(+xv, -0, -zv); + corners[2] = Vec3::newTemp(+xv, -0, +zv); + corners[3] = Vec3::newTemp(-xv, -0, +zv); + corners[4] = Vec3::newTemp(-xv, +yv, -zv); + corners[5] = Vec3::newTemp(+xv, +yv, -zv); + corners[6] = Vec3::newTemp(+xv, +yv, +zv); + corners[7] = Vec3::newTemp(-xv, +yv, +zv); - for ( int i = 0; i < 8; i++ ) - { - if ( flipped ) - { - corners[i]->z -= 1 / 16.0f; - corners[i]->xRot( 40 * PI / 180 ); - } - else - { - corners[i]->z += 1 / 16.0f; - corners[i]->xRot( -40 * PI / 180 ); - } - if (dir == 0 || dir == 7) - { - corners[i]->zRot(180 * PI / 180); - } - if ( dir == 6 || dir == 0 ) - { - corners[i]->yRot( 90 * PI / 180 ); - } + for (int i = 0; i < 8; i++) { + if (flipped) { + corners[i]->z -= 1 / 16.0f; + corners[i]->xRot(40 * PI / 180); + } else { + corners[i]->z += 1 / 16.0f; + corners[i]->xRot(-40 * PI / 180); + } + if (dir == 0 || dir == 7) { + corners[i]->zRot(180 * PI / 180); + } + if (dir == 6 || dir == 0) { + corners[i]->yRot(90 * PI / 180); + } - if ( dir > 0 && dir < 5 ) - { - corners[i]->y -= 6 / 16.0f; - corners[i]->xRot( 90 * PI / 180 ); + if (dir > 0 && dir < 5) { + corners[i]->y -= 6 / 16.0f; + corners[i]->xRot(90 * PI / 180); - if ( dir == 4 ) corners[i]->yRot( 0 * PI / 180 ); - if ( dir == 3 ) corners[i]->yRot( 180 * PI / 180 ); - if ( dir == 2 ) corners[i]->yRot( 90 * PI / 180 ); - if ( dir == 1 ) corners[i]->yRot( -90 * PI / 180 ); + if (dir == 4) corners[i]->yRot(0 * PI / 180); + if (dir == 3) corners[i]->yRot(180 * PI / 180); + if (dir == 2) corners[i]->yRot(90 * PI / 180); + if (dir == 1) corners[i]->yRot(-90 * PI / 180); - corners[i]->x += x + 0.5; - corners[i]->y += y + 8 / 16.0f; - corners[i]->z += z + 0.5; - } - else if (dir == 0 || dir == 7) - { - corners[i]->x += x + 0.5; - corners[i]->y += y + 14 / 16.0f; - corners[i]->z += z + 0.5; - } - else - { - corners[i]->x += x + 0.5; - corners[i]->y += y + 2 / 16.0f; - corners[i]->z += z + 0.5; - } - } - - Vec3* c0 = NULL, *c1 = NULL, *c2 = NULL, *c3 = NULL; - for ( int i = 0; i < 6; i++ ) - { - if ( i == 0 ) - { - u0 = tex->getU(7); - v0 = tex->getV(6); - u1 = tex->getU(9); - v1 = tex->getV(8); - } - else if ( i == 2 ) - { - u0 = tex->getU(7); - v0 = tex->getV(6); - u1 = tex->getU(9); - v1 = tex->getV1(); - } - if ( i == 0 ) - { - c0 = corners[0]; - c1 = corners[1]; - c2 = corners[2]; - c3 = corners[3]; - } - else if ( i == 1 ) - { - c0 = corners[7]; - c1 = corners[6]; - c2 = corners[5]; - c3 = corners[4]; - } - else if ( i == 2 ) - { - c0 = corners[1]; - c1 = corners[0]; - c2 = corners[4]; - c3 = corners[5]; - } - else if ( i == 3 ) - { - c0 = corners[2]; - c1 = corners[1]; - c2 = corners[5]; - c3 = corners[6]; - } - else if ( i == 4 ) - { - c0 = corners[3]; - c1 = corners[2]; - c2 = corners[6]; - c3 = corners[7]; - } - else if ( i == 5 ) - { - c0 = corners[0]; - c1 = corners[3]; - c2 = corners[7]; - c3 = corners[4]; - } - t->vertexUV( ( float )( c0->x ), ( float )( c0->y ), ( float )( c0->z ), ( float )( u0 ), ( float )( v1 ) ); - t->vertexUV( ( float )( c1->x ), ( float )( c1->y ), ( float )( c1->z ), ( float )( u1 ), ( float )( v1 ) ); - t->vertexUV( ( float )( c2->x ), ( float )( c2->y ), ( float )( c2->z ), ( float )( u1 ), ( float )( v0 ) ); - t->vertexUV( ( float )( c3->x ), ( float )( c3->y ), ( float )( c3->z ), ( float )( u0 ), ( float )( v0 ) ); - } -#endif // DISABLE_TESS_FUNCS - return true; + corners[i]->x += x + 0.5; + corners[i]->y += y + 8 / 16.0f; + corners[i]->z += z + 0.5; + } else if (dir == 0 || dir == 7) { + corners[i]->x += x + 0.5; + corners[i]->y += y + 14 / 16.0f; + corners[i]->z += z + 0.5; + } else { + corners[i]->x += x + 0.5; + corners[i]->y += y + 2 / 16.0f; + corners[i]->z += z + 0.5; + } + } + Vec3 *c0 = NULL, *c1 = NULL, *c2 = NULL, *c3 = NULL; + for (int i = 0; i < 6; i++) { + if (i == 0) { + u0 = tex->getU(7); + v0 = tex->getV(6); + u1 = tex->getU(9); + v1 = tex->getV(8); + } else if (i == 2) { + u0 = tex->getU(7); + v0 = tex->getV(6); + u1 = tex->getU(9); + v1 = tex->getV1(); + } + if (i == 0) { + c0 = corners[0]; + c1 = corners[1]; + c2 = corners[2]; + c3 = corners[3]; + } else if (i == 1) { + c0 = corners[7]; + c1 = corners[6]; + c2 = corners[5]; + c3 = corners[4]; + } else if (i == 2) { + c0 = corners[1]; + c1 = corners[0]; + c2 = corners[4]; + c3 = corners[5]; + } else if (i == 3) { + c0 = corners[2]; + c1 = corners[1]; + c2 = corners[5]; + c3 = corners[6]; + } else if (i == 4) { + c0 = corners[3]; + c1 = corners[2]; + c2 = corners[6]; + c3 = corners[7]; + } else if (i == 5) { + c0 = corners[0]; + c1 = corners[3]; + c2 = corners[7]; + c3 = corners[4]; + } + t->vertexUV((float)(c0->x), (float)(c0->y), (float)(c0->z), (float)(u0), + (float)(v1)); + t->vertexUV((float)(c1->x), (float)(c1->y), (float)(c1->z), (float)(u1), + (float)(v1)); + t->vertexUV((float)(c2->x), (float)(c2->y), (float)(c2->z), (float)(u1), + (float)(v0)); + t->vertexUV((float)(c3->x), (float)(c3->y), (float)(c3->z), (float)(u0), + (float)(v0)); + } +#endif // DISABLE_TESS_FUNCS + return true; } -bool TileRenderer_SPU::tesselateTripwireSourceInWorld(Tile_SPU *tt, int x, int y, int z) -{ +bool TileRenderer_SPU::tesselateTripwireSourceInWorld(Tile_SPU* tt, int x, + int y, int z) { #ifdef DISABLE_TESS_FUNCS - Tesselator *t = Tesselator::getInstance(); - int data = level->getData(x, y, z); - int dir = data & TripWireSourceTile::MASK_DIR; - bool attached = (data & TripWireSourceTile::MASK_ATTACHED) == TripWireSourceTile::MASK_ATTACHED; - bool powered = (data & TripWireSourceTile::MASK_POWERED) == TripWireSourceTile::MASK_POWERED; - bool suspended = !level->isTopSolidBlocking(x, y - 1, z); + Tesselator* t = Tesselator::getInstance(); + int data = level->getData(x, y, z); + int dir = data & TripWireSourceTile::MASK_DIR; + bool attached = (data & TripWireSourceTile::MASK_ATTACHED) == + TripWireSourceTile::MASK_ATTACHED; + bool powered = (data & TripWireSourceTile::MASK_POWERED) == + TripWireSourceTile::MASK_POWERED; + bool suspended = !level->isTopSolidBlocking(x, y - 1, z); - bool hadFixed = hasFixedTexture(); - if (!hadFixed) this->setFixedTexture(getTexture(Tile::wood)); + bool hadFixed = hasFixedTexture(); + if (!hadFixed) this->setFixedTexture(getTexture(Tile::wood)); - float boxHeight = 4 / 16.0f; - float boxWidth = 2 / 16.0f; - float boxDepth = 2 / 16.0f; + float boxHeight = 4 / 16.0f; + float boxWidth = 2 / 16.0f; + float boxDepth = 2 / 16.0f; - float boxy0 = 0.3f - boxHeight; - float boxy1 = 0.3f + boxHeight; - if (dir == Direction::NORTH) - { - setShape(0.5f - boxWidth, boxy0, 1 - boxDepth, 0.5f + boxWidth, boxy1, 1); - } - else if (dir == Direction::SOUTH) - { - setShape(0.5f - boxWidth, boxy0, 0, 0.5f + boxWidth, boxy1, boxDepth); - } - else if (dir == Direction::WEST) - { - setShape(1 - boxDepth, boxy0, 0.5f - boxWidth, 1, boxy1, 0.5f + boxWidth); - } - else if (dir == Direction::EAST) - { - setShape(0, boxy0, 0.5f - boxWidth, boxDepth, boxy1, 0.5f + boxWidth); - } + float boxy0 = 0.3f - boxHeight; + float boxy1 = 0.3f + boxHeight; + if (dir == Direction::NORTH) { + setShape(0.5f - boxWidth, boxy0, 1 - boxDepth, 0.5f + boxWidth, boxy1, + 1); + } else if (dir == Direction::SOUTH) { + setShape(0.5f - boxWidth, boxy0, 0, 0.5f + boxWidth, boxy1, boxDepth); + } else if (dir == Direction::WEST) { + setShape(1 - boxDepth, boxy0, 0.5f - boxWidth, 1, boxy1, + 0.5f + boxWidth); + } else if (dir == Direction::EAST) { + setShape(0, boxy0, 0.5f - boxWidth, boxDepth, boxy1, 0.5f + boxWidth); + } - this->tesselateBlockInWorld(tt, x, y, z); - if (!hadFixed) this->clearFixedTexture(); + this->tesselateBlockInWorld(tt, x, y, z); + if (!hadFixed) this->clearFixedTexture(); - float brightness; - if (SharedConstants::TEXTURE_LIGHTING) - { - t->tex2(tt->getLightColor(level, x, y, z)); - brightness = 1; - } - else - { - brightness = tt->getBrightness(level, x, y, z); - } - if (Tile::lightEmission[tt->id] > 0) brightness = 1.0f; - t->color(brightness, brightness, brightness); - Icon *tex = getTexture(tt, 0); + float brightness; + if (SharedConstants::TEXTURE_LIGHTING) { + t->tex2(tt->getLightColor(level, x, y, z)); + brightness = 1; + } else { + brightness = tt->getBrightness(level, x, y, z); + } + if (Tile::lightEmission[tt->id] > 0) brightness = 1.0f; + t->color(brightness, brightness, brightness); + Icon* tex = getTexture(tt, 0); - if (hasFixedTexture()) tex = fixedTexture; - double u0 = tex->getU0(); - double v0 = tex->getV0(); - double u1 = tex->getU1(); - double v1 = tex->getV1(); + if (hasFixedTexture()) tex = fixedTexture; + double u0 = tex->getU0(); + double v0 = tex->getV0(); + double u1 = tex->getU1(); + double v1 = tex->getV1(); - Vec3 *corners[8]; - float stickWidth = 0.75f / 16.0f; - float stickHeight = 0.75f / 16.0f; - float stickLength = 5 / 16.0f; - corners[0] = Vec3::newTemp(-stickWidth, -0, -stickHeight); - corners[1] = Vec3::newTemp(+stickWidth, -0, -stickHeight); - corners[2] = Vec3::newTemp(+stickWidth, -0, +stickHeight); - corners[3] = Vec3::newTemp(-stickWidth, -0, +stickHeight); - corners[4] = Vec3::newTemp(-stickWidth, +stickLength, -stickHeight); - corners[5] = Vec3::newTemp(+stickWidth, +stickLength, -stickHeight); - corners[6] = Vec3::newTemp(+stickWidth, +stickLength, +stickHeight); - corners[7] = Vec3::newTemp(-stickWidth, +stickLength, +stickHeight); + Vec3* corners[8]; + float stickWidth = 0.75f / 16.0f; + float stickHeight = 0.75f / 16.0f; + float stickLength = 5 / 16.0f; + corners[0] = Vec3::newTemp(-stickWidth, -0, -stickHeight); + corners[1] = Vec3::newTemp(+stickWidth, -0, -stickHeight); + corners[2] = Vec3::newTemp(+stickWidth, -0, +stickHeight); + corners[3] = Vec3::newTemp(-stickWidth, -0, +stickHeight); + corners[4] = Vec3::newTemp(-stickWidth, +stickLength, -stickHeight); + corners[5] = Vec3::newTemp(+stickWidth, +stickLength, -stickHeight); + corners[6] = Vec3::newTemp(+stickWidth, +stickLength, +stickHeight); + corners[7] = Vec3::newTemp(-stickWidth, +stickLength, +stickHeight); - for (int i = 0; i < 8; i++) - { - corners[i]->z += 1 / 16.0f; + for (int i = 0; i < 8; i++) { + corners[i]->z += 1 / 16.0f; - if (powered) - { - corners[i]->xRot(30 * PI / 180); - corners[i]->y -= 7 / 16.0f; - } - else if (attached) - { - corners[i]->xRot(5 * PI / 180); - corners[i]->y -= 7 / 16.0f; - } - else - { - corners[i]->xRot(-40 * PI / 180); - corners[i]->y -= 6 / 16.0f; - } + if (powered) { + corners[i]->xRot(30 * PI / 180); + corners[i]->y -= 7 / 16.0f; + } else if (attached) { + corners[i]->xRot(5 * PI / 180); + corners[i]->y -= 7 / 16.0f; + } else { + corners[i]->xRot(-40 * PI / 180); + corners[i]->y -= 6 / 16.0f; + } - corners[i]->xRot(90 * PI / 180); + corners[i]->xRot(90 * PI / 180); - if (dir == Direction::NORTH) corners[i]->yRot(0 * PI / 180); - if (dir == Direction::SOUTH) corners[i]->yRot(180 * PI / 180); - if (dir == Direction::WEST) corners[i]->yRot(90 * PI / 180); - if (dir == Direction::EAST) corners[i]->yRot(-90 * PI / 180); + if (dir == Direction::NORTH) corners[i]->yRot(0 * PI / 180); + if (dir == Direction::SOUTH) corners[i]->yRot(180 * PI / 180); + if (dir == Direction::WEST) corners[i]->yRot(90 * PI / 180); + if (dir == Direction::EAST) corners[i]->yRot(-90 * PI / 180); - corners[i]->x += x + 0.5; - corners[i]->y += y + 5 / 16.0f; - corners[i]->z += z + 0.5; - } + corners[i]->x += x + 0.5; + corners[i]->y += y + 5 / 16.0f; + corners[i]->z += z + 0.5; + } - Vec3 *c0 = NULL, *c1 = NULL, *c2 = NULL, *c3 = NULL; - int stickX0 = 7; - int stickX1 = 9; - int stickY0 = 9; - int stickY1 = 16; + Vec3 *c0 = NULL, *c1 = NULL, *c2 = NULL, *c3 = NULL; + int stickX0 = 7; + int stickX1 = 9; + int stickY0 = 9; + int stickY1 = 16; - for (int i = 0; i < 6; i++) - { - if (i == 0) - { - c0 = corners[0]; - c1 = corners[1]; - c2 = corners[2]; - c3 = corners[3]; - u0 = tex->getU(stickX0); - v0 = tex->getV(stickY0); - u1 = tex->getU(stickX1); - v1 = tex->getV(stickY0 + 2); - } - else if (i == 1) - { - c0 = corners[7]; - c1 = corners[6]; - c2 = corners[5]; - c3 = corners[4]; - } - else if (i == 2) - { - c0 = corners[1]; - c1 = corners[0]; - c2 = corners[4]; - c3 = corners[5]; - u0 = tex->getU(stickX0); - v0 = tex->getV(stickY0); - u1 = tex->getU(stickX1); - v1 = tex->getV(stickY1); - } - else if (i == 3) - { - c0 = corners[2]; - c1 = corners[1]; - c2 = corners[5]; - c3 = corners[6]; - } - else if (i == 4) - { - c0 = corners[3]; - c1 = corners[2]; - c2 = corners[6]; - c3 = corners[7]; - } - else if (i == 5) - { - c0 = corners[0]; - c1 = corners[3]; - c2 = corners[7]; - c3 = corners[4]; - } - t->vertexUV(c0->x, c0->y, c0->z, u0, v1); - t->vertexUV(c1->x, c1->y, c1->z, u1, v1); - t->vertexUV(c2->x, c2->y, c2->z, u1, v0); - t->vertexUV(c3->x, c3->y, c3->z, u0, v0); - } + for (int i = 0; i < 6; i++) { + if (i == 0) { + c0 = corners[0]; + c1 = corners[1]; + c2 = corners[2]; + c3 = corners[3]; + u0 = tex->getU(stickX0); + v0 = tex->getV(stickY0); + u1 = tex->getU(stickX1); + v1 = tex->getV(stickY0 + 2); + } else if (i == 1) { + c0 = corners[7]; + c1 = corners[6]; + c2 = corners[5]; + c3 = corners[4]; + } else if (i == 2) { + c0 = corners[1]; + c1 = corners[0]; + c2 = corners[4]; + c3 = corners[5]; + u0 = tex->getU(stickX0); + v0 = tex->getV(stickY0); + u1 = tex->getU(stickX1); + v1 = tex->getV(stickY1); + } else if (i == 3) { + c0 = corners[2]; + c1 = corners[1]; + c2 = corners[5]; + c3 = corners[6]; + } else if (i == 4) { + c0 = corners[3]; + c1 = corners[2]; + c2 = corners[6]; + c3 = corners[7]; + } else if (i == 5) { + c0 = corners[0]; + c1 = corners[3]; + c2 = corners[7]; + c3 = corners[4]; + } + t->vertexUV(c0->x, c0->y, c0->z, u0, v1); + t->vertexUV(c1->x, c1->y, c1->z, u1, v1); + t->vertexUV(c2->x, c2->y, c2->z, u1, v0); + t->vertexUV(c3->x, c3->y, c3->z, u0, v0); + } + float hoopWidth = 1.5f / 16.0f; + float hoopHeight = 1.5f / 16.0f; + float hoopLength = 0.5f / 16.0f; + corners[0] = Vec3::newTemp(-hoopWidth, -0, -hoopHeight); + corners[1] = Vec3::newTemp(+hoopWidth, -0, -hoopHeight); + corners[2] = Vec3::newTemp(+hoopWidth, -0, +hoopHeight); + corners[3] = Vec3::newTemp(-hoopWidth, -0, +hoopHeight); + corners[4] = Vec3::newTemp(-hoopWidth, +hoopLength, -hoopHeight); + corners[5] = Vec3::newTemp(+hoopWidth, +hoopLength, -hoopHeight); + corners[6] = Vec3::newTemp(+hoopWidth, +hoopLength, +hoopHeight); + corners[7] = Vec3::newTemp(-hoopWidth, +hoopLength, +hoopHeight); - float hoopWidth = 1.5f / 16.0f; - float hoopHeight = 1.5f / 16.0f; - float hoopLength = 0.5f / 16.0f; - corners[0] = Vec3::newTemp(-hoopWidth, -0, -hoopHeight); - corners[1] = Vec3::newTemp(+hoopWidth, -0, -hoopHeight); - corners[2] = Vec3::newTemp(+hoopWidth, -0, +hoopHeight); - corners[3] = Vec3::newTemp(-hoopWidth, -0, +hoopHeight); - corners[4] = Vec3::newTemp(-hoopWidth, +hoopLength, -hoopHeight); - corners[5] = Vec3::newTemp(+hoopWidth, +hoopLength, -hoopHeight); - corners[6] = Vec3::newTemp(+hoopWidth, +hoopLength, +hoopHeight); - corners[7] = Vec3::newTemp(-hoopWidth, +hoopLength, +hoopHeight); + for (int i = 0; i < 8; i++) { + corners[i]->z += 3.5f / 16.0f; - for (int i = 0; i < 8; i++) - { - corners[i]->z += 3.5f / 16.0f; + if (powered) { + corners[i]->y -= 1.5 / 16.0f; + corners[i]->z -= 2.6 / 16.0f; + corners[i]->xRot(0 * PI / 180); + } else if (attached) { + corners[i]->y += 0.25 / 16.0f; + corners[i]->z -= 2.75 / 16.0f; + corners[i]->xRot(10 * PI / 180); + } else { + corners[i]->xRot(50 * PI / 180); + } - if (powered) - { - corners[i]->y -= 1.5 / 16.0f; - corners[i]->z -= 2.6 / 16.0f; - corners[i]->xRot(0 * PI / 180); - } - else if (attached) - { - corners[i]->y += 0.25 / 16.0f; - corners[i]->z -= 2.75 / 16.0f; - corners[i]->xRot(10 * PI / 180); - } - else - { - corners[i]->xRot(50 * PI / 180); - } + if (dir == Direction::NORTH) corners[i]->yRot(0 * PI / 180); + if (dir == Direction::SOUTH) corners[i]->yRot(180 * PI / 180); + if (dir == Direction::WEST) corners[i]->yRot(90 * PI / 180); + if (dir == Direction::EAST) corners[i]->yRot(-90 * PI / 180); - if (dir == Direction::NORTH) corners[i]->yRot(0 * PI / 180); - if (dir == Direction::SOUTH) corners[i]->yRot(180 * PI / 180); - if (dir == Direction::WEST) corners[i]->yRot(90 * PI / 180); - if (dir == Direction::EAST) corners[i]->yRot(-90 * PI / 180); + corners[i]->x += x + 0.5; + corners[i]->y += y + 5 / 16.0f; + corners[i]->z += z + 0.5; + } - corners[i]->x += x + 0.5; - corners[i]->y += y + 5 / 16.0f; - corners[i]->z += z + 0.5; - } + int hoopX0 = 5; + int hoopX1 = 11; + int hoopY0 = 3; + int hoopY1 = 9; - int hoopX0 = 5; - int hoopX1 = 11; - int hoopY0 = 3; - int hoopY1 = 9; + for (int i = 0; i < 6; i++) { + if (i == 0) { + c0 = corners[0]; + c1 = corners[1]; + c2 = corners[2]; + c3 = corners[3]; + u0 = tex->getU(hoopX0); + v0 = tex->getV(hoopY0); + u1 = tex->getU(hoopX1); + v1 = tex->getV(hoopY1); + } else if (i == 1) { + c0 = corners[7]; + c1 = corners[6]; + c2 = corners[5]; + c3 = corners[4]; + } else if (i == 2) { + c0 = corners[1]; + c1 = corners[0]; + c2 = corners[4]; + c3 = corners[5]; + u0 = tex->getU(hoopX0); + v0 = tex->getV(hoopY0); + u1 = tex->getU(hoopX1); + v1 = tex->getV(hoopY0 + 2); + } else if (i == 3) { + c0 = corners[2]; + c1 = corners[1]; + c2 = corners[5]; + c3 = corners[6]; + } else if (i == 4) { + c0 = corners[3]; + c1 = corners[2]; + c2 = corners[6]; + c3 = corners[7]; + } else if (i == 5) { + c0 = corners[0]; + c1 = corners[3]; + c2 = corners[7]; + c3 = corners[4]; + } + t->vertexUV(c0->x, c0->y, c0->z, u0, v1); + t->vertexUV(c1->x, c1->y, c1->z, u1, v1); + t->vertexUV(c2->x, c2->y, c2->z, u1, v0); + t->vertexUV(c3->x, c3->y, c3->z, u0, v0); + } - for (int i = 0; i < 6; i++) - { - if (i == 0) - { - c0 = corners[0]; - c1 = corners[1]; - c2 = corners[2]; - c3 = corners[3]; - u0 = tex->getU(hoopX0); - v0 = tex->getV(hoopY0); - u1 = tex->getU(hoopX1); - v1 = tex->getV(hoopY1); - } - else if (i == 1) - { - c0 = corners[7]; - c1 = corners[6]; - c2 = corners[5]; - c3 = corners[4]; - } - else if (i == 2) - { - c0 = corners[1]; - c1 = corners[0]; - c2 = corners[4]; - c3 = corners[5]; - u0 = tex->getU(hoopX0); - v0 = tex->getV(hoopY0); - u1 = tex->getU(hoopX1); - v1 = tex->getV(hoopY0 + 2); - } - else if (i == 3) - { - c0 = corners[2]; - c1 = corners[1]; - c2 = corners[5]; - c3 = corners[6]; - } - else if (i == 4) - { - c0 = corners[3]; - c1 = corners[2]; - c2 = corners[6]; - c3 = corners[7]; - } - else if (i == 5) - { - c0 = corners[0]; - c1 = corners[3]; - c2 = corners[7]; - c3 = corners[4]; - } - t->vertexUV(c0->x, c0->y, c0->z, u0, v1); - t->vertexUV(c1->x, c1->y, c1->z, u1, v1); - t->vertexUV(c2->x, c2->y, c2->z, u1, v0); - t->vertexUV(c3->x, c3->y, c3->z, u0, v0); - } + if (attached) { + double hoopBottomY = corners[0]->y; + float width = 0.5f / 16.0f; + float top = 0.5f - (width / 2); + float bottom = top + width; + Icon* wireTex = getTexture(Tile::tripWire); + double wireX0 = tex->getU0(); + double wireY0 = tex->getV(attached ? 2 : 0); + double wireX1 = tex->getU1(); + double wireY1 = tex->getV(attached ? 4 : 2); + double floating = (suspended ? 3.5f : 1.5f) / 16.0; - if (attached) - { - double hoopBottomY = corners[0]->y; - float width = 0.5f / 16.0f; - float top = 0.5f - (width / 2); - float bottom = top + width; - Icon *wireTex = getTexture(Tile::tripWire); - double wireX0 = tex->getU0(); - double wireY0 = tex->getV(attached ? 2 : 0); - double wireX1 = tex->getU1(); - double wireY1 = tex->getV(attached ? 4 : 2); - double floating = (suspended ? 3.5f : 1.5f) / 16.0; + brightness = tt->getBrightness(level, x, y, z) * 0.75f; + t->color(brightness, brightness, brightness); - brightness = tt->getBrightness(level, x, y, z) * 0.75f; - t->color(brightness, brightness, brightness); + if (dir == Direction::NORTH) { + t->vertexUV(x + top, y + floating, z + 0.25, wireX0, wireY0); + t->vertexUV(x + bottom, y + floating, z + 0.25, wireX0, wireY1); + t->vertexUV(x + bottom, y + floating, z, wireX1, wireY1); + t->vertexUV(x + top, y + floating, z, wireX1, wireY0); - if (dir == Direction::NORTH) - { - t->vertexUV(x + top, y + floating, z + 0.25, wireX0, wireY0); - t->vertexUV(x + bottom, y + floating, z + 0.25, wireX0, wireY1); - t->vertexUV(x + bottom, y + floating, z, wireX1, wireY1); - t->vertexUV(x + top, y + floating, z, wireX1, wireY0); + t->vertexUV(x + top, hoopBottomY, z + 0.5, wireX0, wireY0); + t->vertexUV(x + bottom, hoopBottomY, z + 0.5, wireX0, wireY1); + t->vertexUV(x + bottom, y + floating, z + 0.25, wireX1, wireY1); + t->vertexUV(x + top, y + floating, z + 0.25, wireX1, wireY0); + } else if (dir == Direction::SOUTH) { + t->vertexUV(x + top, y + floating, z + 0.75, wireX0, wireY0); + t->vertexUV(x + bottom, y + floating, z + 0.75, wireX0, wireY1); + t->vertexUV(x + bottom, hoopBottomY, z + 0.5, wireX1, wireY1); + t->vertexUV(x + top, hoopBottomY, z + 0.5, wireX1, wireY0); - t->vertexUV(x + top, hoopBottomY, z + 0.5, wireX0, wireY0); - t->vertexUV(x + bottom, hoopBottomY, z + 0.5, wireX0, wireY1); - t->vertexUV(x + bottom, y + floating, z + 0.25, wireX1, wireY1); - t->vertexUV(x + top, y + floating, z + 0.25, wireX1, wireY0); - } - else if (dir == Direction::SOUTH) - { - t->vertexUV(x + top, y + floating, z + 0.75, wireX0, wireY0); - t->vertexUV(x + bottom, y + floating, z + 0.75, wireX0, wireY1); - t->vertexUV(x + bottom, hoopBottomY, z + 0.5, wireX1, wireY1); - t->vertexUV(x + top, hoopBottomY, z + 0.5, wireX1, wireY0); + t->vertexUV(x + top, y + floating, z + 1, wireX0, wireY0); + t->vertexUV(x + bottom, y + floating, z + 1, wireX0, wireY1); + t->vertexUV(x + bottom, y + floating, z + 0.75, wireX1, wireY1); + t->vertexUV(x + top, y + floating, z + 0.75, wireX1, wireY0); + } else if (dir == Direction::WEST) { + t->vertexUV(x, y + floating, z + bottom, wireX0, wireY1); + t->vertexUV(x + 0.25, y + floating, z + bottom, wireX1, wireY1); + t->vertexUV(x + 0.25, y + floating, z + top, wireX1, wireY0); + t->vertexUV(x, y + floating, z + top, wireX0, wireY0); - t->vertexUV(x + top, y + floating, z + 1, wireX0, wireY0); - t->vertexUV(x + bottom, y + floating, z + 1, wireX0, wireY1); - t->vertexUV(x + bottom, y + floating, z + 0.75, wireX1, wireY1); - t->vertexUV(x + top, y + floating, z + 0.75, wireX1, wireY0); - } - else if (dir == Direction::WEST) - { - t->vertexUV(x, y + floating, z + bottom, wireX0, wireY1); - t->vertexUV(x + 0.25, y + floating, z + bottom, wireX1, wireY1); - t->vertexUV(x + 0.25, y + floating, z + top, wireX1, wireY0); - t->vertexUV(x, y + floating, z + top, wireX0, wireY0); + t->vertexUV(x + 0.25, y + floating, z + bottom, wireX0, wireY1); + t->vertexUV(x + 0.5, hoopBottomY, z + bottom, wireX1, wireY1); + t->vertexUV(x + 0.5, hoopBottomY, z + top, wireX1, wireY0); + t->vertexUV(x + 0.25, y + floating, z + top, wireX0, wireY0); + } else { + t->vertexUV(x + 0.5, hoopBottomY, z + bottom, wireX0, wireY1); + t->vertexUV(x + 0.75, y + floating, z + bottom, wireX1, wireY1); + t->vertexUV(x + 0.75, y + floating, z + top, wireX1, wireY0); + t->vertexUV(x + 0.5, hoopBottomY, z + top, wireX0, wireY0); - t->vertexUV(x + 0.25, y + floating, z + bottom, wireX0, wireY1); - t->vertexUV(x + 0.5, hoopBottomY, z + bottom, wireX1, wireY1); - t->vertexUV(x + 0.5, hoopBottomY, z + top, wireX1, wireY0); - t->vertexUV(x + 0.25, y + floating, z + top, wireX0, wireY0); - } - else - { - t->vertexUV(x + 0.5, hoopBottomY, z + bottom, wireX0, wireY1); - t->vertexUV(x + 0.75, y + floating, z + bottom, wireX1, wireY1); - t->vertexUV(x + 0.75, y + floating, z + top, wireX1, wireY0); - t->vertexUV(x + 0.5, hoopBottomY, z + top, wireX0, wireY0); + t->vertexUV(x + 0.75, y + floating, z + bottom, wireX0, wireY1); + t->vertexUV(x + 1, y + floating, z + bottom, wireX1, wireY1); + t->vertexUV(x + 1, y + floating, z + top, wireX1, wireY0); + t->vertexUV(x + 0.75, y + floating, z + top, wireX0, wireY0); + } + } +#endif // #ifdef DISABLE_TESS_FUNCS - t->vertexUV(x + 0.75, y + floating, z + bottom, wireX0, wireY1); - t->vertexUV(x + 1, y + floating, z + bottom, wireX1, wireY1); - t->vertexUV(x + 1, y + floating, z + top, wireX1, wireY0); - t->vertexUV(x + 0.75, y + floating, z + top, wireX0, wireY0); - } - } -#endif // #ifdef DISABLE_TESS_FUNCS - - return true; + return true; } -bool TileRenderer_SPU::tesselateTripwireInWorld(Tile_SPU *tt, int x, int y, int z) -{ +bool TileRenderer_SPU::tesselateTripwireInWorld(Tile_SPU* tt, int x, int y, + int z) { #ifdef DISABLE_TESS_FUNCS - Tesselator *t = Tesselator::getInstance(); - Icon *tex = getTexture(tt, 0); - int data = level->getData(x, y, z); - bool attached = (data & TripWireTile::MASK_ATTACHED) == TripWireTile::MASK_ATTACHED; - bool suspended = (data & TripWireTile::MASK_SUSPENDED) == TripWireTile::MASK_SUSPENDED; + Tesselator* t = Tesselator::getInstance(); + Icon* tex = getTexture(tt, 0); + int data = level->getData(x, y, z); + bool attached = + (data & TripWireTile::MASK_ATTACHED) == TripWireTile::MASK_ATTACHED; + bool suspended = + (data & TripWireTile::MASK_SUSPENDED) == TripWireTile::MASK_SUSPENDED; - if (hasFixedTexture()) tex = fixedTexture; + if (hasFixedTexture()) tex = fixedTexture; - float brightness; - if (SharedConstants::TEXTURE_LIGHTING) - { - t->tex2(tt->getLightColor(level, x, y, z)); - } - brightness = tt->getBrightness(level, x, y, z) * 0.75f; - t->color(brightness, brightness, brightness); + float brightness; + if (SharedConstants::TEXTURE_LIGHTING) { + t->tex2(tt->getLightColor(level, x, y, z)); + } + brightness = tt->getBrightness(level, x, y, z) * 0.75f; + t->color(brightness, brightness, brightness); - double wireX0 = tex->getU0(); - double wireY0 = tex->getV(attached ? 2 : 0); - double wireX1 = tex->getU1(); - double wireY1 = tex->getV(attached ? 4 : 2); - double floating = (suspended ? 3.5f : 1.5f) / 16.0; + double wireX0 = tex->getU0(); + double wireY0 = tex->getV(attached ? 2 : 0); + double wireX1 = tex->getU1(); + double wireY1 = tex->getV(attached ? 4 : 2); + double floating = (suspended ? 3.5f : 1.5f) / 16.0; - bool w = TripWireTile::shouldConnectTo(level, x, y, z, data, Direction::WEST); - bool e = TripWireTile::shouldConnectTo(level, x, y, z, data, Direction::EAST); - bool n = TripWireTile::shouldConnectTo(level, x, y, z, data, Direction::NORTH); - bool s = TripWireTile::shouldConnectTo(level, x, y, z, data, Direction::SOUTH); + bool w = + TripWireTile::shouldConnectTo(level, x, y, z, data, Direction::WEST); + bool e = + TripWireTile::shouldConnectTo(level, x, y, z, data, Direction::EAST); + bool n = + TripWireTile::shouldConnectTo(level, x, y, z, data, Direction::NORTH); + bool s = + TripWireTile::shouldConnectTo(level, x, y, z, data, Direction::SOUTH); - float width = 0.5f / 16.0f; - float top = 0.5f - (width / 2); - float bottom = top + width; + float width = 0.5f / 16.0f; + float top = 0.5f - (width / 2); + float bottom = top + width; - if (!n && !e && !s && !w) - { - n = true; - s = true; - } + if (!n && !e && !s && !w) { + n = true; + s = true; + } - if (n) - { - t->vertexUV(x + top, y + floating, z + 0.25, wireX0, wireY0); - t->vertexUV(x + bottom, y + floating, z + 0.25, wireX0, wireY1); - t->vertexUV(x + bottom, y + floating, z, wireX1, wireY1); - t->vertexUV(x + top, y + floating, z, wireX1, wireY0); + if (n) { + t->vertexUV(x + top, y + floating, z + 0.25, wireX0, wireY0); + t->vertexUV(x + bottom, y + floating, z + 0.25, wireX0, wireY1); + t->vertexUV(x + bottom, y + floating, z, wireX1, wireY1); + t->vertexUV(x + top, y + floating, z, wireX1, wireY0); - t->vertexUV(x + top, y + floating, z, wireX1, wireY0); - t->vertexUV(x + bottom, y + floating, z, wireX1, wireY1); - t->vertexUV(x + bottom, y + floating, z + 0.25, wireX0, wireY1); - t->vertexUV(x + top, y + floating, z + 0.25, wireX0, wireY0); - } - if (n || (s && !e && !w)) - { - t->vertexUV(x + top, y + floating, z + 0.5, wireX0, wireY0); - t->vertexUV(x + bottom, y + floating, z + 0.5, wireX0, wireY1); - t->vertexUV(x + bottom, y + floating, z + 0.25, wireX1, wireY1); - t->vertexUV(x + top, y + floating, z + 0.25, wireX1, wireY0); + t->vertexUV(x + top, y + floating, z, wireX1, wireY0); + t->vertexUV(x + bottom, y + floating, z, wireX1, wireY1); + t->vertexUV(x + bottom, y + floating, z + 0.25, wireX0, wireY1); + t->vertexUV(x + top, y + floating, z + 0.25, wireX0, wireY0); + } + if (n || (s && !e && !w)) { + t->vertexUV(x + top, y + floating, z + 0.5, wireX0, wireY0); + t->vertexUV(x + bottom, y + floating, z + 0.5, wireX0, wireY1); + t->vertexUV(x + bottom, y + floating, z + 0.25, wireX1, wireY1); + t->vertexUV(x + top, y + floating, z + 0.25, wireX1, wireY0); - t->vertexUV(x + top, y + floating, z + 0.25, wireX1, wireY0); - t->vertexUV(x + bottom, y + floating, z + 0.25, wireX1, wireY1); - t->vertexUV(x + bottom, y + floating, z + 0.5, wireX0, wireY1); - t->vertexUV(x + top, y + floating, z + 0.5, wireX0, wireY0); - } - if (s || (n && !e && !w)) - { - t->vertexUV(x + top, y + floating, z + 0.75, wireX0, wireY0); - t->vertexUV(x + bottom, y + floating, z + 0.75, wireX0, wireY1); - t->vertexUV(x + bottom, y + floating, z + 0.5, wireX1, wireY1); - t->vertexUV(x + top, y + floating, z + 0.5, wireX1, wireY0); + t->vertexUV(x + top, y + floating, z + 0.25, wireX1, wireY0); + t->vertexUV(x + bottom, y + floating, z + 0.25, wireX1, wireY1); + t->vertexUV(x + bottom, y + floating, z + 0.5, wireX0, wireY1); + t->vertexUV(x + top, y + floating, z + 0.5, wireX0, wireY0); + } + if (s || (n && !e && !w)) { + t->vertexUV(x + top, y + floating, z + 0.75, wireX0, wireY0); + t->vertexUV(x + bottom, y + floating, z + 0.75, wireX0, wireY1); + t->vertexUV(x + bottom, y + floating, z + 0.5, wireX1, wireY1); + t->vertexUV(x + top, y + floating, z + 0.5, wireX1, wireY0); - t->vertexUV(x + top, y + floating, z + 0.5, wireX1, wireY0); - t->vertexUV(x + bottom, y + floating, z + 0.5, wireX1, wireY1); - t->vertexUV(x + bottom, y + floating, z + 0.75, wireX0, wireY1); - t->vertexUV(x + top, y + floating, z + 0.75, wireX0, wireY0); - } - if (s) - { - t->vertexUV(x + top, y + floating, z + 1, wireX0, wireY0); - t->vertexUV(x + bottom, y + floating, z + 1, wireX0, wireY1); - t->vertexUV(x + bottom, y + floating, z + 0.75, wireX1, wireY1); - t->vertexUV(x + top, y + floating, z + 0.75, wireX1, wireY0); + t->vertexUV(x + top, y + floating, z + 0.5, wireX1, wireY0); + t->vertexUV(x + bottom, y + floating, z + 0.5, wireX1, wireY1); + t->vertexUV(x + bottom, y + floating, z + 0.75, wireX0, wireY1); + t->vertexUV(x + top, y + floating, z + 0.75, wireX0, wireY0); + } + if (s) { + t->vertexUV(x + top, y + floating, z + 1, wireX0, wireY0); + t->vertexUV(x + bottom, y + floating, z + 1, wireX0, wireY1); + t->vertexUV(x + bottom, y + floating, z + 0.75, wireX1, wireY1); + t->vertexUV(x + top, y + floating, z + 0.75, wireX1, wireY0); - t->vertexUV(x + top, y + floating, z + 0.75, wireX1, wireY0); - t->vertexUV(x + bottom, y + floating, z + 0.75, wireX1, wireY1); - t->vertexUV(x + bottom, y + floating, z + 1, wireX0, wireY1); - t->vertexUV(x + top, y + floating, z + 1, wireX0, wireY0); - } + t->vertexUV(x + top, y + floating, z + 0.75, wireX1, wireY0); + t->vertexUV(x + bottom, y + floating, z + 0.75, wireX1, wireY1); + t->vertexUV(x + bottom, y + floating, z + 1, wireX0, wireY1); + t->vertexUV(x + top, y + floating, z + 1, wireX0, wireY0); + } - if (w) - { - t->vertexUV(x, y + floating, z + bottom, wireX0, wireY1); - t->vertexUV(x + 0.25, y + floating, z + bottom, wireX1, wireY1); - t->vertexUV(x + 0.25, y + floating, z + top, wireX1, wireY0); - t->vertexUV(x, y + floating, z + top, wireX0, wireY0); + if (w) { + t->vertexUV(x, y + floating, z + bottom, wireX0, wireY1); + t->vertexUV(x + 0.25, y + floating, z + bottom, wireX1, wireY1); + t->vertexUV(x + 0.25, y + floating, z + top, wireX1, wireY0); + t->vertexUV(x, y + floating, z + top, wireX0, wireY0); - t->vertexUV(x, y + floating, z + top, wireX0, wireY0); - t->vertexUV(x + 0.25, y + floating, z + top, wireX1, wireY0); - t->vertexUV(x + 0.25, y + floating, z + bottom, wireX1, wireY1); - t->vertexUV(x, y + floating, z + bottom, wireX0, wireY1); - } - if (w || (e && !n && !s)) - { - t->vertexUV(x + 0.25, y + floating, z + bottom, wireX0, wireY1); - t->vertexUV(x + 0.5, y + floating, z + bottom, wireX1, wireY1); - t->vertexUV(x + 0.5, y + floating, z + top, wireX1, wireY0); - t->vertexUV(x + 0.25, y + floating, z + top, wireX0, wireY0); + t->vertexUV(x, y + floating, z + top, wireX0, wireY0); + t->vertexUV(x + 0.25, y + floating, z + top, wireX1, wireY0); + t->vertexUV(x + 0.25, y + floating, z + bottom, wireX1, wireY1); + t->vertexUV(x, y + floating, z + bottom, wireX0, wireY1); + } + if (w || (e && !n && !s)) { + t->vertexUV(x + 0.25, y + floating, z + bottom, wireX0, wireY1); + t->vertexUV(x + 0.5, y + floating, z + bottom, wireX1, wireY1); + t->vertexUV(x + 0.5, y + floating, z + top, wireX1, wireY0); + t->vertexUV(x + 0.25, y + floating, z + top, wireX0, wireY0); - t->vertexUV(x + 0.25, y + floating, z + top, wireX0, wireY0); - t->vertexUV(x + 0.5, y + floating, z + top, wireX1, wireY0); - t->vertexUV(x + 0.5, y + floating, z + bottom, wireX1, wireY1); - t->vertexUV(x + 0.25, y + floating, z + bottom, wireX0, wireY1); - } - if (e || (w && !n && !s)) - { - t->vertexUV(x + 0.5, y + floating, z + bottom, wireX0, wireY1); - t->vertexUV(x + 0.75, y + floating, z + bottom, wireX1, wireY1); - t->vertexUV(x + 0.75, y + floating, z + top, wireX1, wireY0); - t->vertexUV(x + 0.5, y + floating, z + top, wireX0, wireY0); + t->vertexUV(x + 0.25, y + floating, z + top, wireX0, wireY0); + t->vertexUV(x + 0.5, y + floating, z + top, wireX1, wireY0); + t->vertexUV(x + 0.5, y + floating, z + bottom, wireX1, wireY1); + t->vertexUV(x + 0.25, y + floating, z + bottom, wireX0, wireY1); + } + if (e || (w && !n && !s)) { + t->vertexUV(x + 0.5, y + floating, z + bottom, wireX0, wireY1); + t->vertexUV(x + 0.75, y + floating, z + bottom, wireX1, wireY1); + t->vertexUV(x + 0.75, y + floating, z + top, wireX1, wireY0); + t->vertexUV(x + 0.5, y + floating, z + top, wireX0, wireY0); - t->vertexUV(x + 0.5, y + floating, z + top, wireX0, wireY0); - t->vertexUV(x + 0.75, y + floating, z + top, wireX1, wireY0); - t->vertexUV(x + 0.75, y + floating, z + bottom, wireX1, wireY1); - t->vertexUV(x + 0.5, y + floating, z + bottom, wireX0, wireY1); - } - if (e) - { - t->vertexUV(x + 0.75, y + floating, z + bottom, wireX0, wireY1); - t->vertexUV(x + 1, y + floating, z + bottom, wireX1, wireY1); - t->vertexUV(x + 1, y + floating, z + top, wireX1, wireY0); - t->vertexUV(x + 0.75, y + floating, z + top, wireX0, wireY0); + t->vertexUV(x + 0.5, y + floating, z + top, wireX0, wireY0); + t->vertexUV(x + 0.75, y + floating, z + top, wireX1, wireY0); + t->vertexUV(x + 0.75, y + floating, z + bottom, wireX1, wireY1); + t->vertexUV(x + 0.5, y + floating, z + bottom, wireX0, wireY1); + } + if (e) { + t->vertexUV(x + 0.75, y + floating, z + bottom, wireX0, wireY1); + t->vertexUV(x + 1, y + floating, z + bottom, wireX1, wireY1); + t->vertexUV(x + 1, y + floating, z + top, wireX1, wireY0); + t->vertexUV(x + 0.75, y + floating, z + top, wireX0, wireY0); - t->vertexUV(x + 0.75, y + floating, z + top, wireX0, wireY0); - t->vertexUV(x + 1, y + floating, z + top, wireX1, wireY0); - t->vertexUV(x + 1, y + floating, z + bottom, wireX1, wireY1); - t->vertexUV(x + 0.75, y + floating, z + bottom, wireX0, wireY1); - } -#endif // DISABLE_TESS_FUNCS + t->vertexUV(x + 0.75, y + floating, z + top, wireX0, wireY0); + t->vertexUV(x + 1, y + floating, z + top, wireX1, wireY0); + t->vertexUV(x + 1, y + floating, z + bottom, wireX1, wireY1); + t->vertexUV(x + 0.75, y + floating, z + bottom, wireX0, wireY1); + } +#endif // DISABLE_TESS_FUNCS - return true; + return true; } +bool TileRenderer_SPU::tesselateFireInWorld(FireTile_SPU* tt, int x, int y, + int z) { + Tesselator_SPU* t = getTesselator(); + Icon_SPU* firstTex = tt->getTextureLayer(0); + Icon_SPU* secondTex = tt->getTextureLayer(1); + Icon_SPU* tex = firstTex; -bool TileRenderer_SPU::tesselateFireInWorld( FireTile_SPU* tt, int x, int y, int z ) -{ - Tesselator_SPU* t = getTesselator(); + if (hasFixedTexture()) tex = fixedTexture; - Icon_SPU *firstTex = tt->getTextureLayer(0); - Icon_SPU *secondTex = tt->getTextureLayer(1); - Icon_SPU *tex = firstTex; + if (SharedConstants::TEXTURE_LIGHTING) { + t->color(1.0f, 1.0f, 1.0f); + t->tex2(tt->getLightColor(level, x, y, z)); + } else { + float br = tt->getBrightness(level, x, y, z); + t->color(br, br, br); + } + float u0 = tex->getU0(); + float v0 = tex->getV0(); + float u1 = tex->getU1(); + float v1 = tex->getV1(); + float h = 1.4f; - if (hasFixedTexture()) tex = fixedTexture; + if (level->isSolidBlockingTile(x, y - 1, z) || + FireTile_SPU::canBurn(level, x, y - 1, z)) { + float x0 = x + 0.5f + 0.2f; + float x1 = x + 0.5f - 0.2f; + float z0 = z + 0.5f + 0.2f; + float z1 = z + 0.5f - 0.2f; - if ( SharedConstants::TEXTURE_LIGHTING ) - { - t->color( 1.0f, 1.0f, 1.0f ); - t->tex2( tt->getLightColor( level, x, y, z ) ); - } - else - { - float br = tt->getBrightness( level, x, y, z ); - t->color( br, br, br ); - } - float u0 = tex->getU0(); - float v0 = tex->getV0(); - float u1 = tex->getU1(); - float v1 = tex->getV1(); - float h = 1.4f; + float x0_ = x + 0.5f - 0.3f; + float x1_ = x + 0.5f + 0.3f; + float z0_ = z + 0.5f - 0.3f; + float z1_ = z + 0.5f + 0.3f; - if ( level->isSolidBlockingTile( x, y - 1, z ) || FireTile_SPU::canBurn( level, x, y - 1, z ) ) - { - float x0 = x + 0.5f + 0.2f; - float x1 = x + 0.5f - 0.2f; - float z0 = z + 0.5f + 0.2f; - float z1 = z + 0.5f - 0.2f; + t->vertexUV((float)(x0_), (float)(y + h), (float)(z + 1), (float)(u1), + (float)(v0)); + t->vertexUV((float)(x0), (float)(y + 0), (float)(z + 1), (float)(u1), + (float)(v1)); + t->vertexUV((float)(x0), (float)(y + 0), (float)(z + 0), (float)(u0), + (float)(v1)); + t->vertexUV((float)(x0_), (float)(y + h), (float)(z + 0), (float)(u0), + (float)(v0)); - float x0_ = x + 0.5f - 0.3f; - float x1_ = x + 0.5f + 0.3f; - float z0_ = z + 0.5f - 0.3f; - float z1_ = z + 0.5f + 0.3f; + t->vertexUV((float)(x1_), (float)(y + h), (float)(z + 0), (float)(u1), + (float)(v0)); + t->vertexUV((float)(x1), (float)(y + 0), (float)(z + 0), (float)(u1), + (float)(v1)); + t->vertexUV((float)(x1), (float)(y + 0), (float)(z + 1), (float)(u0), + (float)(v1)); + t->vertexUV((float)(x1_), (float)(y + h), (float)(z + 1), (float)(u0), + (float)(v0)); - t->vertexUV( ( float )( x0_ ), ( float )( y + h ), ( float )( z + 1 ), ( float )( u1 ), ( float )( v0 ) ); - t->vertexUV( ( float )( x0 ), ( float )( y + 0 ), ( float )( z + 1 ), ( float )( u1 ), ( float )( v1 ) ); - t->vertexUV( ( float )( x0 ), ( float )( y + 0 ), ( float )( z + 0 ), ( float )( u0 ), ( float )( v1 ) ); - t->vertexUV( ( float )( x0_ ), ( float )( y + h ), ( float )( z + 0 ), ( float )( u0 ), ( float )( v0 ) ); + tex = secondTex; + u0 = tex->getU0(); + v0 = tex->getV0(); + u1 = tex->getU1(); + v1 = tex->getV1(); - t->vertexUV( ( float )( x1_ ), ( float )( y + h ), ( float )( z + 0 ), ( float )( u1 ), ( float )( v0 ) ); - t->vertexUV( ( float )( x1 ), ( float )( y + 0 ), ( float )( z + 0 ), ( float )( u1 ), ( float )( v1 ) ); - t->vertexUV( ( float )( x1 ), ( float )( y + 0 ), ( float )( z + 1 ), ( float )( u0 ), ( float )( v1 ) ); - t->vertexUV( ( float )( x1_ ), ( float )( y + h ), ( float )( z + 1 ), ( float )( u0 ), ( float )( v0 ) ); + t->vertexUV((float)(x + 1), (float)(y + h), (float)(z1_), (float)(u1), + (float)(v0)); + t->vertexUV((float)(x + 1), (float)(y + 0), (float)(z1), (float)(u1), + (float)(v1)); + t->vertexUV((float)(x + 0), (float)(y + 0), (float)(z1), (float)(u0), + (float)(v1)); + t->vertexUV((float)(x + 0), (float)(y + h), (float)(z1_), (float)(u0), + (float)(v0)); - tex = secondTex; - u0 = tex->getU0(); - v0 = tex->getV0(); - u1 = tex->getU1(); - v1 = tex->getV1(); + t->vertexUV((float)(x + 0), (float)(y + h), (float)(z0_), (float)(u1), + (float)(v0)); + t->vertexUV((float)(x + 0), (float)(y + 0), (float)(z0), (float)(u1), + (float)(v1)); + t->vertexUV((float)(x + 1), (float)(y + 0), (float)(z0), (float)(u0), + (float)(v1)); + t->vertexUV((float)(x + 1), (float)(y + h), (float)(z0_), (float)(u0), + (float)(v0)); - t->vertexUV( ( float )( x + 1 ), ( float )( y + h ), ( float )( z1_ ), ( float )( u1 ), ( float )( v0 ) ); - t->vertexUV( ( float )( x + 1 ), ( float )( y + 0 ), ( float )( z1 ), ( float )( u1 ), ( float )( v1 ) ); - t->vertexUV( ( float )( x + 0 ), ( float )( y + 0 ), ( float )( z1 ), ( float )( u0 ), ( float )( v1 ) ); - t->vertexUV( ( float )( x + 0 ), ( float )( y + h ), ( float )( z1_ ), ( float )( u0 ), ( float )( v0 ) ); + x0 = x + 0.5f - 0.5f; + x1 = x + 0.5f + 0.5f; + z0 = z + 0.5f - 0.5f; + z1 = z + 0.5f + 0.5f; - t->vertexUV( ( float )( x + 0 ), ( float )( y + h ), ( float )( z0_ ), ( float )( u1 ), ( float )( v0 ) ); - t->vertexUV( ( float )( x + 0 ), ( float )( y + 0 ), ( float )( z0 ), ( float )( u1 ), ( float )( v1 ) ); - t->vertexUV( ( float )( x + 1 ), ( float )( y + 0 ), ( float )( z0 ), ( float )( u0 ), ( float )( v1 ) ); - t->vertexUV( ( float )( x + 1 ), ( float )( y + h ), ( float )( z0_ ), ( float )( u0 ), ( float )( v0 ) ); + x0_ = x + 0.5f - 0.4f; + x1_ = x + 0.5f + 0.4f; + z0_ = z + 0.5f - 0.4f; + z1_ = z + 0.5f + 0.4f; - x0 = x + 0.5f - 0.5f; - x1 = x + 0.5f + 0.5f; - z0 = z + 0.5f - 0.5f; - z1 = z + 0.5f + 0.5f; + t->vertexUV((float)(x0_), (float)(y + h), (float)(z + 0), (float)(u0), + (float)(v0)); + t->vertexUV((float)(x0), (float)(y + 0), (float)(z + 0), (float)(u0), + (float)(v1)); + t->vertexUV((float)(x0), (float)(y + 0), (float)(z + 1), (float)(u1), + (float)(v1)); + t->vertexUV((float)(x0_), (float)(y + h), (float)(z + 1), (float)(u1), + (float)(v0)); - x0_ = x + 0.5f - 0.4f; - x1_ = x + 0.5f + 0.4f; - z0_ = z + 0.5f - 0.4f; - z1_ = z + 0.5f + 0.4f; + t->vertexUV((float)(x1_), (float)(y + h), (float)(z + 1), (float)(u0), + (float)(v0)); + t->vertexUV((float)(x1), (float)(y + 0), (float)(z + 1), (float)(u0), + (float)(v1)); + t->vertexUV((float)(x1), (float)(y + 0), (float)(z + 0), (float)(u1), + (float)(v1)); + t->vertexUV((float)(x1_), (float)(y + h), (float)(z + 0), (float)(u1), + (float)(v0)); - t->vertexUV( ( float )( x0_ ), ( float )( y + h ), ( float )( z + 0 ), ( float )( u0 ), ( float )( v0 ) ); - t->vertexUV( ( float )( x0 ), ( float )( y + 0 ), ( float )( z + 0 ), ( float )( u0 ), ( float )( v1 ) ); - t->vertexUV( ( float )( x0 ), ( float )( y + 0 ), ( float )( z + 1 ), ( float )( u1 ), ( float )( v1 ) ); - t->vertexUV( ( float )( x0_ ), ( float )( y + h ), ( float )( z + 1 ), ( float )( u1 ), ( float )( v0 ) ); + tex = firstTex; + u0 = tex->getU0(); + v0 = tex->getV0(); + u1 = tex->getU1(); + v1 = tex->getV1(); - t->vertexUV( ( float )( x1_ ), ( float )( y + h ), ( float )( z + 1 ), ( float )( u0 ), ( float )( v0 ) ); - t->vertexUV( ( float )( x1 ), ( float )( y + 0 ), ( float )( z + 1 ), ( float )( u0 ), ( float )( v1 ) ); - t->vertexUV( ( float )( x1 ), ( float )( y + 0 ), ( float )( z + 0 ), ( float )( u1 ), ( float )( v1 ) ); - t->vertexUV( ( float )( x1_ ), ( float )( y + h ), ( float )( z + 0 ), ( float )( u1 ), ( float )( v0 ) ); + t->vertexUV((float)(x + 0), (float)(y + h), (float)(z1_), (float)(u0), + (float)(v0)); + t->vertexUV((float)(x + 0), (float)(y + 0), (float)(z1), (float)(u0), + (float)(v1)); + t->vertexUV((float)(x + 1), (float)(y + 0), (float)(z1), (float)(u1), + (float)(v1)); + t->vertexUV((float)(x + 1), (float)(y + h), (float)(z1_), (float)(u1), + (float)(v0)); - tex = firstTex; - u0 = tex->getU0(); - v0 = tex->getV0(); - u1 = tex->getU1(); - v1 = tex->getV1(); + t->vertexUV((float)(x + 1), (float)(y + h), (float)(z0_), (float)(u0), + (float)(v0)); + t->vertexUV((float)(x + 1), (float)(y + 0), (float)(z0), (float)(u0), + (float)(v1)); + t->vertexUV((float)(x + 0), (float)(y + 0), (float)(z0), (float)(u1), + (float)(v1)); + t->vertexUV((float)(x + 0), (float)(y + h), (float)(z0_), (float)(u1), + (float)(v0)); + } else { + float r = 0.2f; + float yo = 1 / 16.0f; + if (((x + y + z) & 1) == 1) { + tex = secondTex; + u0 = tex->getU0(); + v0 = tex->getV0(); + u1 = tex->getU1(); + v1 = tex->getV1(); + } + if (((x / 2 + y / 2 + z / 2) & 1) == 1) { + float tmp = u1; + u1 = u0; + u0 = tmp; + } + if (FireTile_SPU::canBurn(level, x - 1, y, z)) { + t->vertexUV((float)(x + r), (float)(y + h + yo), (float)(z + 1.0f), + (float)(u1), (float)(v0)); + t->vertexUV((float)(x + 0.0f), (float)(y + 0.0f + yo), + (float)(z + 1.0f), (float)(u1), (float)(v1)); + t->vertexUV((float)(x + 0.0f), (float)(y + 0.0f + yo), + (float)(z + 0.0f), (float)(u0), (float)(v1)); + t->vertexUV((float)(x + r), (float)(y + h + yo), (float)(z + 0.0f), + (float)(u0), (float)(v0)); - t->vertexUV( ( float )( x + 0 ), ( float )( y + h ), ( float )( z1_ ), ( float )( u0 ), ( float )( v0 ) ); - t->vertexUV( ( float )( x + 0 ), ( float )( y + 0 ), ( float )( z1 ), ( float )( u0 ), ( float )( v1 ) ); - t->vertexUV( ( float )( x + 1 ), ( float )( y + 0 ), ( float )( z1 ), ( float )( u1 ), ( float )( v1 ) ); - t->vertexUV( ( float )( x + 1 ), ( float )( y + h ), ( float )( z1_ ), ( float )( u1 ), ( float )( v0 ) ); + t->vertexUV((float)(x + r), (float)(y + h + yo), (float)(z + 0.0f), + (float)(u0), (float)(v0)); + t->vertexUV((float)(x + 0.0f), (float)(y + 0.0f + yo), + (float)(z + 0.0f), (float)(u0), (float)(v1)); + t->vertexUV((float)(x + 0.0f), (float)(y + 0.0f + yo), + (float)(z + 1.0f), (float)(u1), (float)(v1)); + t->vertexUV((float)(x + r), (float)(y + h + yo), (float)(z + 1.0f), + (float)(u1), (float)(v0)); + } + if (FireTile_SPU::canBurn(level, x + 1, y, z)) { + t->vertexUV((float)(x + 1 - r), (float)(y + h + yo), + (float)(z + 0.0f), (float)(u0), (float)(v0)); + t->vertexUV((float)(x + 1 - 0), (float)(y + 0 + yo), + (float)(z + 0.0f), (float)(u0), (float)(v1)); + t->vertexUV((float)(x + 1 - 0), (float)(y + 0 + yo), + (float)(z + 1.0f), (float)(u1), (float)(v1)); + t->vertexUV((float)(x + 1 - r), (float)(y + h + yo), + (float)(z + 1.0f), (float)(u1), (float)(v0)); - t->vertexUV( ( float )( x + 1 ), ( float )( y + h ), ( float )( z0_ ), ( float )( u0 ), ( float )( v0 ) ); - t->vertexUV( ( float )( x + 1 ), ( float )( y + 0 ), ( float )( z0 ), ( float )( u0 ), ( float )( v1 ) ); - t->vertexUV( ( float )( x + 0 ), ( float )( y + 0 ), ( float )( z0 ), ( float )( u1 ), ( float )( v1 ) ); - t->vertexUV( ( float )( x + 0 ), ( float )( y + h ), ( float )( z0_ ), ( float )( u1 ), ( float )( v0 ) ); - } - else - { - float r = 0.2f; - float yo = 1 / 16.0f; - if ( ( ( x + y + z ) & 1 ) == 1 ) - { - tex = secondTex; - u0 = tex->getU0(); - v0 = tex->getV0(); - u1 = tex->getU1(); - v1 = tex->getV1(); - } - if ( ( ( x / 2 + y / 2 + z / 2 ) & 1 ) == 1 ) - { - float tmp = u1; - u1 = u0; - u0 = tmp; - } - if ( FireTile_SPU::canBurn( level, x - 1, y, z ) ) - { - t->vertexUV( ( float )( x + r ), ( float )( y + h + yo ), ( float )( z + - 1.0f ), ( float )( u1 ), ( float )( v0 ) ); - t->vertexUV( ( float )( x + 0.0f ), ( float )( y + 0.0f + yo ), ( float )( z + - 1.0f ), ( float )( u1 ), ( float )( v1 ) ); - t->vertexUV( ( float )( x + 0.0f ), ( float )( y + 0.0f + yo ), ( float )( z + - 0.0f ), ( float )( u0 ), ( float )( v1 ) ); - t->vertexUV( ( float )( x + r ), ( float )( y + h + yo ), ( float )( z + - 0.0f ), ( float )( u0 ), ( float )( v0 ) ); + t->vertexUV((float)(x + 1.0f - r), (float)(y + h + yo), + (float)(z + 1.0f), (float)(u1), (float)(v0)); + t->vertexUV((float)(x + 1.0f - 0.0f), (float)(y + 0.0f + yo), + (float)(z + 1.0f), (float)(u1), (float)(v1)); + t->vertexUV((float)(x + 1.0f - 0), (float)(y + 0.0f + yo), + (float)(z + 0.0f), (float)(u0), (float)(v1)); + t->vertexUV((float)(x + 1.0f - r), (float)(y + h + yo), + (float)(z + 0.0f), (float)(u0), (float)(v0)); + } + if (FireTile_SPU::canBurn(level, x, y, z - 1)) { + t->vertexUV((float)(x + 0.0f), (float)(y + h + yo), (float)(z + r), + (float)(u1), (float)(v0)); + t->vertexUV((float)(x + 0.0f), (float)(y + 0.0f + yo), + (float)(z + 0.0f), (float)(u1), (float)(v1)); + t->vertexUV((float)(x + 1.0f), (float)(y + 0.0f + yo), + (float)(z + 0.0f), (float)(u0), (float)(v1)); + t->vertexUV((float)(x + 1.0f), (float)(y + h + yo), (float)(z + r), + (float)(u0), (float)(v0)); - t->vertexUV( ( float )( x + r ), ( float )( y + h + yo ), ( float )( z + - 0.0f ), ( float )( u0 ), ( float )( v0 ) ); - t->vertexUV( ( float )( x + 0.0f ), ( float )( y + 0.0f + yo ), ( float )( z + - 0.0f ), ( float )( u0 ), ( float )( v1 ) ); - t->vertexUV( ( float )( x + 0.0f ), ( float )( y + 0.0f + yo ), ( float )( z + - 1.0f ), ( float )( u1 ), ( float )( v1 ) ); - t->vertexUV( ( float )( x + r ), ( float )( y + h + yo ), ( float )( z + - 1.0f ), ( float )( u1 ), ( float )( v0 ) ); - } - if ( FireTile_SPU::canBurn( level, x + 1, y, z ) ) - { - t->vertexUV( ( float )( x + 1 - r ), ( float )( y + h + yo ), ( float )( z + - 0.0f ), ( float )( u0 ), ( float )( v0 ) ); - t->vertexUV( ( float )( x + 1 - 0 ), ( float )( y + 0 + yo ), ( float )( z + - 0.0f ), ( float )( u0 ), ( float )( v1 ) ); - t->vertexUV( ( float )( x + 1 - 0 ), ( float )( y + 0 + yo ), ( float )( z + - 1.0f ), ( float )( u1 ), ( float )( v1 ) ); - t->vertexUV( ( float )( x + 1 - r ), ( float )( y + h + yo ), ( float )( z + - 1.0f ), ( float )( u1 ), ( float )( v0 ) ); + t->vertexUV((float)(x + 1.0f), (float)(y + h + yo), (float)(z + r), + (float)(u0), (float)(v0)); + t->vertexUV((float)(x + 1.0f), (float)(y + 0.0f + yo), + (float)(z + 0.0f), (float)(u0), (float)(v1)); + t->vertexUV((float)(x + 0.0f), (float)(y + 0.0f + yo), + (float)(z + 0.0f), (float)(u1), (float)(v1)); + t->vertexUV((float)(x + 0.0f), (float)(y + h + yo), (float)(z + r), + (float)(u1), (float)(v0)); + } + if (FireTile_SPU::canBurn(level, x, y, z + 1)) { + t->vertexUV((float)(x + 1.0f), (float)(y + h + yo), + (float)(z + 1.0f - r), (float)(u0), (float)(v0)); + t->vertexUV((float)(x + 1.0f), (float)(y + 0.0f + yo), + (float)(z + 1.0f - 0.0f), (float)(u0), (float)(v1)); + t->vertexUV((float)(x + 0.0f), (float)(y + 0.0f + yo), + (float)(z + 1.0f - 0.0f), (float)(u1), (float)(v1)); + t->vertexUV((float)(x + 0.0f), (float)(y + h + yo), + (float)(z + 1.0f - r), (float)(u1), (float)(v0)); - t->vertexUV( ( float )( x + 1.0f - r ), ( float )( y + h + yo ), ( float )( z + - 1.0f ), ( float )( u1 ), ( float )( v0 ) ); - t->vertexUV( ( float )( x + 1.0f - 0.0f ), ( float )( y + 0.0f + yo ), ( float )( z + - 1.0f ), ( float )( u1 ), ( float )( v1 ) ); - t->vertexUV( ( float )( x + 1.0f - 0 ), ( float )( y + 0.0f + yo ), ( float )( z + - 0.0f ), ( float )( u0 ), ( float )( v1 ) ); - t->vertexUV( ( float )( x + 1.0f - r ), ( float )( y + h + yo ), ( float )( z + - 0.0f ), ( float )( u0 ), ( float )( v0 ) ); - } - if ( FireTile_SPU::canBurn( level, x, y, z - 1 ) ) - { - t->vertexUV( ( float )( x + 0.0f ), ( float )( y + h + yo ), ( float )( z + - r ), ( float )( u1 ), ( float )( v0 ) ); - t->vertexUV( ( float )( x + 0.0f ), ( float )( y + 0.0f + yo ), ( float )( z + - 0.0f ), ( float )( u1 ), ( float )( v1 ) ); - t->vertexUV( ( float )( x + 1.0f ), ( float )( y + 0.0f + yo ), ( float )( z + - 0.0f ), ( float )( u0 ), ( float )( v1 ) ); - t->vertexUV( ( float )( x + 1.0f ), ( float )( y + h + yo ), ( float )( z + - r ), ( float )( u0 ), ( float )( v0 ) ); + t->vertexUV((float)(x + 0.0f), (float)(y + h + yo), + (float)(z + 1.0f - r), (float)(u1), (float)(v0)); + t->vertexUV((float)(x + 0.0f), (float)(y + 0.0f + yo), + (float)(z + 1.0f - 0.0f), (float)(u1), (float)(v1)); + t->vertexUV((float)(x + 1.0f), (float)(y + 0.0f + yo), + (float)(z + 1.0f - 0.0f), (float)(u0), (float)(v1)); + t->vertexUV((float)(x + 1.0f), (float)(y + h + yo), + (float)(z + 1.0f - r), (float)(u0), (float)(v0)); + } + if (FireTile_SPU::canBurn(level, x, y + 1.0f, z)) { + float x0 = x + 0.5f + 0.5f; + float x1 = x + 0.5f - 0.5f; + float z0 = z + 0.5f + 0.5f; + float z1 = z + 0.5f - 0.5f; - t->vertexUV( ( float )( x + 1.0f ), ( float )( y + h + yo ), ( float )( z + - r ), ( float )( u0 ), ( float )( v0 ) ); - t->vertexUV( ( float )( x + 1.0f ), ( float )( y + 0.0f + yo ), ( float )( z + - 0.0f ), ( float )( u0 ), ( float )( v1 ) ); - t->vertexUV( ( float )( x + 0.0f ), ( float )( y + 0.0f + yo ), ( float )( z + - 0.0f ), ( float )( u1 ), ( float )( v1 ) ); - t->vertexUV( ( float )( x + 0.0f ), ( float )( y + h + yo ), ( float )( z + - r ), ( float )( u1 ), ( float )( v0 ) ); - } - if ( FireTile_SPU::canBurn( level, x, y, z + 1 ) ) - { - t->vertexUV( ( float )( x + 1.0f ), ( float )( y + h + yo ), ( float )( z + 1.0f - - r ), ( float )( u0 ), ( float )( v0 ) ); - t->vertexUV( ( float )( x + 1.0f ), ( float )( y + 0.0f + yo ), ( float )( z + 1.0f - - 0.0f ), ( float )( u0 ), ( float )( v1 ) ); - t->vertexUV( ( float )( x + 0.0f ), ( float )( y + 0.0f + yo ), ( float )( z + 1.0f - - 0.0f ), ( float )( u1 ), ( float )( v1 ) ); - t->vertexUV( ( float )( x + 0.0f ), ( float )( y + h + yo ), ( float )( z + 1.0f - - r ), ( float )( u1 ), ( float )( v0 ) ); + float x0_ = x + 0.5f - 0.5f; + float x1_ = x + 0.5f + 0.5f; + float z0_ = z + 0.5f - 0.5f; + float z1_ = z + 0.5f + 0.5f; - t->vertexUV( ( float )( x + 0.0f ), ( float )( y + h + yo ), ( float )( z + 1.0f - - r ), ( float )( u1 ), ( float )( v0 ) ); - t->vertexUV( ( float )( x + 0.0f ), ( float )( y + 0.0f + yo ), ( float )( z + 1.0f - - 0.0f ), ( float )( u1 ), ( float )( v1 ) ); - t->vertexUV( ( float )( x + 1.0f ), ( float )( y + 0.0f + yo ), ( float )( z + 1.0f - - 0.0f ), ( float )( u0 ), ( float )( v1 ) ); - t->vertexUV( ( float )( x + 1.0f ), ( float )( y + h + yo ), ( float )( z + 1.0f - - r ), ( float )( u0 ), ( float )( v0 ) ); - } - if ( FireTile_SPU::canBurn( level, x, y + 1.0f, z ) ) - { - float x0 = x + 0.5f + 0.5f; - float x1 = x + 0.5f - 0.5f; - float z0 = z + 0.5f + 0.5f; - float z1 = z + 0.5f - 0.5f; + tex = firstTex; + u0 = tex->getU0(); + v0 = tex->getV0(); + u1 = tex->getU1(); + v1 = tex->getV1(); - float x0_ = x + 0.5f - 0.5f; - float x1_ = x + 0.5f + 0.5f; - float z0_ = z + 0.5f - 0.5f; - float z1_ = z + 0.5f + 0.5f; + y += 1; + h = -0.2f; - tex = firstTex; - u0 = tex->getU0(); - v0 = tex->getV0(); - u1 = tex->getU1(); - v1 = tex->getV1(); + if (((x + y + z) & 1) == 0) { + t->vertexUV((float)(x0_), (float)(y + h), (float)(z + 0), + (float)(u1), (float)(v0)); + t->vertexUV((float)(x0), (float)(y + 0), (float)(z + 0), + (float)(u1), (float)(v1)); + t->vertexUV((float)(x0), (float)(y + 0), (float)(z + 1), + (float)(u0), (float)(v1)); + t->vertexUV((float)(x0_), (float)(y + h), (float)(z + 1), + (float)(u0), (float)(v0)); - y += 1; - h = -0.2f; + tex = secondTex; + u0 = tex->getU0(); + v0 = tex->getV0(); + u1 = tex->getU1(); + v1 = tex->getV1(); - if ( ( ( x + y + z ) & 1 ) == 0 ) - { - t->vertexUV( ( float )( x0_ ), ( float )( y + h ), ( float )( z + - 0 ), ( float )( u1 ), ( float )( v0 ) ); - t->vertexUV( ( float )( x0 ), ( float )( y + 0 ), ( float )( z + - 0 ), ( float )( u1 ), ( float )( v1 ) ); - t->vertexUV( ( float )( x0 ), ( float )( y + 0 ), ( float )( z + - 1 ), ( float )( u0 ), ( float )( v1 ) ); - t->vertexUV( ( float )( x0_ ), ( float )( y + h ), ( float )( z + - 1 ), ( float )( u0 ), ( float )( v0 ) ); + t->vertexUV((float)(x1_), (float)(y + h), (float)(z + 1.0f), + (float)(u1), (float)(v0)); + t->vertexUV((float)(x1), (float)(y + 0.0f), (float)(z + 1.0f), + (float)(u1), (float)(v1)); + t->vertexUV((float)(x1), (float)(y + 0.0f), (float)(z + 0), + (float)(u0), (float)(v1)); + t->vertexUV((float)(x1_), (float)(y + h), (float)(z + 0), + (float)(u0), (float)(v0)); + } else { + t->vertexUV((float)(x + 0.0f), (float)(y + h), (float)(z1_), + (float)(u1), (float)(v0)); + t->vertexUV((float)(x + 0.0f), (float)(y + 0.0f), (float)(z1), + (float)(u1), (float)(v1)); + t->vertexUV((float)(x + 1.0f), (float)(y + 0.0f), (float)(z1), + (float)(u0), (float)(v1)); + t->vertexUV((float)(x + 1.0f), (float)(y + h), (float)(z1_), + (float)(u0), (float)(v0)); - tex = secondTex; - u0 = tex->getU0(); - v0 = tex->getV0(); - u1 = tex->getU1(); - v1 = tex->getV1(); + tex = secondTex; + u0 = tex->getU0(); + v0 = tex->getV0(); + u1 = tex->getU1(); + v1 = tex->getV1(); - t->vertexUV( ( float )( x1_ ), ( float )( y + h ), ( float )( z + - 1.0f ), ( float )( u1 ), ( float )( v0 ) ); - t->vertexUV( ( float )( x1 ), ( float )( y + 0.0f ), ( float )( z + - 1.0f ), ( float )( u1 ), ( float )( v1 ) ); - t->vertexUV( ( float )( x1 ), ( float )( y + 0.0f ), ( float )( z + - 0 ), ( float )( u0 ), ( float )( v1 ) ); - t->vertexUV( ( float )( x1_ ), ( float )( y + h ), ( float )( z + - 0 ), ( float )( u0 ), ( float )( v0 ) ); - } - else - { - t->vertexUV( ( float )( x + 0.0f ), ( float )( y + - h ), ( float )( z1_ ), ( float )( u1 ), ( float )( v0 ) ); - t->vertexUV( ( float )( x + 0.0f ), ( float )( y + - 0.0f ), ( float )( z1 ), ( float )( u1 ), ( float )( v1 ) ); - t->vertexUV( ( float )( x + 1.0f ), ( float )( y + - 0.0f ), ( float )( z1 ), ( float )( u0 ), ( float )( v1 ) ); - t->vertexUV( ( float )( x + 1.0f ), ( float )( y + - h ), ( float )( z1_ ), ( float )( u0 ), ( float )( v0 ) ); - - tex = secondTex; - u0 = tex->getU0(); - v0 = tex->getV0(); - u1 = tex->getU1(); - v1 = tex->getV1(); - - t->vertexUV( ( float )( x + 1.0f ), ( float )( y + - h ), ( float )( z0_ ), ( float )( u1 ), ( float )( v0 ) ); - t->vertexUV( ( float )( x + 1.0f ), ( float )( y + - 0.0f ), ( float )( z0 ), ( float )( u1 ), ( float )( v1 ) ); - t->vertexUV( ( float )( x + 0.0f ), ( float )( y + - 0.0f ), ( float )( z0 ), ( float )( u0 ), ( float )( v1 ) ); - t->vertexUV( ( float )( x + 0.0f ), ( float )( y + - h ), ( float )( z0_ ), ( float )( u0 ), ( float )( v0 ) ); - } - } - } - return true; + t->vertexUV((float)(x + 1.0f), (float)(y + h), (float)(z0_), + (float)(u1), (float)(v0)); + t->vertexUV((float)(x + 1.0f), (float)(y + 0.0f), (float)(z0), + (float)(u1), (float)(v1)); + t->vertexUV((float)(x + 0.0f), (float)(y + 0.0f), (float)(z0), + (float)(u0), (float)(v1)); + t->vertexUV((float)(x + 0.0f), (float)(y + h), (float)(z0_), + (float)(u0), (float)(v0)); + } + } + } + return true; } -bool TileRenderer_SPU::tesselateDustInWorld( Tile_SPU* tt, int x, int y, int z ) -{ +bool TileRenderer_SPU::tesselateDustInWorld(Tile_SPU* tt, int x, int y, int z) { #ifdef DISABLE_TESS_FUNCS - Tesselator_SPU* t = getTesselator(); + Tesselator_SPU* t = getTesselator(); - int data = level->getData( x, y, z ); - Icon_SPU *crossTexture = RedStoneDustTile_SPU::getTextureByName(RedStoneDustTile_SPU::TEXTURE_CROSS); - Icon_SPU *lineTexture = RedStoneDustTile_SPU::getTextureByName(RedStoneDustTile_SPU::TEXTURE_LINE); - Icon_SPU *crossTextureOverlay = RedStoneDustTile_SPU::getTextureByName(RedStoneDustTile_SPU::TEXTURE_CROSS_OVERLAY); - Icon_SPU *lineTextureOverlay = RedStoneDustTile_SPU::getTextureByName(RedStoneDustTile_SPU::TEXTURE_LINE_OVERLAY); + int data = level->getData(x, y, z); + Icon_SPU* crossTexture = RedStoneDustTile_SPU::getTextureByName( + RedStoneDustTile_SPU::TEXTURE_CROSS); + Icon_SPU* lineTexture = RedStoneDustTile_SPU::getTextureByName( + RedStoneDustTile_SPU::TEXTURE_LINE); + Icon_SPU* crossTextureOverlay = RedStoneDustTile_SPU::getTextureByName( + RedStoneDustTile_SPU::TEXTURE_CROSS_OVERLAY); + Icon_SPU* lineTextureOverlay = RedStoneDustTile_SPU::getTextureByName( + RedStoneDustTile_SPU::TEXTURE_LINE_OVERLAY); - float br; - if ( SharedConstants::TEXTURE_LIGHTING ) - { - t->tex2( tt->getLightColor( level, x, y, z ) ); - br = 1; - } - else - { - br = tt->getBrightness( level, x, y, z ); - } - float pow = ( data / 15.0f ); - float red = pow * 0.6f + 0.4f; - if ( data == 0 ) red = 0.3f; + float br; + if (SharedConstants::TEXTURE_LIGHTING) { + t->tex2(tt->getLightColor(level, x, y, z)); + br = 1; + } else { + br = tt->getBrightness(level, x, y, z); + } + float pow = (data / 15.0f); + float red = pow * 0.6f + 0.4f; + if (data == 0) red = 0.3f; - float green = pow * pow * 0.7f - 0.5f; - float blue = pow * pow * 0.6f - 0.7f; - if ( green < 0 ) green = 0; - if ( blue < 0 ) blue = 0; + float green = pow * pow * 0.7f - 0.5f; + float blue = pow * pow * 0.6f - 0.7f; + if (green < 0) green = 0; + if (blue < 0) blue = 0; - if ( SharedConstants::TEXTURE_LIGHTING ) - { - t->color( red, green, blue ); - } - else - { - t->color( br * red, br * green, br * blue ); - } - const float dustOffset = 0.25f / 16.0f; - const float overlayOffset = 0.25f / 16.0f; + if (SharedConstants::TEXTURE_LIGHTING) { + t->color(red, green, blue); + } else { + t->color(br * red, br * green, br * blue); + } + const float dustOffset = 0.25f / 16.0f; + const float overlayOffset = 0.25f / 16.0f; - bool w = RedStoneDustTile_SPU::shouldConnectTo( level, x - 1, y, z, Direction::WEST ) - || ( !level->isSolidBlockingTile( x - 1, y, z ) && RedStoneDustTile_SPU::shouldConnectTo( level, x - 1, y - 1, z, - Direction::UNDEFINED ) ); - bool e = RedStoneDustTile_SPU::shouldConnectTo( level, x + 1, y, z, Direction::EAST ) - || ( !level->isSolidBlockingTile( x + 1, y, z ) && RedStoneDustTile_SPU::shouldConnectTo( level, x + 1, y - 1, z, - Direction::UNDEFINED ) ); - bool n = RedStoneDustTile_SPU::shouldConnectTo( level, x, y, z - 1, Direction::NORTH ) - || ( !level->isSolidBlockingTile( x, y, z - 1 ) && RedStoneDustTile_SPU::shouldConnectTo( level, x, y - 1, z - 1, - Direction::UNDEFINED ) ); - bool s = RedStoneDustTile_SPU::shouldConnectTo( level, x, y, z + 1, Direction::SOUTH ) - || ( !level->isSolidBlockingTile( x, y, z + 1 ) && RedStoneDustTile_SPU::shouldConnectTo( level, x, y - 1, z + 1, - Direction::UNDEFINED ) ); - if ( !level->isSolidBlockingTile( x, y + 1, z ) ) - { - if ( level->isSolidBlockingTile( x - 1, y, z ) && RedStoneDustTile_SPU::shouldConnectTo( level, x - 1, y + 1, z, - Direction::UNDEFINED ) ) w - = true; - if ( level->isSolidBlockingTile( x + 1, y, z ) && RedStoneDustTile_SPU::shouldConnectTo( level, x + 1, y + 1, z, - Direction::UNDEFINED ) ) e - = true; - if ( level->isSolidBlockingTile( x, y, z - 1 ) && RedStoneDustTile_SPU::shouldConnectTo( level, x, y + 1, z - 1, - Direction::UNDEFINED ) ) n - = true; - if ( level->isSolidBlockingTile( x, y, z + 1 ) && RedStoneDustTile_SPU::shouldConnectTo( level, x, y + 1, z + 1, - Direction::UNDEFINED ) ) s - = true; - } - float x0 = ( float )( x + 0.0f ); - float x1 = ( float )( x + 1.0f ); - float z0 = ( float )( z + 0.0f ); - float z1 = ( float )( z + 1.0f ); + bool w = RedStoneDustTile_SPU::shouldConnectTo(level, x - 1, y, z, + Direction::WEST) || + (!level->isSolidBlockingTile(x - 1, y, z) && + RedStoneDustTile_SPU::shouldConnectTo(level, x - 1, y - 1, z, + Direction::UNDEFINED)); + bool e = RedStoneDustTile_SPU::shouldConnectTo(level, x + 1, y, z, + Direction::EAST) || + (!level->isSolidBlockingTile(x + 1, y, z) && + RedStoneDustTile_SPU::shouldConnectTo(level, x + 1, y - 1, z, + Direction::UNDEFINED)); + bool n = RedStoneDustTile_SPU::shouldConnectTo(level, x, y, z - 1, + Direction::NORTH) || + (!level->isSolidBlockingTile(x, y, z - 1) && + RedStoneDustTile_SPU::shouldConnectTo(level, x, y - 1, z - 1, + Direction::UNDEFINED)); + bool s = RedStoneDustTile_SPU::shouldConnectTo(level, x, y, z + 1, + Direction::SOUTH) || + (!level->isSolidBlockingTile(x, y, z + 1) && + RedStoneDustTile_SPU::shouldConnectTo(level, x, y - 1, z + 1, + Direction::UNDEFINED)); + if (!level->isSolidBlockingTile(x, y + 1, z)) { + if (level->isSolidBlockingTile(x - 1, y, z) && + RedStoneDustTile_SPU::shouldConnectTo(level, x - 1, y + 1, z, + Direction::UNDEFINED)) + w = true; + if (level->isSolidBlockingTile(x + 1, y, z) && + RedStoneDustTile_SPU::shouldConnectTo(level, x + 1, y + 1, z, + Direction::UNDEFINED)) + e = true; + if (level->isSolidBlockingTile(x, y, z - 1) && + RedStoneDustTile_SPU::shouldConnectTo(level, x, y + 1, z - 1, + Direction::UNDEFINED)) + n = true; + if (level->isSolidBlockingTile(x, y, z + 1) && + RedStoneDustTile_SPU::shouldConnectTo(level, x, y + 1, z + 1, + Direction::UNDEFINED)) + s = true; + } + float x0 = (float)(x + 0.0f); + float x1 = (float)(x + 1.0f); + float z0 = (float)(z + 0.0f); + float z1 = (float)(z + 1.0f); - int pic = 0; - if ( ( w || e ) && ( !n && !s ) ) pic = 1; - if ( ( n || s ) && ( !e && !w ) ) pic = 2; + int pic = 0; + if ((w || e) && (!n && !s)) pic = 1; + if ((n || s) && (!e && !w)) pic = 2; - if ( pic == 0 ) - { -// if ( e || n || s || w ) - int u0 = 0; - int v0 = 0; - int u1 = SharedConstants::WORLD_RESOLUTION; - int v1 = SharedConstants::WORLD_RESOLUTION; + if (pic == 0) { + // if ( e || n || s || w ) + int u0 = 0; + int v0 = 0; + int u1 = SharedConstants::WORLD_RESOLUTION; + int v1 = SharedConstants::WORLD_RESOLUTION; - int cutDistance = 5; - if (!w) x0 += cutDistance / (float) SharedConstants::WORLD_RESOLUTION; - if (!w) u0 += cutDistance; - if (!e) x1 -= cutDistance / (float) SharedConstants::WORLD_RESOLUTION; - if (!e) u1 -= cutDistance; - if (!n) z0 += cutDistance / (float) SharedConstants::WORLD_RESOLUTION; - if (!n) v0 += cutDistance; - if (!s) z1 -= cutDistance / (float) SharedConstants::WORLD_RESOLUTION; - if (!s) v1 -= cutDistance; - t->vertexUV( ( float )( x1 ), ( float )( y + dustOffset ), ( float )( z1 ), crossTexture->getU(u1), crossTexture->getV(v1) ); - t->vertexUV( ( float )( x1 ), ( float )( y + dustOffset ), ( float )( z0 ), crossTexture->getU(u1), crossTexture->getV(v0) ); - t->vertexUV( ( float )( x0 ), ( float )( y + dustOffset ), ( float )( z0 ), crossTexture->getU(u0), crossTexture->getV(v0) ); - t->vertexUV( ( float )( x0 ), ( float )( y + dustOffset ), ( float )( z1 ), crossTexture->getU(u0), crossTexture->getV(v1) ); + int cutDistance = 5; + if (!w) x0 += cutDistance / (float)SharedConstants::WORLD_RESOLUTION; + if (!w) u0 += cutDistance; + if (!e) x1 -= cutDistance / (float)SharedConstants::WORLD_RESOLUTION; + if (!e) u1 -= cutDistance; + if (!n) z0 += cutDistance / (float)SharedConstants::WORLD_RESOLUTION; + if (!n) v0 += cutDistance; + if (!s) z1 -= cutDistance / (float)SharedConstants::WORLD_RESOLUTION; + if (!s) v1 -= cutDistance; + t->vertexUV((float)(x1), (float)(y + dustOffset), (float)(z1), + crossTexture->getU(u1), crossTexture->getV(v1)); + t->vertexUV((float)(x1), (float)(y + dustOffset), (float)(z0), + crossTexture->getU(u1), crossTexture->getV(v0)); + t->vertexUV((float)(x0), (float)(y + dustOffset), (float)(z0), + crossTexture->getU(u0), crossTexture->getV(v0)); + t->vertexUV((float)(x0), (float)(y + dustOffset), (float)(z1), + crossTexture->getU(u0), crossTexture->getV(v1)); - t->color( br, br, br ); - t->vertexUV( ( float )( x1 ), ( float )( y + dustOffset ), ( float )( z1 ), crossTextureOverlay->getU(u1), crossTextureOverlay->getV(v1) ); - t->vertexUV( ( float )( x1 ), ( float )( y + dustOffset ), ( float )( z0 ), crossTextureOverlay->getU(u1), crossTextureOverlay->getV(v0) ); - t->vertexUV( ( float )( x0 ), ( float )( y + dustOffset ), ( float )( z0 ), crossTextureOverlay->getU(u0), crossTextureOverlay->getV(v0) ); - t->vertexUV( ( float )( x0 ), ( float )( y + dustOffset ), ( float )( z1 ), crossTextureOverlay->getU(u0), crossTextureOverlay->getV(v1) ); - } - else if ( pic == 1 ) - { - t->vertexUV( ( float )( x1 ), ( float )( y + dustOffset ), ( float )( z1 ), lineTexture->getU1(), lineTexture->getV1() ); - t->vertexUV( ( float )( x1 ), ( float )( y + dustOffset ), ( float )( z0 ), lineTexture->getU1(), lineTexture->getV0() ); - t->vertexUV( ( float )( x0 ), ( float )( y + dustOffset ), ( float )( z0 ), lineTexture->getU0(), lineTexture->getV0() ); - t->vertexUV( ( float )( x0 ), ( float )( y + dustOffset ), ( float )( z1 ), lineTexture->getU0(), lineTexture->getV1() ); + t->color(br, br, br); + t->vertexUV((float)(x1), (float)(y + dustOffset), (float)(z1), + crossTextureOverlay->getU(u1), + crossTextureOverlay->getV(v1)); + t->vertexUV((float)(x1), (float)(y + dustOffset), (float)(z0), + crossTextureOverlay->getU(u1), + crossTextureOverlay->getV(v0)); + t->vertexUV((float)(x0), (float)(y + dustOffset), (float)(z0), + crossTextureOverlay->getU(u0), + crossTextureOverlay->getV(v0)); + t->vertexUV((float)(x0), (float)(y + dustOffset), (float)(z1), + crossTextureOverlay->getU(u0), + crossTextureOverlay->getV(v1)); + } else if (pic == 1) { + t->vertexUV((float)(x1), (float)(y + dustOffset), (float)(z1), + lineTexture->getU1(), lineTexture->getV1()); + t->vertexUV((float)(x1), (float)(y + dustOffset), (float)(z0), + lineTexture->getU1(), lineTexture->getV0()); + t->vertexUV((float)(x0), (float)(y + dustOffset), (float)(z0), + lineTexture->getU0(), lineTexture->getV0()); + t->vertexUV((float)(x0), (float)(y + dustOffset), (float)(z1), + lineTexture->getU0(), lineTexture->getV1()); - t->color( br, br, br ); - t->vertexUV( ( float )( x1 ), ( float )( y + overlayOffset ), ( float )( z1 ), lineTextureOverlay->getU1(), lineTextureOverlay->getV1() ); - t->vertexUV( ( float )( x1 ), ( float )( y + overlayOffset ), ( float )( z0 ), lineTextureOverlay->getU1(), lineTextureOverlay->getV0() ); - t->vertexUV( ( float )( x0 ), ( float )( y + overlayOffset ), ( float )( z0 ), lineTextureOverlay->getU0(), lineTextureOverlay->getV0() ); - t->vertexUV( ( float )( x0 ), ( float )( y + overlayOffset ), ( float )( z1 ), lineTextureOverlay->getU0(), lineTextureOverlay->getV1() ); - } - else - { - t->vertexUV( ( float )( x1 ), ( float )( y + dustOffset ), ( float )( z1 ), lineTexture->getU1(), lineTexture->getV1() ); - t->vertexUV( ( float )( x1 ), ( float )( y + dustOffset ), ( float )( z0 ), lineTexture->getU0(), lineTexture->getV1() ); - t->vertexUV( ( float )( x0 ), ( float )( y + dustOffset ), ( float )( z0 ), lineTexture->getU0(), lineTexture->getV0() ); - t->vertexUV( ( float )( x0 ), ( float )( y + dustOffset ), ( float )( z1 ), lineTexture->getU1(), lineTexture->getV0() ); + t->color(br, br, br); + t->vertexUV((float)(x1), (float)(y + overlayOffset), (float)(z1), + lineTextureOverlay->getU1(), lineTextureOverlay->getV1()); + t->vertexUV((float)(x1), (float)(y + overlayOffset), (float)(z0), + lineTextureOverlay->getU1(), lineTextureOverlay->getV0()); + t->vertexUV((float)(x0), (float)(y + overlayOffset), (float)(z0), + lineTextureOverlay->getU0(), lineTextureOverlay->getV0()); + t->vertexUV((float)(x0), (float)(y + overlayOffset), (float)(z1), + lineTextureOverlay->getU0(), lineTextureOverlay->getV1()); + } else { + t->vertexUV((float)(x1), (float)(y + dustOffset), (float)(z1), + lineTexture->getU1(), lineTexture->getV1()); + t->vertexUV((float)(x1), (float)(y + dustOffset), (float)(z0), + lineTexture->getU0(), lineTexture->getV1()); + t->vertexUV((float)(x0), (float)(y + dustOffset), (float)(z0), + lineTexture->getU0(), lineTexture->getV0()); + t->vertexUV((float)(x0), (float)(y + dustOffset), (float)(z1), + lineTexture->getU1(), lineTexture->getV0()); - t->color( br, br, br ); - t->vertexUV( ( float )( x1 ), ( float )( y + overlayOffset ), ( float )( z1 ), lineTextureOverlay->getU1(), lineTextureOverlay->getV1() ); - t->vertexUV( ( float )( x1 ), ( float )( y + overlayOffset ), ( float )( z0 ), lineTextureOverlay->getU0(), lineTextureOverlay->getV1() ); - t->vertexUV( ( float )( x0 ), ( float )( y + overlayOffset ), ( float )( z0 ), lineTextureOverlay->getU0(), lineTextureOverlay->getV0() ); - t->vertexUV( ( float )( x0 ), ( float )( y + overlayOffset ), ( float )( z1 ), lineTextureOverlay->getU1(), lineTextureOverlay->getV0() ); - } + t->color(br, br, br); + t->vertexUV((float)(x1), (float)(y + overlayOffset), (float)(z1), + lineTextureOverlay->getU1(), lineTextureOverlay->getV1()); + t->vertexUV((float)(x1), (float)(y + overlayOffset), (float)(z0), + lineTextureOverlay->getU0(), lineTextureOverlay->getV1()); + t->vertexUV((float)(x0), (float)(y + overlayOffset), (float)(z0), + lineTextureOverlay->getU0(), lineTextureOverlay->getV0()); + t->vertexUV((float)(x0), (float)(y + overlayOffset), (float)(z1), + lineTextureOverlay->getU1(), lineTextureOverlay->getV0()); + } - if ( !level->isSolidBlockingTile( x, y + 1, z ) ) - { - const float yStretch = .35f / 16.0f; + if (!level->isSolidBlockingTile(x, y + 1, z)) { + const float yStretch = .35f / 16.0f; - if ( level->isSolidBlockingTile( x - 1, y, z ) && level->getTile( x - 1, y + 1, z ) == Tile_SPU::redStoneDust_Id ) - { - t->color( br * red, br * green, br * blue ); - t->vertexUV( ( float )( x + dustOffset ), ( float )( y + 1 + yStretch ), ( float )( z + 1 ), lineTexture->getU1(), lineTexture->getV0() ); - t->vertexUV( ( float )( x + dustOffset ), ( float )( y + 0 ), ( float )( z + 1 ), lineTexture->getU0(), lineTexture->getV0() ); - t->vertexUV( ( float )( x + dustOffset ), ( float )( y + 0 ), ( float )( z + 0 ), lineTexture->getU0(), lineTexture->getV1() ); - t->vertexUV( ( float )( x + dustOffset ), ( float )( y + 1 + yStretch ), ( float )( z + 0 ), lineTexture->getU1(), lineTexture->getV1() ); + if (level->isSolidBlockingTile(x - 1, y, z) && + level->getTile(x - 1, y + 1, z) == Tile_SPU::redStoneDust_Id) { + t->color(br * red, br * green, br * blue); + t->vertexUV((float)(x + dustOffset), (float)(y + 1 + yStretch), + (float)(z + 1), lineTexture->getU1(), + lineTexture->getV0()); + t->vertexUV((float)(x + dustOffset), (float)(y + 0), (float)(z + 1), + lineTexture->getU0(), lineTexture->getV0()); + t->vertexUV((float)(x + dustOffset), (float)(y + 0), (float)(z + 0), + lineTexture->getU0(), lineTexture->getV1()); + t->vertexUV((float)(x + dustOffset), (float)(y + 1 + yStretch), + (float)(z + 0), lineTexture->getU1(), + lineTexture->getV1()); - t->color( br, br, br ); - t->vertexUV( ( float )( x + overlayOffset ), ( float )( y + 1 + yStretch ), ( float )( z + 1 ), lineTextureOverlay->getU1(), lineTextureOverlay->getV0() ); - t->vertexUV( ( float )( x + overlayOffset ), ( float )( y + 0 ), ( float )( z + 1 ), lineTextureOverlay->getU0(), lineTextureOverlay->getV0() ); - t->vertexUV( ( float )( x + overlayOffset ), ( float )( y + 0 ), ( float )( z + 0 ), lineTextureOverlay->getU0(), lineTextureOverlay->getV1() ); - t->vertexUV( ( float )( x + overlayOffset ), ( float )( y + 1 + yStretch ), ( float )( z + 0 ), lineTextureOverlay->getU1(), lineTextureOverlay->getV1() ); - } - if ( level->isSolidBlockingTile( x + 1, y, z ) && level->getTile( x + 1, y + 1, z ) == Tile_SPU::redStoneDust_Id ) - { - t->color( br * red, br * green, br * blue ); - t->vertexUV( ( float )( x + 1 - dustOffset ), ( float )( y + 0 ), ( float )( z + 1 ), lineTexture->getU0(), lineTexture->getV1() ); - t->vertexUV( ( float )( x + 1 - dustOffset ), ( float )( y + 1 + yStretch ), ( float )( z + 1 ), lineTexture->getU1(), lineTexture->getV1() ); - t->vertexUV( ( float )( x + 1 - dustOffset ), ( float )( y + 1 + yStretch ), ( float )( z + 0 ), lineTexture->getU1(), lineTexture->getV0() ); - t->vertexUV( ( float )( x + 1 - dustOffset ), ( float )( y + 0 ), ( float )( z + 0 ), lineTexture->getU0(), lineTexture->getV0() ); + t->color(br, br, br); + t->vertexUV((float)(x + overlayOffset), (float)(y + 1 + yStretch), + (float)(z + 1), lineTextureOverlay->getU1(), + lineTextureOverlay->getV0()); + t->vertexUV((float)(x + overlayOffset), (float)(y + 0), + (float)(z + 1), lineTextureOverlay->getU0(), + lineTextureOverlay->getV0()); + t->vertexUV((float)(x + overlayOffset), (float)(y + 0), + (float)(z + 0), lineTextureOverlay->getU0(), + lineTextureOverlay->getV1()); + t->vertexUV((float)(x + overlayOffset), (float)(y + 1 + yStretch), + (float)(z + 0), lineTextureOverlay->getU1(), + lineTextureOverlay->getV1()); + } + if (level->isSolidBlockingTile(x + 1, y, z) && + level->getTile(x + 1, y + 1, z) == Tile_SPU::redStoneDust_Id) { + t->color(br * red, br * green, br * blue); + t->vertexUV((float)(x + 1 - dustOffset), (float)(y + 0), + (float)(z + 1), lineTexture->getU0(), + lineTexture->getV1()); + t->vertexUV((float)(x + 1 - dustOffset), (float)(y + 1 + yStretch), + (float)(z + 1), lineTexture->getU1(), + lineTexture->getV1()); + t->vertexUV((float)(x + 1 - dustOffset), (float)(y + 1 + yStretch), + (float)(z + 0), lineTexture->getU1(), + lineTexture->getV0()); + t->vertexUV((float)(x + 1 - dustOffset), (float)(y + 0), + (float)(z + 0), lineTexture->getU0(), + lineTexture->getV0()); - t->color( br, br, br ); - t->vertexUV( ( float )( x + 1 - overlayOffset ), ( float )( y + 0 ), ( float )( z + 1 ), lineTextureOverlay->getU0(), lineTextureOverlay->getV1() ); - t->vertexUV( ( float )( x + 1 - overlayOffset ), ( float )( y + 1 + yStretch ), ( float )( z + 1 ), lineTextureOverlay->getU1(), lineTextureOverlay->getV1() ); - t->vertexUV( ( float )( x + 1 - overlayOffset ), ( float )( y + 1 + yStretch ), ( float )( z + 0 ), lineTextureOverlay->getU1(), lineTextureOverlay->getV0() ); - t->vertexUV( ( float )( x + 1 - overlayOffset ), ( float )( y + 0 ), ( float )( z + 0 ), lineTextureOverlay->getU0(), lineTextureOverlay->getV0() ); - } - if ( level->isSolidBlockingTile( x, y, z - 1 ) && level->getTile( x, y + 1, z - 1 ) == Tile_SPU::redStoneDust_Id ) - { - t->color( br * red, br * green, br * blue ); - t->vertexUV( ( float )( x + 1 ), ( float )( y + 0 ), ( float )( z + dustOffset ), lineTexture->getU0(), lineTexture->getV1() ); - t->vertexUV( ( float )( x + 1 ), ( float )( y + 1 + yStretch ), ( float )( z + dustOffset ), lineTexture->getU1(), lineTexture->getV1() ); - t->vertexUV( ( float )( x + 0 ), ( float )( y + 1 + yStretch ), ( float )( z + dustOffset ), lineTexture->getU1(), lineTexture->getV0() ); - t->vertexUV( ( float )( x + 0 ), ( float )( y + 0 ), ( float )( z + dustOffset ), lineTexture->getU0(), lineTexture->getV0() ); + t->color(br, br, br); + t->vertexUV((float)(x + 1 - overlayOffset), (float)(y + 0), + (float)(z + 1), lineTextureOverlay->getU0(), + lineTextureOverlay->getV1()); + t->vertexUV((float)(x + 1 - overlayOffset), + (float)(y + 1 + yStretch), (float)(z + 1), + lineTextureOverlay->getU1(), + lineTextureOverlay->getV1()); + t->vertexUV((float)(x + 1 - overlayOffset), + (float)(y + 1 + yStretch), (float)(z + 0), + lineTextureOverlay->getU1(), + lineTextureOverlay->getV0()); + t->vertexUV((float)(x + 1 - overlayOffset), (float)(y + 0), + (float)(z + 0), lineTextureOverlay->getU0(), + lineTextureOverlay->getV0()); + } + if (level->isSolidBlockingTile(x, y, z - 1) && + level->getTile(x, y + 1, z - 1) == Tile_SPU::redStoneDust_Id) { + t->color(br * red, br * green, br * blue); + t->vertexUV((float)(x + 1), (float)(y + 0), (float)(z + dustOffset), + lineTexture->getU0(), lineTexture->getV1()); + t->vertexUV((float)(x + 1), (float)(y + 1 + yStretch), + (float)(z + dustOffset), lineTexture->getU1(), + lineTexture->getV1()); + t->vertexUV((float)(x + 0), (float)(y + 1 + yStretch), + (float)(z + dustOffset), lineTexture->getU1(), + lineTexture->getV0()); + t->vertexUV((float)(x + 0), (float)(y + 0), (float)(z + dustOffset), + lineTexture->getU0(), lineTexture->getV0()); - t->color( br, br, br ); - t->vertexUV( ( float )( x + 1 ), ( float )( y + 0 ), ( float )( z + overlayOffset ), lineTextureOverlay->getU0(), lineTextureOverlay->getV1() ); - t->vertexUV( ( float )( x + 1 ), ( float )( y + 1 + yStretch ), ( float )( z + overlayOffset ), lineTextureOverlay->getU1(), lineTextureOverlay->getV1() ); - t->vertexUV( ( float )( x + 0 ), ( float )( y + 1 + yStretch ), ( float )( z + overlayOffset ), lineTextureOverlay->getU1(), lineTextureOverlay->getV0() ); - t->vertexUV( ( float )( x + 0 ), ( float )( y + 0 ), ( float )( z + overlayOffset ), lineTextureOverlay->getU0(), lineTextureOverlay->getV0() ); - } - if ( level->isSolidBlockingTile( x, y, z + 1 ) && level->getTile( x, y + 1, z + 1 ) == Tile_SPU::redStoneDust_Id ) - { - t->color( br * red, br * green, br * blue ); - t->vertexUV( ( float )( x + 1 ), ( float )( y + 1 + yStretch ), ( float )( z + 1 - dustOffset ), lineTexture->getU1(), lineTexture->getV0() ); - t->vertexUV( ( float )( x + 1 ), ( float )( y + 0 ), ( float )( z + 1 - dustOffset ), lineTexture->getU0(), lineTexture->getV0() ); - t->vertexUV( ( float )( x + 0 ), ( float )( y + 0 ), ( float )( z + 1 - dustOffset ), lineTexture->getU0(), lineTexture->getV1() ); - t->vertexUV( ( float )( x + 0 ), ( float )( y + 1 + yStretch ), ( float )( z + 1 - dustOffset ), lineTexture->getU1(), lineTexture->getV1() ); + t->color(br, br, br); + t->vertexUV((float)(x + 1), (float)(y + 0), + (float)(z + overlayOffset), lineTextureOverlay->getU0(), + lineTextureOverlay->getV1()); + t->vertexUV((float)(x + 1), (float)(y + 1 + yStretch), + (float)(z + overlayOffset), lineTextureOverlay->getU1(), + lineTextureOverlay->getV1()); + t->vertexUV((float)(x + 0), (float)(y + 1 + yStretch), + (float)(z + overlayOffset), lineTextureOverlay->getU1(), + lineTextureOverlay->getV0()); + t->vertexUV((float)(x + 0), (float)(y + 0), + (float)(z + overlayOffset), lineTextureOverlay->getU0(), + lineTextureOverlay->getV0()); + } + if (level->isSolidBlockingTile(x, y, z + 1) && + level->getTile(x, y + 1, z + 1) == Tile_SPU::redStoneDust_Id) { + t->color(br * red, br * green, br * blue); + t->vertexUV((float)(x + 1), (float)(y + 1 + yStretch), + (float)(z + 1 - dustOffset), lineTexture->getU1(), + lineTexture->getV0()); + t->vertexUV((float)(x + 1), (float)(y + 0), + (float)(z + 1 - dustOffset), lineTexture->getU0(), + lineTexture->getV0()); + t->vertexUV((float)(x + 0), (float)(y + 0), + (float)(z + 1 - dustOffset), lineTexture->getU0(), + lineTexture->getV1()); + t->vertexUV((float)(x + 0), (float)(y + 1 + yStretch), + (float)(z + 1 - dustOffset), lineTexture->getU1(), + lineTexture->getV1()); - t->color( br, br, br ); - t->vertexUV( ( float )( x + 1 ), ( float )( y + 1 + yStretch ), ( float )( z + 1 - overlayOffset ), lineTextureOverlay->getU1(), lineTextureOverlay->getV0() ); - t->vertexUV( ( float )( x + 1 ), ( float )( y + 0 ), ( float )( z + 1 - overlayOffset ), lineTextureOverlay->getU0(), lineTextureOverlay->getV0() ); - t->vertexUV( ( float )( x + 0 ), ( float )( y + 0 ), ( float )( z + 1 - overlayOffset ), lineTextureOverlay->getU0(), lineTextureOverlay->getV1() ); - t->vertexUV( ( float )( x + 0 ), ( float )( y + 1 + yStretch ), ( float )( z + 1 - overlayOffset ), lineTextureOverlay->getU1(), lineTextureOverlay->getV1() ); - } - } -#endif // #ifdef DISABLE_TESS_FUNCS + t->color(br, br, br); + t->vertexUV((float)(x + 1), (float)(y + 1 + yStretch), + (float)(z + 1 - overlayOffset), + lineTextureOverlay->getU1(), + lineTextureOverlay->getV0()); + t->vertexUV( + (float)(x + 1), (float)(y + 0), (float)(z + 1 - overlayOffset), + lineTextureOverlay->getU0(), lineTextureOverlay->getV0()); + t->vertexUV( + (float)(x + 0), (float)(y + 0), (float)(z + 1 - overlayOffset), + lineTextureOverlay->getU0(), lineTextureOverlay->getV1()); + t->vertexUV((float)(x + 0), (float)(y + 1 + yStretch), + (float)(z + 1 - overlayOffset), + lineTextureOverlay->getU1(), + lineTextureOverlay->getV1()); + } + } +#endif // #ifdef DISABLE_TESS_FUNCS - return true; + return true; } -bool TileRenderer_SPU::tesselateRailInWorld( RailTile_SPU* tt, int x, int y, int z ) -{ - Tesselator_SPU* t = getTesselator(); - int data = level->getData( x, y, z ); +bool TileRenderer_SPU::tesselateRailInWorld(RailTile_SPU* tt, int x, int y, + int z) { + Tesselator_SPU* t = getTesselator(); + int data = level->getData(x, y, z); - Icon_SPU *tex = getTexture(tt, 0, data); - if (hasFixedTexture()) tex = fixedTexture; + Icon_SPU* tex = getTexture(tt, 0, data); + if (hasFixedTexture()) tex = fixedTexture; - if ( tt->isUsesDataBit() ) - { - data &= RailTile_SPU::RAIL_DIRECTION_MASK; - } + if (tt->isUsesDataBit()) { + data &= RailTile_SPU::RAIL_DIRECTION_MASK; + } - if ( SharedConstants::TEXTURE_LIGHTING ) - { - t->tex2( tt->getLightColor( level, x, y, z ) ); - t->color( 1.0f, 1.0f, 1.0f ); - } - else - { - float br = tt->getBrightness( level, x, y, z ); - t->color( br, br, br ); - } + if (SharedConstants::TEXTURE_LIGHTING) { + t->tex2(tt->getLightColor(level, x, y, z)); + t->color(1.0f, 1.0f, 1.0f); + } else { + float br = tt->getBrightness(level, x, y, z); + t->color(br, br, br); + } - float u0 = tex->getU0(); - float v0 = tex->getV0(); - float u1 = tex->getU1(); - float v1 = tex->getV1(); + float u0 = tex->getU0(); + float v0 = tex->getV0(); + float u1 = tex->getU1(); + float v1 = tex->getV1(); - float r = 1 / 16.0f; + float r = 1 / 16.0f; - float x0 = ( float )( x + 1 ); - float x1 = ( float )( x + 1 ); - float x2 = ( float )( x + 0 ); - float x3 = ( float )( x + 0 ); + float x0 = (float)(x + 1); + float x1 = (float)(x + 1); + float x2 = (float)(x + 0); + float x3 = (float)(x + 0); - float z0 = ( float )( z + 0 ); - float z1 = ( float )( z + 1 ); - float z2 = ( float )( z + 1 ); - float z3 = ( float )( z + 0 ); + float z0 = (float)(z + 0); + float z1 = (float)(z + 1); + float z2 = (float)(z + 1); + float z3 = (float)(z + 0); - float y0 = ( float )( y + r ); - float y1 = ( float )( y + r ); - float y2 = ( float )( y + r ); - float y3 = ( float )( y + r ); + float y0 = (float)(y + r); + float y1 = (float)(y + r); + float y2 = (float)(y + r); + float y3 = (float)(y + r); - if ( data == 1 || data == 2 || data == 3 || data == 7 ) - { - x0 = x3 = ( float )( x + 1 ); - x1 = x2 = ( float )( x + 0 ); - z0 = z1 = ( float )( z + 1 ); - z2 = z3 = ( float )( z + 0 ); - } - else if ( data == 8 ) - { - x0 = x1 = ( float )( x + 0 ); - x2 = x3 = ( float )( x + 1 ); - z0 = z3 = ( float )( z + 1 ); - z1 = z2 = ( float )( z + 0 ); - } - else if ( data == 9 ) - { - x0 = x3 = ( float )( x + 0 ); - x1 = x2 = ( float )( x + 1 ); - z0 = z1 = ( float )( z + 0 ); - z2 = z3 = ( float )( z + 1 ); - } + if (data == 1 || data == 2 || data == 3 || data == 7) { + x0 = x3 = (float)(x + 1); + x1 = x2 = (float)(x + 0); + z0 = z1 = (float)(z + 1); + z2 = z3 = (float)(z + 0); + } else if (data == 8) { + x0 = x1 = (float)(x + 0); + x2 = x3 = (float)(x + 1); + z0 = z3 = (float)(z + 1); + z1 = z2 = (float)(z + 0); + } else if (data == 9) { + x0 = x3 = (float)(x + 0); + x1 = x2 = (float)(x + 1); + z0 = z1 = (float)(z + 0); + z2 = z3 = (float)(z + 1); + } - if ( data == 2 || data == 4 ) - { - y0 += 1; - y3 += 1; - } - else if ( data == 3 || data == 5 ) - { - y1 += 1; - y2 += 1; - } + if (data == 2 || data == 4) { + y0 += 1; + y3 += 1; + } else if (data == 3 || data == 5) { + y1 += 1; + y2 += 1; + } - t->vertexUV( ( float )( x0 ), ( float )( y0 ), ( float )( z0 ), ( float )( u1 ), ( float )( v0 ) ); - t->vertexUV( ( float )( x1 ), ( float )( y1 ), ( float )( z1 ), ( float )( u1 ), ( float )( v1 ) ); - t->vertexUV( ( float )( x2 ), ( float )( y2 ), ( float )( z2 ), ( float )( u0 ), ( float )( v1 ) ); - t->vertexUV( ( float )( x3 ), ( float )( y3 ), ( float )( z3 ), ( float )( u0 ), ( float )( v0 ) ); + t->vertexUV((float)(x0), (float)(y0), (float)(z0), (float)(u1), + (float)(v0)); + t->vertexUV((float)(x1), (float)(y1), (float)(z1), (float)(u1), + (float)(v1)); + t->vertexUV((float)(x2), (float)(y2), (float)(z2), (float)(u0), + (float)(v1)); + t->vertexUV((float)(x3), (float)(y3), (float)(z3), (float)(u0), + (float)(v0)); - t->vertexUV( ( float )( x3 ), ( float )( y3 ), ( float )( z3 ), ( float )( u0 ), ( float )( v0 ) ); - t->vertexUV( ( float )( x2 ), ( float )( y2 ), ( float )( z2 ), ( float )( u0 ), ( float )( v1 ) ); - t->vertexUV( ( float )( x1 ), ( float )( y1 ), ( float )( z1 ), ( float )( u1 ), ( float )( v1 ) ); - t->vertexUV( ( float )( x0 ), ( float )( y0 ), ( float )( z0 ), ( float )( u1 ), ( float )( v0 ) ); - - return true; + t->vertexUV((float)(x3), (float)(y3), (float)(z3), (float)(u0), + (float)(v0)); + t->vertexUV((float)(x2), (float)(y2), (float)(z2), (float)(u0), + (float)(v1)); + t->vertexUV((float)(x1), (float)(y1), (float)(z1), (float)(u1), + (float)(v1)); + t->vertexUV((float)(x0), (float)(y0), (float)(z0), (float)(u1), + (float)(v0)); + return true; } -bool TileRenderer_SPU::tesselateLadderInWorld( Tile_SPU* tt, int x, int y, int z ) -{ - Tesselator_SPU* t = getTesselator(); +bool TileRenderer_SPU::tesselateLadderInWorld(Tile_SPU* tt, int x, int y, + int z) { + Tesselator_SPU* t = getTesselator(); - Icon_SPU *tex = getTexture(tt, 0); + Icon_SPU* tex = getTexture(tt, 0); - if (hasFixedTexture()) tex = fixedTexture; + if (hasFixedTexture()) tex = fixedTexture; - if ( SharedConstants::TEXTURE_LIGHTING ) - { - t->tex2( tt->getLightColor( level, x, y, z ) ); - float br = 1; - t->color( br, br, br ); - } - else - { - float br = tt->getBrightness( level, x, y, z ); - t->color( br, br, br ); - } - float u0 = tex->getU0(); - float v0 = tex->getV0(); - float u1 = tex->getU1(); - float v1 = tex->getV1(); + if (SharedConstants::TEXTURE_LIGHTING) { + t->tex2(tt->getLightColor(level, x, y, z)); + float br = 1; + t->color(br, br, br); + } else { + float br = tt->getBrightness(level, x, y, z); + t->color(br, br, br); + } + float u0 = tex->getU0(); + float v0 = tex->getV0(); + float u1 = tex->getU1(); + float v1 = tex->getV1(); - int face = level->getData( x, y, z ); + int face = level->getData(x, y, z); - float o = 0 / 16.0f; - float r = 0.05f; - if ( face == 5 ) - { - t->vertexUV( ( float )( x + r ), ( float )( y + 1 + o ), ( float )( z + 1 + - o ), ( float )( u0 ), ( float )( v0 ) ); - t->vertexUV( ( float )( x + r ), ( float )( y + 0 - o ), ( float )( z + 1 + - o ), ( float )( u0 ), ( float )( v1 ) ); - t->vertexUV( ( float )( x + r ), ( float )( y + 0 - o ), ( float )( z + 0 - - o ), ( float )( u1 ), ( float )( v1 ) ); - t->vertexUV( ( float )( x + r ), ( float )( y + 1 + o ), ( float )( z + 0 - - o ), ( float )( u1 ), ( float )( v0 ) ); - } - if ( face == 4 ) - { - t->vertexUV( ( float )( x + 1 - r ), ( float )( y + 0 - o ), ( float )( z + 1 + - o ), ( float )( u1 ), ( float )( v1 ) ); - t->vertexUV( ( float )( x + 1 - r ), ( float )( y + 1 + o ), ( float )( z + 1 + - o ), ( float )( u1 ), ( float )( v0 ) ); - t->vertexUV( ( float )( x + 1 - r ), ( float )( y + 1 + o ), ( float )( z + 0 - - o ), ( float )( u0 ), ( float )( v0 ) ); - t->vertexUV( ( float )( x + 1 - r ), ( float )( y + 0 - o ), ( float )( z + 0 - - o ), ( float )( u0 ), ( float )( v1 ) ); - } - if ( face == 3 ) - { - t->vertexUV( ( float )( x + 1 + o ), ( float )( y + 0 - o ), ( float )( z + - r ), ( float )( u1 ), ( float )( v1 ) ); - t->vertexUV( ( float )( x + 1 + o ), ( float )( y + 1 + o ), ( float )( z + - r ), ( float )( u1 ), ( float )( v0 ) ); - t->vertexUV( ( float )( x + 0 - o ), ( float )( y + 1 + o ), ( float )( z + - r ), ( float )( u0 ), ( float )( v0 ) ); - t->vertexUV( ( float )( x + 0 - o ), ( float )( y + 0 - o ), ( float )( z + - r ), ( float )( u0 ), ( float )( v1 ) ); - } - if ( face == 2 ) - { - t->vertexUV( ( float )( x + 1 + o ), ( float )( y + 1 + o ), ( float )( z + 1 - - r ), ( float )( u0 ), ( float )( v0 ) ); - t->vertexUV( ( float )( x + 1 + o ), ( float )( y + 0 - o ), ( float )( z + 1 - - r ), ( float )( u0 ), ( float )( v1 ) ); - t->vertexUV( ( float )( x + 0 - o ), ( float )( y + 0 - o ), ( float )( z + 1 - - r ), ( float )( u1 ), ( float )( v1 ) ); - t->vertexUV( ( float )( x + 0 - o ), ( float )( y + 1 + o ), ( float )( z + 1 - - r ), ( float )( u1 ), ( float )( v0 ) ); - } - return true; + float o = 0 / 16.0f; + float r = 0.05f; + if (face == 5) { + t->vertexUV((float)(x + r), (float)(y + 1 + o), (float)(z + 1 + o), + (float)(u0), (float)(v0)); + t->vertexUV((float)(x + r), (float)(y + 0 - o), (float)(z + 1 + o), + (float)(u0), (float)(v1)); + t->vertexUV((float)(x + r), (float)(y + 0 - o), (float)(z + 0 - o), + (float)(u1), (float)(v1)); + t->vertexUV((float)(x + r), (float)(y + 1 + o), (float)(z + 0 - o), + (float)(u1), (float)(v0)); + } + if (face == 4) { + t->vertexUV((float)(x + 1 - r), (float)(y + 0 - o), (float)(z + 1 + o), + (float)(u1), (float)(v1)); + t->vertexUV((float)(x + 1 - r), (float)(y + 1 + o), (float)(z + 1 + o), + (float)(u1), (float)(v0)); + t->vertexUV((float)(x + 1 - r), (float)(y + 1 + o), (float)(z + 0 - o), + (float)(u0), (float)(v0)); + t->vertexUV((float)(x + 1 - r), (float)(y + 0 - o), (float)(z + 0 - o), + (float)(u0), (float)(v1)); + } + if (face == 3) { + t->vertexUV((float)(x + 1 + o), (float)(y + 0 - o), (float)(z + r), + (float)(u1), (float)(v1)); + t->vertexUV((float)(x + 1 + o), (float)(y + 1 + o), (float)(z + r), + (float)(u1), (float)(v0)); + t->vertexUV((float)(x + 0 - o), (float)(y + 1 + o), (float)(z + r), + (float)(u0), (float)(v0)); + t->vertexUV((float)(x + 0 - o), (float)(y + 0 - o), (float)(z + r), + (float)(u0), (float)(v1)); + } + if (face == 2) { + t->vertexUV((float)(x + 1 + o), (float)(y + 1 + o), (float)(z + 1 - r), + (float)(u0), (float)(v0)); + t->vertexUV((float)(x + 1 + o), (float)(y + 0 - o), (float)(z + 1 - r), + (float)(u0), (float)(v1)); + t->vertexUV((float)(x + 0 - o), (float)(y + 0 - o), (float)(z + 1 - r), + (float)(u1), (float)(v1)); + t->vertexUV((float)(x + 0 - o), (float)(y + 1 + o), (float)(z + 1 - r), + (float)(u1), (float)(v0)); + } + return true; } -bool TileRenderer_SPU::tesselateVineInWorld( Tile_SPU* tt, int x, int y, int z ) -{ - Tesselator_SPU* t = getTesselator(); +bool TileRenderer_SPU::tesselateVineInWorld(Tile_SPU* tt, int x, int y, int z) { + Tesselator_SPU* t = getTesselator(); - Icon_SPU *tex = getTexture(tt, 0); + Icon_SPU* tex = getTexture(tt, 0); - if (hasFixedTexture()) tex = fixedTexture; + if (hasFixedTexture()) tex = fixedTexture; + float br = 1; + if (SharedConstants::TEXTURE_LIGHTING) { + t->tex2(tt->getLightColor(level, x, y, z)); + } else { + br = tt->getBrightness(level, x, y, z); + } + { + int col = tt->getColor(level, x, y, z); + float r = ((col >> 16) & 0xff) / 255.0f; + float g = ((col >> 8) & 0xff) / 255.0f; + float b = ((col) & 0xff) / 255.0f; - float br = 1; - if ( SharedConstants::TEXTURE_LIGHTING ) - { - t->tex2( tt->getLightColor( level, x, y, z ) ); - } - else - { - br = tt->getBrightness( level, x, y, z ); - } - { - int col = tt->getColor( level, x, y, z ); - float r = ( ( col >> 16 ) & 0xff ) / 255.0f; - float g = ( ( col >> 8 ) & 0xff ) / 255.0f; - float b = ( ( col )& 0xff ) / 255.0f; + t->color(br * r, br * g, br * b); + } - t->color( br * r, br * g, br * b ); - } + float u0 = tex->getU0(); + float v0 = tex->getV0(); + float u1 = tex->getU1(); + float v1 = tex->getV1(); - float u0 = tex->getU0(); - float v0 = tex->getV0(); - float u1 = tex->getU1(); - float v1 = tex->getV1(); + float r = 0.05f; + int facings = level->getData(x, y, z); - float r = 0.05f; - int facings = level->getData( x, y, z ); + if ((facings & VineTile_SPU::VINE_WEST) != 0) { + t->vertexUV(x + r, y + 1, z + 1, u0, v0); + t->vertexUV(x + r, y + 0, z + 1, u0, v1); + t->vertexUV(x + r, y + 0, z + 0, u1, v1); + t->vertexUV(x + r, y + 1, z + 0, u1, v0); - if ( ( facings & VineTile_SPU::VINE_WEST ) != 0 ) - { - t->vertexUV( x + r, y + 1, z + 1, u0, v0 ); - t->vertexUV( x + r, y + 0, z + 1, u0, v1 ); - t->vertexUV( x + r, y + 0, z + 0, u1, v1 ); - t->vertexUV( x + r, y + 1, z + 0, u1, v0 ); + t->vertexUV(x + r, y + 1, z + 0, u1, v0); + t->vertexUV(x + r, y + 0, z + 0, u1, v1); + t->vertexUV(x + r, y + 0, z + 1, u0, v1); + t->vertexUV(x + r, y + 1, z + 1, u0, v0); + } + if ((facings & VineTile_SPU::VINE_EAST) != 0) { + t->vertexUV(x + 1 - r, y + 0, z + 1, u1, v1); + t->vertexUV(x + 1 - r, y + 1, z + 1, u1, v0); + t->vertexUV(x + 1 - r, y + 1, z + 0, u0, v0); + t->vertexUV(x + 1 - r, y + 0, z + 0, u0, v1); - t->vertexUV( x + r, y + 1, z + 0, u1, v0 ); - t->vertexUV( x + r, y + 0, z + 0, u1, v1 ); - t->vertexUV( x + r, y + 0, z + 1, u0, v1 ); - t->vertexUV( x + r, y + 1, z + 1, u0, v0 ); - } - if ( ( facings & VineTile_SPU::VINE_EAST ) != 0 ) - { - t->vertexUV( x + 1 - r, y + 0, z + 1, u1, v1 ); - t->vertexUV( x + 1 - r, y + 1, z + 1, u1, v0 ); - t->vertexUV( x + 1 - r, y + 1, z + 0, u0, v0 ); - t->vertexUV( x + 1 - r, y + 0, z + 0, u0, v1 ); + t->vertexUV(x + 1 - r, y + 0, z + 0, u0, v1); + t->vertexUV(x + 1 - r, y + 1, z + 0, u0, v0); + t->vertexUV(x + 1 - r, y + 1, z + 1, u1, v0); + t->vertexUV(x + 1 - r, y + 0, z + 1, u1, v1); + } + if ((facings & VineTile_SPU::VINE_NORTH) != 0) { + t->vertexUV(x + 1, y + 0, z + r, u1, v1); + t->vertexUV(x + 1, y + 1, z + r, u1, v0); + t->vertexUV(x + 0, y + 1, z + r, u0, v0); + t->vertexUV(x + 0, y + 0, z + r, u0, v1); - t->vertexUV( x + 1 - r, y + 0, z + 0, u0, v1 ); - t->vertexUV( x + 1 - r, y + 1, z + 0, u0, v0 ); - t->vertexUV( x + 1 - r, y + 1, z + 1, u1, v0 ); - t->vertexUV( x + 1 - r, y + 0, z + 1, u1, v1 ); - } - if ( ( facings & VineTile_SPU::VINE_NORTH ) != 0 ) - { - t->vertexUV( x + 1, y + 0, z + r, u1, v1 ); - t->vertexUV( x + 1, y + 1, z + r, u1, v0 ); - t->vertexUV( x + 0, y + 1, z + r, u0, v0 ); - t->vertexUV( x + 0, y + 0, z + r, u0, v1 ); + t->vertexUV(x + 0, y + 0, z + r, u0, v1); + t->vertexUV(x + 0, y + 1, z + r, u0, v0); + t->vertexUV(x + 1, y + 1, z + r, u1, v0); + t->vertexUV(x + 1, y + 0, z + r, u1, v1); + } + if ((facings & VineTile_SPU::VINE_SOUTH) != 0) { + t->vertexUV(x + 1, y + 1, z + 1 - r, u0, v0); + t->vertexUV(x + 1, y + 0, z + 1 - r, u0, v1); + t->vertexUV(x + 0, y + 0, z + 1 - r, u1, v1); + t->vertexUV(x + 0, y + 1, z + 1 - r, u1, v0); - t->vertexUV( x + 0, y + 0, z + r, u0, v1 ); - t->vertexUV( x + 0, y + 1, z + r, u0, v0 ); - t->vertexUV( x + 1, y + 1, z + r, u1, v0 ); - t->vertexUV( x + 1, y + 0, z + r, u1, v1 ); - } - if ( ( facings & VineTile_SPU::VINE_SOUTH ) != 0 ) - { - t->vertexUV( x + 1, y + 1, z + 1 - r, u0, v0 ); - t->vertexUV( x + 1, y + 0, z + 1 - r, u0, v1 ); - t->vertexUV( x + 0, y + 0, z + 1 - r, u1, v1 ); - t->vertexUV( x + 0, y + 1, z + 1 - r, u1, v0 ); - - t->vertexUV( x + 0, y + 1, z + 1 - r, u1, v0 ); - t->vertexUV( x + 0, y + 0, z + 1 - r, u1, v1 ); - t->vertexUV( x + 1, y + 0, z + 1 - r, u0, v1 ); - t->vertexUV( x + 1, y + 1, z + 1 - r, u0, v0 ); - } - if ( level->isSolidBlockingTile( x, y + 1, z ) ) - { - t->vertexUV( x + 1, y + 1 - r, z + 0, u0, v0 ); - t->vertexUV( x + 1, y + 1 - r, z + 1, u0, v1 ); - t->vertexUV( x + 0, y + 1 - r, z + 1, u1, v1 ); - t->vertexUV( x + 0, y + 1 - r, z + 0, u1, v0 ); - } - return true; + t->vertexUV(x + 0, y + 1, z + 1 - r, u1, v0); + t->vertexUV(x + 0, y + 0, z + 1 - r, u1, v1); + t->vertexUV(x + 1, y + 0, z + 1 - r, u0, v1); + t->vertexUV(x + 1, y + 1, z + 1 - r, u0, v0); + } + if (level->isSolidBlockingTile(x, y + 1, z)) { + t->vertexUV(x + 1, y + 1 - r, z + 0, u0, v0); + t->vertexUV(x + 1, y + 1 - r, z + 1, u0, v1); + t->vertexUV(x + 0, y + 1 - r, z + 1, u1, v1); + t->vertexUV(x + 0, y + 1 - r, z + 0, u1, v0); + } + return true; } -bool TileRenderer_SPU::tesselateThinFenceInWorld( ThinFenceTile* tt, int x, int y, int z ) -{ +bool TileRenderer_SPU::tesselateThinFenceInWorld(ThinFenceTile* tt, int x, + int y, int z) { #ifdef DISABLE_TESS_FUNCS - int depth = level->getDepth(); - Tesselator_SPU* t = getTesselator(); + int depth = level->getDepth(); + Tesselator_SPU* t = getTesselator(); - float br; - if ( SharedConstants::TEXTURE_LIGHTING ) - { - t->tex2( tt->getLightColor( level, x, y, z ) ); - br = 1; - } - else - { - br = tt->getBrightness( level, x, y, z ); - } - int col = tt->getColor( level, x, y, z ); - float r = ( ( col >> 16 ) & 0xff ) / 255.0f; - float g = ( ( col >> 8 ) & 0xff ) / 255.0f; - float b = ( ( col )& 0xff ) / 255.0f; + float br; + if (SharedConstants::TEXTURE_LIGHTING) { + t->tex2(tt->getLightColor(level, x, y, z)); + br = 1; + } else { + br = tt->getBrightness(level, x, y, z); + } + int col = tt->getColor(level, x, y, z); + float r = ((col >> 16) & 0xff) / 255.0f; + float g = ((col >> 8) & 0xff) / 255.0f; + float b = ((col) & 0xff) / 255.0f; - if ( GameRenderer::anaglyph3d ) - { - float cr = ( r * 30 + g * 59 + b * 11 ) / 100; - float cg = ( r * 30 + g * 70 ) / ( 100 ); - float cb = ( r * 30 + b * 70 ) / ( 100 ); + if (GameRenderer::anaglyph3d) { + float cr = (r * 30 + g * 59 + b * 11) / 100; + float cg = (r * 30 + g * 70) / (100); + float cb = (r * 30 + b * 70) / (100); - r = cr; - g = cg; - b = cb; - } - t->color( br * r, br * g, br * b ); + r = cr; + g = cg; + b = cb; + } + t->color(br * r, br * g, br * b); - Icon_SPU *tex; - Icon_SPU *edgeTex; + Icon_SPU* tex; + Icon_SPU* edgeTex; - if ( hasFixedTexture() ) - { - tex = fixedTexture; - edgeTex = fixedTexture; - } - else - { - int data = level->getData( x, y, z ); - tex = getTexture( tt, 0, data ); - edgeTex = tt->getEdgeTexture(); - } + if (hasFixedTexture()) { + tex = fixedTexture; + edgeTex = fixedTexture; + } else { + int data = level->getData(x, y, z); + tex = getTexture(tt, 0, data); + edgeTex = tt->getEdgeTexture(); + } - int xt = tex->getX(); - int yt = tex->getY(); - float u0 = tex->getU0(); - float u1 = tex->getU(8); - float u2 = tex->getU1(); - float v0 = tex->getV0(); - float v2 = tex->getV1(); + int xt = tex->getX(); + int yt = tex->getY(); + float u0 = tex->getU0(); + float u1 = tex->getU(8); + float u2 = tex->getU1(); + float v0 = tex->getV0(); + float v2 = tex->getV1(); - int xet = edgeTex->getX(); - int yet = edgeTex->getY(); + int xet = edgeTex->getX(); + int yet = edgeTex->getY(); - float iu0 = edgeTex->getU(7); - float iu1 = edgeTex->getU(9); - float iv0 = edgeTex->getV0(); - float iv1 = edgeTex->getV(8); - float iv2 = edgeTex->getV1(); + float iu0 = edgeTex->getU(7); + float iu1 = edgeTex->getU(9); + float iv0 = edgeTex->getV0(); + float iv1 = edgeTex->getV(8); + float iv2 = edgeTex->getV1(); - float x0 = (float)x; - float x1 = x + 0.5f; - float x2 = x + 1.0f; - float z0 = (float)z; - float z1 = z + 0.5f; - float z2 = z + 1.0f; - float ix0 = x + 0.5f - 1.0f / 16.0f; - float ix1 = x + 0.5f + 1.0f / 16.0f; - float iz0 = z + 0.5f - 1.0f / 16.0f; - float iz1 = z + 0.5f + 1.0f / 16.0f; + float x0 = (float)x; + float x1 = x + 0.5f; + float x2 = x + 1.0f; + float z0 = (float)z; + float z1 = z + 0.5f; + float z2 = z + 1.0f; + float ix0 = x + 0.5f - 1.0f / 16.0f; + float ix1 = x + 0.5f + 1.0f / 16.0f; + float iz0 = z + 0.5f - 1.0f / 16.0f; + float iz1 = z + 0.5f + 1.0f / 16.0f; - bool n = tt->attachsTo( level->getTile( x, y, z - 1 ) ); - bool s = tt->attachsTo( level->getTile( x, y, z + 1 ) ); - bool w = tt->attachsTo( level->getTile( x - 1, y, z ) ); - bool e = tt->attachsTo( level->getTile( x + 1, y, z ) ); + bool n = tt->attachsTo(level->getTile(x, y, z - 1)); + bool s = tt->attachsTo(level->getTile(x, y, z + 1)); + bool w = tt->attachsTo(level->getTile(x - 1, y, z)); + bool e = tt->attachsTo(level->getTile(x + 1, y, z)); - bool up = tt->shouldRenderFace( level, x, y + 1, z, Facing::UP ); - bool down = tt->shouldRenderFace( level, x, y - 1, z, Facing::DOWN ); + bool up = tt->shouldRenderFace(level, x, y + 1, z, Facing::UP); + bool down = tt->shouldRenderFace(level, x, y - 1, z, Facing::DOWN); - const float noZFightingOffset = 0.01f; - const float noZFightingOffsetB = 0.005; + const float noZFightingOffset = 0.01f; + const float noZFightingOffsetB = 0.005; - if ( ( w && e ) || ( !w && !e && !n && !s ) ) - { - t->vertexUV( x0, y + 1, z1, u0, v0 ); - t->vertexUV( x0, y + 0, z1, u0, v2 ); - t->vertexUV( x2, y + 0, z1, u2, v2 ); - t->vertexUV( x2, y + 1, z1, u2, v0 ); + if ((w && e) || (!w && !e && !n && !s)) { + t->vertexUV(x0, y + 1, z1, u0, v0); + t->vertexUV(x0, y + 0, z1, u0, v2); + t->vertexUV(x2, y + 0, z1, u2, v2); + t->vertexUV(x2, y + 1, z1, u2, v0); - t->vertexUV( x2, y + 1, z1, u0, v0 ); - t->vertexUV( x2, y + 0, z1, u0, v2 ); - t->vertexUV( x0, y + 0, z1, u2, v2 ); - t->vertexUV( x0, y + 1, z1, u2, v0 ); + t->vertexUV(x2, y + 1, z1, u0, v0); + t->vertexUV(x2, y + 0, z1, u0, v2); + t->vertexUV(x0, y + 0, z1, u2, v2); + t->vertexUV(x0, y + 1, z1, u2, v0); - if ( up ) - { - // small edge texture - t->vertexUV( x0, y + 1 + noZFightingOffset, iz1, iu1, iv2 ); - t->vertexUV( x2, y + 1 + noZFightingOffset, iz1, iu1, iv0 ); - t->vertexUV( x2, y + 1 + noZFightingOffset, iz0, iu0, iv0 ); - t->vertexUV( x0, y + 1 + noZFightingOffset, iz0, iu0, iv2 ); + if (up) { + // small edge texture + t->vertexUV(x0, y + 1 + noZFightingOffset, iz1, iu1, iv2); + t->vertexUV(x2, y + 1 + noZFightingOffset, iz1, iu1, iv0); + t->vertexUV(x2, y + 1 + noZFightingOffset, iz0, iu0, iv0); + t->vertexUV(x0, y + 1 + noZFightingOffset, iz0, iu0, iv2); - t->vertexUV( x2, y + 1 + noZFightingOffset, iz1, iu1, iv2 ); - t->vertexUV( x0, y + 1 + noZFightingOffset, iz1, iu1, iv0 ); - t->vertexUV( x0, y + 1 + noZFightingOffset, iz0, iu0, iv0 ); - t->vertexUV( x2, y + 1 + noZFightingOffset, iz0, iu0, iv2 ); - } - else - { - if ( y < ( depth - 1 ) && level->isEmptyTile( x - 1, y + 1, z ) ) - { - t->vertexUV( x0, y + 1 + noZFightingOffset, iz1, iu1, iv1 ); - t->vertexUV( x1, y + 1 + noZFightingOffset, iz1, iu1, iv2 ); - t->vertexUV( x1, y + 1 + noZFightingOffset, iz0, iu0, iv2 ); - t->vertexUV( x0, y + 1 + noZFightingOffset, iz0, iu0, iv1 ); + t->vertexUV(x2, y + 1 + noZFightingOffset, iz1, iu1, iv2); + t->vertexUV(x0, y + 1 + noZFightingOffset, iz1, iu1, iv0); + t->vertexUV(x0, y + 1 + noZFightingOffset, iz0, iu0, iv0); + t->vertexUV(x2, y + 1 + noZFightingOffset, iz0, iu0, iv2); + } else { + if (y < (depth - 1) && level->isEmptyTile(x - 1, y + 1, z)) { + t->vertexUV(x0, y + 1 + noZFightingOffset, iz1, iu1, iv1); + t->vertexUV(x1, y + 1 + noZFightingOffset, iz1, iu1, iv2); + t->vertexUV(x1, y + 1 + noZFightingOffset, iz0, iu0, iv2); + t->vertexUV(x0, y + 1 + noZFightingOffset, iz0, iu0, iv1); - t->vertexUV( x1, y + 1 + noZFightingOffset, iz1, iu1, iv1 ); - t->vertexUV( x0, y + 1 + noZFightingOffset, iz1, iu1, iv2 ); - t->vertexUV( x0, y + 1 + noZFightingOffset, iz0, iu0, iv2 ); - t->vertexUV( x1, y + 1 + noZFightingOffset, iz0, iu0, iv1 ); - } - if ( y < ( depth - 1 ) && level->isEmptyTile( x + 1, y + 1, z ) ) - { - t->vertexUV( x1, y + 1 + noZFightingOffset, iz1, iu1, iv0 ); - t->vertexUV( x2, y + 1 + noZFightingOffset, iz1, iu1, iv1 ); - t->vertexUV( x2, y + 1 + noZFightingOffset, iz0, iu0, iv1 ); - t->vertexUV( x1, y + 1 + noZFightingOffset, iz0, iu0, iv0 ); + t->vertexUV(x1, y + 1 + noZFightingOffset, iz1, iu1, iv1); + t->vertexUV(x0, y + 1 + noZFightingOffset, iz1, iu1, iv2); + t->vertexUV(x0, y + 1 + noZFightingOffset, iz0, iu0, iv2); + t->vertexUV(x1, y + 1 + noZFightingOffset, iz0, iu0, iv1); + } + if (y < (depth - 1) && level->isEmptyTile(x + 1, y + 1, z)) { + t->vertexUV(x1, y + 1 + noZFightingOffset, iz1, iu1, iv0); + t->vertexUV(x2, y + 1 + noZFightingOffset, iz1, iu1, iv1); + t->vertexUV(x2, y + 1 + noZFightingOffset, iz0, iu0, iv1); + t->vertexUV(x1, y + 1 + noZFightingOffset, iz0, iu0, iv0); - t->vertexUV( x2, y + 1 + noZFightingOffset, iz1, iu1, iv0 ); - t->vertexUV( x1, y + 1 + noZFightingOffset, iz1, iu1, iv1 ); - t->vertexUV( x1, y + 1 + noZFightingOffset, iz0, iu0, iv1 ); - t->vertexUV( x2, y + 1 + noZFightingOffset, iz0, iu0, iv0 ); - } - } - if ( down ) - { - // small edge texture - t->vertexUV( x0, y - noZFightingOffset, iz1, iu1, iv2 ); - t->vertexUV( x2, y - noZFightingOffset, iz1, iu1, iv0 ); - t->vertexUV( x2, y - noZFightingOffset, iz0, iu0, iv0 ); - t->vertexUV( x0, y - noZFightingOffset, iz0, iu0, iv2 ); + t->vertexUV(x2, y + 1 + noZFightingOffset, iz1, iu1, iv0); + t->vertexUV(x1, y + 1 + noZFightingOffset, iz1, iu1, iv1); + t->vertexUV(x1, y + 1 + noZFightingOffset, iz0, iu0, iv1); + t->vertexUV(x2, y + 1 + noZFightingOffset, iz0, iu0, iv0); + } + } + if (down) { + // small edge texture + t->vertexUV(x0, y - noZFightingOffset, iz1, iu1, iv2); + t->vertexUV(x2, y - noZFightingOffset, iz1, iu1, iv0); + t->vertexUV(x2, y - noZFightingOffset, iz0, iu0, iv0); + t->vertexUV(x0, y - noZFightingOffset, iz0, iu0, iv2); - t->vertexUV( x2, y - noZFightingOffset, iz1, iu1, iv2 ); - t->vertexUV( x0, y - noZFightingOffset, iz1, iu1, iv0 ); - t->vertexUV( x0, y - noZFightingOffset, iz0, iu0, iv0 ); - t->vertexUV( x2, y - noZFightingOffset, iz0, iu0, iv2 ); - } - else - { - if ( y > 1 && level->isEmptyTile( x - 1, y - 1, z ) ) - { - t->vertexUV( x0, y - noZFightingOffset, iz1, iu1, iv1 ); - t->vertexUV( x1, y - noZFightingOffset, iz1, iu1, iv2 ); - t->vertexUV( x1, y - noZFightingOffset, iz0, iu0, iv2 ); - t->vertexUV( x0, y - noZFightingOffset, iz0, iu0, iv1 ); + t->vertexUV(x2, y - noZFightingOffset, iz1, iu1, iv2); + t->vertexUV(x0, y - noZFightingOffset, iz1, iu1, iv0); + t->vertexUV(x0, y - noZFightingOffset, iz0, iu0, iv0); + t->vertexUV(x2, y - noZFightingOffset, iz0, iu0, iv2); + } else { + if (y > 1 && level->isEmptyTile(x - 1, y - 1, z)) { + t->vertexUV(x0, y - noZFightingOffset, iz1, iu1, iv1); + t->vertexUV(x1, y - noZFightingOffset, iz1, iu1, iv2); + t->vertexUV(x1, y - noZFightingOffset, iz0, iu0, iv2); + t->vertexUV(x0, y - noZFightingOffset, iz0, iu0, iv1); - t->vertexUV( x1, y - noZFightingOffset, iz1, iu1, iv1 ); - t->vertexUV( x0, y - noZFightingOffset, iz1, iu1, iv2 ); - t->vertexUV( x0, y - noZFightingOffset, iz0, iu0, iv2 ); - t->vertexUV( x1, y - noZFightingOffset, iz0, iu0, iv1 ); - } - if ( y > 1 && level->isEmptyTile( x + 1, y - 1, z ) ) - { - t->vertexUV( x1, y - noZFightingOffset, iz1, iu1, iv0 ); - t->vertexUV( x2, y - noZFightingOffset, iz1, iu1, iv1 ); - t->vertexUV( x2, y - noZFightingOffset, iz0, iu0, iv1 ); - t->vertexUV( x1, y - noZFightingOffset, iz0, iu0, iv0 ); + t->vertexUV(x1, y - noZFightingOffset, iz1, iu1, iv1); + t->vertexUV(x0, y - noZFightingOffset, iz1, iu1, iv2); + t->vertexUV(x0, y - noZFightingOffset, iz0, iu0, iv2); + t->vertexUV(x1, y - noZFightingOffset, iz0, iu0, iv1); + } + if (y > 1 && level->isEmptyTile(x + 1, y - 1, z)) { + t->vertexUV(x1, y - noZFightingOffset, iz1, iu1, iv0); + t->vertexUV(x2, y - noZFightingOffset, iz1, iu1, iv1); + t->vertexUV(x2, y - noZFightingOffset, iz0, iu0, iv1); + t->vertexUV(x1, y - noZFightingOffset, iz0, iu0, iv0); - t->vertexUV( x2, y - noZFightingOffset, iz1, iu1, iv0 ); - t->vertexUV( x1, y - noZFightingOffset, iz1, iu1, iv1 ); - t->vertexUV( x1, y - noZFightingOffset, iz0, iu0, iv1 ); - t->vertexUV( x2, y - noZFightingOffset, iz0, iu0, iv0 ); - } - } - } - else if ( w && !e ) - { - // half-step towards west - t->vertexUV( x0, y + 1, z1, u0, v0 ); - t->vertexUV( x0, y + 0, z1, u0, v2 ); - t->vertexUV( x1, y + 0, z1, u1, v2 ); - t->vertexUV( x1, y + 1, z1, u1, v0 ); + t->vertexUV(x2, y - noZFightingOffset, iz1, iu1, iv0); + t->vertexUV(x1, y - noZFightingOffset, iz1, iu1, iv1); + t->vertexUV(x1, y - noZFightingOffset, iz0, iu0, iv1); + t->vertexUV(x2, y - noZFightingOffset, iz0, iu0, iv0); + } + } + } else if (w && !e) { + // half-step towards west + t->vertexUV(x0, y + 1, z1, u0, v0); + t->vertexUV(x0, y + 0, z1, u0, v2); + t->vertexUV(x1, y + 0, z1, u1, v2); + t->vertexUV(x1, y + 1, z1, u1, v0); - t->vertexUV( x1, y + 1, z1, u0, v0 ); - t->vertexUV( x1, y + 0, z1, u0, v2 ); - t->vertexUV( x0, y + 0, z1, u1, v2 ); - t->vertexUV( x0, y + 1, z1, u1, v0 ); + t->vertexUV(x1, y + 1, z1, u0, v0); + t->vertexUV(x1, y + 0, z1, u0, v2); + t->vertexUV(x0, y + 0, z1, u1, v2); + t->vertexUV(x0, y + 1, z1, u1, v0); - // small edge texture - if ( !s && !n ) - { - t->vertexUV( x1, y + 1, iz1, iu0, iv0 ); - t->vertexUV( x1, y + 0, iz1, iu0, iv2 ); - t->vertexUV( x1, y + 0, iz0, iu1, iv2 ); - t->vertexUV( x1, y + 1, iz0, iu1, iv0 ); + // small edge texture + if (!s && !n) { + t->vertexUV(x1, y + 1, iz1, iu0, iv0); + t->vertexUV(x1, y + 0, iz1, iu0, iv2); + t->vertexUV(x1, y + 0, iz0, iu1, iv2); + t->vertexUV(x1, y + 1, iz0, iu1, iv0); - t->vertexUV( x1, y + 1, iz0, iu0, iv0 ); - t->vertexUV( x1, y + 0, iz0, iu0, iv2 ); - t->vertexUV( x1, y + 0, iz1, iu1, iv2 ); - t->vertexUV( x1, y + 1, iz1, iu1, iv0 ); - } + t->vertexUV(x1, y + 1, iz0, iu0, iv0); + t->vertexUV(x1, y + 0, iz0, iu0, iv2); + t->vertexUV(x1, y + 0, iz1, iu1, iv2); + t->vertexUV(x1, y + 1, iz1, iu1, iv0); + } - if ( up || ( y < ( depth - 1 ) && level->isEmptyTile( x - 1, y + 1, z ) ) ) - { - // small edge texture - t->vertexUV( x0, y + 1 + noZFightingOffset, iz1, iu1, iv1 ); - t->vertexUV( x1, y + 1 + noZFightingOffset, iz1, iu1, iv2 ); - t->vertexUV( x1, y + 1 + noZFightingOffset, iz0, iu0, iv2 ); - t->vertexUV( x0, y + 1 + noZFightingOffset, iz0, iu0, iv1 ); + if (up || (y < (depth - 1) && level->isEmptyTile(x - 1, y + 1, z))) { + // small edge texture + t->vertexUV(x0, y + 1 + noZFightingOffset, iz1, iu1, iv1); + t->vertexUV(x1, y + 1 + noZFightingOffset, iz1, iu1, iv2); + t->vertexUV(x1, y + 1 + noZFightingOffset, iz0, iu0, iv2); + t->vertexUV(x0, y + 1 + noZFightingOffset, iz0, iu0, iv1); - t->vertexUV( x1, y + 1 + noZFightingOffset, iz1, iu1, iv1 ); - t->vertexUV( x0, y + 1 + noZFightingOffset, iz1, iu1, iv2 ); - t->vertexUV( x0, y + 1 + noZFightingOffset, iz0, iu0, iv2 ); - t->vertexUV( x1, y + 1 + noZFightingOffset, iz0, iu0, iv1 ); - } - if ( down || ( y > 1 && level->isEmptyTile( x - 1, y - 1, z ) ) ) - { - // small edge texture - t->vertexUV( x0, y - noZFightingOffset, iz1, iu1, iv1 ); - t->vertexUV( x1, y - noZFightingOffset, iz1, iu1, iv2 ); - t->vertexUV( x1, y - noZFightingOffset, iz0, iu0, iv2 ); - t->vertexUV( x0, y - noZFightingOffset, iz0, iu0, iv1 ); + t->vertexUV(x1, y + 1 + noZFightingOffset, iz1, iu1, iv1); + t->vertexUV(x0, y + 1 + noZFightingOffset, iz1, iu1, iv2); + t->vertexUV(x0, y + 1 + noZFightingOffset, iz0, iu0, iv2); + t->vertexUV(x1, y + 1 + noZFightingOffset, iz0, iu0, iv1); + } + if (down || (y > 1 && level->isEmptyTile(x - 1, y - 1, z))) { + // small edge texture + t->vertexUV(x0, y - noZFightingOffset, iz1, iu1, iv1); + t->vertexUV(x1, y - noZFightingOffset, iz1, iu1, iv2); + t->vertexUV(x1, y - noZFightingOffset, iz0, iu0, iv2); + t->vertexUV(x0, y - noZFightingOffset, iz0, iu0, iv1); - t->vertexUV( x1, y - noZFightingOffset, iz1, iu1, iv1 ); - t->vertexUV( x0, y - noZFightingOffset, iz1, iu1, iv2 ); - t->vertexUV( x0, y - noZFightingOffset, iz0, iu0, iv2 ); - t->vertexUV( x1, y - noZFightingOffset, iz0, iu0, iv1 ); - } + t->vertexUV(x1, y - noZFightingOffset, iz1, iu1, iv1); + t->vertexUV(x0, y - noZFightingOffset, iz1, iu1, iv2); + t->vertexUV(x0, y - noZFightingOffset, iz0, iu0, iv2); + t->vertexUV(x1, y - noZFightingOffset, iz0, iu0, iv1); + } - } - else if ( !w && e ) - { - // half-step towards east - t->vertexUV( x1, y + 1, z1, u1, v0 ); - t->vertexUV( x1, y + 0, z1, u1, v2 ); - t->vertexUV( x2, y + 0, z1, u2, v2 ); - t->vertexUV( x2, y + 1, z1, u2, v0 ); + } else if (!w && e) { + // half-step towards east + t->vertexUV(x1, y + 1, z1, u1, v0); + t->vertexUV(x1, y + 0, z1, u1, v2); + t->vertexUV(x2, y + 0, z1, u2, v2); + t->vertexUV(x2, y + 1, z1, u2, v0); - t->vertexUV( x2, y + 1, z1, u1, v0 ); - t->vertexUV( x2, y + 0, z1, u1, v2 ); - t->vertexUV( x1, y + 0, z1, u2, v2 ); - t->vertexUV( x1, y + 1, z1, u2, v0 ); + t->vertexUV(x2, y + 1, z1, u1, v0); + t->vertexUV(x2, y + 0, z1, u1, v2); + t->vertexUV(x1, y + 0, z1, u2, v2); + t->vertexUV(x1, y + 1, z1, u2, v0); - // small edge texture - if ( !s && !n ) - { - t->vertexUV( x1, y + 1, iz0, iu0, iv0 ); - t->vertexUV( x1, y + 0, iz0, iu0, iv2 ); - t->vertexUV( x1, y + 0, iz1, iu1, iv2 ); - t->vertexUV( x1, y + 1, iz1, iu1, iv0 ); + // small edge texture + if (!s && !n) { + t->vertexUV(x1, y + 1, iz0, iu0, iv0); + t->vertexUV(x1, y + 0, iz0, iu0, iv2); + t->vertexUV(x1, y + 0, iz1, iu1, iv2); + t->vertexUV(x1, y + 1, iz1, iu1, iv0); - t->vertexUV( x1, y + 1, iz1, iu0, iv0 ); - t->vertexUV( x1, y + 0, iz1, iu0, iv2 ); - t->vertexUV( x1, y + 0, iz0, iu1, iv2 ); - t->vertexUV( x1, y + 1, iz0, iu1, iv0 ); - } + t->vertexUV(x1, y + 1, iz1, iu0, iv0); + t->vertexUV(x1, y + 0, iz1, iu0, iv2); + t->vertexUV(x1, y + 0, iz0, iu1, iv2); + t->vertexUV(x1, y + 1, iz0, iu1, iv0); + } - if ( up || ( y < ( depth - 1 ) && level->isEmptyTile( x + 1, y + 1, z ) ) ) - { - // small edge texture - t->vertexUV( x1, y + 1 + noZFightingOffset, iz1, iu1, iv0 ); - t->vertexUV( x2, y + 1 + noZFightingOffset, iz1, iu1, iv1 ); - t->vertexUV( x2, y + 1 + noZFightingOffset, iz0, iu0, iv1 ); - t->vertexUV( x1, y + 1 + noZFightingOffset, iz0, iu0, iv0 ); + if (up || (y < (depth - 1) && level->isEmptyTile(x + 1, y + 1, z))) { + // small edge texture + t->vertexUV(x1, y + 1 + noZFightingOffset, iz1, iu1, iv0); + t->vertexUV(x2, y + 1 + noZFightingOffset, iz1, iu1, iv1); + t->vertexUV(x2, y + 1 + noZFightingOffset, iz0, iu0, iv1); + t->vertexUV(x1, y + 1 + noZFightingOffset, iz0, iu0, iv0); - t->vertexUV( x2, y + 1 + noZFightingOffset, iz1, iu1, iv0 ); - t->vertexUV( x1, y + 1 + noZFightingOffset, iz1, iu1, iv1 ); - t->vertexUV( x1, y + 1 + noZFightingOffset, iz0, iu0, iv1 ); - t->vertexUV( x2, y + 1 + noZFightingOffset, iz0, iu0, iv0 ); - } - if ( down || ( y > 1 && level->isEmptyTile( x + 1, y - 1, z ) ) ) - { - // small edge texture - t->vertexUV( x1, y - noZFightingOffset, iz1, iu1, iv0 ); - t->vertexUV( x2, y - noZFightingOffset, iz1, iu1, iv1 ); - t->vertexUV( x2, y - noZFightingOffset, iz0, iu0, iv1 ); - t->vertexUV( x1, y - noZFightingOffset, iz0, iu0, iv0 ); + t->vertexUV(x2, y + 1 + noZFightingOffset, iz1, iu1, iv0); + t->vertexUV(x1, y + 1 + noZFightingOffset, iz1, iu1, iv1); + t->vertexUV(x1, y + 1 + noZFightingOffset, iz0, iu0, iv1); + t->vertexUV(x2, y + 1 + noZFightingOffset, iz0, iu0, iv0); + } + if (down || (y > 1 && level->isEmptyTile(x + 1, y - 1, z))) { + // small edge texture + t->vertexUV(x1, y - noZFightingOffset, iz1, iu1, iv0); + t->vertexUV(x2, y - noZFightingOffset, iz1, iu1, iv1); + t->vertexUV(x2, y - noZFightingOffset, iz0, iu0, iv1); + t->vertexUV(x1, y - noZFightingOffset, iz0, iu0, iv0); - t->vertexUV( x2, y - noZFightingOffset, iz1, iu1, iv0 ); - t->vertexUV( x1, y - noZFightingOffset, iz1, iu1, iv1 ); - t->vertexUV( x1, y - noZFightingOffset, iz0, iu0, iv1 ); - t->vertexUV( x2, y - noZFightingOffset, iz0, iu0, iv0 ); - } + t->vertexUV(x2, y - noZFightingOffset, iz1, iu1, iv0); + t->vertexUV(x1, y - noZFightingOffset, iz1, iu1, iv1); + t->vertexUV(x1, y - noZFightingOffset, iz0, iu0, iv1); + t->vertexUV(x2, y - noZFightingOffset, iz0, iu0, iv0); + } + } - } + if ((n && s) || (!w && !e && !n && !s)) { + // straight north-south + t->vertexUV(x1, y + 1, z2, u0, v0); + t->vertexUV(x1, y + 0, z2, u0, v2); + t->vertexUV(x1, y + 0, z0, u2, v2); + t->vertexUV(x1, y + 1, z0, u2, v0); - if ( ( n && s ) || ( !w && !e && !n && !s ) ) - { - // straight north-south - t->vertexUV( x1, y + 1, z2, u0, v0 ); - t->vertexUV( x1, y + 0, z2, u0, v2 ); - t->vertexUV( x1, y + 0, z0, u2, v2 ); - t->vertexUV( x1, y + 1, z0, u2, v0 ); + t->vertexUV(x1, y + 1, z0, u0, v0); + t->vertexUV(x1, y + 0, z0, u0, v2); + t->vertexUV(x1, y + 0, z2, u2, v2); + t->vertexUV(x1, y + 1, z2, u2, v0); - t->vertexUV( x1, y + 1, z0, u0, v0 ); - t->vertexUV( x1, y + 0, z0, u0, v2 ); - t->vertexUV( x1, y + 0, z2, u2, v2 ); - t->vertexUV( x1, y + 1, z2, u2, v0 ); + if (up) { + // small edge texture + t->vertexUV(ix1, y + 1 + noZFightingOffset, z2, iu1, iv2); + t->vertexUV(ix1, y + 1 + noZFightingOffset, z0, iu1, iv0); + t->vertexUV(ix0, y + 1 + noZFightingOffset, z0, iu0, iv0); + t->vertexUV(ix0, y + 1 + noZFightingOffset, z2, iu0, iv2); - if ( up ) - { - // small edge texture - t->vertexUV( ix1, y + 1 + noZFightingOffset, z2, iu1, iv2 ); - t->vertexUV( ix1, y + 1 + noZFightingOffset, z0, iu1, iv0 ); - t->vertexUV( ix0, y + 1 + noZFightingOffset, z0, iu0, iv0 ); - t->vertexUV( ix0, y + 1 + noZFightingOffset, z2, iu0, iv2 ); + t->vertexUV(ix1, y + 1 + noZFightingOffset, z0, iu1, iv2); + t->vertexUV(ix1, y + 1 + noZFightingOffset, z2, iu1, iv0); + t->vertexUV(ix0, y + 1 + noZFightingOffset, z2, iu0, iv0); + t->vertexUV(ix0, y + 1 + noZFightingOffset, z0, iu0, iv2); + } else { + if (y < (depth - 1) && level->isEmptyTile(x, y + 1, z - 1)) { + t->vertexUV(ix0, y + 1 + noZFightingOffset, z0, iu1, iv0); + t->vertexUV(ix0, y + 1 + noZFightingOffset, z1, iu1, iv1); + t->vertexUV(ix1, y + 1 + noZFightingOffset, z1, iu0, iv1); + t->vertexUV(ix1, y + 1 + noZFightingOffset, z0, iu0, iv0); - t->vertexUV( ix1, y + 1 + noZFightingOffset, z0, iu1, iv2 ); - t->vertexUV( ix1, y + 1 + noZFightingOffset, z2, iu1, iv0 ); - t->vertexUV( ix0, y + 1 + noZFightingOffset, z2, iu0, iv0 ); - t->vertexUV( ix0, y + 1 + noZFightingOffset, z0, iu0, iv2 ); - } - else - { - if ( y < ( depth - 1 ) && level->isEmptyTile( x, y + 1, z - 1 ) ) - { - t->vertexUV( ix0, y + 1 + noZFightingOffset, z0, iu1, iv0 ); - t->vertexUV( ix0, y + 1 + noZFightingOffset, z1, iu1, iv1 ); - t->vertexUV( ix1, y + 1 + noZFightingOffset, z1, iu0, iv1 ); - t->vertexUV( ix1, y + 1 + noZFightingOffset, z0, iu0, iv0 ); + t->vertexUV(ix0, y + 1 + noZFightingOffset, z1, iu1, iv0); + t->vertexUV(ix0, y + 1 + noZFightingOffset, z0, iu1, iv1); + t->vertexUV(ix1, y + 1 + noZFightingOffset, z0, iu0, iv1); + t->vertexUV(ix1, y + 1 + noZFightingOffset, z1, iu0, iv0); + } + if (y < (depth - 1) && level->isEmptyTile(x, y + 1, z + 1)) { + t->vertexUV(ix0, y + 1 + noZFightingOffset, z1, iu0, iv1); + t->vertexUV(ix0, y + 1 + noZFightingOffset, z2, iu0, iv2); + t->vertexUV(ix1, y + 1 + noZFightingOffset, z2, iu1, iv2); + t->vertexUV(ix1, y + 1 + noZFightingOffset, z1, iu1, iv1); - t->vertexUV( ix0, y + 1 + noZFightingOffset, z1, iu1, iv0 ); - t->vertexUV( ix0, y + 1 + noZFightingOffset, z0, iu1, iv1 ); - t->vertexUV( ix1, y + 1 + noZFightingOffset, z0, iu0, iv1 ); - t->vertexUV( ix1, y + 1 + noZFightingOffset, z1, iu0, iv0 ); - } - if ( y < ( depth - 1 ) && level->isEmptyTile( x, y + 1, z + 1 ) ) - { - t->vertexUV( ix0, y + 1 + noZFightingOffset, z1, iu0, iv1 ); - t->vertexUV( ix0, y + 1 + noZFightingOffset, z2, iu0, iv2 ); - t->vertexUV( ix1, y + 1 + noZFightingOffset, z2, iu1, iv2 ); - t->vertexUV( ix1, y + 1 + noZFightingOffset, z1, iu1, iv1 ); + t->vertexUV(ix0, y + 1 + noZFightingOffset, z2, iu0, iv1); + t->vertexUV(ix0, y + 1 + noZFightingOffset, z1, iu0, iv2); + t->vertexUV(ix1, y + 1 + noZFightingOffset, z1, iu1, iv2); + t->vertexUV(ix1, y + 1 + noZFightingOffset, z2, iu1, iv1); + } + } + if (down) { + // small edge texture + t->vertexUV(ix1, y - noZFightingOffset, z2, iu1, iv2); + t->vertexUV(ix1, y - noZFightingOffset, z0, iu1, iv0); + t->vertexUV(ix0, y - noZFightingOffset, z0, iu0, iv0); + t->vertexUV(ix0, y - noZFightingOffset, z2, iu0, iv2); - t->vertexUV( ix0, y + 1 + noZFightingOffset, z2, iu0, iv1 ); - t->vertexUV( ix0, y + 1 + noZFightingOffset, z1, iu0, iv2 ); - t->vertexUV( ix1, y + 1 + noZFightingOffset, z1, iu1, iv2 ); - t->vertexUV( ix1, y + 1 + noZFightingOffset, z2, iu1, iv1 ); - } - } - if ( down ) - { - // small edge texture - t->vertexUV( ix1, y - noZFightingOffset, z2, iu1, iv2 ); - t->vertexUV( ix1, y - noZFightingOffset, z0, iu1, iv0 ); - t->vertexUV( ix0, y - noZFightingOffset, z0, iu0, iv0 ); - t->vertexUV( ix0, y - noZFightingOffset, z2, iu0, iv2 ); + t->vertexUV(ix1, y - noZFightingOffset, z0, iu1, iv2); + t->vertexUV(ix1, y - noZFightingOffset, z2, iu1, iv0); + t->vertexUV(ix0, y - noZFightingOffset, z2, iu0, iv0); + t->vertexUV(ix0, y - noZFightingOffset, z0, iu0, iv2); + } else { + if (y > 1 && level->isEmptyTile(x, y - 1, z - 1)) { + // north half-step + t->vertexUV(ix0, y - noZFightingOffset, z0, iu1, iv0); + t->vertexUV(ix0, y - noZFightingOffset, z1, iu1, iv1); + t->vertexUV(ix1, y - noZFightingOffset, z1, iu0, iv1); + t->vertexUV(ix1, y - noZFightingOffset, z0, iu0, iv0); - t->vertexUV( ix1, y - noZFightingOffset, z0, iu1, iv2 ); - t->vertexUV( ix1, y - noZFightingOffset, z2, iu1, iv0 ); - t->vertexUV( ix0, y - noZFightingOffset, z2, iu0, iv0 ); - t->vertexUV( ix0, y - noZFightingOffset, z0, iu0, iv2 ); - } - else - { - if ( y > 1 && level->isEmptyTile( x, y - 1, z - 1 ) ) - { - // north half-step - t->vertexUV( ix0, y - noZFightingOffset, z0, iu1, iv0 ); - t->vertexUV( ix0, y - noZFightingOffset, z1, iu1, iv1 ); - t->vertexUV( ix1, y - noZFightingOffset, z1, iu0, iv1 ); - t->vertexUV( ix1, y - noZFightingOffset, z0, iu0, iv0 ); + t->vertexUV(ix0, y - noZFightingOffset, z1, iu1, iv0); + t->vertexUV(ix0, y - noZFightingOffset, z0, iu1, iv1); + t->vertexUV(ix1, y - noZFightingOffset, z0, iu0, iv1); + t->vertexUV(ix1, y - noZFightingOffset, z1, iu0, iv0); + } + if (y > 1 && level->isEmptyTile(x, y - 1, z + 1)) { + // south half-step + t->vertexUV(ix0, y - noZFightingOffset, z1, iu0, iv1); + t->vertexUV(ix0, y - noZFightingOffset, z2, iu0, iv2); + t->vertexUV(ix1, y - noZFightingOffset, z2, iu1, iv2); + t->vertexUV(ix1, y - noZFightingOffset, z1, iu1, iv1); - t->vertexUV( ix0, y - noZFightingOffset, z1, iu1, iv0 ); - t->vertexUV( ix0, y - noZFightingOffset, z0, iu1, iv1 ); - t->vertexUV( ix1, y - noZFightingOffset, z0, iu0, iv1 ); - t->vertexUV( ix1, y - noZFightingOffset, z1, iu0, iv0 ); - } - if ( y > 1 && level->isEmptyTile( x, y - 1, z + 1 ) ) - { - // south half-step - t->vertexUV( ix0, y - noZFightingOffset, z1, iu0, iv1 ); - t->vertexUV( ix0, y - noZFightingOffset, z2, iu0, iv2 ); - t->vertexUV( ix1, y - noZFightingOffset, z2, iu1, iv2 ); - t->vertexUV( ix1, y - noZFightingOffset, z1, iu1, iv1 ); + t->vertexUV(ix0, y - noZFightingOffset, z2, iu0, iv1); + t->vertexUV(ix0, y - noZFightingOffset, z1, iu0, iv2); + t->vertexUV(ix1, y - noZFightingOffset, z1, iu1, iv2); + t->vertexUV(ix1, y - noZFightingOffset, z2, iu1, iv1); + } + } - t->vertexUV( ix0, y - noZFightingOffset, z2, iu0, iv1 ); - t->vertexUV( ix0, y - noZFightingOffset, z1, iu0, iv2 ); - t->vertexUV( ix1, y - noZFightingOffset, z1, iu1, iv2 ); - t->vertexUV( ix1, y - noZFightingOffset, z2, iu1, iv1 ); - } - } + } else if (n && !s) { + // half-step towards north + t->vertexUV(x1, y + 1, z0, u0, v0); + t->vertexUV(x1, y + 0, z0, u0, v2); + t->vertexUV(x1, y + 0, z1, u1, v2); + t->vertexUV(x1, y + 1, z1, u1, v0); - } - else if ( n && !s ) - { - // half-step towards north - t->vertexUV( x1, y + 1, z0, u0, v0 ); - t->vertexUV( x1, y + 0, z0, u0, v2 ); - t->vertexUV( x1, y + 0, z1, u1, v2 ); - t->vertexUV( x1, y + 1, z1, u1, v0 ); + t->vertexUV(x1, y + 1, z1, u0, v0); + t->vertexUV(x1, y + 0, z1, u0, v2); + t->vertexUV(x1, y + 0, z0, u1, v2); + t->vertexUV(x1, y + 1, z0, u1, v0); - t->vertexUV( x1, y + 1, z1, u0, v0 ); - t->vertexUV( x1, y + 0, z1, u0, v2 ); - t->vertexUV( x1, y + 0, z0, u1, v2 ); - t->vertexUV( x1, y + 1, z0, u1, v0 ); + // small edge texture + if (!e && !w) { + t->vertexUV(ix0, y + 1, z1, iu0, iv0); + t->vertexUV(ix0, y + 0, z1, iu0, iv2); + t->vertexUV(ix1, y + 0, z1, iu1, iv2); + t->vertexUV(ix1, y + 1, z1, iu1, iv0); - // small edge texture - if ( !e && !w ) - { - t->vertexUV( ix0, y + 1, z1, iu0, iv0 ); - t->vertexUV( ix0, y + 0, z1, iu0, iv2 ); - t->vertexUV( ix1, y + 0, z1, iu1, iv2 ); - t->vertexUV( ix1, y + 1, z1, iu1, iv0 ); + t->vertexUV(ix1, y + 1, z1, iu0, iv0); + t->vertexUV(ix1, y + 0, z1, iu0, iv2); + t->vertexUV(ix0, y + 0, z1, iu1, iv2); + t->vertexUV(ix0, y + 1, z1, iu1, iv0); + } - t->vertexUV( ix1, y + 1, z1, iu0, iv0 ); - t->vertexUV( ix1, y + 0, z1, iu0, iv2 ); - t->vertexUV( ix0, y + 0, z1, iu1, iv2 ); - t->vertexUV( ix0, y + 1, z1, iu1, iv0 ); - } + if (up || (y < (depth - 1) && level->isEmptyTile(x, y + 1, z - 1))) { + // small edge texture + t->vertexUV(ix0, y + 1 + noZFightingOffset, z0, iu1, iv0); + t->vertexUV(ix0, y + 1 + noZFightingOffset, z1, iu1, iv1); + t->vertexUV(ix1, y + 1 + noZFightingOffset, z1, iu0, iv1); + t->vertexUV(ix1, y + 1 + noZFightingOffset, z0, iu0, iv0); - if ( up || ( y < ( depth - 1 ) && level->isEmptyTile( x, y + 1, z - 1 ) ) ) - { - // small edge texture - t->vertexUV( ix0, y + 1 + noZFightingOffset, z0, iu1, iv0 ); - t->vertexUV( ix0, y + 1 + noZFightingOffset, z1, iu1, iv1 ); - t->vertexUV( ix1, y + 1 + noZFightingOffset, z1, iu0, iv1 ); - t->vertexUV( ix1, y + 1 + noZFightingOffset, z0, iu0, iv0 ); + t->vertexUV(ix0, y + 1 + noZFightingOffset, z1, iu1, iv0); + t->vertexUV(ix0, y + 1 + noZFightingOffset, z0, iu1, iv1); + t->vertexUV(ix1, y + 1 + noZFightingOffset, z0, iu0, iv1); + t->vertexUV(ix1, y + 1 + noZFightingOffset, z1, iu0, iv0); + } - t->vertexUV( ix0, y + 1 + noZFightingOffset, z1, iu1, iv0 ); - t->vertexUV( ix0, y + 1 + noZFightingOffset, z0, iu1, iv1 ); - t->vertexUV( ix1, y + 1 + noZFightingOffset, z0, iu0, iv1 ); - t->vertexUV( ix1, y + 1 + noZFightingOffset, z1, iu0, iv0 ); - } + if (down || (y > 1 && level->isEmptyTile(x, y - 1, z - 1))) { + // small edge texture + t->vertexUV(ix0, y - noZFightingOffset, z0, iu1, iv0); + t->vertexUV(ix0, y - noZFightingOffset, z1, iu1, iv1); + t->vertexUV(ix1, y - noZFightingOffset, z1, iu0, iv1); + t->vertexUV(ix1, y - noZFightingOffset, z0, iu0, iv0); - if ( down || ( y > 1 && level->isEmptyTile( x, y - 1, z - 1 ) ) ) - { - // small edge texture - t->vertexUV( ix0, y - noZFightingOffset, z0, iu1, iv0 ); - t->vertexUV( ix0, y - noZFightingOffset, z1, iu1, iv1 ); - t->vertexUV( ix1, y - noZFightingOffset, z1, iu0, iv1 ); - t->vertexUV( ix1, y - noZFightingOffset, z0, iu0, iv0 ); + t->vertexUV(ix0, y - noZFightingOffset, z1, iu1, iv0); + t->vertexUV(ix0, y - noZFightingOffset, z0, iu1, iv1); + t->vertexUV(ix1, y - noZFightingOffset, z0, iu0, iv1); + t->vertexUV(ix1, y - noZFightingOffset, z1, iu0, iv0); + } - t->vertexUV( ix0, y - noZFightingOffset, z1, iu1, iv0 ); - t->vertexUV( ix0, y - noZFightingOffset, z0, iu1, iv1 ); - t->vertexUV( ix1, y - noZFightingOffset, z0, iu0, iv1 ); - t->vertexUV( ix1, y - noZFightingOffset, z1, iu0, iv0 ); - } + } else if (!n && s) { + // half-step towards south + t->vertexUV(x1, y + 1, z1, u1, v0); + t->vertexUV(x1, y + 0, z1, u1, v2); + t->vertexUV(x1, y + 0, z2, u2, v2); + t->vertexUV(x1, y + 1, z2, u2, v0); - } - else if ( !n && s ) - { - // half-step towards south - t->vertexUV( x1, y + 1, z1, u1, v0 ); - t->vertexUV( x1, y + 0, z1, u1, v2 ); - t->vertexUV( x1, y + 0, z2, u2, v2 ); - t->vertexUV( x1, y + 1, z2, u2, v0 ); + t->vertexUV(x1, y + 1, z2, u1, v0); + t->vertexUV(x1, y + 0, z2, u1, v2); + t->vertexUV(x1, y + 0, z1, u2, v2); + t->vertexUV(x1, y + 1, z1, u2, v0); - t->vertexUV( x1, y + 1, z2, u1, v0 ); - t->vertexUV( x1, y + 0, z2, u1, v2 ); - t->vertexUV( x1, y + 0, z1, u2, v2 ); - t->vertexUV( x1, y + 1, z1, u2, v0 ); + // small edge texture + if (!e && !w) { + t->vertexUV(ix1, y + 1, z1, iu0, iv0); + t->vertexUV(ix1, y + 0, z1, iu0, iv2); + t->vertexUV(ix0, y + 0, z1, iu1, iv2); + t->vertexUV(ix0, y + 1, z1, iu1, iv0); - // small edge texture - if ( !e && !w ) - { - t->vertexUV( ix1, y + 1, z1, iu0, iv0 ); - t->vertexUV( ix1, y + 0, z1, iu0, iv2 ); - t->vertexUV( ix0, y + 0, z1, iu1, iv2 ); - t->vertexUV( ix0, y + 1, z1, iu1, iv0 ); + t->vertexUV(ix0, y + 1, z1, iu0, iv0); + t->vertexUV(ix0, y + 0, z1, iu0, iv2); + t->vertexUV(ix1, y + 0, z1, iu1, iv2); + t->vertexUV(ix1, y + 1, z1, iu1, iv0); + } - t->vertexUV( ix0, y + 1, z1, iu0, iv0 ); - t->vertexUV( ix0, y + 0, z1, iu0, iv2 ); - t->vertexUV( ix1, y + 0, z1, iu1, iv2 ); - t->vertexUV( ix1, y + 1, z1, iu1, iv0 ); - } + if (up || (y < (depth - 1) && level->isEmptyTile(x, y + 1, z + 1))) { + // small edge texture + t->vertexUV(ix0, y + 1 + noZFightingOffset, z1, iu0, iv1); + t->vertexUV(ix0, y + 1 + noZFightingOffset, z2, iu0, iv2); + t->vertexUV(ix1, y + 1 + noZFightingOffset, z2, iu1, iv2); + t->vertexUV(ix1, y + 1 + noZFightingOffset, z1, iu1, iv1); - if ( up || ( y < ( depth - 1 ) && level->isEmptyTile( x, y + 1, z + 1 ) ) ) - { - // small edge texture - t->vertexUV( ix0, y + 1 + noZFightingOffset, z1, iu0, iv1 ); - t->vertexUV( ix0, y + 1 + noZFightingOffset, z2, iu0, iv2 ); - t->vertexUV( ix1, y + 1 + noZFightingOffset, z2, iu1, iv2 ); - t->vertexUV( ix1, y + 1 + noZFightingOffset, z1, iu1, iv1 ); + t->vertexUV(ix0, y + 1 + noZFightingOffset, z2, iu0, iv1); + t->vertexUV(ix0, y + 1 + noZFightingOffset, z1, iu0, iv2); + t->vertexUV(ix1, y + 1 + noZFightingOffset, z1, iu1, iv2); + t->vertexUV(ix1, y + 1 + noZFightingOffset, z2, iu1, iv1); + } + if (down || (y > 1 && level->isEmptyTile(x, y - 1, z + 1))) { + // small edge texture + t->vertexUV(ix0, y - noZFightingOffset, z1, iu0, iv1); + t->vertexUV(ix0, y - noZFightingOffset, z2, iu0, iv2); + t->vertexUV(ix1, y - noZFightingOffset, z2, iu1, iv2); + t->vertexUV(ix1, y - noZFightingOffset, z1, iu1, iv1); - t->vertexUV( ix0, y + 1 + noZFightingOffset, z2, iu0, iv1 ); - t->vertexUV( ix0, y + 1 + noZFightingOffset, z1, iu0, iv2 ); - t->vertexUV( ix1, y + 1 + noZFightingOffset, z1, iu1, iv2 ); - t->vertexUV( ix1, y + 1 + noZFightingOffset, z2, iu1, iv1 ); - } - if ( down || ( y > 1 && level->isEmptyTile( x, y - 1, z + 1 ) ) ) - { - // small edge texture - t->vertexUV( ix0, y - noZFightingOffset, z1, iu0, iv1 ); - t->vertexUV( ix0, y - noZFightingOffset, z2, iu0, iv2 ); - t->vertexUV( ix1, y - noZFightingOffset, z2, iu1, iv2 ); - t->vertexUV( ix1, y - noZFightingOffset, z1, iu1, iv1 ); + t->vertexUV(ix0, y - noZFightingOffset, z2, iu0, iv1); + t->vertexUV(ix0, y - noZFightingOffset, z1, iu0, iv2); + t->vertexUV(ix1, y - noZFightingOffset, z1, iu1, iv2); + t->vertexUV(ix1, y - noZFightingOffset, z2, iu1, iv1); + } + } +#endif // DISABLE_TESS_FUNCS - t->vertexUV( ix0, y - noZFightingOffset, z2, iu0, iv1 ); - t->vertexUV( ix0, y - noZFightingOffset, z1, iu0, iv2 ); - t->vertexUV( ix1, y - noZFightingOffset, z1, iu1, iv2 ); - t->vertexUV( ix1, y - noZFightingOffset, z2, iu1, iv1 ); - } - - } -#endif // DISABLE_TESS_FUNCS - - return true; + return true; } -bool TileRenderer_SPU::tesselateCrossInWorld( Tile_SPU* tt, int x, int y, int z ) -{ - Tesselator_SPU* t = getTesselator(); +bool TileRenderer_SPU::tesselateCrossInWorld(Tile_SPU* tt, int x, int y, + int z) { + Tesselator_SPU* t = getTesselator(); - float br; - if ( SharedConstants::TEXTURE_LIGHTING ) - { - t->tex2( tt->getLightColor( level, x, y, z ) ); - br = 1; - } - else - { - br = tt->getBrightness( level, x, y, z ); - } + float br; + if (SharedConstants::TEXTURE_LIGHTING) { + t->tex2(tt->getLightColor(level, x, y, z)); + br = 1; + } else { + br = tt->getBrightness(level, x, y, z); + } - int col = tt->getColor( level, x, y, z ); - float r = ( ( col >> 16 ) & 0xff ) / 255.0f; - float g = ( ( col >> 8 ) & 0xff ) / 255.0f; - float b = ( ( col )& 0xff ) / 255.0f; + int col = tt->getColor(level, x, y, z); + float r = ((col >> 16) & 0xff) / 255.0f; + float g = ((col >> 8) & 0xff) / 255.0f; + float b = ((col) & 0xff) / 255.0f; - if ( isAnaglyph3d() ) - { - float cr = ( r * 30 + g * 59 + b * 11 ) / 100; - float cg = ( r * 30 + g * 70 ) / ( 100 ); - float cb = ( r * 30 + b * 70 ) / ( 100 ); + if (isAnaglyph3d()) { + float cr = (r * 30 + g * 59 + b * 11) / 100; + float cg = (r * 30 + g * 70) / (100); + float cb = (r * 30 + b * 70) / (100); - r = cr; - g = cg; - b = cb; - } - t->color( br * r, br * g, br * b ); + r = cr; + g = cg; + b = cb; + } + t->color(br * r, br * g, br * b); - float xt = (float)x; - float yt = (float)y; - float zt = (float)z; + float xt = (float)x; + float yt = (float)y; + float zt = (float)z; - if (tt->id == Tile_SPU::tallgrass_Id) - { - int64_t seed = (x * 3129871) ^ (z * 116129781l) ^ (y); - seed = seed * seed * 42317861 + seed * 11; - - xt += ((((seed >> 16) & 0xf) / 15.0f) - 0.5f) * 0.5f; - yt += ((((seed >> 20) & 0xf) / 15.0f) - 1.0f) * 0.2f; - zt += ((((seed >> 24) & 0xf) / 15.0f) - 0.5f) * 0.5f; - } + if (tt->id == Tile_SPU::tallgrass_Id) { + int64_t seed = (x * 3129871) ^ (z * 116129781l) ^ (y); + seed = seed * seed * 42317861 + seed * 11; - tesselateCrossTexture( tt, level->getData( x, y, z ), xt, yt, zt, 1 ); - return true; + xt += ((((seed >> 16) & 0xf) / 15.0f) - 0.5f) * 0.5f; + yt += ((((seed >> 20) & 0xf) / 15.0f) - 1.0f) * 0.2f; + zt += ((((seed >> 24) & 0xf) / 15.0f) - 0.5f) * 0.5f; + } + + tesselateCrossTexture(tt, level->getData(x, y, z), xt, yt, zt, 1); + return true; } -bool TileRenderer_SPU::tesselateStemInWorld( Tile_SPU* _tt, int x, int y, int z ) -{ - StemTile_SPU* tt = ( StemTile_SPU* )_tt; - Tesselator_SPU* t = getTesselator(); +bool TileRenderer_SPU::tesselateStemInWorld(Tile_SPU* _tt, int x, int y, + int z) { + StemTile_SPU* tt = (StemTile_SPU*)_tt; + Tesselator_SPU* t = getTesselator(); - float br; - if ( SharedConstants::TEXTURE_LIGHTING ) - { - t->tex2( tt->getLightColor( level, x, y, z ) ); - br = 1; - } - else - { - br = tt->getBrightness( level, x, y, z ); - } - int col = tt->getColor( level, x, y, z ); - float r = ( ( col >> 16 ) & 0xff ) / 255.0f; - float g = ( ( col >> 8 ) & 0xff ) / 255.0f; - float b = ( ( col )& 0xff ) / 255.0f; + float br; + if (SharedConstants::TEXTURE_LIGHTING) { + t->tex2(tt->getLightColor(level, x, y, z)); + br = 1; + } else { + br = tt->getBrightness(level, x, y, z); + } + int col = tt->getColor(level, x, y, z); + float r = ((col >> 16) & 0xff) / 255.0f; + float g = ((col >> 8) & 0xff) / 255.0f; + float b = ((col) & 0xff) / 255.0f; - if ( isAnaglyph3d()) - { - float cr = ( r * 30.0f + g * 59.0f + b * 11.0f ) / 100.0f; - float cg = ( r * 30.0f + g * 70.0f ) / ( 100.0f ); - float cb = ( r * 30.0f + b * 70.0f ) / ( 100.0f ); + if (isAnaglyph3d()) { + float cr = (r * 30.0f + g * 59.0f + b * 11.0f) / 100.0f; + float cg = (r * 30.0f + g * 70.0f) / (100.0f); + float cb = (r * 30.0f + b * 70.0f) / (100.0f); - r = cr; - g = cg; - b = cb; - } - t->color( br * r, br * g, br * b ); + r = cr; + g = cg; + b = cb; + } + t->color(br * r, br * g, br * b); - tt->updateShape( level, x, y, z ); - int dir = tt->getConnectDir( level, x, y, z ); - if ( dir < 0 ) - { - tesselateStemTexture( tt, level->getData( x, y, z ), tileShapeY1, x, y - 1 / 16.0f, z ); - } - else - { - tesselateStemTexture( tt, level->getData( x, y, z ), 0.5f, x, y - 1 / 16.0f, z ); - tesselateStemDirTexture( tt, level->getData( x, y, z ), dir, tileShapeY1, x, y - 1 / 16.0f, z ); - } - return true; + tt->updateShape(level, x, y, z); + int dir = tt->getConnectDir(level, x, y, z); + if (dir < 0) { + tesselateStemTexture(tt, level->getData(x, y, z), tileShapeY1, x, + y - 1 / 16.0f, z); + } else { + tesselateStemTexture(tt, level->getData(x, y, z), 0.5f, x, + y - 1 / 16.0f, z); + tesselateStemDirTexture(tt, level->getData(x, y, z), dir, tileShapeY1, + x, y - 1 / 16.0f, z); + } + return true; } -bool TileRenderer_SPU::tesselateRowInWorld( Tile_SPU* tt, int x, int y, int z ) -{ - Tesselator_SPU* t = getTesselator(); +bool TileRenderer_SPU::tesselateRowInWorld(Tile_SPU* tt, int x, int y, int z) { + Tesselator_SPU* t = getTesselator(); - if ( SharedConstants::TEXTURE_LIGHTING ) - { - t->tex2( tt->getLightColor( level, x, y, z ) ); - t->color( 1.0f, 1.0f, 1.0f ); - } - else - { - float br = tt->getBrightness( level, x, y, z ); - t->color( br, br, br ); - } + if (SharedConstants::TEXTURE_LIGHTING) { + t->tex2(tt->getLightColor(level, x, y, z)); + t->color(1.0f, 1.0f, 1.0f); + } else { + float br = tt->getBrightness(level, x, y, z); + t->color(br, br, br); + } - tesselateRowTexture( tt, level->getData( x, y, z ), x, y - 1.0f / 16.0f, z ); - return true; + tesselateRowTexture(tt, level->getData(x, y, z), x, y - 1.0f / 16.0f, z); + return true; } -void TileRenderer_SPU::tesselateTorch( Tile_SPU* tt, float x, float y, float z, float xxa, float zza, int data ) -{ - Tesselator_SPU* t = getTesselator(); +void TileRenderer_SPU::tesselateTorch(Tile_SPU* tt, float x, float y, float z, + float xxa, float zza, int data) { + Tesselator_SPU* t = getTesselator(); - Icon_SPU *tex = getTexture(tt, Facing::DOWN, data); + Icon_SPU* tex = getTexture(tt, Facing::DOWN, data); - if (hasFixedTexture()) tex = fixedTexture; - float u0 = tex->getU0(); - float v0 = tex->getV0(); - float u1 = tex->getU1(); - float v1 = tex->getV1(); + if (hasFixedTexture()) tex = fixedTexture; + float u0 = tex->getU0(); + float v0 = tex->getV0(); + float u1 = tex->getU1(); + float v1 = tex->getV1(); - float ut0 = tex->getU(7); - float vt0 = tex->getV(6); - float ut1 = tex->getU(9); - float vt1 = tex->getV(8); + float ut0 = tex->getU(7); + float vt0 = tex->getV(6); + float ut1 = tex->getU(9); + float vt1 = tex->getV(8); - float ub0 = tex->getU(7); - float vb0 = tex->getV(13); - float ub1 = tex->getU(9); - float vb1 = tex->getV(15); + float ub0 = tex->getU(7); + float vb0 = tex->getV(13); + float ub1 = tex->getU(9); + float vb1 = tex->getV(15); - x += 0.5f; - z += 0.5f; + x += 0.5f; + z += 0.5f; - float x0 = x - 0.5f; - float x1 = x + 0.5f; - float z0 = z - 0.5f; - float z1 = z + 0.5f; - float r = 1 / 16.0f; + float x0 = x - 0.5f; + float x1 = x + 0.5f; + float z0 = z - 0.5f; + float z1 = z + 0.5f; + float r = 1 / 16.0f; - float h = 10.0f / 16.0f; - t->vertexUV( ( float )( x + xxa * ( 1 - h ) - r ), ( float )( y + h ), ( float )( z + zza * ( 1 - h ) - r ), ut0, vt0 ); - t->vertexUV( ( float )( x + xxa * ( 1 - h ) - r ), ( float )( y + h ), ( float )( z + zza * ( 1 - h ) + r ), ut0, vt1 ); - t->vertexUV( ( float )( x + xxa * ( 1 - h ) + r ), ( float )( y + h ), ( float )( z + zza * ( 1 - h ) + r ), ut1, vt1 ); - t->vertexUV( ( float )( x + xxa * ( 1 - h ) + r ), ( float )( y + h ), ( float )( z + zza * ( 1 - h ) - r ), ut1, vt0 ); + float h = 10.0f / 16.0f; + t->vertexUV((float)(x + xxa * (1 - h) - r), (float)(y + h), + (float)(z + zza * (1 - h) - r), ut0, vt0); + t->vertexUV((float)(x + xxa * (1 - h) - r), (float)(y + h), + (float)(z + zza * (1 - h) + r), ut0, vt1); + t->vertexUV((float)(x + xxa * (1 - h) + r), (float)(y + h), + (float)(z + zza * (1 - h) + r), ut1, vt1); + t->vertexUV((float)(x + xxa * (1 - h) + r), (float)(y + h), + (float)(z + zza * (1 - h) - r), ut1, vt0); - t->vertexUV( (float)(x + r + xxa), (float) y, (float)(z - r + zza), ub1, vb0); - t->vertexUV( (float)(x + r + xxa), (float) y, (float)(z + r + zza), ub1, vb1); - t->vertexUV( (float)(x - r + xxa), (float) y, (float)(z + r + zza), ub0, vb1); - t->vertexUV( (float)(x - r + xxa), (float) y, (float)(z - r + zza), ub0, vb0); + t->vertexUV((float)(x + r + xxa), (float)y, (float)(z - r + zza), ub1, vb0); + t->vertexUV((float)(x + r + xxa), (float)y, (float)(z + r + zza), ub1, vb1); + t->vertexUV((float)(x - r + xxa), (float)y, (float)(z + r + zza), ub0, vb1); + t->vertexUV((float)(x - r + xxa), (float)y, (float)(z - r + zza), ub0, vb0); - t->vertexUV( ( float )( x - r ), ( float )( y + 1 ), ( float )( z0 ), ( float )( u0 ), ( float )( v0 ) ); - t->vertexUV( ( float )( x - r + xxa ), ( float )( y + 0 ), ( float )( z0 + - zza ), ( float )( u0 ), ( float )( v1 ) ); - t->vertexUV( ( float )( x - r + xxa ), ( float )( y + 0 ), ( float )( z1 + - zza ), ( float )( u1 ), ( float )( v1 ) ); - t->vertexUV( ( float )( x - r ), ( float )( y + 1 ), ( float )( z1 ), ( float )( u1 ), ( float )( v0 ) ); + t->vertexUV((float)(x - r), (float)(y + 1), (float)(z0), (float)(u0), + (float)(v0)); + t->vertexUV((float)(x - r + xxa), (float)(y + 0), (float)(z0 + zza), + (float)(u0), (float)(v1)); + t->vertexUV((float)(x - r + xxa), (float)(y + 0), (float)(z1 + zza), + (float)(u1), (float)(v1)); + t->vertexUV((float)(x - r), (float)(y + 1), (float)(z1), (float)(u1), + (float)(v0)); - t->vertexUV( ( float )( x + r ), ( float )( y + 1 ), ( float )( z1 ), ( float )( u0 ), ( float )( v0 ) ); - t->vertexUV( ( float )( x + xxa + r ), ( float )( y + 0 ), ( float )( z1 + - zza ), ( float )( u0 ), ( float )( v1 ) ); - t->vertexUV( ( float )( x + xxa + r ), ( float )( y + 0 ), ( float )( z0 + - zza ), ( float )( u1 ), ( float )( v1 ) ); - t->vertexUV( ( float )( x + r ), ( float )( y + 1 ), ( float )( z0 ), ( float )( u1 ), ( float )( v0 ) ); + t->vertexUV((float)(x + r), (float)(y + 1), (float)(z1), (float)(u0), + (float)(v0)); + t->vertexUV((float)(x + xxa + r), (float)(y + 0), (float)(z1 + zza), + (float)(u0), (float)(v1)); + t->vertexUV((float)(x + xxa + r), (float)(y + 0), (float)(z0 + zza), + (float)(u1), (float)(v1)); + t->vertexUV((float)(x + r), (float)(y + 1), (float)(z0), (float)(u1), + (float)(v0)); - t->vertexUV( ( float )( x0 ), ( float )( y + 1 ), ( float )( z + r ), ( float )( u0 ), ( float )( v0 ) ); - t->vertexUV( ( float )( x0 + xxa ), ( float )( y + 0 ), ( float )( z + r + - zza ), ( float )( u0 ), ( float )( v1 ) ); - t->vertexUV( ( float )( x1 + xxa ), ( float )( y + 0 ), ( float )( z + r + - zza ), ( float )( u1 ), ( float )( v1 ) ); - t->vertexUV( ( float )( x1 ), ( float )( y + 1 ), ( float )( z + r ), ( float )( u1 ), ( float )( v0 ) ); + t->vertexUV((float)(x0), (float)(y + 1), (float)(z + r), (float)(u0), + (float)(v0)); + t->vertexUV((float)(x0 + xxa), (float)(y + 0), (float)(z + r + zza), + (float)(u0), (float)(v1)); + t->vertexUV((float)(x1 + xxa), (float)(y + 0), (float)(z + r + zza), + (float)(u1), (float)(v1)); + t->vertexUV((float)(x1), (float)(y + 1), (float)(z + r), (float)(u1), + (float)(v0)); - t->vertexUV( ( float )( x1 ), ( float )( y + 1 ), ( float )( z - r ), ( float )( u0 ), ( float )( v0 ) ); - t->vertexUV( ( float )( x1 + xxa ), ( float )( y + 0 ), ( float )( z - r + - zza ), ( float )( u0 ), ( float )( v1 ) ); - t->vertexUV( ( float )( x0 + xxa ), ( float )( y + 0 ), ( float )( z - r + - zza ), ( float )( u1 ), ( float )( v1 ) ); - t->vertexUV( ( float )( x0 ), ( float )( y + 1 ), ( float )( z - r ), ( float )( u1 ), ( float )( v0 ) ); + t->vertexUV((float)(x1), (float)(y + 1), (float)(z - r), (float)(u0), + (float)(v0)); + t->vertexUV((float)(x1 + xxa), (float)(y + 0), (float)(z - r + zza), + (float)(u0), (float)(v1)); + t->vertexUV((float)(x0 + xxa), (float)(y + 0), (float)(z - r + zza), + (float)(u1), (float)(v1)); + t->vertexUV((float)(x0), (float)(y + 1), (float)(z - r), (float)(u1), + (float)(v0)); } -void TileRenderer_SPU::tesselateCrossTexture( Tile_SPU* tt, int data, float x, float y, float z, float scale ) -{ - Tesselator_SPU* t = getTesselator(); +void TileRenderer_SPU::tesselateCrossTexture(Tile_SPU* tt, int data, float x, + float y, float z, float scale) { + Tesselator_SPU* t = getTesselator(); - Icon_SPU *tex = getTexture(tt, 0, data); + Icon_SPU* tex = getTexture(tt, 0, data); - if (hasFixedTexture()) tex = fixedTexture; - float u0 = tex->getU0(); - float v0 = tex->getV0(); - float u1 = tex->getU1(); - float v1 = tex->getV1(); + if (hasFixedTexture()) tex = fixedTexture; + float u0 = tex->getU0(); + float v0 = tex->getV0(); + float u1 = tex->getU1(); + float v1 = tex->getV1(); - float width = 0.45 * scale; - float x0 = x + 0.5 - width; - float x1 = x + 0.5 + width; - float z0 = z + 0.5 - width; - float z1 = z + 0.5 + width; + float width = 0.45 * scale; + float x0 = x + 0.5 - width; + float x1 = x + 0.5 + width; + float z0 = z + 0.5 - width; + float z1 = z + 0.5 + width; - t->vertexUV( ( float )( x0 ), ( float )( y + scale ), ( float )( z0 ), ( float )( u0 ), ( float )( v0 ) ); - t->vertexUV( ( float )( x0 ), ( float )( y + 0 ), ( float )( z0 ), ( float )( u0 ), ( float )( v1 ) ); - t->vertexUV( ( float )( x1 ), ( float )( y + 0 ), ( float )( z1 ), ( float )( u1 ), ( float )( v1 ) ); - t->vertexUV( ( float )( x1 ), ( float )( y + scale ), ( float )( z1 ), ( float )( u1 ), ( float )( v0 ) ); + t->vertexUV((float)(x0), (float)(y + scale), (float)(z0), (float)(u0), + (float)(v0)); + t->vertexUV((float)(x0), (float)(y + 0), (float)(z0), (float)(u0), + (float)(v1)); + t->vertexUV((float)(x1), (float)(y + 0), (float)(z1), (float)(u1), + (float)(v1)); + t->vertexUV((float)(x1), (float)(y + scale), (float)(z1), (float)(u1), + (float)(v0)); - t->vertexUV( ( float )( x1 ), ( float )( y + scale ), ( float )( z1 ), ( float )( u0 ), ( float )( v0 ) ); - t->vertexUV( ( float )( x1 ), ( float )( y + 0 ), ( float )( z1 ), ( float )( u0 ), ( float )( v1 ) ); - t->vertexUV( ( float )( x0 ), ( float )( y + 0 ), ( float )( z0 ), ( float )( u1 ), ( float )( v1 ) ); - t->vertexUV( ( float )( x0 ), ( float )( y + scale ), ( float )( z0 ), ( float )( u1 ), ( float )( v0 ) ); + t->vertexUV((float)(x1), (float)(y + scale), (float)(z1), (float)(u0), + (float)(v0)); + t->vertexUV((float)(x1), (float)(y + 0), (float)(z1), (float)(u0), + (float)(v1)); + t->vertexUV((float)(x0), (float)(y + 0), (float)(z0), (float)(u1), + (float)(v1)); + t->vertexUV((float)(x0), (float)(y + scale), (float)(z0), (float)(u1), + (float)(v0)); - t->vertexUV( ( float )( x0 ), ( float )( y + scale ), ( float )( z1 ), ( float )( u0 ), ( float )( v0 ) ); - t->vertexUV( ( float )( x0 ), ( float )( y + 0 ), ( float )( z1 ), ( float )( u0 ), ( float )( v1 ) ); - t->vertexUV( ( float )( x1 ), ( float )( y + 0 ), ( float )( z0 ), ( float )( u1 ), ( float )( v1 ) ); - t->vertexUV( ( float )( x1 ), ( float )( y + scale ), ( float )( z0 ), ( float )( u1 ), ( float )( v0 ) ); + t->vertexUV((float)(x0), (float)(y + scale), (float)(z1), (float)(u0), + (float)(v0)); + t->vertexUV((float)(x0), (float)(y + 0), (float)(z1), (float)(u0), + (float)(v1)); + t->vertexUV((float)(x1), (float)(y + 0), (float)(z0), (float)(u1), + (float)(v1)); + t->vertexUV((float)(x1), (float)(y + scale), (float)(z0), (float)(u1), + (float)(v0)); - t->vertexUV( ( float )( x1 ), ( float )( y + scale ), ( float )( z0 ), ( float )( u0 ), ( float )( v0 ) ); - t->vertexUV( ( float )( x1 ), ( float )( y + 0 ), ( float )( z0 ), ( float )( u0 ), ( float )( v1 ) ); - t->vertexUV( ( float )( x0 ), ( float )( y + 0 ), ( float )( z1 ), ( float )( u1 ), ( float )( v1 ) ); - t->vertexUV( ( float )( x0 ), ( float )( y + scale ), ( float )( z1 ), ( float )( u1 ), ( float )( v0 ) ); + t->vertexUV((float)(x1), (float)(y + scale), (float)(z0), (float)(u0), + (float)(v0)); + t->vertexUV((float)(x1), (float)(y + 0), (float)(z0), (float)(u0), + (float)(v1)); + t->vertexUV((float)(x0), (float)(y + 0), (float)(z1), (float)(u1), + (float)(v1)); + t->vertexUV((float)(x0), (float)(y + scale), (float)(z1), (float)(u1), + (float)(v0)); } -void TileRenderer_SPU::tesselateStemTexture( Tile_SPU* tt, int data, float h, float x, float y, float z ) -{ -// #ifdef DISABLE_TESS_FUNCS - Tesselator_SPU* t = getTesselator(); +void TileRenderer_SPU::tesselateStemTexture(Tile_SPU* tt, int data, float h, + float x, float y, float z) { + // #ifdef DISABLE_TESS_FUNCS + Tesselator_SPU* t = getTesselator(); - Icon_SPU *tex = getTexture(tt, 0, data); + Icon_SPU* tex = getTexture(tt, 0, data); - if (hasFixedTexture()) tex = fixedTexture; - float u0 = tex->getU0(); - float v0 = tex->getV0(); - float u1 = tex->getU1(); - float v1 = tex->getV(h * SharedConstants::WORLD_RESOLUTION); + if (hasFixedTexture()) tex = fixedTexture; + float u0 = tex->getU0(); + float v0 = tex->getV0(); + float u1 = tex->getU1(); + float v1 = tex->getV(h * SharedConstants::WORLD_RESOLUTION); - float x0 = x + 0.5f - 0.45f; - float x1 = x + 0.5f + 0.45f; - float z0 = z + 0.5f - 0.45f; - float z1 = z + 0.5f + 0.45f; + float x0 = x + 0.5f - 0.45f; + float x1 = x + 0.5f + 0.45f; + float z0 = z + 0.5f - 0.45f; + float z1 = z + 0.5f + 0.45f; - t->vertexUV( x0, y + h, z0, u0, v0 ); - t->vertexUV( x0, y + 0, z0, u0, v1 ); - t->vertexUV( x1, y + 0, z1, u1, v1 ); - t->vertexUV( x1, y + h, z1, u1, v0 ); + t->vertexUV(x0, y + h, z0, u0, v0); + t->vertexUV(x0, y + 0, z0, u0, v1); + t->vertexUV(x1, y + 0, z1, u1, v1); + t->vertexUV(x1, y + h, z1, u1, v0); - t->vertexUV( x1, y + h, z1, u0, v0 ); - t->vertexUV( x1, y + 0, z1, u0, v1 ); - t->vertexUV( x0, y + 0, z0, u1, v1 ); - t->vertexUV( x0, y + h, z0, u1, v0 ); + t->vertexUV(x1, y + h, z1, u0, v0); + t->vertexUV(x1, y + 0, z1, u0, v1); + t->vertexUV(x0, y + 0, z0, u1, v1); + t->vertexUV(x0, y + h, z0, u1, v0); - t->vertexUV( x0, y + h, z1, u0, v0 ); - t->vertexUV( x0, y + 0, z1, u0, v1 ); - t->vertexUV( x1, y + 0, z0, u1, v1 ); - t->vertexUV( x1, y + h, z0, u1, v0 ); + t->vertexUV(x0, y + h, z1, u0, v0); + t->vertexUV(x0, y + 0, z1, u0, v1); + t->vertexUV(x1, y + 0, z0, u1, v1); + t->vertexUV(x1, y + h, z0, u1, v0); - t->vertexUV( x1, y + h, z0, u0, v0 ); - t->vertexUV( x1, y + 0, z0, u0, v1 ); - t->vertexUV( x0, y + 0, z1, u1, v1 ); - t->vertexUV( x0, y + h, z1, u1, v0 ); -// #endif // DISABLE_TESS_FUNCS + t->vertexUV(x1, y + h, z0, u0, v0); + t->vertexUV(x1, y + 0, z0, u0, v1); + t->vertexUV(x0, y + 0, z1, u1, v1); + t->vertexUV(x0, y + h, z1, u1, v0); + // #endif // DISABLE_TESS_FUNCS } -bool TileRenderer_SPU::tesselateLilypadInWorld(WaterlilyTile_SPU *tt, int x, int y, int z) -{ - Tesselator_SPU* t = getTesselator(); +bool TileRenderer_SPU::tesselateLilypadInWorld(WaterlilyTile_SPU* tt, int x, + int y, int z) { + Tesselator_SPU* t = getTesselator(); - Icon_SPU *tex = getTexture(tt, Facing::UP); + Icon_SPU* tex = getTexture(tt, Facing::UP); - if (hasFixedTexture()) tex = fixedTexture; + if (hasFixedTexture()) tex = fixedTexture; float h = 0.25f / 16.0f; - float u0 = tex->getU0(); - float v0 = tex->getV0(); - float u1 = tex->getU1(); - float v1 = tex->getV1(); + float u0 = tex->getU0(); + float v0 = tex->getV0(); + float u1 = tex->getU1(); + float v1 = tex->getV1(); int64_t seed = (x * 3129871) ^ (z * 116129781l) ^ (y); seed = seed * seed * 42317861 + seed * 11; - int dir = (int) ((seed >> 16) & 0x3); - - + int dir = (int)((seed >> 16) & 0x3); t->tex2(tt->getLightColor(level, x, y, z)); @@ -3831,2700 +3774,2731 @@ bool TileRenderer_SPU::tesselateLilypadInWorld(WaterlilyTile_SPU *tt, int x, int return true; } -void TileRenderer_SPU::tesselateStemDirTexture( StemTile_SPU* tt, int data, int dir, float h, float x, float y, float z ) -{ - Tesselator_SPU* t = getTesselator(); +void TileRenderer_SPU::tesselateStemDirTexture(StemTile_SPU* tt, int data, + int dir, float h, float x, + float y, float z) { + Tesselator_SPU* t = getTesselator(); - Icon_SPU *tex = tt->getAngledTexture(); + Icon_SPU* tex = tt->getAngledTexture(); - if (hasFixedTexture()) tex = fixedTexture; - float u0 = tex->getU0(); - float v0 = tex->getV0(); - float u1 = tex->getU1(); - float v1 = tex->getV1(); + if (hasFixedTexture()) tex = fixedTexture; + float u0 = tex->getU0(); + float v0 = tex->getV0(); + float u1 = tex->getU1(); + float v1 = tex->getV1(); - float x0 = x + 0.5f - 0.5f; - float x1 = x + 0.5f + 0.5f; - float z0 = z + 0.5f - 0.5f; - float z1 = z + 0.5f + 0.5f; + float x0 = x + 0.5f - 0.5f; + float x1 = x + 0.5f + 0.5f; + float z0 = z + 0.5f - 0.5f; + float z1 = z + 0.5f + 0.5f; - float xm = x + 0.5f; - float zm = z + 0.5f; + float xm = x + 0.5f; + float zm = z + 0.5f; - if ( ( dir + 1 ) / 2 % 2 == 1 ) - { - float tmp = u1; - u1 = u0; - u0 = tmp; - } + if ((dir + 1) / 2 % 2 == 1) { + float tmp = u1; + u1 = u0; + u0 = tmp; + } - if ( dir < 2 ) - { - t->vertexUV( x0, y + h, zm, u0, v0 ); - t->vertexUV( x0, y + 0, zm, u0, v1 ); - t->vertexUV( x1, y + 0, zm, u1, v1 ); - t->vertexUV( x1, y + h, zm, u1, v0 ); + if (dir < 2) { + t->vertexUV(x0, y + h, zm, u0, v0); + t->vertexUV(x0, y + 0, zm, u0, v1); + t->vertexUV(x1, y + 0, zm, u1, v1); + t->vertexUV(x1, y + h, zm, u1, v0); - t->vertexUV( x1, y + h, zm, u1, v0 ); - t->vertexUV( x1, y + 0, zm, u1, v1 ); - t->vertexUV( x0, y + 0, zm, u0, v1 ); - t->vertexUV( x0, y + h, zm, u0, v0 ); - } - else - { - t->vertexUV( xm, y + h, z1, u0, v0 ); - t->vertexUV( xm, y + 0, z1, u0, v1 ); - t->vertexUV( xm, y + 0, z0, u1, v1 ); - t->vertexUV( xm, y + h, z0, u1, v0 ); + t->vertexUV(x1, y + h, zm, u1, v0); + t->vertexUV(x1, y + 0, zm, u1, v1); + t->vertexUV(x0, y + 0, zm, u0, v1); + t->vertexUV(x0, y + h, zm, u0, v0); + } else { + t->vertexUV(xm, y + h, z1, u0, v0); + t->vertexUV(xm, y + 0, z1, u0, v1); + t->vertexUV(xm, y + 0, z0, u1, v1); + t->vertexUV(xm, y + h, z0, u1, v0); - t->vertexUV( xm, y + h, z0, u1, v0 ); - t->vertexUV( xm, y + 0, z0, u1, v1 ); - t->vertexUV( xm, y + 0, z1, u0, v1 ); - t->vertexUV( xm, y + h, z1, u0, v0 ); - } + t->vertexUV(xm, y + h, z0, u1, v0); + t->vertexUV(xm, y + 0, z0, u1, v1); + t->vertexUV(xm, y + 0, z1, u0, v1); + t->vertexUV(xm, y + h, z1, u0, v0); + } } +void TileRenderer_SPU::tesselateRowTexture(Tile_SPU* tt, int data, float x, + float y, float z) { + Tesselator_SPU* t = getTesselator(); -void TileRenderer_SPU::tesselateRowTexture( Tile_SPU* tt, int data, float x, float y, float z ) -{ - Tesselator_SPU* t = getTesselator(); + Icon_SPU* tex = getTexture(tt, 0, data); - Icon_SPU *tex = getTexture(tt, 0, data); + if (hasFixedTexture()) tex = fixedTexture; + float u0 = tex->getU0(); + float v0 = tex->getV0(); + float u1 = tex->getU1(); + float v1 = tex->getV1(); - if (hasFixedTexture()) tex = fixedTexture; - float u0 = tex->getU0(); - float v0 = tex->getV0(); - float u1 = tex->getU1(); - float v1 = tex->getV1(); + float x0 = x + 0.5f - 0.25f; + float x1 = x + 0.5f + 0.25f; + float z0 = z + 0.5f - 0.5f; + float z1 = z + 0.5f + 0.5f; - float x0 = x + 0.5f - 0.25f; - float x1 = x + 0.5f + 0.25f; - float z0 = z + 0.5f - 0.5f; - float z1 = z + 0.5f + 0.5f; + t->vertexUV((float)(x0), (float)(y + 1), (float)(z0), (float)(u0), + (float)(v0)); + t->vertexUV((float)(x0), (float)(y + 0), (float)(z0), (float)(u0), + (float)(v1)); + t->vertexUV((float)(x0), (float)(y + 0), (float)(z1), (float)(u1), + (float)(v1)); + t->vertexUV((float)(x0), (float)(y + 1), (float)(z1), (float)(u1), + (float)(v0)); - t->vertexUV( ( float )( x0 ), ( float )( y + 1 ), ( float )( z0 ), ( float )( u0 ), ( float )( v0 ) ); - t->vertexUV( ( float )( x0 ), ( float )( y + 0 ), ( float )( z0 ), ( float )( u0 ), ( float )( v1 ) ); - t->vertexUV( ( float )( x0 ), ( float )( y + 0 ), ( float )( z1 ), ( float )( u1 ), ( float )( v1 ) ); - t->vertexUV( ( float )( x0 ), ( float )( y + 1 ), ( float )( z1 ), ( float )( u1 ), ( float )( v0 ) ); + t->vertexUV((float)(x0), (float)(y + 1), (float)(z1), (float)(u0), + (float)(v0)); + t->vertexUV((float)(x0), (float)(y + 0), (float)(z1), (float)(u0), + (float)(v1)); + t->vertexUV((float)(x0), (float)(y + 0), (float)(z0), (float)(u1), + (float)(v1)); + t->vertexUV((float)(x0), (float)(y + 1), (float)(z0), (float)(u1), + (float)(v0)); - t->vertexUV( ( float )( x0 ), ( float )( y + 1 ), ( float )( z1 ), ( float )( u0 ), ( float )( v0 ) ); - t->vertexUV( ( float )( x0 ), ( float )( y + 0 ), ( float )( z1 ), ( float )( u0 ), ( float )( v1 ) ); - t->vertexUV( ( float )( x0 ), ( float )( y + 0 ), ( float )( z0 ), ( float )( u1 ), ( float )( v1 ) ); - t->vertexUV( ( float )( x0 ), ( float )( y + 1 ), ( float )( z0 ), ( float )( u1 ), ( float )( v0 ) ); + t->vertexUV((float)(x1), (float)(y + 1), (float)(z1), (float)(u0), + (float)(v0)); + t->vertexUV((float)(x1), (float)(y + 0), (float)(z1), (float)(u0), + (float)(v1)); + t->vertexUV((float)(x1), (float)(y + 0), (float)(z0), (float)(u1), + (float)(v1)); + t->vertexUV((float)(x1), (float)(y + 1), (float)(z0), (float)(u1), + (float)(v0)); - t->vertexUV( ( float )( x1 ), ( float )( y + 1 ), ( float )( z1 ), ( float )( u0 ), ( float )( v0 ) ); - t->vertexUV( ( float )( x1 ), ( float )( y + 0 ), ( float )( z1 ), ( float )( u0 ), ( float )( v1 ) ); - t->vertexUV( ( float )( x1 ), ( float )( y + 0 ), ( float )( z0 ), ( float )( u1 ), ( float )( v1 ) ); - t->vertexUV( ( float )( x1 ), ( float )( y + 1 ), ( float )( z0 ), ( float )( u1 ), ( float )( v0 ) ); + t->vertexUV((float)(x1), (float)(y + 1), (float)(z0), (float)(u0), + (float)(v0)); + t->vertexUV((float)(x1), (float)(y + 0), (float)(z0), (float)(u0), + (float)(v1)); + t->vertexUV((float)(x1), (float)(y + 0), (float)(z1), (float)(u1), + (float)(v1)); + t->vertexUV((float)(x1), (float)(y + 1), (float)(z1), (float)(u1), + (float)(v0)); - t->vertexUV( ( float )( x1 ), ( float )( y + 1 ), ( float )( z0 ), ( float )( u0 ), ( float )( v0 ) ); - t->vertexUV( ( float )( x1 ), ( float )( y + 0 ), ( float )( z0 ), ( float )( u0 ), ( float )( v1 ) ); - t->vertexUV( ( float )( x1 ), ( float )( y + 0 ), ( float )( z1 ), ( float )( u1 ), ( float )( v1 ) ); - t->vertexUV( ( float )( x1 ), ( float )( y + 1 ), ( float )( z1 ), ( float )( u1 ), ( float )( v0 ) ); + x0 = x + 0.5f - 0.5f; + x1 = x + 0.5f + 0.5f; + z0 = z + 0.5f - 0.25f; + z1 = z + 0.5f + 0.25f; - x0 = x + 0.5f - 0.5f; - x1 = x + 0.5f + 0.5f; - z0 = z + 0.5f - 0.25f; - z1 = z + 0.5f + 0.25f; + t->vertexUV((float)(x0), (float)(y + 1), (float)(z0), (float)(u0), + (float)(v0)); + t->vertexUV((float)(x0), (float)(y + 0), (float)(z0), (float)(u0), + (float)(v1)); + t->vertexUV((float)(x1), (float)(y + 0), (float)(z0), (float)(u1), + (float)(v1)); + t->vertexUV((float)(x1), (float)(y + 1), (float)(z0), (float)(u1), + (float)(v0)); - t->vertexUV( ( float )( x0 ), ( float )( y + 1 ), ( float )( z0 ), ( float )( u0 ), ( float )( v0 ) ); - t->vertexUV( ( float )( x0 ), ( float )( y + 0 ), ( float )( z0 ), ( float )( u0 ), ( float )( v1 ) ); - t->vertexUV( ( float )( x1 ), ( float )( y + 0 ), ( float )( z0 ), ( float )( u1 ), ( float )( v1 ) ); - t->vertexUV( ( float )( x1 ), ( float )( y + 1 ), ( float )( z0 ), ( float )( u1 ), ( float )( v0 ) ); + t->vertexUV((float)(x1), (float)(y + 1), (float)(z0), (float)(u0), + (float)(v0)); + t->vertexUV((float)(x1), (float)(y + 0), (float)(z0), (float)(u0), + (float)(v1)); + t->vertexUV((float)(x0), (float)(y + 0), (float)(z0), (float)(u1), + (float)(v1)); + t->vertexUV((float)(x0), (float)(y + 1), (float)(z0), (float)(u1), + (float)(v0)); - t->vertexUV( ( float )( x1 ), ( float )( y + 1 ), ( float )( z0 ), ( float )( u0 ), ( float )( v0 ) ); - t->vertexUV( ( float )( x1 ), ( float )( y + 0 ), ( float )( z0 ), ( float )( u0 ), ( float )( v1 ) ); - t->vertexUV( ( float )( x0 ), ( float )( y + 0 ), ( float )( z0 ), ( float )( u1 ), ( float )( v1 ) ); - t->vertexUV( ( float )( x0 ), ( float )( y + 1 ), ( float )( z0 ), ( float )( u1 ), ( float )( v0 ) ); - - t->vertexUV( ( float )( x1 ), ( float )( y + 1 ), ( float )( z1 ), ( float )( u0 ), ( float )( v0 ) ); - t->vertexUV( ( float )( x1 ), ( float )( y + 0 ), ( float )( z1 ), ( float )( u0 ), ( float )( v1 ) ); - t->vertexUV( ( float )( x0 ), ( float )( y + 0 ), ( float )( z1 ), ( float )( u1 ), ( float )( v1 ) ); - t->vertexUV( ( float )( x0 ), ( float )( y + 1 ), ( float )( z1 ), ( float )( u1 ), ( float )( v0 ) ); - - t->vertexUV( ( float )( x0 ), ( float )( y + 1 ), ( float )( z1 ), ( float )( u0 ), ( float )( v0 ) ); - t->vertexUV( ( float )( x0 ), ( float )( y + 0 ), ( float )( z1 ), ( float )( u0 ), ( float )( v1 ) ); - t->vertexUV( ( float )( x1 ), ( float )( y + 0 ), ( float )( z1 ), ( float )( u1 ), ( float )( v1 ) ); - t->vertexUV( ( float )( x1 ), ( float )( y + 1 ), ( float )( z1 ), ( float )( u1 ), ( float )( v0 ) ); + t->vertexUV((float)(x1), (float)(y + 1), (float)(z1), (float)(u0), + (float)(v0)); + t->vertexUV((float)(x1), (float)(y + 0), (float)(z1), (float)(u0), + (float)(v1)); + t->vertexUV((float)(x0), (float)(y + 0), (float)(z1), (float)(u1), + (float)(v1)); + t->vertexUV((float)(x0), (float)(y + 1), (float)(z1), (float)(u1), + (float)(v0)); + t->vertexUV((float)(x0), (float)(y + 1), (float)(z1), (float)(u0), + (float)(v0)); + t->vertexUV((float)(x0), (float)(y + 0), (float)(z1), (float)(u0), + (float)(v1)); + t->vertexUV((float)(x1), (float)(y + 0), (float)(z1), (float)(u1), + (float)(v1)); + t->vertexUV((float)(x1), (float)(y + 1), (float)(z1), (float)(u1), + (float)(v0)); } -bool TileRenderer_SPU::tesselateWaterInWorld( Tile_SPU* tt, int x, int y, int z ) -{ - // 4J Java comment - // TODO: This all needs to change. Somehow. - Tesselator_SPU* t = getTesselator(); +bool TileRenderer_SPU::tesselateWaterInWorld(Tile_SPU* tt, int x, int y, + int z) { + // 4J Java comment + // TODO: This all needs to change. Somehow. + Tesselator_SPU* t = getTesselator(); - int col = tt->getColor( level, x, y, z ); - float r = ( col >> 16 & 0xff ) / 255.0f; - float g = ( col >> 8 & 0xff ) / 255.0f; - float b = ( col & 0xff ) / 255.0f; - bool up = tt->shouldRenderFace( level, x, y + 1, z, 1 ); - bool down = tt->shouldRenderFace( level, x, y - 1, z, 0 ); - bool dirs[4]; - dirs[0] = tt->shouldRenderFace( level, x, y, z - 1, 2 ); - dirs[1] = tt->shouldRenderFace( level, x, y, z + 1, 3 ); - dirs[2] = tt->shouldRenderFace( level, x - 1, y, z, 4 ); - dirs[3] = tt->shouldRenderFace( level, x + 1, y, z, 5 ); + int col = tt->getColor(level, x, y, z); + float r = (col >> 16 & 0xff) / 255.0f; + float g = (col >> 8 & 0xff) / 255.0f; + float b = (col & 0xff) / 255.0f; + bool up = tt->shouldRenderFace(level, x, y + 1, z, 1); + bool down = tt->shouldRenderFace(level, x, y - 1, z, 0); + bool dirs[4]; + dirs[0] = tt->shouldRenderFace(level, x, y, z - 1, 2); + dirs[1] = tt->shouldRenderFace(level, x, y, z + 1, 3); + dirs[2] = tt->shouldRenderFace(level, x - 1, y, z, 4); + dirs[3] = tt->shouldRenderFace(level, x + 1, y, z, 5); - if ( !up && !down && !dirs[0] && !dirs[1] && !dirs[2] && !dirs[3] ) return false; + if (!up && !down && !dirs[0] && !dirs[1] && !dirs[2] && !dirs[3]) + return false; - bool changed = false; - float c10 = 0.5f; - float c11 = 1; - float c2 = 0.8f; - float c3 = 0.6f; + bool changed = false; + float c10 = 0.5f; + float c11 = 1; + float c2 = 0.8f; + float c3 = 0.6f; - float yo0 = 0; - float yo1 = 1; + float yo0 = 0; + float yo1 = 1; - Material_SPU* m = tt->getMaterial(); - int data = level->getData( x, y, z ); + Material_SPU* m = tt->getMaterial(); + int data = level->getData(x, y, z); - float h0 = getWaterHeight( x, y, z, m ); - float h1 = getWaterHeight( x, y, z + 1, m ); - float h2 = getWaterHeight( x + 1, y, z + 1, m ); - float h3 = getWaterHeight( x + 1, y, z, m ); + float h0 = getWaterHeight(x, y, z, m); + float h1 = getWaterHeight(x, y, z + 1, m); + float h2 = getWaterHeight(x + 1, y, z + 1, m); + float h3 = getWaterHeight(x + 1, y, z, m); float offs = 0.001f; - // 4J - added. Farm tiles often found beside water, but they consider themselves non-solid as they only extend up to 15.0f / 16.0f. - // If the max height of this water is below that level, don't bother rendering sides bordering onto farmland. - float maxh = h0; - if ( h1 > maxh ) maxh = h1; - if ( h2 > maxh ) maxh = h2; - if ( h3 > maxh ) maxh = h3; - if ( maxh <= ( 15.0f / 16.0f ) ) - { - if ( level->getTile( x, y, z - 1 ) == Tile_SPU::farmland_Id ) - { - dirs[0] = false; - } - if ( level->getTile( x, y, z + 1 ) == Tile_SPU::farmland_Id ) - { - dirs[1] = false; - } - if ( level->getTile( x - 1, y, z ) == Tile_SPU::farmland_Id ) - { - dirs[2] = false; - } - if ( level->getTile( x + 1, y, z ) == Tile_SPU::farmland_Id ) - { - dirs[3] = false; - } - } + // 4J - added. Farm tiles often found beside water, but they consider + // themselves non-solid as they only extend up to 15.0f / 16.0f. If the max + // height of this water is below that level, don't bother rendering sides + // bordering onto farmland. + float maxh = h0; + if (h1 > maxh) maxh = h1; + if (h2 > maxh) maxh = h2; + if (h3 > maxh) maxh = h3; + if (maxh <= (15.0f / 16.0f)) { + if (level->getTile(x, y, z - 1) == Tile_SPU::farmland_Id) { + dirs[0] = false; + } + if (level->getTile(x, y, z + 1) == Tile_SPU::farmland_Id) { + dirs[1] = false; + } + if (level->getTile(x - 1, y, z) == Tile_SPU::farmland_Id) { + dirs[2] = false; + } + if (level->getTile(x + 1, y, z) == Tile_SPU::farmland_Id) { + dirs[3] = false; + } + } - if ( noCulling || up ) - { - changed = true; - Icon_SPU *tex = getTexture( tt, 1, data ); - float angle = ( float )LiquidTile_SPU::getSlopeAngle( level, x, y, z, m ); - if ( angle > -999 ) - { - tex = getTexture( tt, 2, data ); - } + if (noCulling || up) { + changed = true; + Icon_SPU* tex = getTexture(tt, 1, data); + float angle = (float)LiquidTile_SPU::getSlopeAngle(level, x, y, z, m); + if (angle > -999) { + tex = getTexture(tt, 2, data); + } h0 -= offs; h1 -= offs; h2 -= offs; h3 -= offs; - float u00, u01, u10, u11; - float v00, v01, v10, v11; - if ( angle < -999 ) - { - u00 = tex->getU(0); - v00 = tex->getV(0); - u01 = u00; - v01 = tex->getV(SharedConstants::WORLD_RESOLUTION); - u10 = tex->getU(SharedConstants::WORLD_RESOLUTION); - v10 = v01; - u11 = u10; - v11 = v00; - } - else - { - float s = sinf(angle) * .25f; - float c = cosf(angle) * .25f; - float cc = SharedConstants::WORLD_RESOLUTION * .5f; - u00 = tex->getU(cc + (-c - s) * SharedConstants::WORLD_RESOLUTION); - v00 = tex->getV(cc + (-c + s) * SharedConstants::WORLD_RESOLUTION); - u01 = tex->getU(cc + (-c + s) * SharedConstants::WORLD_RESOLUTION); - v01 = tex->getV(cc + (+c + s) * SharedConstants::WORLD_RESOLUTION); - u10 = tex->getU(cc + (+c + s) * SharedConstants::WORLD_RESOLUTION); - v10 = tex->getV(cc + (+c - s) * SharedConstants::WORLD_RESOLUTION); - u11 = tex->getU(cc + (+c - s) * SharedConstants::WORLD_RESOLUTION); - v11 = tex->getV(cc + (-c - s) * SharedConstants::WORLD_RESOLUTION); - } + float u00, u01, u10, u11; + float v00, v01, v10, v11; + if (angle < -999) { + u00 = tex->getU(0); + v00 = tex->getV(0); + u01 = u00; + v01 = tex->getV(SharedConstants::WORLD_RESOLUTION); + u10 = tex->getU(SharedConstants::WORLD_RESOLUTION); + v10 = v01; + u11 = u10; + v11 = v00; + } else { + float s = sinf(angle) * .25f; + float c = cosf(angle) * .25f; + float cc = SharedConstants::WORLD_RESOLUTION * .5f; + u00 = tex->getU(cc + (-c - s) * SharedConstants::WORLD_RESOLUTION); + v00 = tex->getV(cc + (-c + s) * SharedConstants::WORLD_RESOLUTION); + u01 = tex->getU(cc + (-c + s) * SharedConstants::WORLD_RESOLUTION); + v01 = tex->getV(cc + (+c + s) * SharedConstants::WORLD_RESOLUTION); + u10 = tex->getU(cc + (+c + s) * SharedConstants::WORLD_RESOLUTION); + v10 = tex->getV(cc + (+c - s) * SharedConstants::WORLD_RESOLUTION); + u11 = tex->getU(cc + (+c - s) * SharedConstants::WORLD_RESOLUTION); + v11 = tex->getV(cc + (-c - s) * SharedConstants::WORLD_RESOLUTION); + } - float br; - if ( SharedConstants::TEXTURE_LIGHTING ) - { - t->tex2( tt->getLightColor( level, x, y, z ) ); - br = 1; - } - else - { - br = tt->getBrightness( level, x, y, z ); - } - t->color( c11 * br * r, c11 * br * g, c11 * br * b ); - t->vertexUV( ( float )( x + 0.0f ), ( float )( y + h0 ), ( float )( z + 0.0f ), u00, v00 ); - t->vertexUV( ( float )( x + 0.0f ), ( float )( y + h1 ), ( float )( z + 1.0f ), u01, v01 ); - t->vertexUV( ( float )( x + 1.0f ), ( float )( y + h2 ), ( float )( z + 1.0f ), u10, v10 ); - t->vertexUV( ( float )( x + 1.0f ), ( float )( y + h3 ), ( float )( z + 0.0f ), u11, v11 ); - } + float br; + if (SharedConstants::TEXTURE_LIGHTING) { + t->tex2(tt->getLightColor(level, x, y, z)); + br = 1; + } else { + br = tt->getBrightness(level, x, y, z); + } + t->color(c11 * br * r, c11 * br * g, c11 * br * b); + t->vertexUV((float)(x + 0.0f), (float)(y + h0), (float)(z + 0.0f), u00, + v00); + t->vertexUV((float)(x + 0.0f), (float)(y + h1), (float)(z + 1.0f), u01, + v01); + t->vertexUV((float)(x + 1.0f), (float)(y + h2), (float)(z + 1.0f), u10, + v10); + t->vertexUV((float)(x + 1.0f), (float)(y + h3), (float)(z + 0.0f), u11, + v11); + } - if ( noCulling || down ) - { - float br; - if ( SharedConstants::TEXTURE_LIGHTING ) - { - t->tex2( tt->getLightColor( level, x, y - 1, z ) ); - br = 1; - } - else - { - br = tt->getBrightness( level, x, y - 1, z ); - } - t->color( c10 * br, c10 * br, c10 * br ); - renderFaceDown( tt, x, y + offs, z, getTexture( tt, 0 ) ); - changed = true; - } + if (noCulling || down) { + float br; + if (SharedConstants::TEXTURE_LIGHTING) { + t->tex2(tt->getLightColor(level, x, y - 1, z)); + br = 1; + } else { + br = tt->getBrightness(level, x, y - 1, z); + } + t->color(c10 * br, c10 * br, c10 * br); + renderFaceDown(tt, x, y + offs, z, getTexture(tt, 0)); + changed = true; + } - for ( int face = 0; face < 4; face++ ) - { - int xt = x; - int yt = y; - int zt = z; + for (int face = 0; face < 4; face++) { + int xt = x; + int yt = y; + int zt = z; - if ( face == 0 ) zt--; - if ( face == 1 ) zt++; - if ( face == 2 ) xt--; - if ( face == 3 ) xt++; + if (face == 0) zt--; + if (face == 1) zt++; + if (face == 2) xt--; + if (face == 3) xt++; - Icon_SPU *tex = getTexture(tt, face + 2, data); + Icon_SPU* tex = getTexture(tt, face + 2, data); - if ( noCulling || dirs[face] ) - { - float hh0; - float hh1; - float x0, z0, x1, z1; - if ( face == 0 ) - { - hh0 = ( float )( h0 ); - hh1 = ( float )( h3 ); - x0 = ( float )( x ); - x1 = ( float )( x + 1 ); - z0 = ( float )( z + offs); - z1 = ( float )( z + offs); - } - else if ( face == 1 ) - { - hh0 = ( float )( h2 ); - hh1 = ( float )( h1 ); - x0 = ( float )( x + 1 ); - x1 = ( float )( x ); - z0 = ( float )( z + 1 - offs); - z1 = ( float )( z + 1 - offs); - } - else if ( face == 2 ) - { - hh0 = ( float )( h1 ); - hh1 = ( float )( h0 ); - x0 = ( float )( x + offs); - x1 = ( float )( x + offs); - z0 = ( float )( z + 1 ); - z1 = ( float )( z ); - } - else - { - hh0 = ( float )( h3 ); - hh1 = ( float )( h2 ); - x0 = ( float )( x + 1 - offs); - x1 = ( float )( x + 1 - offs); - z0 = ( float )( z ); - z1 = ( float )( z + 1 ); - } + if (noCulling || dirs[face]) { + float hh0; + float hh1; + float x0, z0, x1, z1; + if (face == 0) { + hh0 = (float)(h0); + hh1 = (float)(h3); + x0 = (float)(x); + x1 = (float)(x + 1); + z0 = (float)(z + offs); + z1 = (float)(z + offs); + } else if (face == 1) { + hh0 = (float)(h2); + hh1 = (float)(h1); + x0 = (float)(x + 1); + x1 = (float)(x); + z0 = (float)(z + 1 - offs); + z1 = (float)(z + 1 - offs); + } else if (face == 2) { + hh0 = (float)(h1); + hh1 = (float)(h0); + x0 = (float)(x + offs); + x1 = (float)(x + offs); + z0 = (float)(z + 1); + z1 = (float)(z); + } else { + hh0 = (float)(h3); + hh1 = (float)(h2); + x0 = (float)(x + 1 - offs); + x1 = (float)(x + 1 - offs); + z0 = (float)(z); + z1 = (float)(z + 1); + } + changed = true; + float u0 = tex->getU(0); + float u1 = tex->getU(SharedConstants::WORLD_RESOLUTION * .5f); - changed = true; - float u0 = tex->getU(0); - float u1 = tex->getU(SharedConstants::WORLD_RESOLUTION * .5f); + // int yTex = tex->getY(); + float v01 = + tex->getV((1 - hh0) * SharedConstants::WORLD_RESOLUTION * .5f); + float v02 = + tex->getV((1 - hh1) * SharedConstants::WORLD_RESOLUTION * .5f); + float v1 = tex->getV(SharedConstants::WORLD_RESOLUTION * .5f); -// int yTex = tex->getY(); - float v01 = tex->getV((1 - hh0) * SharedConstants::WORLD_RESOLUTION * .5f); - float v02 = tex->getV((1 - hh1) * SharedConstants::WORLD_RESOLUTION * .5f); - float v1 = tex->getV(SharedConstants::WORLD_RESOLUTION * .5f); + float br; + if (SharedConstants::TEXTURE_LIGHTING) { + t->tex2(tt->getLightColor(level, xt, yt, zt)); + br = 1; + } else { + br = tt->getBrightness(level, xt, yt, zt); + } + if (face < 2) + br *= c2; + else + br *= c3; - float br; - if ( SharedConstants::TEXTURE_LIGHTING ) - { - t->tex2( tt->getLightColor( level, xt, yt, zt ) ); - br = 1; - } - else - { - br = tt->getBrightness( level, xt, yt, zt ); - } - if ( face < 2 ) br *= c2; - else - br *= c3; + t->color(c11 * br * r, c11 * br * g, c11 * br * b); + t->vertexUV((float)(x0), (float)(y + hh0), (float)(z0), (float)(u0), + (float)(v01)); + t->vertexUV((float)(x1), (float)(y + hh1), (float)(z1), (float)(u1), + (float)(v02)); + t->vertexUV((float)(x1), (float)(y + 0), (float)(z1), (float)(u1), + (float)(v1)); + t->vertexUV((float)(x0), (float)(y + 0), (float)(z0), (float)(u0), + (float)(v1)); + } + } - t->color( c11 * br * r, c11 * br * g, c11 * br * b ); - t->vertexUV( ( float )( x0 ), ( float )( y + hh0 ), ( float )( z0 ), ( float )( u0 ), ( float )( v01 ) ); - t->vertexUV( ( float )( x1 ), ( float )( y + hh1 ), ( float )( z1 ), ( float )( u1 ), ( float )( v02 ) ); - t->vertexUV( ( float )( x1 ), ( float )( y + 0 ), ( float )( z1 ), ( float )( u1 ), ( float )( v1 ) ); - t->vertexUV( ( float )( x0 ), ( float )( y + 0 ), ( float )( z0 ), ( float )( u0 ), ( float )( v1 ) ); + tileShapeY0 = yo0; + tileShapeY1 = yo1; - } - - } - - tileShapeY0 = yo0; - tileShapeY1 = yo1; - - return changed; + return changed; } -float TileRenderer_SPU::getWaterHeight( int x, int y, int z, Material_SPU* m ) -{ - int count = 0; - float h = 0; - for ( int i = 0; i < 4; i++ ) - { - int xx = x - ( i & 1 ); - int yy = y; - int zz = z - ( ( i >> 1 ) & 1 ); - if ( level->getMaterial( xx, yy + 1, zz ) == m ) - { - return 1; - } - Material_SPU* tm = level->getMaterial( xx, yy, zz ); - if ( tm == m ) - { - int d = level->getData( xx, yy, zz ); - if ( d >= 8 || d == 0 ) - { - h += ( LiquidTile_SPU::getHeight( d ) )* 10; - count += 10; - } - h += LiquidTile_SPU::getHeight( d ); - count++; - } - else if ( !tm->isSolid() ) - { - h += 1; - count++; - } - } - return 1 - h / count; +float TileRenderer_SPU::getWaterHeight(int x, int y, int z, Material_SPU* m) { + int count = 0; + float h = 0; + for (int i = 0; i < 4; i++) { + int xx = x - (i & 1); + int yy = y; + int zz = z - ((i >> 1) & 1); + if (level->getMaterial(xx, yy + 1, zz) == m) { + return 1; + } + Material_SPU* tm = level->getMaterial(xx, yy, zz); + if (tm == m) { + int d = level->getData(xx, yy, zz); + if (d >= 8 || d == 0) { + h += (LiquidTile_SPU::getHeight(d)) * 10; + count += 10; + } + h += LiquidTile_SPU::getHeight(d); + count++; + } else if (!tm->isSolid()) { + h += 1; + count++; + } + } + return 1 - h / count; } -void TileRenderer_SPU::renderBlock( Tile_SPU* tt, ChunkRebuildData* level, int x, int y, int z ) -{ - renderBlock(tt, level, x, y, z, 0); +void TileRenderer_SPU::renderBlock(Tile_SPU* tt, ChunkRebuildData* level, int x, + int y, int z) { + renderBlock(tt, level, x, y, z, 0); } -void TileRenderer_SPU::renderBlock(Tile_SPU *tt, ChunkRebuildData *level, int x, int y, int z, int data) -{ - float c10 = 0.5f; - float c11 = 1; - float c2 = 0.8f; - float c3 = 0.6f; +void TileRenderer_SPU::renderBlock(Tile_SPU* tt, ChunkRebuildData* level, int x, + int y, int z, int data) { + float c10 = 0.5f; + float c11 = 1; + float c2 = 0.8f; + float c3 = 0.6f; - Tesselator_SPU* t = getTesselator(); - t->begin(); - if ( SharedConstants::TEXTURE_LIGHTING ) - { - t->tex2( tt->getLightColor( level, x, y, z ) ); - } - float center = SharedConstants::TEXTURE_LIGHTING ? 1 : tt->getBrightness( level, x, y, z ); - float br = SharedConstants::TEXTURE_LIGHTING ? 1 : tt->getBrightness( level, x, y - 1, z ); + Tesselator_SPU* t = getTesselator(); + t->begin(); + if (SharedConstants::TEXTURE_LIGHTING) { + t->tex2(tt->getLightColor(level, x, y, z)); + } + float center = SharedConstants::TEXTURE_LIGHTING + ? 1 + : tt->getBrightness(level, x, y, z); + float br = SharedConstants::TEXTURE_LIGHTING + ? 1 + : tt->getBrightness(level, x, y - 1, z); - if ( br < center ) br = center; - t->color( c10 * br, c10 * br, c10 * br ); - renderFaceDown( tt, -0.5f, -0.5f, -0.5f, getTexture( tt, 0, data ) ); + if (br < center) br = center; + t->color(c10 * br, c10 * br, c10 * br); + renderFaceDown(tt, -0.5f, -0.5f, -0.5f, getTexture(tt, 0, data)); - br = SharedConstants::TEXTURE_LIGHTING ? 1 : tt->getBrightness( level, x, y + 1, z ); - if ( br < center ) br = center; - t->color( c11 * br, c11 * br, c11 * br ); - renderFaceUp( tt, -0.5f, -0.5f, -0.5f, getTexture( tt, 1, data ) ); + br = SharedConstants::TEXTURE_LIGHTING + ? 1 + : tt->getBrightness(level, x, y + 1, z); + if (br < center) br = center; + t->color(c11 * br, c11 * br, c11 * br); + renderFaceUp(tt, -0.5f, -0.5f, -0.5f, getTexture(tt, 1, data)); - br = SharedConstants::TEXTURE_LIGHTING ? 1 : tt->getBrightness( level, x, y, z - 1 ); - if ( br < center ) br = center; - t->color( c2 * br, c2 * br, c2 * br ); - renderNorth( tt, -0.5f, -0.5f, -0.5f, getTexture( tt, 2, data ) ); + br = SharedConstants::TEXTURE_LIGHTING + ? 1 + : tt->getBrightness(level, x, y, z - 1); + if (br < center) br = center; + t->color(c2 * br, c2 * br, c2 * br); + renderNorth(tt, -0.5f, -0.5f, -0.5f, getTexture(tt, 2, data)); - br = SharedConstants::TEXTURE_LIGHTING ? 1 : tt->getBrightness( level, x, y, z + 1 ); - if ( br < center ) br = center; - t->color( c2 * br, c2 * br, c2 * br ); - renderSouth( tt, -0.5f, -0.5f, -0.5f, getTexture( tt, 3, data ) ); + br = SharedConstants::TEXTURE_LIGHTING + ? 1 + : tt->getBrightness(level, x, y, z + 1); + if (br < center) br = center; + t->color(c2 * br, c2 * br, c2 * br); + renderSouth(tt, -0.5f, -0.5f, -0.5f, getTexture(tt, 3, data)); - br = SharedConstants::TEXTURE_LIGHTING ? 1 : tt->getBrightness( level, x - 1, y, z ); - if ( br < center ) br = center; - t->color( c3 * br, c3 * br, c3 * br ); - renderWest( tt, -0.5f, -0.5f, -0.5f, getTexture( tt, 4, data ) ); - - br = SharedConstants::TEXTURE_LIGHTING ? 1 : tt->getBrightness( level, x + 1, y, z ); - if ( br < center ) br = center; - t->color( c3 * br, c3 * br, c3 * br ); - renderEast( tt, -0.5f, -0.5f, -0.5f, getTexture( tt, 5, data ) ); - t->end(); + br = SharedConstants::TEXTURE_LIGHTING + ? 1 + : tt->getBrightness(level, x - 1, y, z); + if (br < center) br = center; + t->color(c3 * br, c3 * br, c3 * br); + renderWest(tt, -0.5f, -0.5f, -0.5f, getTexture(tt, 4, data)); + br = SharedConstants::TEXTURE_LIGHTING + ? 1 + : tt->getBrightness(level, x + 1, y, z); + if (br < center) br = center; + t->color(c3 * br, c3 * br, c3 * br); + renderEast(tt, -0.5f, -0.5f, -0.5f, getTexture(tt, 5, data)); + t->end(); } -bool TileRenderer_SPU::tesselateBlockInWorld( Tile_SPU* tt, int x, int y, int z ) -{ - int col = tt->getColor( level, x, y, z ); - float r = ( ( col >> 16 ) & 0xff ) / 255.0f; - float g = ( ( col >> 8 ) & 0xff ) / 255.0f; - float b = ( ( col )& 0xff ) / 255.0f; +bool TileRenderer_SPU::tesselateBlockInWorld(Tile_SPU* tt, int x, int y, + int z) { + int col = tt->getColor(level, x, y, z); + float r = ((col >> 16) & 0xff) / 255.0f; + float g = ((col >> 8) & 0xff) / 255.0f; + float b = ((col) & 0xff) / 255.0f; - if ( isAnaglyph3d()) - { - float cr = ( r * 30 + g * 59 + b * 11 ) / 100; - float cg = ( r * 30 + g * 70 ) / ( 100 ); - float cb = ( r * 30 + b * 70 ) / ( 100 ); + if (isAnaglyph3d()) { + float cr = (r * 30 + g * 59 + b * 11) / 100; + float cg = (r * 30 + g * 70) / (100); + float cb = (r * 30 + b * 70) / (100); - r = cr; - g = cg; - b = cb; - } + r = cr; + g = cg; + b = cb; + } - if ( level->m_tileData.lightEmission[tt->id] == 0 )//4J - TODO/remove (Minecraft::useAmbientOcclusion()) - { - if ( SharedConstants::TEXTURE_LIGHTING ) - { - return tesselateBlockInWorldWithAmbienceOcclusionTexLighting( tt, x, y, z, r, g, b ); - } - else - { - return tesselateBlockInWorldWithAmbienceOcclusionOldLighting( tt, x, y, z, r, g, b ); - } - } - else - { - return tesselateBlockInWorld( tt, x, y, z, r, g, b ); - } + if (level->m_tileData.lightEmission[tt->id] == + 0) // 4J - TODO/remove (Minecraft::useAmbientOcclusion()) + { + if (SharedConstants::TEXTURE_LIGHTING) { + return tesselateBlockInWorldWithAmbienceOcclusionTexLighting( + tt, x, y, z, r, g, b); + } else { + return tesselateBlockInWorldWithAmbienceOcclusionOldLighting( + tt, x, y, z, r, g, b); + } + } else { + return tesselateBlockInWorld(tt, x, y, z, r, g, b); + } } -bool TileRenderer_SPU::tesselateTreeInWorld(Tile_SPU *tt, int x, int y, int z) -{ - int data = level->getData(x, y, z); - int facing = data & TreeTile_SPU::MASK_FACING; +bool TileRenderer_SPU::tesselateTreeInWorld(Tile_SPU* tt, int x, int y, int z) { + int data = level->getData(x, y, z); + int facing = data & TreeTile_SPU::MASK_FACING; - if (facing == TreeTile_SPU::FACING_X) - { - northFlip = FLIP_CW; - southFlip = FLIP_CW; - upFlip = FLIP_CW; - downFlip = FLIP_CW; - } - else if (facing == TreeTile_SPU::FACING_Z) - { - eastFlip = FLIP_CW; - westFlip = FLIP_CW; - } + if (facing == TreeTile_SPU::FACING_X) { + northFlip = FLIP_CW; + southFlip = FLIP_CW; + upFlip = FLIP_CW; + downFlip = FLIP_CW; + } else if (facing == TreeTile_SPU::FACING_Z) { + eastFlip = FLIP_CW; + westFlip = FLIP_CW; + } - bool result = tesselateBlockInWorld(tt, x, y, z); + bool result = tesselateBlockInWorld(tt, x, y, z); - eastFlip = 0; - northFlip = 0; - southFlip = 0; - westFlip = 0; - upFlip = 0; - downFlip = 0; + eastFlip = 0; + northFlip = 0; + southFlip = 0; + westFlip = 0; + upFlip = 0; + downFlip = 0; - return result; + return result; } -bool TileRenderer_SPU::tesselateQuartzInWorld(Tile_SPU *tt, int x, int y, int z) -{ - int data = level->getData(x, y, z); +bool TileRenderer_SPU::tesselateQuartzInWorld(Tile_SPU* tt, int x, int y, + int z) { + int data = level->getData(x, y, z); - if (data == QuartzBlockTile_SPU::TYPE_LINES_X) - { - northFlip = FLIP_CW; - southFlip = FLIP_CW; - upFlip = FLIP_CW; - downFlip = FLIP_CW; - } - else if (data == QuartzBlockTile_SPU::TYPE_LINES_Z) - { - eastFlip = FLIP_CW; - westFlip = FLIP_CW; - } + if (data == QuartzBlockTile_SPU::TYPE_LINES_X) { + northFlip = FLIP_CW; + southFlip = FLIP_CW; + upFlip = FLIP_CW; + downFlip = FLIP_CW; + } else if (data == QuartzBlockTile_SPU::TYPE_LINES_Z) { + eastFlip = FLIP_CW; + westFlip = FLIP_CW; + } - bool result = tesselateBlockInWorld(tt, x, y, z); + bool result = tesselateBlockInWorld(tt, x, y, z); - eastFlip = 0; - northFlip = 0; - southFlip = 0; - westFlip = 0; - upFlip = 0; - downFlip = 0; + eastFlip = 0; + northFlip = 0; + southFlip = 0; + westFlip = 0; + upFlip = 0; + downFlip = 0; - return result; + return result; } -bool TileRenderer_SPU::tesselateCocoaInWorld(CocoaTile_SPU *tt, int x, int y, int z) -{ +bool TileRenderer_SPU::tesselateCocoaInWorld(CocoaTile_SPU* tt, int x, int y, + int z) { #ifdef DISABLE_TESS_FUNCS - Tesselator *t = Tesselator::getInstance(); + Tesselator* t = Tesselator::getInstance(); - if (SharedConstants::TEXTURE_LIGHTING) - { - t->tex2(tt->getLightColor(level, x, y, z)); - t->color(1.0f, 1.0f, 1.0f); - } - else - { - float br = tt->getBrightness(level, x, y, z); - if (Tile::lightEmission[tt->id] > 0) br = 1.0f; - t->color(br, br, br); - } + if (SharedConstants::TEXTURE_LIGHTING) { + t->tex2(tt->getLightColor(level, x, y, z)); + t->color(1.0f, 1.0f, 1.0f); + } else { + float br = tt->getBrightness(level, x, y, z); + if (Tile::lightEmission[tt->id] > 0) br = 1.0f; + t->color(br, br, br); + } - int data = level->getData(x, y, z); - int dir = DirectionalTile::getDirection(data); - int age = CocoaTile::getAge(data); - Icon *tex = tt->getTextureForAge(age); + int data = level->getData(x, y, z); + int dir = DirectionalTile::getDirection(data); + int age = CocoaTile::getAge(data); + Icon* tex = tt->getTextureForAge(age); - int cocoaWidth = 4 + age * 2; - int cocoaHeight = 5 + age * 2; + int cocoaWidth = 4 + age * 2; + int cocoaHeight = 5 + age * 2; - double us = 15.0 - cocoaWidth; - double ue = 15.0; - double vs = 4.0; - double ve = 4.0 + cocoaHeight; - double u0 = tex->getU(us, true); - double u1 = tex->getU(ue, true); - double v0 = tex->getV(vs, true); - double v1 = tex->getV(ve, true); + double us = 15.0 - cocoaWidth; + double ue = 15.0; + double vs = 4.0; + double ve = 4.0 + cocoaHeight; + double u0 = tex->getU(us, true); + double u1 = tex->getU(ue, true); + double v0 = tex->getV(vs, true); + double v1 = tex->getV(ve, true); + double offX = 0; + double offZ = 0; - double offX = 0; - double offZ = 0; + switch (dir) { + case Direction::NORTH: + offX = 8.0 - cocoaWidth / 2; + offZ = 1.0; + break; + case Direction::SOUTH: + offX = 8.0 - cocoaWidth / 2; + offZ = 15.0 - cocoaWidth; + break; + case Direction::EAST: + offX = 15.0 - cocoaWidth; + offZ = 8.0 - cocoaWidth / 2; + break; + case Direction::WEST: + offX = 1.0; + offZ = 8.0 - cocoaWidth / 2; + break; + } - switch (dir) - { - case Direction::NORTH: - offX = 8.0 - cocoaWidth / 2; - offZ = 1.0; - break; - case Direction::SOUTH: - offX = 8.0 - cocoaWidth / 2; - offZ = 15.0 - cocoaWidth; - break; - case Direction::EAST: - offX = 15.0 - cocoaWidth; - offZ = 8.0 - cocoaWidth / 2; - break; - case Direction::WEST: - offX = 1.0; - offZ = 8.0 - cocoaWidth / 2; - break; - } + double x0 = x + offX / 16.0; + double x1 = x + (offX + cocoaWidth) / 16.0; + double y0 = y + (12.0 - cocoaHeight) / 16.0; + double y1 = y + 12.0 / 16.0; + double z0 = z + offZ / 16.0; + double z1 = z + (offZ + cocoaWidth) / 16.0; - double x0 = x + offX / 16.0; - double x1 = x + (offX + cocoaWidth) / 16.0; - double y0 = y + (12.0 - cocoaHeight) / 16.0; - double y1 = y + 12.0 / 16.0; - double z0 = z + offZ / 16.0; - double z1 = z + (offZ + cocoaWidth) / 16.0; + // west + { + t->vertexUV(x0, y0, z0, u0, v1); + t->vertexUV(x0, y0, z1, u1, v1); + t->vertexUV(x0, y1, z1, u1, v0); + t->vertexUV(x0, y1, z0, u0, v0); + } + // east + { + t->vertexUV(x1, y0, z1, u0, v1); + t->vertexUV(x1, y0, z0, u1, v1); + t->vertexUV(x1, y1, z0, u1, v0); + t->vertexUV(x1, y1, z1, u0, v0); + } + // north + { + t->vertexUV(x1, y0, z0, u0, v1); + t->vertexUV(x0, y0, z0, u1, v1); + t->vertexUV(x0, y1, z0, u1, v0); + t->vertexUV(x1, y1, z0, u0, v0); + } + // south + { + t->vertexUV(x0, y0, z1, u0, v1); + t->vertexUV(x1, y0, z1, u1, v1); + t->vertexUV(x1, y1, z1, u1, v0); + t->vertexUV(x0, y1, z1, u0, v0); + } - // west - { - t->vertexUV(x0, y0, z0, u0, v1); - t->vertexUV(x0, y0, z1, u1, v1); - t->vertexUV(x0, y1, z1, u1, v0); - t->vertexUV(x0, y1, z0, u0, v0); - } - // east - { - t->vertexUV(x1, y0, z1, u0, v1); - t->vertexUV(x1, y0, z0, u1, v1); - t->vertexUV(x1, y1, z0, u1, v0); - t->vertexUV(x1, y1, z1, u0, v0); - } - // north - { - t->vertexUV(x1, y0, z0, u0, v1); - t->vertexUV(x0, y0, z0, u1, v1); - t->vertexUV(x0, y1, z0, u1, v0); - t->vertexUV(x1, y1, z0, u0, v0); - } - // south - { - t->vertexUV(x0, y0, z1, u0, v1); - t->vertexUV(x1, y0, z1, u1, v1); - t->vertexUV(x1, y1, z1, u1, v0); - t->vertexUV(x0, y1, z1, u0, v0); - } + int topWidth = cocoaWidth; + if (age >= 2) { + // special case because the top piece didn't fit + topWidth--; + } - int topWidth = cocoaWidth; - if (age >= 2) - { - // special case because the top piece didn't fit - topWidth--; - } + u0 = tex->getU0(true); + u1 = tex->getU(topWidth, true); + v0 = tex->getV0(true); + v1 = tex->getV(topWidth, true); - u0 = tex->getU0(true); - u1 = tex->getU(topWidth, true); - v0 = tex->getV0(true); - v1 = tex->getV(topWidth, true); + // top + { + t->vertexUV(x0, y1, z1, u0, v1); + t->vertexUV(x1, y1, z1, u1, v1); + t->vertexUV(x1, y1, z0, u1, v0); + t->vertexUV(x0, y1, z0, u0, v0); + } + // bottom + { + t->vertexUV(x0, y0, z0, u0, v0); + t->vertexUV(x1, y0, z0, u1, v0); + t->vertexUV(x1, y0, z1, u1, v1); + t->vertexUV(x0, y0, z1, u0, v1); + } - // top - { - t->vertexUV(x0, y1, z1, u0, v1); - t->vertexUV(x1, y1, z1, u1, v1); - t->vertexUV(x1, y1, z0, u1, v0); - t->vertexUV(x0, y1, z0, u0, v0); - } - // bottom - { - t->vertexUV(x0, y0, z0, u0, v0); - t->vertexUV(x1, y0, z0, u1, v0); - t->vertexUV(x1, y0, z1, u1, v1); - t->vertexUV(x0, y0, z1, u0, v1); - } + // stalk + u0 = tex->getU(12, true); + u1 = tex->getU1(true); + v0 = tex->getV0(true); + v1 = tex->getV(4, true); - // stalk - u0 = tex->getU(12, true); - u1 = tex->getU1(true); - v0 = tex->getV0(true); - v1 = tex->getV(4, true); + offX = 8; + offZ = 0; - offX = 8; - offZ = 0; + switch (dir) { + case Direction::NORTH: + offX = 8.0; + offZ = 0.0; + break; + case Direction::SOUTH: + offX = 8; + offZ = 12; + { + double temp = u0; + u0 = u1; + u1 = temp; + } + break; + case Direction::EAST: + offX = 12.0; + offZ = 8.0; + { + double temp = u0; + u0 = u1; + u1 = temp; + } + break; + case Direction::WEST: + offX = 0.0; + offZ = 8.0; + break; + } - switch (dir) - { - case Direction::NORTH: - offX = 8.0; - offZ = 0.0; - break; - case Direction::SOUTH: - offX = 8; - offZ = 12; - { - double temp = u0; - u0 = u1; - u1 = temp; - } - break; - case Direction::EAST: - offX = 12.0; - offZ = 8.0; - { - double temp = u0; - u0 = u1; - u1 = temp; - } - break; - case Direction::WEST: - offX = 0.0; - offZ = 8.0; - break; - } + x0 = x + offX / 16.0; + x1 = x + (offX + 4.0) / 16.0; + y0 = y + 12.0 / 16.0; + y1 = y + 16.0 / 16.0; + z0 = z + offZ / 16.0; + z1 = z + (offZ + 4.0) / 16.0; + if (dir == Direction::NORTH || dir == Direction::SOUTH) { + // west + { + t->vertexUV(x0, y0, z0, u1, v1); + t->vertexUV(x0, y0, z1, u0, v1); + t->vertexUV(x0, y1, z1, u0, v0); + t->vertexUV(x0, y1, z0, u1, v0); + } + // east + { + t->vertexUV(x0, y0, z1, u0, v1); + t->vertexUV(x0, y0, z0, u1, v1); + t->vertexUV(x0, y1, z0, u1, v0); + t->vertexUV(x0, y1, z1, u0, v0); + } + } else if (dir == Direction::WEST || dir == Direction::EAST) { + // north + { + t->vertexUV(x1, y0, z0, u0, v1); + t->vertexUV(x0, y0, z0, u1, v1); + t->vertexUV(x0, y1, z0, u1, v0); + t->vertexUV(x1, y1, z0, u0, v0); + } + // south + { + t->vertexUV(x0, y0, z0, u1, v1); + t->vertexUV(x1, y0, z0, u0, v1); + t->vertexUV(x1, y1, z0, u0, v0); + t->vertexUV(x0, y1, z0, u1, v0); + } + } - x0 = x + offX / 16.0; - x1 = x + (offX + 4.0) / 16.0; - y0 = y + 12.0 / 16.0; - y1 = y + 16.0 / 16.0; - z0 = z + offZ / 16.0; - z1 = z + (offZ + 4.0) / 16.0; - if (dir == Direction::NORTH || dir == Direction::SOUTH) - { - // west - { - t->vertexUV(x0, y0, z0, u1, v1); - t->vertexUV(x0, y0, z1, u0, v1); - t->vertexUV(x0, y1, z1, u0, v0); - t->vertexUV(x0, y1, z0, u1, v0); - } - // east - { - t->vertexUV(x0, y0, z1, u0, v1); - t->vertexUV(x0, y0, z0, u1, v1); - t->vertexUV(x0, y1, z0, u1, v0); - t->vertexUV(x0, y1, z1, u0, v0); - } - } - else if (dir == Direction::WEST || dir == Direction::EAST) - { - // north - { - t->vertexUV(x1, y0, z0, u0, v1); - t->vertexUV(x0, y0, z0, u1, v1); - t->vertexUV(x0, y1, z0, u1, v0); - t->vertexUV(x1, y1, z0, u0, v0); - } - // south - { - t->vertexUV(x0, y0, z0, u1, v1); - t->vertexUV(x1, y0, z0, u0, v1); - t->vertexUV(x1, y1, z0, u0, v0); - t->vertexUV(x0, y1, z0, u1, v0); - } - } - -#endif // DISABLE_TESS_FUNCS - return true; +#endif // DISABLE_TESS_FUNCS + return true; } // 4J - brought changes forward from 1.8.2 -bool TileRenderer_SPU::tesselateBlockInWorldWithAmbienceOcclusionTexLighting( Tile_SPU* tt, int pX, int pY, int pZ, - float pBaseRed, float pBaseGreen, - float pBaseBlue ) -{ - // 4J - added these faceFlags so we can detect whether this block is going to have no visible faces and early out - // the original code checked noCulling and shouldRenderFace directly where faceFlags is used now - int faceFlags = 0; - if ( noCulling ) - { - faceFlags = 0x3f; - } - else - { -/*#ifdef _DEBUG - if(dynamic_cast(tt)!=NULL) - { - // stair tile - faceFlags |= tt->shouldRenderFace( level, pX, pY - 1, pZ, 0 ) ? 0x01 : 0; - faceFlags |= tt->shouldRenderFace( level, pX, pY + 1, pZ, 1 ) ? 0x02 : 0; - faceFlags |= tt->shouldRenderFace( level, pX, pY, pZ - 1, 2 ) ? 0x04 : 0; - faceFlags |= tt->shouldRenderFace( level, pX, pY, pZ + 1, 3 ) ? 0x08 : 0; - faceFlags |= tt->shouldRenderFace( level, pX - 1, pY, pZ, 4 ) ? 0x10 : 0; - faceFlags |= tt->shouldRenderFace( level, pX + 1, pY, pZ, 5 ) ? 0x20 : 0; +bool TileRenderer_SPU::tesselateBlockInWorldWithAmbienceOcclusionTexLighting( + Tile_SPU* tt, int pX, int pY, int pZ, float pBaseRed, float pBaseGreen, + float pBaseBlue) { + // 4J - added these faceFlags so we can detect whether this block is going + // to have no visible faces and early out the original code checked + // noCulling and shouldRenderFace directly where faceFlags is used now + int faceFlags = 0; + if (noCulling) { + faceFlags = 0x3f; + } else { + /*#ifdef _DEBUG + if(dynamic_cast(tt)!=NULL) + { + // stair tile + faceFlags |= tt->shouldRenderFace( level, pX, pY + - 1, pZ, 0 ) ? 0x01 : 0; faceFlags |= tt->shouldRenderFace( level, pX, + pY + 1, pZ, 1 ) ? 0x02 : 0; faceFlags |= tt->shouldRenderFace( level, + pX, pY, pZ - 1, 2 ) ? 0x04 : 0; faceFlags |= tt->shouldRenderFace( + level, pX, pY, pZ + 1, 3 ) ? 0x08 : 0; faceFlags |= + tt->shouldRenderFace( level, pX - 1, pY, pZ, 4 ) ? 0x10 : 0; faceFlags + |= tt->shouldRenderFace( level, pX + 1, pY, pZ, 5 ) ? 0x20 : 0; - printf("Stair tile\n"); - } - else - { - faceFlags |= tt->shouldRenderFace( level, pX, pY - 1, pZ, 0 ) ? 0x01 : 0; - faceFlags |= tt->shouldRenderFace( level, pX, pY + 1, pZ, 1 ) ? 0x02 : 0; - faceFlags |= tt->shouldRenderFace( level, pX, pY, pZ - 1, 2 ) ? 0x04 : 0; - faceFlags |= tt->shouldRenderFace( level, pX, pY, pZ + 1, 3 ) ? 0x08 : 0; - faceFlags |= tt->shouldRenderFace( level, pX - 1, pY, pZ, 4 ) ? 0x10 : 0; - faceFlags |= tt->shouldRenderFace( level, pX + 1, pY, pZ, 5 ) ? 0x20 : 0; + printf("Stair tile\n"); + } + else + { + faceFlags |= tt->shouldRenderFace( level, pX, pY + - 1, pZ, 0 ) ? 0x01 : 0; faceFlags |= tt->shouldRenderFace( level, pX, + pY + 1, pZ, 1 ) ? 0x02 : 0; faceFlags |= tt->shouldRenderFace( level, + pX, pY, pZ - 1, 2 ) ? 0x04 : 0; faceFlags |= tt->shouldRenderFace( + level, pX, pY, pZ + 1, 3 ) ? 0x08 : 0; faceFlags |= + tt->shouldRenderFace( level, pX - 1, pY, pZ, 4 ) ? 0x10 : 0; faceFlags + |= tt->shouldRenderFace( level, pX + 1, pY, pZ, 5 ) ? 0x20 : 0; - } -#else*/ - faceFlags |= tt->shouldRenderFace( level, pX, pY - 1, pZ, 0 ) ? 0x01 : 0; - faceFlags |= tt->shouldRenderFace( level, pX, pY + 1, pZ, 1 ) ? 0x02 : 0; - faceFlags |= tt->shouldRenderFace( level, pX, pY, pZ - 1, 2 ) ? 0x04 : 0; - faceFlags |= tt->shouldRenderFace( level, pX, pY, pZ + 1, 3 ) ? 0x08 : 0; - faceFlags |= tt->shouldRenderFace( level, pX - 1, pY, pZ, 4 ) ? 0x10 : 0; - faceFlags |= tt->shouldRenderFace( level, pX + 1, pY, pZ, 5 ) ? 0x20 : 0; -//#endif - } - if ( faceFlags == 0 ) - { - return false; - } + } + #else*/ + faceFlags |= tt->shouldRenderFace(level, pX, pY - 1, pZ, 0) ? 0x01 : 0; + faceFlags |= tt->shouldRenderFace(level, pX, pY + 1, pZ, 1) ? 0x02 : 0; + faceFlags |= tt->shouldRenderFace(level, pX, pY, pZ - 1, 2) ? 0x04 : 0; + faceFlags |= tt->shouldRenderFace(level, pX, pY, pZ + 1, 3) ? 0x08 : 0; + faceFlags |= tt->shouldRenderFace(level, pX - 1, pY, pZ, 4) ? 0x10 : 0; + faceFlags |= tt->shouldRenderFace(level, pX + 1, pY, pZ, 5) ? 0x20 : 0; + // #endif + } + if (faceFlags == 0) { + return false; + } + // If we are only rendering the bottom face and we're at the bottom of the + // world, we shouldn't be able to see this - don't render anything + if ((faceFlags == 1) && (pY == 0)) { + return false; + } - // If we are only rendering the bottom face and we're at the bottom of the world, we shouldn't be able to see this - don't render anything - if( ( faceFlags == 1 ) && ( pY == 0 ) ) - { - return false; - } + applyAmbienceOcclusion = true; + float ll1 = ll000; + float ll2 = ll000; + float ll3 = ll000; + float ll4 = ll000; + bool tint0 = true; + bool tint1 = true; + bool tint2 = true; + bool tint3 = true; + bool tint4 = true; + bool tint5 = true; - applyAmbienceOcclusion = true; - float ll1 = ll000; - float ll2 = ll000; - float ll3 = ll000; - float ll4 = ll000; - bool tint0 = true; - bool tint1 = true; - bool tint2 = true; - bool tint3 = true; - bool tint4 = true; - bool tint5 = true; + ll000 = tt->getShadeBrightness(level, pX, pY, pZ); + // Tile* t2 = Tile::tiles[tt->id]; + // if(t2->getShadeBrightness(level->m_pRegion, pX, pY, pZ) != ll000) + // { + // app.DebugPrintf("Failed\n"); + // ll000 = tt->getShadeBrightness( level, pX, pY, pZ ); + // ll000 = t2->getShadeBrightness(level->m_pRegion, pX, pY, pZ); + // } + llx00 = tt->getShadeBrightness(level, pX - 1, pY, pZ); + ll0y0 = tt->getShadeBrightness(level, pX, pY - 1, pZ); + ll00z = tt->getShadeBrightness(level, pX, pY, pZ - 1); + llX00 = tt->getShadeBrightness(level, pX + 1, pY, pZ); + ll0Y0 = tt->getShadeBrightness(level, pX, pY + 1, pZ); + ll00Z = tt->getShadeBrightness(level, pX, pY, pZ + 1); + // 4J - these changes brought forward from 1.2.3 + int centerColor = tt->getLightColor(level, pX, pY, pZ); + int ccx00 = centerColor; + int cc0y0 = centerColor; + int cc00z = centerColor; + int ccX00 = centerColor; + int cc0Y0 = centerColor; + int cc00Z = centerColor; - ll000 = tt->getShadeBrightness( level, pX, pY, pZ ); -// Tile* t2 = Tile::tiles[tt->id]; -// if(t2->getShadeBrightness(level->m_pRegion, pX, pY, pZ) != ll000) -// { -// app.DebugPrintf("Failed\n"); -// ll000 = tt->getShadeBrightness( level, pX, pY, pZ ); -// ll000 = t2->getShadeBrightness(level->m_pRegion, pX, pY, pZ); -// } - llx00 = tt->getShadeBrightness( level, pX - 1, pY, pZ ); - ll0y0 = tt->getShadeBrightness( level, pX, pY - 1, pZ ); - ll00z = tt->getShadeBrightness( level, pX, pY, pZ - 1 ); - llX00 = tt->getShadeBrightness( level, pX + 1, pY, pZ ); - ll0Y0 = tt->getShadeBrightness( level, pX, pY + 1, pZ ); - ll00Z = tt->getShadeBrightness( level, pX, pY, pZ + 1 ); + if (tileShapeY0 <= 0 || !level->isSolidRenderTile(pX, pY - 1, pZ)) + cc0y0 = tt->getLightColor(level, pX, pY - 1, pZ); + if (tileShapeY1 >= 1 || !level->isSolidRenderTile(pX, pY + 1, pZ)) + cc0Y0 = tt->getLightColor(level, pX, pY + 1, pZ); + if (tileShapeX0 <= 0 || !level->isSolidRenderTile(pX - 1, pY, pZ)) + ccx00 = tt->getLightColor(level, pX - 1, pY, pZ); + if (tileShapeX1 >= 1 || !level->isSolidRenderTile(pX + 1, pY, pZ)) + ccX00 = tt->getLightColor(level, pX + 1, pY, pZ); + if (tileShapeZ0 <= 0 || !level->isSolidRenderTile(pX, pY, pZ - 1)) + cc00z = tt->getLightColor(level, pX, pY, pZ - 1); + if (tileShapeZ1 >= 1 || !level->isSolidRenderTile(pX, pY, pZ + 1)) + cc00Z = tt->getLightColor(level, pX, pY, pZ + 1); + Tesselator_SPU* t = getTesselator(); + t->tex2(0xf000f); + llTransXY0 = + level->m_tileData.transculent[level->getTile(pX + 1, pY + 1, pZ)]; + llTransXy0 = + level->m_tileData.transculent[level->getTile(pX + 1, pY - 1, pZ)]; + llTransX0Z = + level->m_tileData.transculent[level->getTile(pX + 1, pY, pZ + 1)]; + llTransX0z = + level->m_tileData.transculent[level->getTile(pX + 1, pY, pZ - 1)]; + llTransxY0 = + level->m_tileData.transculent[level->getTile(pX - 1, pY + 1, pZ)]; + llTransxy0 = + level->m_tileData.transculent[level->getTile(pX - 1, pY - 1, pZ)]; + llTransx0z = + level->m_tileData.transculent[level->getTile(pX - 1, pY, pZ - 1)]; + llTransx0Z = + level->m_tileData.transculent[level->getTile(pX - 1, pY, pZ + 1)]; + llTrans0YZ = + level->m_tileData.transculent[level->getTile(pX, pY + 1, pZ + 1)]; + llTrans0Yz = + level->m_tileData.transculent[level->getTile(pX, pY + 1, pZ - 1)]; + llTrans0yZ = + level->m_tileData.transculent[level->getTile(pX, pY - 1, pZ + 1)]; + llTrans0yz = + level->m_tileData.transculent[level->getTile(pX, pY - 1, pZ - 1)]; - // 4J - these changes brought forward from 1.2.3 - int centerColor = tt->getLightColor( level, pX, pY, pZ ); - int ccx00 = centerColor; - int cc0y0 = centerColor; - int cc00z = centerColor; - int ccX00 = centerColor; - int cc0Y0 = centerColor; - int cc00Z = centerColor; + if (getTexture(tt) == &Tile_SPU::ms_pTileData->grass_iconTop) + tint0 = tint2 = tint3 = tint4 = tint5 = false; + if (hasFixedTexture()) tint0 = tint2 = tint3 = tint4 = tint5 = false; + if (faceFlags & 0x01) { + if (blsmooth > 0) { + if (tileShapeY0 <= 0) + pY--; // 4J - condition brought forwardEnterCriticalSection + // from 1.2.3 - if (tileShapeY0 <= 0 || !level->isSolidRenderTile(pX, pY - 1, pZ)) cc0y0 = tt->getLightColor(level, pX, pY - 1, pZ); - if (tileShapeY1 >= 1 || !level->isSolidRenderTile(pX, pY + 1, pZ)) cc0Y0 = tt->getLightColor(level, pX, pY + 1, pZ); - if (tileShapeX0 <= 0 || !level->isSolidRenderTile(pX - 1, pY, pZ)) ccx00 = tt->getLightColor(level, pX - 1, pY, pZ); - if (tileShapeX1 >= 1 || !level->isSolidRenderTile(pX + 1, pY, pZ)) ccX00 = tt->getLightColor(level, pX + 1, pY, pZ); - if (tileShapeZ0 <= 0 || !level->isSolidRenderTile(pX, pY, pZ - 1)) cc00z = tt->getLightColor(level, pX, pY, pZ - 1); - if (tileShapeZ1 >= 1 || !level->isSolidRenderTile(pX, pY, pZ + 1)) cc00Z = tt->getLightColor(level, pX, pY, pZ + 1); + ccxy0 = tt->getLightColor(level, pX - 1, pY, pZ); + cc0yz = tt->getLightColor(level, pX, pY, pZ - 1); + cc0yZ = tt->getLightColor(level, pX, pY, pZ + 1); + ccXy0 = tt->getLightColor(level, pX + 1, pY, pZ); + llxy0 = tt->getShadeBrightness(level, pX - 1, pY, pZ); + ll0yz = tt->getShadeBrightness(level, pX, pY, pZ - 1); + ll0yZ = tt->getShadeBrightness(level, pX, pY, pZ + 1); + llXy0 = tt->getShadeBrightness(level, pX + 1, pY, pZ); - Tesselator_SPU* t = getTesselator(); - t->tex2( 0xf000f ); + if (llTrans0yz || llTransxy0) { + llxyz = tt->getShadeBrightness(level, pX - 1, pY, pZ - 1); + ccxyz = tt->getLightColor(level, pX - 1, pY, pZ - 1); + } else { + llxyz = llxy0; + ccxyz = ccxy0; + } + if (llTrans0yZ || llTransxy0) { + llxyZ = tt->getShadeBrightness(level, pX - 1, pY, pZ + 1); + ccxyZ = tt->getLightColor(level, pX - 1, pY, pZ + 1); + } else { + llxyZ = llxy0; + ccxyZ = ccxy0; + } + if (llTrans0yz || llTransXy0) { + llXyz = tt->getShadeBrightness(level, pX + 1, pY, pZ - 1); + ccXyz = tt->getLightColor(level, pX + 1, pY, pZ - 1); + } else { + llXyz = llXy0; + ccXyz = ccXy0; + } + if (llTrans0yZ || llTransXy0) { + llXyZ = tt->getShadeBrightness(level, pX + 1, pY, pZ + 1); + ccXyZ = tt->getLightColor(level, pX + 1, pY, pZ + 1); + } else { + llXyZ = llXy0; + ccXyZ = ccXy0; + } - llTransXY0 = level->m_tileData.transculent[level->getTile( pX + 1, pY + 1, pZ )]; - llTransXy0 = level->m_tileData.transculent[level->getTile( pX + 1, pY - 1, pZ )]; - llTransX0Z = level->m_tileData.transculent[level->getTile( pX + 1, pY, pZ + 1 )]; - llTransX0z = level->m_tileData.transculent[level->getTile( pX + 1, pY, pZ - 1 )]; - llTransxY0 = level->m_tileData.transculent[level->getTile( pX - 1, pY + 1, pZ )]; - llTransxy0 = level->m_tileData.transculent[level->getTile( pX - 1, pY - 1, pZ )]; - llTransx0z = level->m_tileData.transculent[level->getTile( pX - 1, pY, pZ - 1 )]; - llTransx0Z = level->m_tileData.transculent[level->getTile( pX - 1, pY, pZ + 1 )]; - llTrans0YZ = level->m_tileData.transculent[level->getTile( pX, pY + 1, pZ + 1 )]; - llTrans0Yz = level->m_tileData.transculent[level->getTile( pX, pY + 1, pZ - 1 )]; - llTrans0yZ = level->m_tileData.transculent[level->getTile( pX, pY - 1, pZ + 1 )]; - llTrans0yz = level->m_tileData.transculent[level->getTile( pX, pY - 1, pZ - 1 )]; + if (tileShapeY0 <= 0) + pY++; // 4J - condition brought forward from 1.2.3 + ll1 = (llxyZ + llxy0 + ll0yZ + ll0y0) / 4.0f; + ll4 = (ll0yZ + ll0y0 + llXyZ + llXy0) / 4.0f; + ll3 = (ll0y0 + ll0yz + llXy0 + llXyz) / 4.0f; + ll2 = (llxy0 + llxyz + ll0y0 + ll0yz) / 4.0f; - if ( getTexture(tt)== &Tile_SPU::ms_pTileData->grass_iconTop ) - tint0 = tint2 = tint3 = tint4 = tint5 = false; - if ( hasFixedTexture() ) tint0 = tint2 = tint3 = tint4 = tint5 = false; + tc1 = blend(ccxyZ, ccxy0, cc0yZ, cc0y0); + tc4 = blend(cc0yZ, ccXyZ, ccXy0, cc0y0); + tc3 = blend(cc0yz, ccXy0, ccXyz, cc0y0); + tc2 = blend(ccxy0, ccxyz, cc0yz, cc0y0); + } else { + ll1 = ll2 = ll3 = ll4 = ll0y0; + tc1 = tc2 = tc3 = tc4 = ccxy0; + } + c1r = c2r = c3r = c4r = (tint0 ? pBaseRed : 1.0f) * 0.5f; + c1g = c2g = c3g = c4g = (tint0 ? pBaseGreen : 1.0f) * 0.5f; + c1b = c2b = c3b = c4b = (tint0 ? pBaseBlue : 1.0f) * 0.5f; + c1r *= ll1; + c1g *= ll1; + c1b *= ll1; + c2r *= ll2; + c2g *= ll2; + c2b *= ll2; + c3r *= ll3; + c3g *= ll3; + c3b *= ll3; + c4r *= ll4; + c4g *= ll4; + c4b *= ll4; - if ( faceFlags & 0x01 ) - { - if ( blsmooth > 0 ) - { - if ( tileShapeY0 <= 0 ) pY--; // 4J - condition brought forwardEnterCriticalSection from 1.2.3 + renderFaceDown(tt, (float)pX, (float)pY, (float)pZ, + getTexture(tt, level, pX, pY, pZ, 0)); + } + if (faceFlags & 0x02) { + if (blsmooth > 0) { + if (tileShapeY1 >= 1) + pY++; // 4J - condition brought forward from 1.2.3 - ccxy0 = tt->getLightColor( level, pX - 1, pY, pZ ); - cc0yz = tt->getLightColor( level, pX, pY, pZ - 1 ); - cc0yZ = tt->getLightColor( level, pX, pY, pZ + 1 ); - ccXy0 = tt->getLightColor( level, pX + 1, pY, pZ ); + ccxY0 = tt->getLightColor(level, pX - 1, pY, pZ); + ccXY0 = tt->getLightColor(level, pX + 1, pY, pZ); + cc0Yz = tt->getLightColor(level, pX, pY, pZ - 1); + cc0YZ = tt->getLightColor(level, pX, pY, pZ + 1); - llxy0 = tt->getShadeBrightness( level, pX - 1, pY, pZ ); - ll0yz = tt->getShadeBrightness( level, pX, pY, pZ - 1 ); - ll0yZ = tt->getShadeBrightness( level, pX, pY, pZ + 1 ); - llXy0 = tt->getShadeBrightness( level, pX + 1, pY, pZ ); + llxY0 = tt->getShadeBrightness(level, pX - 1, pY, pZ); + llXY0 = tt->getShadeBrightness(level, pX + 1, pY, pZ); + ll0Yz = tt->getShadeBrightness(level, pX, pY, pZ - 1); + ll0YZ = tt->getShadeBrightness(level, pX, pY, pZ + 1); - if ( llTrans0yz || llTransxy0 ) - { - llxyz = tt->getShadeBrightness( level, pX - 1, pY, pZ - 1 ); - ccxyz = tt->getLightColor( level, pX - 1, pY, pZ - 1 ); - } - else - { - llxyz = llxy0; - ccxyz = ccxy0; - } - if ( llTrans0yZ || llTransxy0 ) - { - llxyZ = tt->getShadeBrightness( level, pX - 1, pY, pZ + 1 ); - ccxyZ = tt->getLightColor( level, pX - 1, pY, pZ + 1 ); - } - else - { - llxyZ = llxy0; - ccxyZ = ccxy0; - } - if ( llTrans0yz || llTransXy0 ) - { - llXyz = tt->getShadeBrightness( level, pX + 1, pY, pZ - 1 ); - ccXyz = tt->getLightColor( level, pX + 1, pY, pZ - 1 ); - } - else - { - llXyz = llXy0; - ccXyz = ccXy0; - } - if ( llTrans0yZ || llTransXy0 ) - { - llXyZ = tt->getShadeBrightness( level, pX + 1, pY, pZ + 1 ); - ccXyZ = tt->getLightColor( level, pX + 1, pY, pZ + 1 ); - } - else - { - llXyZ = llXy0; - ccXyZ = ccXy0; - } + if (llTrans0Yz || llTransxY0) { + llxYz = tt->getShadeBrightness(level, pX - 1, pY, pZ - 1); + ccxYz = tt->getLightColor(level, pX - 1, pY, pZ - 1); + } else { + llxYz = llxY0; + ccxYz = ccxY0; + } + if (llTrans0Yz || llTransXY0) { + llXYz = tt->getShadeBrightness(level, pX + 1, pY, pZ - 1); + ccXYz = tt->getLightColor(level, pX + 1, pY, pZ - 1); + } else { + llXYz = llXY0; + ccXYz = ccXY0; + } + if (llTrans0YZ || llTransxY0) { + llxYZ = tt->getShadeBrightness(level, pX - 1, pY, pZ + 1); + ccxYZ = tt->getLightColor(level, pX - 1, pY, pZ + 1); + } else { + llxYZ = llxY0; + ccxYZ = ccxY0; + } + if (llTrans0YZ || llTransXY0) { + llXYZ = tt->getShadeBrightness(level, pX + 1, pY, pZ + 1); + ccXYZ = tt->getLightColor(level, pX + 1, pY, pZ + 1); + } else { + llXYZ = llXY0; + ccXYZ = ccXY0; + } + if (tileShapeY1 >= 1) + pY--; // 4J - condition brought forward from 1.2.3 - if ( tileShapeY0 <= 0 ) pY++; // 4J - condition brought forward from 1.2.3 - ll1 = ( llxyZ + llxy0 + ll0yZ + ll0y0 ) / 4.0f; - ll4 = ( ll0yZ + ll0y0 + llXyZ + llXy0 ) / 4.0f; - ll3 = ( ll0y0 + ll0yz + llXy0 + llXyz ) / 4.0f; - ll2 = ( llxy0 + llxyz + ll0y0 + ll0yz ) / 4.0f; + ll4 = (llxYZ + llxY0 + ll0YZ + ll0Y0) / 4.0f; + ll1 = (ll0YZ + ll0Y0 + llXYZ + llXY0) / 4.0f; + ll2 = (ll0Y0 + ll0Yz + llXY0 + llXYz) / 4.0f; + ll3 = (llxY0 + llxYz + ll0Y0 + ll0Yz) / 4.0f; - tc1 = blend( ccxyZ, ccxy0, cc0yZ, cc0y0 ); - tc4 = blend( cc0yZ, ccXyZ, ccXy0, cc0y0 ); - tc3 = blend( cc0yz, ccXy0, ccXyz, cc0y0 ); - tc2 = blend( ccxy0, ccxyz, cc0yz, cc0y0 ); - } - else - { - ll1 = ll2 = ll3 = ll4 = ll0y0; - tc1 = tc2 = tc3 = tc4 = ccxy0; - } - c1r = c2r = c3r = c4r = ( tint0 ? pBaseRed : 1.0f ) * 0.5f; - c1g = c2g = c3g = c4g = ( tint0 ? pBaseGreen : 1.0f ) * 0.5f; - c1b = c2b = c3b = c4b = ( tint0 ? pBaseBlue : 1.0f ) * 0.5f; - c1r *= ll1; - c1g *= ll1; - c1b *= ll1; - c2r *= ll2; - c2g *= ll2; - c2b *= ll2; - c3r *= ll3; - c3g *= ll3; - c3b *= ll3; - c4r *= ll4; - c4g *= ll4; - c4b *= ll4; + tc4 = blend(ccxYZ, ccxY0, cc0YZ, cc0Y0); + tc1 = blend(cc0YZ, ccXYZ, ccXY0, cc0Y0); + tc2 = blend(cc0Yz, ccXY0, ccXYz, cc0Y0); + tc3 = blend(ccxY0, ccxYz, cc0Yz, cc0Y0); + } else { + ll1 = ll2 = ll3 = ll4 = ll0Y0; + tc1 = tc2 = tc3 = tc4 = cc0Y0; + } + c1r = c2r = c3r = c4r = (tint1 ? pBaseRed : 1.0f); + c1g = c2g = c3g = c4g = (tint1 ? pBaseGreen : 1.0f); + c1b = c2b = c3b = c4b = (tint1 ? pBaseBlue : 1.0f); + c1r *= ll1; + c1g *= ll1; + c1b *= ll1; + c2r *= ll2; + c2g *= ll2; + c2b *= ll2; + c3r *= ll3; + c3g *= ll3; + c3b *= ll3; + c4r *= ll4; + c4g *= ll4; + c4b *= ll4; - renderFaceDown( tt, ( float )pX, ( float )pY, ( float )pZ, getTexture( tt, level, pX, pY, pZ, 0 ) ); - } - if ( faceFlags & 0x02 ) - { - if ( blsmooth > 0 ) - { - if ( tileShapeY1 >= 1 ) pY++; // 4J - condition brought forward from 1.2.3 + renderFaceUp(tt, (float)pX, (float)pY, (float)pZ, + getTexture(tt, level, pX, pY, pZ, 1)); + } + if (faceFlags & 0x04) { + if (blsmooth > 0) { + if (tileShapeZ0 <= 0) + pZ--; // 4J - condition brought forward from 1.2.3 + llx0z = tt->getShadeBrightness(level, pX - 1, pY, pZ); + ll0yz = tt->getShadeBrightness(level, pX, pY - 1, pZ); + ll0Yz = tt->getShadeBrightness(level, pX, pY + 1, pZ); + llX0z = tt->getShadeBrightness(level, pX + 1, pY, pZ); - ccxY0 = tt->getLightColor( level, pX - 1, pY, pZ ); - ccXY0 = tt->getLightColor( level, pX + 1, pY, pZ ); - cc0Yz = tt->getLightColor( level, pX, pY, pZ - 1 ); - cc0YZ = tt->getLightColor( level, pX, pY, pZ + 1 ); + ccx0z = tt->getLightColor(level, pX - 1, pY, pZ); + cc0yz = tt->getLightColor(level, pX, pY - 1, pZ); + cc0Yz = tt->getLightColor(level, pX, pY + 1, pZ); + ccX0z = tt->getLightColor(level, pX + 1, pY, pZ); - llxY0 = tt->getShadeBrightness( level, pX - 1, pY, pZ ); - llXY0 = tt->getShadeBrightness( level, pX + 1, pY, pZ ); - ll0Yz = tt->getShadeBrightness( level, pX, pY, pZ - 1 ); - ll0YZ = tt->getShadeBrightness( level, pX, pY, pZ + 1 ); - - if ( llTrans0Yz || llTransxY0 ) - { - llxYz = tt->getShadeBrightness( level, pX - 1, pY, pZ - 1 ); - ccxYz = tt->getLightColor( level, pX - 1, pY, pZ - 1 ); - } - else - { - llxYz = llxY0; - ccxYz = ccxY0; - } - if ( llTrans0Yz || llTransXY0 ) - { - llXYz = tt->getShadeBrightness( level, pX + 1, pY, pZ - 1 ); - ccXYz = tt->getLightColor( level, pX + 1, pY, pZ - 1 ); - } - else - { - llXYz = llXY0; - ccXYz = ccXY0; - } - if ( llTrans0YZ || llTransxY0 ) - { - llxYZ = tt->getShadeBrightness( level, pX - 1, pY, pZ + 1 ); - ccxYZ = tt->getLightColor( level, pX - 1, pY, pZ + 1 ); - } - else - { - llxYZ = llxY0; - ccxYZ = ccxY0; - } - if ( llTrans0YZ || llTransXY0 ) - { - llXYZ = tt->getShadeBrightness( level, pX + 1, pY, pZ + 1 ); - ccXYZ = tt->getLightColor( level, pX + 1, pY, pZ + 1 ); - } - else - { - llXYZ = llXY0; - ccXYZ = ccXY0; - } - if ( tileShapeY1 >= 1 ) pY--; // 4J - condition brought forward from 1.2.3 - - ll4 = ( llxYZ + llxY0 + ll0YZ + ll0Y0 ) / 4.0f; - ll1 = ( ll0YZ + ll0Y0 + llXYZ + llXY0 ) / 4.0f; - ll2 = ( ll0Y0 + ll0Yz + llXY0 + llXYz ) / 4.0f; - ll3 = ( llxY0 + llxYz + ll0Y0 + ll0Yz ) / 4.0f; - - tc4 = blend( ccxYZ, ccxY0, cc0YZ, cc0Y0 ); - tc1 = blend( cc0YZ, ccXYZ, ccXY0, cc0Y0 ); - tc2 = blend( cc0Yz, ccXY0, ccXYz, cc0Y0 ); - tc3 = blend( ccxY0, ccxYz, cc0Yz, cc0Y0 ); - } - else - { - ll1 = ll2 = ll3 = ll4 = ll0Y0; - tc1 = tc2 = tc3 = tc4 = cc0Y0; - } - c1r = c2r = c3r = c4r = ( tint1 ? pBaseRed : 1.0f ); - c1g = c2g = c3g = c4g = ( tint1 ? pBaseGreen : 1.0f ); - c1b = c2b = c3b = c4b = ( tint1 ? pBaseBlue : 1.0f ); - c1r *= ll1; - c1g *= ll1; - c1b *= ll1; - c2r *= ll2; - c2g *= ll2; - c2b *= ll2; - c3r *= ll3; - c3g *= ll3; - c3b *= ll3; - c4r *= ll4; - c4g *= ll4; - c4b *= ll4; - - - renderFaceUp( tt, ( float )pX, ( float )pY, ( float )pZ, getTexture( tt, level, pX, pY, pZ, 1 ) ); - } - if ( faceFlags & 0x04 ) - { - if ( blsmooth > 0 ) - { - if ( tileShapeZ0 <= 0 ) pZ--; // 4J - condition brought forward from 1.2.3 - llx0z = tt->getShadeBrightness( level, pX - 1, pY, pZ ); - ll0yz = tt->getShadeBrightness( level, pX, pY - 1, pZ ); - ll0Yz = tt->getShadeBrightness( level, pX, pY + 1, pZ ); - llX0z = tt->getShadeBrightness( level, pX + 1, pY, pZ ); - - ccx0z = tt->getLightColor( level, pX - 1, pY, pZ ); - cc0yz = tt->getLightColor( level, pX, pY - 1, pZ ); - cc0Yz = tt->getLightColor( level, pX, pY + 1, pZ ); - ccX0z = tt->getLightColor( level, pX + 1, pY, pZ ); - - if ( llTransx0z || llTrans0yz ) - { - llxyz = tt->getShadeBrightness( level, pX - 1, pY - 1, pZ ); - ccxyz = tt->getLightColor( level, pX - 1, pY - 1, pZ ); - } - else - { - llxyz = llx0z; - ccxyz = ccx0z; - } - if ( llTransx0z || llTrans0Yz ) - { - llxYz = tt->getShadeBrightness( level, pX - 1, pY + 1, pZ ); - ccxYz = tt->getLightColor( level, pX - 1, pY + 1, pZ ); - } - else - { - llxYz = llx0z; - ccxYz = ccx0z; - } - if ( llTransX0z || llTrans0yz ) - { - llXyz = tt->getShadeBrightness( level, pX + 1, pY - 1, pZ ); - ccXyz = tt->getLightColor( level, pX + 1, pY - 1, pZ ); - } - else - { - llXyz = llX0z; - ccXyz = ccX0z; - } - if ( llTransX0z || llTrans0Yz ) - { - llXYz = tt->getShadeBrightness( level, pX + 1, pY + 1, pZ ); - ccXYz = tt->getLightColor( level, pX + 1, pY + 1, pZ ); - } - else - { - llXYz = llX0z; - ccXYz = ccX0z; - } - if ( tileShapeZ0 <= 0 ) pZ++; // 4J - condition brought forward from 1.2.3 + if (llTransx0z || llTrans0yz) { + llxyz = tt->getShadeBrightness(level, pX - 1, pY - 1, pZ); + ccxyz = tt->getLightColor(level, pX - 1, pY - 1, pZ); + } else { + llxyz = llx0z; + ccxyz = ccx0z; + } + if (llTransx0z || llTrans0Yz) { + llxYz = tt->getShadeBrightness(level, pX - 1, pY + 1, pZ); + ccxYz = tt->getLightColor(level, pX - 1, pY + 1, pZ); + } else { + llxYz = llx0z; + ccxYz = ccx0z; + } + if (llTransX0z || llTrans0yz) { + llXyz = tt->getShadeBrightness(level, pX + 1, pY - 1, pZ); + ccXyz = tt->getLightColor(level, pX + 1, pY - 1, pZ); + } else { + llXyz = llX0z; + ccXyz = ccX0z; + } + if (llTransX0z || llTrans0Yz) { + llXYz = tt->getShadeBrightness(level, pX + 1, pY + 1, pZ); + ccXYz = tt->getLightColor(level, pX + 1, pY + 1, pZ); + } else { + llXYz = llX0z; + ccXYz = ccX0z; + } + if (tileShapeZ0 <= 0) + pZ++; // 4J - condition brought forward from 1.2.3 #ifdef _XBOX - #pragma message(__LOC__"ambientOcclusion NEEDS CHANGED FROM A BOOL ") +#pragma message(__LOC__ "ambientOcclusion NEEDS CHANGED FROM A BOOL ") #endif - if (smoothShapeLighting && g_ambientOcclusionMax)//minecraft->options->ambientOcclusion >= Options::AO_MAX) - { - float _ll1 = (llx0z + llxYz + ll00z + ll0Yz) / 4.0f; - float _ll2 = (ll00z + ll0Yz + llX0z + llXYz) / 4.0f; - float _ll3 = (ll0yz + ll00z + llXyz + llX0z) / 4.0f; - float _ll4 = (llxyz + llx0z + ll0yz + ll00z) / 4.0f; - ll1 = (float) (_ll1 * tileShapeY1 * (1.0 - tileShapeX0) + _ll2 * tileShapeY0 * tileShapeX0 + _ll3 * (1.0 - tileShapeY1) * tileShapeX0 + _ll4 * (1.0 - tileShapeY1) - * (1.0 - tileShapeX0)); - ll2 = (float) (_ll1 * tileShapeY1 * (1.0 - tileShapeX1) + _ll2 * tileShapeY1 * tileShapeX1 + _ll3 * (1.0 - tileShapeY1) * tileShapeX1 + _ll4 * (1.0 - tileShapeY1) - * (1.0 - tileShapeX1)); - ll3 = (float) (_ll1 * tileShapeY0 * (1.0 - tileShapeX1) + _ll2 * tileShapeY0 * tileShapeX1 + _ll3 * (1.0 - tileShapeY0) * tileShapeX1 + _ll4 * (1.0 - tileShapeY0) - * (1.0 - tileShapeX1)); - ll4 = (float) (_ll1 * tileShapeY0 * (1.0 - tileShapeX0) + _ll2 * tileShapeY0 * tileShapeX0 + _ll3 * (1.0 - tileShapeY0) * tileShapeX0 + _ll4 * (1.0 - tileShapeY0) - * (1.0 - tileShapeX0)); + if (smoothShapeLighting && + g_ambientOcclusionMax) // minecraft->options->ambientOcclusion + // >= Options::AO_MAX) + { + float _ll1 = (llx0z + llxYz + ll00z + ll0Yz) / 4.0f; + float _ll2 = (ll00z + ll0Yz + llX0z + llXYz) / 4.0f; + float _ll3 = (ll0yz + ll00z + llXyz + llX0z) / 4.0f; + float _ll4 = (llxyz + llx0z + ll0yz + ll00z) / 4.0f; + ll1 = (float)(_ll1 * tileShapeY1 * (1.0 - tileShapeX0) + + _ll2 * tileShapeY0 * tileShapeX0 + + _ll3 * (1.0 - tileShapeY1) * tileShapeX0 + + _ll4 * (1.0 - tileShapeY1) * (1.0 - tileShapeX0)); + ll2 = (float)(_ll1 * tileShapeY1 * (1.0 - tileShapeX1) + + _ll2 * tileShapeY1 * tileShapeX1 + + _ll3 * (1.0 - tileShapeY1) * tileShapeX1 + + _ll4 * (1.0 - tileShapeY1) * (1.0 - tileShapeX1)); + ll3 = (float)(_ll1 * tileShapeY0 * (1.0 - tileShapeX1) + + _ll2 * tileShapeY0 * tileShapeX1 + + _ll3 * (1.0 - tileShapeY0) * tileShapeX1 + + _ll4 * (1.0 - tileShapeY0) * (1.0 - tileShapeX1)); + ll4 = (float)(_ll1 * tileShapeY0 * (1.0 - tileShapeX0) + + _ll2 * tileShapeY0 * tileShapeX0 + + _ll3 * (1.0 - tileShapeY0) * tileShapeX0 + + _ll4 * (1.0 - tileShapeY0) * (1.0 - tileShapeX0)); - int _tc1 = blend(ccx0z, ccxYz, cc0Yz, cc00z); - int _tc2 = blend(cc0Yz, ccX0z, ccXYz, cc00z); - int _tc3 = blend(cc0yz, ccXyz, ccX0z, cc00z); - int _tc4 = blend(ccxyz, ccx0z, cc0yz, cc00z); - tc1 = blend(_tc1, _tc2, _tc3, _tc4, tileShapeY1 * (1.0 - tileShapeX0), tileShapeY1 * tileShapeX0, (1.0 - tileShapeY1) * tileShapeX0, (1.0 - tileShapeY1) * (1.0 - tileShapeX0)); - tc2 = blend(_tc1, _tc2, _tc3, _tc4, tileShapeY1 * (1.0 - tileShapeX1), tileShapeY1 * tileShapeX1, (1.0 - tileShapeY1) * tileShapeX1, (1.0 - tileShapeY1) * (1.0 - tileShapeX1)); - tc3 = blend(_tc1, _tc2, _tc3, _tc4, tileShapeY0 * (1.0 - tileShapeX1), tileShapeY0 * tileShapeX1, (1.0 - tileShapeY0) * tileShapeX1, (1.0 - tileShapeY0) * (1.0 - tileShapeX1)); - tc4 = blend(_tc1, _tc2, _tc3, _tc4, tileShapeY0 * (1.0 - tileShapeX0), tileShapeY0 * tileShapeX0, (1.0 - tileShapeY0) * tileShapeX0, (1.0 - tileShapeY0) * (1.0 - tileShapeX0)); - } else { - ll1 = ( llx0z + llxYz + ll00z + ll0Yz ) / 4.0f; - ll2 = ( ll00z + ll0Yz + llX0z + llXYz ) / 4.0f; - ll3 = ( ll0yz + ll00z + llXyz + llX0z ) / 4.0f; - ll4 = ( llxyz + llx0z + ll0yz + ll00z ) / 4.0f; + int _tc1 = blend(ccx0z, ccxYz, cc0Yz, cc00z); + int _tc2 = blend(cc0Yz, ccX0z, ccXYz, cc00z); + int _tc3 = blend(cc0yz, ccXyz, ccX0z, cc00z); + int _tc4 = blend(ccxyz, ccx0z, cc0yz, cc00z); + tc1 = blend(_tc1, _tc2, _tc3, _tc4, + tileShapeY1 * (1.0 - tileShapeX0), + tileShapeY1 * tileShapeX0, + (1.0 - tileShapeY1) * tileShapeX0, + (1.0 - tileShapeY1) * (1.0 - tileShapeX0)); + tc2 = blend(_tc1, _tc2, _tc3, _tc4, + tileShapeY1 * (1.0 - tileShapeX1), + tileShapeY1 * tileShapeX1, + (1.0 - tileShapeY1) * tileShapeX1, + (1.0 - tileShapeY1) * (1.0 - tileShapeX1)); + tc3 = blend(_tc1, _tc2, _tc3, _tc4, + tileShapeY0 * (1.0 - tileShapeX1), + tileShapeY0 * tileShapeX1, + (1.0 - tileShapeY0) * tileShapeX1, + (1.0 - tileShapeY0) * (1.0 - tileShapeX1)); + tc4 = blend(_tc1, _tc2, _tc3, _tc4, + tileShapeY0 * (1.0 - tileShapeX0), + tileShapeY0 * tileShapeX0, + (1.0 - tileShapeY0) * tileShapeX0, + (1.0 - tileShapeY0) * (1.0 - tileShapeX0)); + } else { + ll1 = (llx0z + llxYz + ll00z + ll0Yz) / 4.0f; + ll2 = (ll00z + ll0Yz + llX0z + llXYz) / 4.0f; + ll3 = (ll0yz + ll00z + llXyz + llX0z) / 4.0f; + ll4 = (llxyz + llx0z + ll0yz + ll00z) / 4.0f; - tc1 = blend( ccx0z, ccxYz, cc0Yz, cc00z ); - tc2 = blend( cc0Yz, ccX0z, ccXYz, cc00z ); - tc3 = blend( cc0yz, ccXyz, ccX0z, cc00z ); - tc4 = blend( ccxyz, ccx0z, cc0yz, cc00z ); - } - } - else - { - ll1 = ll2 = ll3 = ll4 = ll00z; - tc1 = tc2 = tc3 = tc4 = cc00z; - } - c1r = c2r = c3r = c4r = ( tint2 ? pBaseRed : 1.0f ) * 0.8f; - c1g = c2g = c3g = c4g = ( tint2 ? pBaseGreen : 1.0f ) * 0.8f; - c1b = c2b = c3b = c4b = ( tint2 ? pBaseBlue : 1.0f ) * 0.8f; - c1r *= ll1; - c1g *= ll1; - c1b *= ll1; - c2r *= ll2; - c2g *= ll2; - c2b *= ll2; - c3r *= ll3; - c3g *= ll3; - c3b *= ll3; - c4r *= ll4; - c4g *= ll4; - c4b *= ll4; + tc1 = blend(ccx0z, ccxYz, cc0Yz, cc00z); + tc2 = blend(cc0Yz, ccX0z, ccXYz, cc00z); + tc3 = blend(cc0yz, ccXyz, ccX0z, cc00z); + tc4 = blend(ccxyz, ccx0z, cc0yz, cc00z); + } + } else { + ll1 = ll2 = ll3 = ll4 = ll00z; + tc1 = tc2 = tc3 = tc4 = cc00z; + } + c1r = c2r = c3r = c4r = (tint2 ? pBaseRed : 1.0f) * 0.8f; + c1g = c2g = c3g = c4g = (tint2 ? pBaseGreen : 1.0f) * 0.8f; + c1b = c2b = c3b = c4b = (tint2 ? pBaseBlue : 1.0f) * 0.8f; + c1r *= ll1; + c1g *= ll1; + c1b *= ll1; + c2r *= ll2; + c2g *= ll2; + c2b *= ll2; + c3r *= ll3; + c3g *= ll3; + c3b *= ll3; + c4r *= ll4; + c4g *= ll4; + c4b *= ll4; + Icon_SPU* tex = getTexture(tt, level, pX, pY, pZ, 2); + renderNorth(tt, (float)pX, (float)pY, (float)pZ, tex); - Icon_SPU *tex = getTexture(tt, level, pX, pY, pZ, 2); - renderNorth( tt, ( float )pX, ( float )pY, ( float )pZ, tex ); + if (fancy && + (tex == &Tile_SPU::ms_pTileData->iconData[Tile_SPU::grass_Id] && + !hasFixedTexture())) { + c1r *= pBaseRed; + c2r *= pBaseRed; + c3r *= pBaseRed; + c4r *= pBaseRed; + c1g *= pBaseGreen; + c2g *= pBaseGreen; + c3g *= pBaseGreen; + c4g *= pBaseGreen; + c1b *= pBaseBlue; + c2b *= pBaseBlue; + c3b *= pBaseBlue; + c4b *= pBaseBlue; + bool prev = t->setMipmapEnable( + false); // 4J added - this is rendering the little bit of grass + // at the top of the side of dirt, don't mipmap it + renderNorth(tt, (float)pX, (float)pY, (float)pZ, + GrassTile_SPU::getSideTextureOverlay()); + t->setMipmapEnable(prev); + } + } + if (faceFlags & 0x08) { + if (blsmooth > 0) { + if (tileShapeZ1 >= 1) + pZ++; // 4J - condition brought forward from 1.2.3 - if ( fancy && (tex == &Tile_SPU::ms_pTileData->iconData[Tile_SPU::grass_Id] && !hasFixedTexture() )) - { - c1r *= pBaseRed; - c2r *= pBaseRed; - c3r *= pBaseRed; - c4r *= pBaseRed; - c1g *= pBaseGreen; - c2g *= pBaseGreen; - c3g *= pBaseGreen; - c4g *= pBaseGreen; - c1b *= pBaseBlue; - c2b *= pBaseBlue; - c3b *= pBaseBlue; - c4b *= pBaseBlue; - bool prev = t->setMipmapEnable( false ); // 4J added - this is rendering the little bit of grass at the top of the side of dirt, don't mipmap it - renderNorth( tt, ( float )pX, ( float )pY, ( float )pZ, GrassTile_SPU::getSideTextureOverlay() ); - t->setMipmapEnable( prev ); - } - } - if ( faceFlags & 0x08 ) - { - if ( blsmooth > 0 ) - { - if ( tileShapeZ1 >= 1 ) pZ++; // 4J - condition brought forward from 1.2.3 + llx0Z = tt->getShadeBrightness(level, pX - 1, pY, pZ); + llX0Z = tt->getShadeBrightness(level, pX + 1, pY, pZ); + ll0yZ = tt->getShadeBrightness(level, pX, pY - 1, pZ); + ll0YZ = tt->getShadeBrightness(level, pX, pY + 1, pZ); - llx0Z = tt->getShadeBrightness( level, pX - 1, pY, pZ ); - llX0Z = tt->getShadeBrightness( level, pX + 1, pY, pZ ); - ll0yZ = tt->getShadeBrightness( level, pX, pY - 1, pZ ); - ll0YZ = tt->getShadeBrightness( level, pX, pY + 1, pZ ); + ccx0Z = tt->getLightColor(level, pX - 1, pY, pZ); + ccX0Z = tt->getLightColor(level, pX + 1, pY, pZ); + cc0yZ = tt->getLightColor(level, pX, pY - 1, pZ); + cc0YZ = tt->getLightColor(level, pX, pY + 1, pZ); - ccx0Z = tt->getLightColor( level, pX - 1, pY, pZ ); - ccX0Z = tt->getLightColor( level, pX + 1, pY, pZ ); - cc0yZ = tt->getLightColor( level, pX, pY - 1, pZ ); - cc0YZ = tt->getLightColor( level, pX, pY + 1, pZ ); + if (llTransx0Z || llTrans0yZ) { + llxyZ = tt->getShadeBrightness(level, pX - 1, pY - 1, pZ); + ccxyZ = tt->getLightColor(level, pX - 1, pY - 1, pZ); + } else { + llxyZ = llx0Z; + ccxyZ = ccx0Z; + } + if (llTransx0Z || llTrans0YZ) { + llxYZ = tt->getShadeBrightness(level, pX - 1, pY + 1, pZ); + ccxYZ = tt->getLightColor(level, pX - 1, pY + 1, pZ); + } else { + llxYZ = llx0Z; + ccxYZ = ccx0Z; + } + if (llTransX0Z || llTrans0yZ) { + llXyZ = tt->getShadeBrightness(level, pX + 1, pY - 1, pZ); + ccXyZ = tt->getLightColor(level, pX + 1, pY - 1, pZ); + } else { + llXyZ = llX0Z; + ccXyZ = ccX0Z; + } + if (llTransX0Z || llTrans0YZ) { + llXYZ = tt->getShadeBrightness(level, pX + 1, pY + 1, pZ); + ccXYZ = tt->getLightColor(level, pX + 1, pY + 1, pZ); + } else { + llXYZ = llX0Z; + ccXYZ = ccX0Z; + } + if (tileShapeZ1 >= 1) + pZ--; // 4J - condition brought forward from 1.2.3 + if (smoothShapeLighting && + g_ambientOcclusionMax) // minecraft->options->ambientOcclusion + // >= Options::AO_MAX) + { + float _ll1 = (llx0Z + llxYZ + ll00Z + ll0YZ) / 4.0f; + float _ll4 = (ll00Z + ll0YZ + llX0Z + llXYZ) / 4.0f; + float _ll3 = (ll0yZ + ll00Z + llXyZ + llX0Z) / 4.0f; + float _ll2 = (llxyZ + llx0Z + ll0yZ + ll00Z) / 4.0f; + ll1 = (float)(_ll1 * tileShapeY1 * (1.0 - tileShapeX0) + + _ll4 * tileShapeY1 * tileShapeX0 + + _ll3 * (1.0 - tileShapeY1) * tileShapeX0 + + _ll2 * (1.0 - tileShapeY1) * (1.0 - tileShapeX0)); + ll2 = (float)(_ll1 * tileShapeY0 * (1.0 - tileShapeX0) + + _ll4 * tileShapeY0 * tileShapeX0 + + _ll3 * (1.0 - tileShapeY0) * tileShapeX0 + + _ll2 * (1.0 - tileShapeY0) * (1.0 - tileShapeX0)); + ll3 = (float)(_ll1 * tileShapeY0 * (1.0 - tileShapeX1) + + _ll4 * tileShapeY0 * tileShapeX1 + + _ll3 * (1.0 - tileShapeY0) * tileShapeX1 + + _ll2 * (1.0 - tileShapeY0) * (1.0 - tileShapeX1)); + ll4 = (float)(_ll1 * tileShapeY1 * (1.0 - tileShapeX1) + + _ll4 * tileShapeY1 * tileShapeX1 + + _ll3 * (1.0 - tileShapeY1) * tileShapeX1 + + _ll2 * (1.0 - tileShapeY1) * (1.0 - tileShapeX1)); - if ( llTransx0Z || llTrans0yZ ) - { - llxyZ = tt->getShadeBrightness( level, pX - 1, pY - 1, pZ ); - ccxyZ = tt->getLightColor( level, pX - 1, pY - 1, pZ ); - } - else - { - llxyZ = llx0Z; - ccxyZ = ccx0Z; - } - if ( llTransx0Z || llTrans0YZ ) - { - llxYZ = tt->getShadeBrightness( level, pX - 1, pY + 1, pZ ); - ccxYZ = tt->getLightColor( level, pX - 1, pY + 1, pZ ); - } - else - { - llxYZ = llx0Z; - ccxYZ = ccx0Z; - } - if ( llTransX0Z || llTrans0yZ ) - { - llXyZ = tt->getShadeBrightness( level, pX + 1, pY - 1, pZ ); - ccXyZ = tt->getLightColor( level, pX + 1, pY - 1, pZ ); - } - else - { - llXyZ = llX0Z; - ccXyZ = ccX0Z; - } - if ( llTransX0Z || llTrans0YZ ) - { - llXYZ = tt->getShadeBrightness( level, pX + 1, pY + 1, pZ ); - ccXYZ = tt->getLightColor( level, pX + 1, pY + 1, pZ ); - } - else - { - llXYZ = llX0Z; - ccXYZ = ccX0Z; - } - if ( tileShapeZ1 >= 1 ) pZ--; // 4J - condition brought forward from 1.2.3 - if (smoothShapeLighting && g_ambientOcclusionMax)//minecraft->options->ambientOcclusion >= Options::AO_MAX) - { - float _ll1 = (llx0Z + llxYZ + ll00Z + ll0YZ) / 4.0f; - float _ll4 = (ll00Z + ll0YZ + llX0Z + llXYZ) / 4.0f; - float _ll3 = (ll0yZ + ll00Z + llXyZ + llX0Z) / 4.0f; - float _ll2 = (llxyZ + llx0Z + ll0yZ + ll00Z) / 4.0f; - ll1 = (float) (_ll1 * tileShapeY1 * (1.0 - tileShapeX0) + _ll4 * tileShapeY1 * tileShapeX0 + _ll3 * (1.0 - tileShapeY1) * tileShapeX0 + _ll2 * (1.0 - tileShapeY1) - * (1.0 - tileShapeX0)); - ll2 = (float) (_ll1 * tileShapeY0 * (1.0 - tileShapeX0) + _ll4 * tileShapeY0 * tileShapeX0 + _ll3 * (1.0 - tileShapeY0) * tileShapeX0 + _ll2 * (1.0 - tileShapeY0) - * (1.0 - tileShapeX0)); - ll3 = (float) (_ll1 * tileShapeY0 * (1.0 - tileShapeX1) + _ll4 * tileShapeY0 * tileShapeX1 + _ll3 * (1.0 - tileShapeY0) * tileShapeX1 + _ll2 * (1.0 - tileShapeY0) - * (1.0 - tileShapeX1)); - ll4 = (float) (_ll1 * tileShapeY1 * (1.0 - tileShapeX1) + _ll4 * tileShapeY1 * tileShapeX1 + _ll3 * (1.0 - tileShapeY1) * tileShapeX1 + _ll2 * (1.0 - tileShapeY1) - * (1.0 - tileShapeX1)); + int _tc1 = blend(ccx0Z, ccxYZ, cc0YZ, cc00Z); + int _tc4 = blend(cc0YZ, ccX0Z, ccXYZ, cc00Z); + int _tc3 = blend(cc0yZ, ccXyZ, ccX0Z, cc00Z); + int _tc2 = blend(ccxyZ, ccx0Z, cc0yZ, cc00Z); + tc1 = blend(_tc1, _tc2, _tc3, _tc4, + tileShapeY1 * (1.0 - tileShapeX0), + (1.0 - tileShapeY1) * (1.0 - tileShapeX0), + (1.0 - tileShapeY1) * tileShapeX0, + tileShapeY1 * tileShapeX0); + tc2 = blend(_tc1, _tc2, _tc3, _tc4, + tileShapeY0 * (1.0 - tileShapeX0), + (1.0 - tileShapeY0) * (1.0 - tileShapeX0), + (1.0 - tileShapeY0) * tileShapeX0, + tileShapeY0 * tileShapeX0); + tc3 = blend(_tc1, _tc2, _tc3, _tc4, + tileShapeY0 * (1.0 - tileShapeX1), + (1.0 - tileShapeY0) * (1.0 - tileShapeX1), + (1.0 - tileShapeY0) * tileShapeX1, + tileShapeY0 * tileShapeX1); + tc4 = blend(_tc1, _tc2, _tc3, _tc4, + tileShapeY1 * (1.0 - tileShapeX1), + (1.0 - tileShapeY1) * (1.0 - tileShapeX1), + (1.0 - tileShapeY1) * tileShapeX1, + tileShapeY1 * tileShapeX1); + } else { + ll1 = (llx0Z + llxYZ + ll00Z + ll0YZ) / 4.0f; + ll4 = (ll00Z + ll0YZ + llX0Z + llXYZ) / 4.0f; + ll3 = (ll0yZ + ll00Z + llXyZ + llX0Z) / 4.0f; + ll2 = (llxyZ + llx0Z + ll0yZ + ll00Z) / 4.0f; - int _tc1 = blend(ccx0Z, ccxYZ, cc0YZ, cc00Z); - int _tc4 = blend(cc0YZ, ccX0Z, ccXYZ, cc00Z); - int _tc3 = blend(cc0yZ, ccXyZ, ccX0Z, cc00Z); - int _tc2 = blend(ccxyZ, ccx0Z, cc0yZ, cc00Z); - tc1 = blend(_tc1, _tc2, _tc3, _tc4, tileShapeY1 * (1.0 - tileShapeX0), (1.0 - tileShapeY1) * (1.0 - tileShapeX0), (1.0 - tileShapeY1) * tileShapeX0, tileShapeY1 * tileShapeX0); - tc2 = blend(_tc1, _tc2, _tc3, _tc4, tileShapeY0 * (1.0 - tileShapeX0), (1.0 - tileShapeY0) * (1.0 - tileShapeX0), (1.0 - tileShapeY0) * tileShapeX0, tileShapeY0 * tileShapeX0); - tc3 = blend(_tc1, _tc2, _tc3, _tc4, tileShapeY0 * (1.0 - tileShapeX1), (1.0 - tileShapeY0) * (1.0 - tileShapeX1), (1.0 - tileShapeY0) * tileShapeX1, tileShapeY0 * tileShapeX1); - tc4 = blend(_tc1, _tc2, _tc3, _tc4, tileShapeY1 * (1.0 - tileShapeX1), (1.0 - tileShapeY1) * (1.0 - tileShapeX1), (1.0 - tileShapeY1) * tileShapeX1, tileShapeY1 * tileShapeX1); - } - else - { - ll1 = ( llx0Z + llxYZ + ll00Z + ll0YZ ) / 4.0f; - ll4 = ( ll00Z + ll0YZ + llX0Z + llXYZ ) / 4.0f; - ll3 = ( ll0yZ + ll00Z + llXyZ + llX0Z ) / 4.0f; - ll2 = ( llxyZ + llx0Z + ll0yZ + ll00Z ) / 4.0f; + tc1 = blend(ccx0Z, ccxYZ, cc0YZ, cc00Z); + tc4 = blend(cc0YZ, ccX0Z, ccXYZ, cc00Z); + tc3 = blend(cc0yZ, ccXyZ, ccX0Z, cc00Z); + tc2 = blend(ccxyZ, ccx0Z, cc0yZ, cc00Z); + } + } else { + ll1 = ll2 = ll3 = ll4 = ll00Z; + tc1 = tc2 = tc3 = tc4 = cc00Z; + } + c1r = c2r = c3r = c4r = (tint3 ? pBaseRed : 1.0f) * 0.8f; + c1g = c2g = c3g = c4g = (tint3 ? pBaseGreen : 1.0f) * 0.8f; + c1b = c2b = c3b = c4b = (tint3 ? pBaseBlue : 1.0f) * 0.8f; + c1r *= ll1; + c1g *= ll1; + c1b *= ll1; + c2r *= ll2; + c2g *= ll2; + c2b *= ll2; + c3r *= ll3; + c3g *= ll3; + c3b *= ll3; + c4r *= ll4; + c4g *= ll4; + c4b *= ll4; + Icon_SPU* tex = getTexture(tt, level, pX, pY, pZ, 3); + renderSouth(tt, (float)pX, (float)pY, (float)pZ, + getTexture(tt, level, pX, pY, pZ, 3)); - tc1 = blend( ccx0Z, ccxYZ, cc0YZ, cc00Z ); - tc4 = blend( cc0YZ, ccX0Z, ccXYZ, cc00Z ); - tc3 = blend( cc0yZ, ccXyZ, ccX0Z, cc00Z ); - tc2 = blend( ccxyZ, ccx0Z, cc0yZ, cc00Z ); - } - } - else - { - ll1 = ll2 = ll3 = ll4 = ll00Z; - tc1 = tc2 = tc3 = tc4 = cc00Z; - } - c1r = c2r = c3r = c4r = ( tint3 ? pBaseRed : 1.0f ) * 0.8f; - c1g = c2g = c3g = c4g = ( tint3 ? pBaseGreen : 1.0f ) * 0.8f; - c1b = c2b = c3b = c4b = ( tint3 ? pBaseBlue : 1.0f ) * 0.8f; - c1r *= ll1; - c1g *= ll1; - c1b *= ll1; - c2r *= ll2; - c2g *= ll2; - c2b *= ll2; - c3r *= ll3; - c3g *= ll3; - c3b *= ll3; - c4r *= ll4; - c4g *= ll4; - c4b *= ll4; - Icon_SPU *tex = getTexture(tt, level, pX, pY, pZ, 3); - renderSouth( tt, ( float )pX, ( float )pY, ( float )pZ, getTexture(tt, level, pX, pY, pZ, 3 ) ); + if (fancy && + (tex == &Tile_SPU::ms_pTileData->iconData[Tile_SPU::grass_Id] && + !hasFixedTexture())) { + c1r *= pBaseRed; + c2r *= pBaseRed; + c3r *= pBaseRed; + c4r *= pBaseRed; + c1g *= pBaseGreen; + c2g *= pBaseGreen; + c3g *= pBaseGreen; + c4g *= pBaseGreen; + c1b *= pBaseBlue; + c2b *= pBaseBlue; + c3b *= pBaseBlue; + c4b *= pBaseBlue; + bool prev = t->setMipmapEnable( + false); // 4J added - this is rendering the little bit of grass + // at the top of the side of dirt, don't mipmap it + renderSouth(tt, (float)pX, (float)pY, (float)pZ, + GrassTile_SPU::getSideTextureOverlay()); + t->setMipmapEnable(prev); + } + } + if (faceFlags & 0x10) { + if (blsmooth > 0) { + if (tileShapeX0 <= 0) + pX--; // 4J - condition brought forward from 1.2.3 + llxy0 = tt->getShadeBrightness(level, pX, pY - 1, pZ); + llx0z = tt->getShadeBrightness(level, pX, pY, pZ - 1); + llx0Z = tt->getShadeBrightness(level, pX, pY, pZ + 1); + llxY0 = tt->getShadeBrightness(level, pX, pY + 1, pZ); - if ( fancy && (tex == &Tile_SPU::ms_pTileData->iconData[Tile_SPU::grass_Id] && !hasFixedTexture() )) - { - c1r *= pBaseRed; - c2r *= pBaseRed; - c3r *= pBaseRed; - c4r *= pBaseRed; - c1g *= pBaseGreen; - c2g *= pBaseGreen; - c3g *= pBaseGreen; - c4g *= pBaseGreen; - c1b *= pBaseBlue; - c2b *= pBaseBlue; - c3b *= pBaseBlue; - c4b *= pBaseBlue; - bool prev = t->setMipmapEnable( false ); // 4J added - this is rendering the little bit of grass at the top of the side of dirt, don't mipmap it - renderSouth( tt, ( float )pX, ( float )pY, ( float )pZ, GrassTile_SPU::getSideTextureOverlay() ); - t->setMipmapEnable( prev ); - } - } - if ( faceFlags & 0x10 ) - { - if ( blsmooth > 0 ) - { - if ( tileShapeX0 <= 0 ) pX--; // 4J - condition brought forward from 1.2.3 - llxy0 = tt->getShadeBrightness( level, pX, pY - 1, pZ ); - llx0z = tt->getShadeBrightness( level, pX, pY, pZ - 1 ); - llx0Z = tt->getShadeBrightness( level, pX, pY, pZ + 1 ); - llxY0 = tt->getShadeBrightness( level, pX, pY + 1, pZ ); + ccxy0 = tt->getLightColor(level, pX, pY - 1, pZ); + ccx0z = tt->getLightColor(level, pX, pY, pZ - 1); + ccx0Z = tt->getLightColor(level, pX, pY, pZ + 1); + ccxY0 = tt->getLightColor(level, pX, pY + 1, pZ); - ccxy0 = tt->getLightColor( level, pX, pY - 1, pZ ); - ccx0z = tt->getLightColor( level, pX, pY, pZ - 1 ); - ccx0Z = tt->getLightColor( level, pX, pY, pZ + 1 ); - ccxY0 = tt->getLightColor( level, pX, pY + 1, pZ ); + if (llTransx0z || llTransxy0) { + llxyz = tt->getShadeBrightness(level, pX, pY - 1, pZ - 1); + ccxyz = tt->getLightColor(level, pX, pY - 1, pZ - 1); + } else { + llxyz = llx0z; + ccxyz = ccx0z; + } + if (llTransx0Z || llTransxy0) { + llxyZ = tt->getShadeBrightness(level, pX, pY - 1, pZ + 1); + ccxyZ = tt->getLightColor(level, pX, pY - 1, pZ + 1); + } else { + llxyZ = llx0Z; + ccxyZ = ccx0Z; + } + if (llTransx0z || llTransxY0) { + llxYz = tt->getShadeBrightness(level, pX, pY + 1, pZ - 1); + ccxYz = tt->getLightColor(level, pX, pY + 1, pZ - 1); + } else { + llxYz = llx0z; + ccxYz = ccx0z; + } + if (llTransx0Z || llTransxY0) { + llxYZ = tt->getShadeBrightness(level, pX, pY + 1, pZ + 1); + ccxYZ = tt->getLightColor(level, pX, pY + 1, pZ + 1); + } else { + llxYZ = llx0Z; + ccxYZ = ccx0Z; + } + if (tileShapeX0 <= 0) + pX++; // 4J - condition brought forward from 1.2.3 + if (smoothShapeLighting && + g_ambientOcclusionMax) // minecraft->options->ambientOcclusion + // >= Options::AO_MAX) + { + float _ll4 = (llxy0 + llxyZ + llx00 + llx0Z) / 4.0f; + float _ll1 = (llx00 + llx0Z + llxY0 + llxYZ) / 4.0f; + float _ll2 = (llx0z + llx00 + llxYz + llxY0) / 4.0f; + float _ll3 = (llxyz + llxy0 + llx0z + llx00) / 4.0f; + ll1 = (float)(_ll1 * tileShapeY1 * tileShapeZ1 + + _ll2 * tileShapeY1 * (1.0 - tileShapeZ1) + + _ll3 * (1.0 - tileShapeY1) * (1.0 - tileShapeZ1) + + _ll4 * (1.0 - tileShapeY1) * tileShapeZ1); + ll2 = (float)(_ll1 * tileShapeY1 * tileShapeZ0 + + _ll2 * tileShapeY1 * (1.0 - tileShapeZ0) + + _ll3 * (1.0 - tileShapeY1) * (1.0 - tileShapeZ0) + + _ll4 * (1.0 - tileShapeY1) * tileShapeZ0); + ll3 = (float)(_ll1 * tileShapeY0 * tileShapeZ0 + + _ll2 * tileShapeY0 * (1.0 - tileShapeZ0) + + _ll3 * (1.0 - tileShapeY0) * (1.0 - tileShapeZ0) + + _ll4 * (1.0 - tileShapeY0) * tileShapeZ0); + ll4 = (float)(_ll1 * tileShapeY0 * tileShapeZ1 + + _ll2 * tileShapeY0 * (1.0 - tileShapeZ1) + + _ll3 * (1.0 - tileShapeY0) * (1.0 - tileShapeZ1) + + _ll4 * (1.0 - tileShapeY0) * tileShapeZ1); - if ( llTransx0z || llTransxy0 ) - { - llxyz = tt->getShadeBrightness( level, pX, pY - 1, pZ - 1 ); - ccxyz = tt->getLightColor( level, pX, pY - 1, pZ - 1 ); - } - else - { - llxyz = llx0z; - ccxyz = ccx0z; - } - if ( llTransx0Z || llTransxy0 ) - { - llxyZ = tt->getShadeBrightness( level, pX, pY - 1, pZ + 1 ); - ccxyZ = tt->getLightColor( level, pX, pY - 1, pZ + 1 ); - } - else - { - llxyZ = llx0Z; - ccxyZ = ccx0Z; - } - if ( llTransx0z || llTransxY0 ) - { - llxYz = tt->getShadeBrightness( level, pX, pY + 1, pZ - 1 ); - ccxYz = tt->getLightColor( level, pX, pY + 1, pZ - 1 ); - } - else - { - llxYz = llx0z; - ccxYz = ccx0z; - } - if ( llTransx0Z || llTransxY0 ) - { - llxYZ = tt->getShadeBrightness( level, pX, pY + 1, pZ + 1 ); - ccxYZ = tt->getLightColor( level, pX, pY + 1, pZ + 1 ); - } - else - { - llxYZ = llx0Z; - ccxYZ = ccx0Z; - } - if ( tileShapeX0 <= 0 ) pX++; // 4J - condition brought forward from 1.2.3 - if (smoothShapeLighting && g_ambientOcclusionMax)//minecraft->options->ambientOcclusion >= Options::AO_MAX) - { - float _ll4 = (llxy0 + llxyZ + llx00 + llx0Z) / 4.0f; - float _ll1 = (llx00 + llx0Z + llxY0 + llxYZ) / 4.0f; - float _ll2 = (llx0z + llx00 + llxYz + llxY0) / 4.0f; - float _ll3 = (llxyz + llxy0 + llx0z + llx00) / 4.0f; - ll1 = (float) (_ll1 * tileShapeY1 * tileShapeZ1 + _ll2 * tileShapeY1 * (1.0 - tileShapeZ1) + _ll3 * (1.0 - tileShapeY1) * (1.0 - tileShapeZ1) + _ll4 * (1.0 - tileShapeY1) - * tileShapeZ1); - ll2 = (float) (_ll1 * tileShapeY1 * tileShapeZ0 + _ll2 * tileShapeY1 * (1.0 - tileShapeZ0) + _ll3 * (1.0 - tileShapeY1) * (1.0 - tileShapeZ0) + _ll4 * (1.0 - tileShapeY1) - * tileShapeZ0); - ll3 = (float) (_ll1 * tileShapeY0 * tileShapeZ0 + _ll2 * tileShapeY0 * (1.0 - tileShapeZ0) + _ll3 * (1.0 - tileShapeY0) * (1.0 - tileShapeZ0) + _ll4 * (1.0 - tileShapeY0) - * tileShapeZ0); - ll4 = (float) (_ll1 * tileShapeY0 * tileShapeZ1 + _ll2 * tileShapeY0 * (1.0 - tileShapeZ1) + _ll3 * (1.0 - tileShapeY0) * (1.0 - tileShapeZ1) + _ll4 * (1.0 - tileShapeY0) - * tileShapeZ1); + int _tc4 = blend(ccxy0, ccxyZ, ccx0Z, ccx00); + int _tc1 = blend(ccx0Z, ccxY0, ccxYZ, ccx00); + int _tc2 = blend(ccx0z, ccxYz, ccxY0, ccx00); + int _tc3 = blend(ccxyz, ccxy0, ccx0z, ccx00); + tc1 = blend(_tc1, _tc2, _tc3, _tc4, tileShapeY1 * tileShapeZ1, + tileShapeY1 * (1.0 - tileShapeZ1), + (1.0 - tileShapeY1) * (1.0 - tileShapeZ1), + (1.0 - tileShapeY1) * tileShapeZ1); + tc2 = blend(_tc1, _tc2, _tc3, _tc4, tileShapeY1 * tileShapeZ0, + tileShapeY1 * (1.0 - tileShapeZ0), + (1.0 - tileShapeY1) * (1.0 - tileShapeZ0), + (1.0 - tileShapeY1) * tileShapeZ0); + tc3 = blend(_tc1, _tc2, _tc3, _tc4, tileShapeY0 * tileShapeZ0, + tileShapeY0 * (1.0 - tileShapeZ0), + (1.0 - tileShapeY0) * (1.0 - tileShapeZ0), + (1.0 - tileShapeY0) * tileShapeZ0); + tc4 = blend(_tc1, _tc2, _tc3, _tc4, tileShapeY0 * tileShapeZ1, + tileShapeY0 * (1.0 - tileShapeZ1), + (1.0 - tileShapeY0) * (1.0 - tileShapeZ1), + (1.0 - tileShapeY0) * tileShapeZ1); + } else { + ll4 = (llxy0 + llxyZ + llx00 + llx0Z) / 4.0f; + ll1 = (llx00 + llx0Z + llxY0 + llxYZ) / 4.0f; + ll2 = (llx0z + llx00 + llxYz + llxY0) / 4.0f; + ll3 = (llxyz + llxy0 + llx0z + llx00) / 4.0f; - int _tc4 = blend(ccxy0, ccxyZ, ccx0Z, ccx00); - int _tc1 = blend(ccx0Z, ccxY0, ccxYZ, ccx00); - int _tc2 = blend(ccx0z, ccxYz, ccxY0, ccx00); - int _tc3 = blend(ccxyz, ccxy0, ccx0z, ccx00); - tc1 = blend(_tc1, _tc2, _tc3, _tc4, tileShapeY1 * tileShapeZ1, tileShapeY1 * (1.0 - tileShapeZ1), (1.0 - tileShapeY1) * (1.0 - tileShapeZ1), (1.0 - tileShapeY1) * tileShapeZ1); - tc2 = blend(_tc1, _tc2, _tc3, _tc4, tileShapeY1 * tileShapeZ0, tileShapeY1 * (1.0 - tileShapeZ0), (1.0 - tileShapeY1) * (1.0 - tileShapeZ0), (1.0 - tileShapeY1) * tileShapeZ0); - tc3 = blend(_tc1, _tc2, _tc3, _tc4, tileShapeY0 * tileShapeZ0, tileShapeY0 * (1.0 - tileShapeZ0), (1.0 - tileShapeY0) * (1.0 - tileShapeZ0), (1.0 - tileShapeY0) * tileShapeZ0); - tc4 = blend(_tc1, _tc2, _tc3, _tc4, tileShapeY0 * tileShapeZ1, tileShapeY0 * (1.0 - tileShapeZ1), (1.0 - tileShapeY0) * (1.0 - tileShapeZ1), (1.0 - tileShapeY0) * tileShapeZ1); - } - else - { - ll4 = ( llxy0 + llxyZ + llx00 + llx0Z ) / 4.0f; - ll1 = ( llx00 + llx0Z + llxY0 + llxYZ ) / 4.0f; - ll2 = ( llx0z + llx00 + llxYz + llxY0 ) / 4.0f; - ll3 = ( llxyz + llxy0 + llx0z + llx00 ) / 4.0f; + tc4 = blend(ccxy0, ccxyZ, ccx0Z, ccx00); + tc1 = blend(ccx0Z, ccxY0, ccxYZ, ccx00); + tc2 = blend(ccx0z, ccxYz, ccxY0, ccx00); + tc3 = blend(ccxyz, ccxy0, ccx0z, ccx00); + } + } else { + ll1 = ll2 = ll3 = ll4 = llx00; + tc1 = tc2 = tc3 = tc4 = ccx00; + } + c1r = c2r = c3r = c4r = (tint4 ? pBaseRed : 1.0f) * 0.6f; + c1g = c2g = c3g = c4g = (tint4 ? pBaseGreen : 1.0f) * 0.6f; + c1b = c2b = c3b = c4b = (tint4 ? pBaseBlue : 1.0f) * 0.6f; + c1r *= ll1; + c1g *= ll1; + c1b *= ll1; + c2r *= ll2; + c2g *= ll2; + c2b *= ll2; + c3r *= ll3; + c3g *= ll3; + c3b *= ll3; + c4r *= ll4; + c4g *= ll4; + c4b *= ll4; + Icon_SPU* tex = getTexture(tt, level, pX, pY, pZ, 4); + renderWest(tt, (float)pX, (float)pY, (float)pZ, tex); - tc4 = blend( ccxy0, ccxyZ, ccx0Z, ccx00 ); - tc1 = blend( ccx0Z, ccxY0, ccxYZ, ccx00 ); - tc2 = blend( ccx0z, ccxYz, ccxY0, ccx00 ); - tc3 = blend( ccxyz, ccxy0, ccx0z, ccx00 ); - } - } - else - { - ll1 = ll2 = ll3 = ll4 = llx00; - tc1 = tc2 = tc3 = tc4 = ccx00; - } - c1r = c2r = c3r = c4r = ( tint4 ? pBaseRed : 1.0f ) * 0.6f; - c1g = c2g = c3g = c4g = ( tint4 ? pBaseGreen : 1.0f ) * 0.6f; - c1b = c2b = c3b = c4b = ( tint4 ? pBaseBlue : 1.0f ) * 0.6f; - c1r *= ll1; - c1g *= ll1; - c1b *= ll1; - c2r *= ll2; - c2g *= ll2; - c2b *= ll2; - c3r *= ll3; - c3g *= ll3; - c3b *= ll3; - c4r *= ll4; - c4g *= ll4; - c4b *= ll4; - Icon_SPU *tex = getTexture(tt, level, pX, pY, pZ, 4); - renderWest( tt, ( float )pX, ( float )pY, ( float )pZ, tex ); + if (fancy && + (tex == &Tile_SPU::ms_pTileData->iconData[Tile_SPU::grass_Id] && + !hasFixedTexture())) { + c1r *= pBaseRed; + c2r *= pBaseRed; + c3r *= pBaseRed; + c4r *= pBaseRed; + c1g *= pBaseGreen; + c2g *= pBaseGreen; + c3g *= pBaseGreen; + c4g *= pBaseGreen; + c1b *= pBaseBlue; + c2b *= pBaseBlue; + c3b *= pBaseBlue; + c4b *= pBaseBlue; + bool prev = t->setMipmapEnable( + false); // 4J added - this is rendering the little bit of grass + // at the top of the side of dirt, don't mipmap it + renderWest(tt, (float)pX, (float)pY, (float)pZ, + GrassTile_SPU::getSideTextureOverlay()); + t->setMipmapEnable(prev); + } + } + if (faceFlags & 0x20) { + if (blsmooth > 0) { + if (tileShapeX1 >= 1) + pX++; // 4J - condition brought forward from 1.2.3 + llXy0 = tt->getShadeBrightness(level, pX, pY - 1, pZ); + llX0z = tt->getShadeBrightness(level, pX, pY, pZ - 1); + llX0Z = tt->getShadeBrightness(level, pX, pY, pZ + 1); + llXY0 = tt->getShadeBrightness(level, pX, pY + 1, pZ); - if ( fancy && (tex == &Tile_SPU::ms_pTileData->iconData[Tile_SPU::grass_Id] && !hasFixedTexture() )) - { - c1r *= pBaseRed; - c2r *= pBaseRed; - c3r *= pBaseRed; - c4r *= pBaseRed; - c1g *= pBaseGreen; - c2g *= pBaseGreen; - c3g *= pBaseGreen; - c4g *= pBaseGreen; - c1b *= pBaseBlue; - c2b *= pBaseBlue; - c3b *= pBaseBlue; - c4b *= pBaseBlue; - bool prev = t->setMipmapEnable( false ); // 4J added - this is rendering the little bit of grass at the top of the side of dirt, don't mipmap it - renderWest( tt, ( float )pX, ( float )pY, ( float )pZ, GrassTile_SPU::getSideTextureOverlay() ); - t->setMipmapEnable( prev ); - } - } - if ( faceFlags & 0x20 ) - { - if ( blsmooth > 0 ) - { - if ( tileShapeX1 >= 1 ) pX++; // 4J - condition brought forward from 1.2.3 - llXy0 = tt->getShadeBrightness( level, pX, pY - 1, pZ ); - llX0z = tt->getShadeBrightness( level, pX, pY, pZ - 1 ); - llX0Z = tt->getShadeBrightness( level, pX, pY, pZ + 1 ); - llXY0 = tt->getShadeBrightness( level, pX, pY + 1, pZ ); + ccXy0 = tt->getLightColor(level, pX, pY - 1, pZ); + ccX0z = tt->getLightColor(level, pX, pY, pZ - 1); + ccX0Z = tt->getLightColor(level, pX, pY, pZ + 1); + ccXY0 = tt->getLightColor(level, pX, pY + 1, pZ); - ccXy0 = tt->getLightColor( level, pX, pY - 1, pZ ); - ccX0z = tt->getLightColor( level, pX, pY, pZ - 1 ); - ccX0Z = tt->getLightColor( level, pX, pY, pZ + 1 ); - ccXY0 = tt->getLightColor( level, pX, pY + 1, pZ ); + if (llTransXy0 || llTransX0z) { + llXyz = tt->getShadeBrightness(level, pX, pY - 1, pZ - 1); + ccXyz = tt->getLightColor(level, pX, pY - 1, pZ - 1); + } else { + llXyz = llX0z; + ccXyz = ccX0z; + } + if (llTransXy0 || llTransX0Z) { + llXyZ = tt->getShadeBrightness(level, pX, pY - 1, pZ + 1); + ccXyZ = tt->getLightColor(level, pX, pY - 1, pZ + 1); + } else { + llXyZ = llX0Z; + ccXyZ = ccX0Z; + } + if (llTransXY0 || llTransX0z) { + llXYz = tt->getShadeBrightness(level, pX, pY + 1, pZ - 1); + ccXYz = tt->getLightColor(level, pX, pY + 1, pZ - 1); + } else { + llXYz = llX0z; + ccXYz = ccX0z; + } + if (llTransXY0 || llTransX0Z) { + llXYZ = tt->getShadeBrightness(level, pX, pY + 1, pZ + 1); + ccXYZ = tt->getLightColor(level, pX, pY + 1, pZ + 1); + } else { + llXYZ = llX0Z; + ccXYZ = ccX0Z; + } + if (tileShapeX1 >= 1) + pX--; // 4J - condition brought forward from 1.2.3 + if (smoothShapeLighting && + g_ambientOcclusionMax) // minecraft->options->ambientOcclusion + // >= Options::AO_MAX) + { + float _ll1 = (llXy0 + llXyZ + llX00 + llX0Z) / 4.0f; + float _ll2 = (llXyz + llXy0 + llX0z + llX00) / 4.0f; + float _ll3 = (llX0z + llX00 + llXYz + llXY0) / 4.0f; + float _ll4 = (llX00 + llX0Z + llXY0 + llXYZ) / 4.0f; + ll1 = (float)(_ll1 * (1.0 - tileShapeY0) * tileShapeZ1 + + _ll2 * (1.0 - tileShapeY0) * (1.0 - tileShapeZ1) + + _ll3 * tileShapeY0 * (1.0 - tileShapeZ1) + + _ll4 * tileShapeY0 * tileShapeZ1); + ll2 = (float)(_ll1 * (1.0 - tileShapeY0) * tileShapeZ0 + + _ll2 * (1.0 - tileShapeY0) * (1.0 - tileShapeZ0) + + _ll3 * tileShapeY0 * (1.0 - tileShapeZ0) + + _ll4 * tileShapeY0 * tileShapeZ0); + ll3 = (float)(_ll1 * (1.0 - tileShapeY1) * tileShapeZ0 + + _ll2 * (1.0 - tileShapeY1) * (1.0 - tileShapeZ0) + + _ll3 * tileShapeY1 * (1.0 - tileShapeZ0) + + _ll4 * tileShapeY1 * tileShapeZ0); + ll4 = (float)(_ll1 * (1.0 - tileShapeY1) * tileShapeZ1 + + _ll2 * (1.0 - tileShapeY1) * (1.0 - tileShapeZ1) + + _ll3 * tileShapeY1 * (1.0 - tileShapeZ1) + + _ll4 * tileShapeY1 * tileShapeZ1); - if ( llTransXy0 || llTransX0z ) - { - llXyz = tt->getShadeBrightness( level, pX, pY - 1, pZ - 1 ); - ccXyz = tt->getLightColor( level, pX, pY - 1, pZ - 1 ); - } - else - { - llXyz = llX0z; - ccXyz = ccX0z; - } - if ( llTransXy0 || llTransX0Z ) - { - llXyZ = tt->getShadeBrightness( level, pX, pY - 1, pZ + 1 ); - ccXyZ = tt->getLightColor( level, pX, pY - 1, pZ + 1 ); - } - else - { - llXyZ = llX0Z; - ccXyZ = ccX0Z; - } - if ( llTransXY0 || llTransX0z ) - { - llXYz = tt->getShadeBrightness( level, pX, pY + 1, pZ - 1 ); - ccXYz = tt->getLightColor( level, pX, pY + 1, pZ - 1 ); - } - else - { - llXYz = llX0z; - ccXYz = ccX0z; - } - if ( llTransXY0 || llTransX0Z ) - { - llXYZ = tt->getShadeBrightness( level, pX, pY + 1, pZ + 1 ); - ccXYZ = tt->getLightColor( level, pX, pY + 1, pZ + 1 ); - } - else - { - llXYZ = llX0Z; - ccXYZ = ccX0Z; - } - if ( tileShapeX1 >= 1 ) pX--; // 4J - condition brought forward from 1.2.3 - if (smoothShapeLighting && g_ambientOcclusionMax)//minecraft->options->ambientOcclusion >= Options::AO_MAX) - { - float _ll1 = (llXy0 + llXyZ + llX00 + llX0Z) / 4.0f; - float _ll2 = (llXyz + llXy0 + llX0z + llX00) / 4.0f; - float _ll3 = (llX0z + llX00 + llXYz + llXY0) / 4.0f; - float _ll4 = (llX00 + llX0Z + llXY0 + llXYZ) / 4.0f; - ll1 = (float) (_ll1 * (1.0 - tileShapeY0) * tileShapeZ1 + _ll2 * (1.0 - tileShapeY0) * (1.0 - tileShapeZ1) + _ll3 * tileShapeY0 * (1.0 - tileShapeZ1) + _ll4 * tileShapeY0 - * tileShapeZ1); - ll2 = (float) (_ll1 * (1.0 - tileShapeY0) * tileShapeZ0 + _ll2 * (1.0 - tileShapeY0) * (1.0 - tileShapeZ0) + _ll3 * tileShapeY0 * (1.0 - tileShapeZ0) + _ll4 * tileShapeY0 - * tileShapeZ0); - ll3 = (float) (_ll1 * (1.0 - tileShapeY1) * tileShapeZ0 + _ll2 * (1.0 - tileShapeY1) * (1.0 - tileShapeZ0) + _ll3 * tileShapeY1 * (1.0 - tileShapeZ0) + _ll4 * tileShapeY1 - * tileShapeZ0); - ll4 = (float) (_ll1 * (1.0 - tileShapeY1) * tileShapeZ1 + _ll2 * (1.0 - tileShapeY1) * (1.0 - tileShapeZ1) + _ll3 * tileShapeY1 * (1.0 - tileShapeZ1) + _ll4 * tileShapeY1 - * tileShapeZ1); + int _tc1 = blend(ccXy0, ccXyZ, ccX0Z, ccX00); + int _tc4 = blend(ccX0Z, ccXY0, ccXYZ, ccX00); + int _tc3 = blend(ccX0z, ccXYz, ccXY0, ccX00); + int _tc2 = blend(ccXyz, ccXy0, ccX0z, ccX00); + tc1 = blend(_tc1, _tc2, _tc3, _tc4, + (1.0 - tileShapeY0) * tileShapeZ1, + (1.0 - tileShapeY0) * (1.0 - tileShapeZ1), + tileShapeY0 * (1.0 - tileShapeZ1), + tileShapeY0 * tileShapeZ1); + tc2 = blend(_tc1, _tc2, _tc3, _tc4, + (1.0 - tileShapeY0) * tileShapeZ0, + (1.0 - tileShapeY0) * (1.0 - tileShapeZ0), + tileShapeY0 * (1.0 - tileShapeZ0), + tileShapeY0 * tileShapeZ0); + tc3 = blend(_tc1, _tc2, _tc3, _tc4, + (1.0 - tileShapeY1) * tileShapeZ0, + (1.0 - tileShapeY1) * (1.0 - tileShapeZ0), + tileShapeY1 * (1.0 - tileShapeZ0), + tileShapeY1 * tileShapeZ0); + tc4 = blend(_tc1, _tc2, _tc3, _tc4, + (1.0 - tileShapeY1) * tileShapeZ1, + (1.0 - tileShapeY1) * (1.0 - tileShapeZ1), + tileShapeY1 * (1.0 - tileShapeZ1), + tileShapeY1 * tileShapeZ1); + } else { + ll1 = (llXy0 + llXyZ + llX00 + llX0Z) / 4.0f; + ll2 = (llXyz + llXy0 + llX0z + llX00) / 4.0f; + ll3 = (llX0z + llX00 + llXYz + llXY0) / 4.0f; + ll4 = (llX00 + llX0Z + llXY0 + llXYZ) / 4.0f; - int _tc1 = blend(ccXy0, ccXyZ, ccX0Z, ccX00); - int _tc4 = blend(ccX0Z, ccXY0, ccXYZ, ccX00); - int _tc3 = blend(ccX0z, ccXYz, ccXY0, ccX00); - int _tc2 = blend(ccXyz, ccXy0, ccX0z, ccX00); - tc1 = blend(_tc1, _tc2, _tc3, _tc4, (1.0 - tileShapeY0) * tileShapeZ1, (1.0 - tileShapeY0) * (1.0 - tileShapeZ1), tileShapeY0 * (1.0 - tileShapeZ1), tileShapeY0 * tileShapeZ1); - tc2 = blend(_tc1, _tc2, _tc3, _tc4, (1.0 - tileShapeY0) * tileShapeZ0, (1.0 - tileShapeY0) * (1.0 - tileShapeZ0), tileShapeY0 * (1.0 - tileShapeZ0), tileShapeY0 * tileShapeZ0); - tc3 = blend(_tc1, _tc2, _tc3, _tc4, (1.0 - tileShapeY1) * tileShapeZ0, (1.0 - tileShapeY1) * (1.0 - tileShapeZ0), tileShapeY1 * (1.0 - tileShapeZ0), tileShapeY1 * tileShapeZ0); - tc4 = blend(_tc1, _tc2, _tc3, _tc4, (1.0 - tileShapeY1) * tileShapeZ1, (1.0 - tileShapeY1) * (1.0 - tileShapeZ1), tileShapeY1 * (1.0 - tileShapeZ1), tileShapeY1 * tileShapeZ1); - } - else - { - ll1 = (llXy0 + llXyZ + llX00 + llX0Z) / 4.0f; - ll2 = (llXyz + llXy0 + llX0z + llX00) / 4.0f; - ll3 = (llX0z + llX00 + llXYz + llXY0) / 4.0f; - ll4 = (llX00 + llX0Z + llXY0 + llXYZ) / 4.0f; + tc1 = blend(ccXy0, ccXyZ, ccX0Z, ccX00); + tc4 = blend(ccX0Z, ccXY0, ccXYZ, ccX00); + tc3 = blend(ccX0z, ccXYz, ccXY0, ccX00); + tc2 = blend(ccXyz, ccXy0, ccX0z, ccX00); + } + } else { + ll1 = ll2 = ll3 = ll4 = llX00; + tc1 = tc2 = tc3 = tc4 = ccX00; + } + c1r = c2r = c3r = c4r = (tint5 ? pBaseRed : 1.0f) * 0.6f; + c1g = c2g = c3g = c4g = (tint5 ? pBaseGreen : 1.0f) * 0.6f; + c1b = c2b = c3b = c4b = (tint5 ? pBaseBlue : 1.0f) * 0.6f; + c1r *= ll1; + c1g *= ll1; + c1b *= ll1; + c2r *= ll2; + c2g *= ll2; + c2b *= ll2; + c3r *= ll3; + c3g *= ll3; + c3b *= ll3; + c4r *= ll4; + c4g *= ll4; + c4b *= ll4; - tc1 = blend(ccXy0, ccXyZ, ccX0Z, ccX00); - tc4 = blend(ccX0Z, ccXY0, ccXYZ, ccX00); - tc3 = blend(ccX0z, ccXYz, ccXY0, ccX00); - tc2 = blend(ccXyz, ccXy0, ccX0z, ccX00); - } - } - else - { - ll1 = ll2 = ll3 = ll4 = llX00; - tc1 = tc2 = tc3 = tc4 = ccX00; - } - c1r = c2r = c3r = c4r = ( tint5 ? pBaseRed : 1.0f ) * 0.6f; - c1g = c2g = c3g = c4g = ( tint5 ? pBaseGreen : 1.0f ) * 0.6f; - c1b = c2b = c3b = c4b = ( tint5 ? pBaseBlue : 1.0f ) * 0.6f; - c1r *= ll1; - c1g *= ll1; - c1b *= ll1; - c2r *= ll2; - c2g *= ll2; - c2b *= ll2; - c3r *= ll3; - c3g *= ll3; - c3b *= ll3; - c4r *= ll4; - c4g *= ll4; - c4b *= ll4; + Icon_SPU* tex = getTexture(tt, level, pX, pY, pZ, 5); + renderEast(tt, (float)pX, (float)pY, (float)pZ, tex); + if (fancy && + (tex == &Tile_SPU::ms_pTileData->iconData[Tile_SPU::grass_Id] && + !hasFixedTexture())) { + c1r *= pBaseRed; + c2r *= pBaseRed; + c3r *= pBaseRed; + c4r *= pBaseRed; + c1g *= pBaseGreen; + c2g *= pBaseGreen; + c3g *= pBaseGreen; + c4g *= pBaseGreen; + c1b *= pBaseBlue; + c2b *= pBaseBlue; + c3b *= pBaseBlue; + c4b *= pBaseBlue; - Icon_SPU *tex = getTexture(tt, level, pX, pY, pZ, 5); - renderEast( tt, ( float )pX, ( float )pY, ( float )pZ, tex ); - if ( fancy && (tex == &Tile_SPU::ms_pTileData->iconData[Tile_SPU::grass_Id] && !hasFixedTexture() )) - { - c1r *= pBaseRed; - c2r *= pBaseRed; - c3r *= pBaseRed; - c4r *= pBaseRed; - c1g *= pBaseGreen; - c2g *= pBaseGreen; - c3g *= pBaseGreen; - c4g *= pBaseGreen; - c1b *= pBaseBlue; - c2b *= pBaseBlue; - c3b *= pBaseBlue; - c4b *= pBaseBlue; - - bool prev = t->setMipmapEnable( false ); // 4J added - this is rendering the little bit of grass at the top of the side of dirt, don't mipmap it - renderEast( tt, ( float )pX, ( float )pY, ( float )pZ, GrassTile_SPU::getSideTextureOverlay() ); - t->setMipmapEnable( prev ); - } - } - applyAmbienceOcclusion = false; - - return true; + bool prev = t->setMipmapEnable( + false); // 4J added - this is rendering the little bit of grass + // at the top of the side of dirt, don't mipmap it + renderEast(tt, (float)pX, (float)pY, (float)pZ, + GrassTile_SPU::getSideTextureOverlay()); + t->setMipmapEnable(prev); + } + } + applyAmbienceOcclusion = false; + return true; } -bool TileRenderer_SPU::tesselateBlockInWorldWithAmbienceOcclusionOldLighting( Tile_SPU* tt, int pX, int pY, int pZ, - float pBaseRed, float pBaseGreen, - float pBaseBlue ) -{ -// -// // 4J - added these faceFlags so we can detect whether this block is going to have no visible faces and early out -// // the original code checked noCulling and shouldRenderFace directly where faceFlags is used now -// int faceFlags = 0; -// if ( noCulling ) -// { -// faceFlags = 0x3f; -// } -// else -// { -// faceFlags |= tt->shouldRenderFace( level, pX, pY - 1, pZ, 0 ) ? 0x01 : 0; -// faceFlags |= tt->shouldRenderFace( level, pX, pY + 1, pZ, 1 ) ? 0x02 : 0; -// faceFlags |= tt->shouldRenderFace( level, pX, pY, pZ - 1, 2 ) ? 0x04 : 0; -// faceFlags |= tt->shouldRenderFace( level, pX, pY, pZ + 1, 3 ) ? 0x08 : 0; -// faceFlags |= tt->shouldRenderFace( level, pX - 1, pY, pZ, 4 ) ? 0x10 : 0; -// faceFlags |= tt->shouldRenderFace( level, pX + 1, pY, pZ, 5 ) ? 0x20 : 0; -// } -// if ( faceFlags == 0 ) -// { -// return false; -// } -// -// applyAmbienceOcclusion = true; -// float ll1 = ll000; -// float ll2 = ll000; -// float ll3 = ll000; -// float ll4 = ll000; -// bool tint0 = true; -// bool tint1 = true; -// bool tint2 = true; -// bool tint3 = true; -// bool tint4 = true; -// bool tint5 = true; -// -// -// ll000 = tt->getBrightness( level, pX, pY, pZ ); -// llx00 = tt->getBrightness( level, pX - 1, pY, pZ ); -// ll0y0 = tt->getBrightness( level, pX, pY - 1, pZ ); -// ll00z = tt->getBrightness( level, pX, pY, pZ - 1 ); -// llX00 = tt->getBrightness( level, pX + 1, pY, pZ ); -// ll0Y0 = tt->getBrightness( level, pX, pY + 1, pZ ); -// ll00Z = tt->getBrightness( level, pX, pY, pZ + 1 ); -// -// llTransXY0 = level->m_tileData.transculent[level->getTile( pX + 1, pY + 1, pZ )]; -// llTransXy0 = level->m_tileData.transculent[level->getTile( pX + 1, pY - 1, pZ )]; -// llTransX0Z = level->m_tileData.transculent[level->getTile( pX + 1, pY, pZ + 1 )]; -// llTransX0z = level->m_tileData.transculent[level->getTile( pX + 1, pY, pZ - 1 )]; -// llTransxY0 = level->m_tileData.transculent[level->getTile( pX - 1, pY + 1, pZ )]; -// llTransxy0 = level->m_tileData.transculent[level->getTile( pX - 1, pY - 1, pZ )]; -// llTransx0z = level->m_tileData.transculent[level->getTile( pX - 1, pY, pZ - 1 )]; -// llTransx0Z = level->m_tileData.transculent[level->getTile( pX - 1, pY, pZ + 1 )]; -// llTrans0YZ = level->m_tileData.transculent[level->getTile( pX, pY + 1, pZ + 1 )]; -// llTrans0Yz = level->m_tileData.transculent[level->getTile( pX, pY + 1, pZ - 1 )]; -// llTrans0yZ = level->m_tileData.transculent[level->getTile( pX, pY - 1, pZ + 1 )]; -// llTrans0yz = level->m_tileData.transculent[level->getTile( pX, pY - 1, pZ - 1 )]; -// -// spu_print("Have to add texture name check here\n"); -// if ( getTexture(tt)->getName().compare(L"grass_top") == 0 ) tint0 = tint2 = tint3 = tint4 = tint5 = false; -// if ( hasFixedTexture() ) tint0 = tint2 = tint3 = tint4 = tint5 = false; -// -// if ( faceFlags & 0x01 ) -// { -// if ( blsmooth > 0 ) -// { -// pY--; -// -// llxy0 = tt->getBrightness( level, pX - 1, pY, pZ ); -// ll0yz = tt->getBrightness( level, pX, pY, pZ - 1 ); -// ll0yZ = tt->getBrightness( level, pX, pY, pZ + 1 ); -// llXy0 = tt->getBrightness( level, pX + 1, pY, pZ ); -// -// if ( llTrans0yz || llTransxy0 ) -// { -// llxyz = tt->getBrightness( level, pX - 1, pY, pZ - 1 ); -// } -// else -// { -// llxyz = llxy0; -// } -// if ( llTrans0yZ || llTransxy0 ) -// { -// llxyZ = tt->getBrightness( level, pX - 1, pY, pZ + 1 ); -// } -// else -// { -// llxyZ = llxy0; -// } -// if ( llTrans0yz || llTransXy0 ) -// { -// llXyz = tt->getBrightness( level, pX + 1, pY, pZ - 1 ); -// } -// else -// { -// llXyz = llXy0; -// } -// if ( llTrans0yZ || llTransXy0 ) -// { -// llXyZ = tt->getBrightness( level, pX + 1, pY, pZ + 1 ); -// } -// else -// { -// llXyZ = llXy0; -// } -// -// pY++; -// ll1 = ( llxyZ + llxy0 + ll0yZ + ll0y0 ) / 4.0f; -// ll4 = ( ll0yZ + ll0y0 + llXyZ + llXy0 ) / 4.0f; -// ll3 = ( ll0y0 + ll0yz + llXy0 + llXyz ) / 4.0f; -// ll2 = ( llxy0 + llxyz + ll0y0 + ll0yz ) / 4.0f; -// } -// else -// { -// ll1 = ll2 = ll3 = ll4 = ll0y0; -// } -// c1r = c2r = c3r = c4r = ( tint0 ? pBaseRed : 1.0f ) * 0.5f; -// c1g = c2g = c3g = c4g = ( tint0 ? pBaseGreen : 1.0f ) * 0.5f; -// c1b = c2b = c3b = c4b = ( tint0 ? pBaseBlue : 1.0f ) * 0.5f; -// c1r *= ll1; -// c1g *= ll1; -// c1b *= ll1; -// c2r *= ll2; -// c2g *= ll2; -// c2b *= ll2; -// c3r *= ll3; -// c3g *= ll3; -// c3b *= ll3; -// c4r *= ll4; -// c4g *= ll4; -// c4b *= ll4; -// -// renderFaceDown( tt, ( float )pX, ( float )pY, ( float )pZ, getTexture( tt, level, pX, pY, pZ, 0 ) ); -// } -// if ( faceFlags & 0x02 ) -// { -// if ( blsmooth > 0 ) -// { -// pY++; -// -// llxY0 = tt->getBrightness( level, pX - 1, pY, pZ ); -// llXY0 = tt->getBrightness( level, pX + 1, pY, pZ ); -// ll0Yz = tt->getBrightness( level, pX, pY, pZ - 1 ); -// ll0YZ = tt->getBrightness( level, pX, pY, pZ + 1 ); -// -// if ( llTrans0Yz || llTransxY0 ) -// { -// llxYz = tt->getBrightness( level, pX - 1, pY, pZ - 1 ); -// } -// else -// { -// llxYz = llxY0; -// } -// if ( llTrans0Yz || llTransXY0 ) -// { -// llXYz = tt->getBrightness( level, pX + 1, pY, pZ - 1 ); -// } -// else -// { -// llXYz = llXY0; -// } -// if ( llTrans0YZ || llTransxY0 ) -// { -// llxYZ = tt->getBrightness( level, pX - 1, pY, pZ + 1 ); -// } -// else -// { -// llxYZ = llxY0; -// } -// if ( llTrans0YZ || llTransXY0 ) -// { -// llXYZ = tt->getBrightness( level, pX + 1, pY, pZ + 1 ); -// } -// else -// { -// llXYZ = llXY0; -// } -// pY--; -// -// ll4 = ( llxYZ + llxY0 + ll0YZ + ll0Y0 ) / 4.0f; -// ll1 = ( ll0YZ + ll0Y0 + llXYZ + llXY0 ) / 4.0f; -// ll2 = ( ll0Y0 + ll0Yz + llXY0 + llXYz ) / 4.0f; -// ll3 = ( llxY0 + llxYz + ll0Y0 + ll0Yz ) / 4.0f; -// } -// else -// { -// ll1 = ll2 = ll3 = ll4 = ll0Y0; -// } -// c1r = c2r = c3r = c4r = ( tint1 ? pBaseRed : 1.0f ); -// c1g = c2g = c3g = c4g = ( tint1 ? pBaseGreen : 1.0f ); -// c1b = c2b = c3b = c4b = ( tint1 ? pBaseBlue : 1.0f ); -// c1r *= ll1; -// c1g *= ll1; -// c1b *= ll1; -// c2r *= ll2; -// c2g *= ll2; -// c2b *= ll2; -// c3r *= ll3; -// c3g *= ll3; -// c3b *= ll3; -// c4r *= ll4; -// c4g *= ll4; -// c4b *= ll4; -// renderFaceUp( tt, ( float )pX, ( float )pY, ( float )pZ, getTexture( tt, level, pX, pY, pZ, 1 ) ); -// } -// if ( faceFlags & 0x04 ) -// { -// if ( blsmooth > 0 ) -// { -// pZ--; -// llx0z = tt->getBrightness( level, pX - 1, pY, pZ ); -// ll0yz = tt->getBrightness( level, pX, pY - 1, pZ ); -// ll0Yz = tt->getBrightness( level, pX, pY + 1, pZ ); -// llX0z = tt->getBrightness( level, pX + 1, pY, pZ ); -// -// if ( llTransx0z || llTrans0yz ) -// { -// llxyz = tt->getBrightness( level, pX - 1, pY - 1, pZ ); -// } -// else -// { -// llxyz = llx0z; -// } -// if ( llTransx0z || llTrans0Yz ) -// { -// llxYz = tt->getBrightness( level, pX - 1, pY + 1, pZ ); -// } -// else -// { -// llxYz = llx0z; -// } -// if ( llTransX0z || llTrans0yz ) -// { -// llXyz = tt->getBrightness( level, pX + 1, pY - 1, pZ ); -// } -// else -// { -// llXyz = llX0z; -// } -// if ( llTransX0z || llTrans0Yz ) -// { -// llXYz = tt->getBrightness( level, pX + 1, pY + 1, pZ ); -// } -// else -// { -// llXYz = llX0z; -// } -// pZ++; -// ll1 = ( llx0z + llxYz + ll00z + ll0Yz ) / 4.0f; -// ll2 = ( ll00z + ll0Yz + llX0z + llXYz ) / 4.0f; -// ll3 = ( ll0yz + ll00z + llXyz + llX0z ) / 4.0f; -// ll4 = ( llxyz + llx0z + ll0yz + ll00z ) / 4.0f; -// } -// else -// { -// ll1 = ll2 = ll3 = ll4 = ll00z; -// } -// c1r = c2r = c3r = c4r = ( tint2 ? pBaseRed : 1.0f ) * 0.8f; -// c1g = c2g = c3g = c4g = ( tint2 ? pBaseGreen : 1.0f ) * 0.8f; -// c1b = c2b = c3b = c4b = ( tint2 ? pBaseBlue : 1.0f ) * 0.8f; -// c1r *= ll1; -// c1g *= ll1; -// c1b *= ll1; -// c2r *= ll2; -// c2g *= ll2; -// c2b *= ll2; -// c3r *= ll3; -// c3g *= ll3; -// c3b *= ll3; -// c4r *= ll4; -// c4g *= ll4; -// c4b *= ll4; -// -// Icon_SPU *tex = getTexture(tt, level, pX, pY, pZ, 2); -// renderNorth( tt, ( float )pX, ( float )pY, ( float )pZ, tex ); -// -// if ( fancy && (tex->getName().compare(L"grass_side") == 0) && !hasFixedTexture()) -// { -// c1r *= pBaseRed; -// c2r *= pBaseRed; -// c3r *= pBaseRed; -// c4r *= pBaseRed; -// c1g *= pBaseGreen; -// c2g *= pBaseGreen; -// c3g *= pBaseGreen; -// c4g *= pBaseGreen; -// c1b *= pBaseBlue; -// c2b *= pBaseBlue; -// c3b *= pBaseBlue; -// c4b *= pBaseBlue; -// renderNorth( tt, ( float )pX, ( float )pY, ( float )pZ, getGrassSideTextureOverlay() ); -// } -// } -// if ( faceFlags & 0x08 ) -// { -// if ( blsmooth > 0 ) -// { -// pZ++; -// -// llx0Z = tt->getBrightness( level, pX - 1, pY, pZ ); -// llX0Z = tt->getBrightness( level, pX + 1, pY, pZ ); -// ll0yZ = tt->getBrightness( level, pX, pY - 1, pZ ); -// ll0YZ = tt->getBrightness( level, pX, pY + 1, pZ ); -// -// if ( llTransx0Z || llTrans0yZ ) -// { -// llxyZ = tt->getBrightness( level, pX - 1, pY - 1, pZ ); -// } -// else -// { -// llxyZ = llx0Z; -// } -// if ( llTransx0Z || llTrans0YZ ) -// { -// llxYZ = tt->getBrightness( level, pX - 1, pY + 1, pZ ); -// } -// else -// { -// llxYZ = llx0Z; -// } -// if ( llTransX0Z || llTrans0yZ ) -// { -// llXyZ = tt->getBrightness( level, pX + 1, pY - 1, pZ ); -// } -// else -// { -// llXyZ = llX0Z; -// } -// if ( llTransX0Z || llTrans0YZ ) -// { -// llXYZ = tt->getBrightness( level, pX + 1, pY + 1, pZ ); -// } -// else -// { -// llXYZ = llX0Z; -// } -// pZ--; -// ll1 = ( llx0Z + llxYZ + ll00Z + ll0YZ ) / 4.0f; -// ll4 = ( ll00Z + ll0YZ + llX0Z + llXYZ ) / 4.0f; -// ll3 = ( ll0yZ + ll00Z + llXyZ + llX0Z ) / 4.0f; -// ll2 = ( llxyZ + llx0Z + ll0yZ + ll00Z ) / 4.0f; -// } -// else -// { -// ll1 = ll2 = ll3 = ll4 = ll00Z; -// } -// c1r = c2r = c3r = c4r = ( tint3 ? pBaseRed : 1.0f ) * 0.8f; -// c1g = c2g = c3g = c4g = ( tint3 ? pBaseGreen : 1.0f ) * 0.8f; -// c1b = c2b = c3b = c4b = ( tint3 ? pBaseBlue : 1.0f ) * 0.8f; -// c1r *= ll1; -// c1g *= ll1; -// c1b *= ll1; -// c2r *= ll2; -// c2g *= ll2; -// c2b *= ll2; -// c3r *= ll3; -// c3g *= ll3; -// c3b *= ll3; -// c4r *= ll4; -// c4g *= ll4; -// c4b *= ll4; -// Icon_SPU *tex = getTexture(tt, level, pX, pY, pZ, 3); -// renderSouth( tt, ( float )pX, ( float )pY, ( float )pZ, getTexture(tt, level, pX, pY, pZ, 3 ) ); -// if ( fancy && (tex->getName().compare(L"grass_side") == 0) && !hasFixedTexture() ) -// { -// c1r *= pBaseRed; -// c2r *= pBaseRed; -// c3r *= pBaseRed; -// c4r *= pBaseRed; -// c1g *= pBaseGreen; -// c2g *= pBaseGreen; -// c3g *= pBaseGreen; -// c4g *= pBaseGreen; -// c1b *= pBaseBlue; -// c2b *= pBaseBlue; -// c3b *= pBaseBlue; -// c4b *= pBaseBlue; -// renderSouth( tt, ( float )pX, ( float )pY, ( float )pZ, getGrassSideTextureOverlay() ); -// } -// } -// if ( faceFlags & 0x10 ) -// { -// if ( blsmooth > 0 ) -// { -// pX--; -// llxy0 = tt->getBrightness( level, pX, pY - 1, pZ ); -// llx0z = tt->getBrightness( level, pX, pY, pZ - 1 ); -// llx0Z = tt->getBrightness( level, pX, pY, pZ + 1 ); -// llxY0 = tt->getBrightness( level, pX, pY + 1, pZ ); -// -// if ( llTransx0z || llTransxy0 ) -// { -// llxyz = tt->getBrightness( level, pX, pY - 1, pZ - 1 ); -// } -// else -// { -// llxyz = llx0z; -// } -// if ( llTransx0Z || llTransxy0 ) -// { -// llxyZ = tt->getBrightness( level, pX, pY - 1, pZ + 1 ); -// } -// else -// { -// llxyZ = llx0Z; -// } -// if ( llTransx0z || llTransxY0 ) -// { -// llxYz = tt->getBrightness( level, pX, pY + 1, pZ - 1 ); -// } -// else -// { -// llxYz = llx0z; -// } -// if ( llTransx0Z || llTransxY0 ) -// { -// llxYZ = tt->getBrightness( level, pX, pY + 1, pZ + 1 ); -// } -// else -// { -// llxYZ = llx0Z; -// } -// pX++; -// ll4 = ( llxy0 + llxyZ + llx00 + llx0Z ) / 4.0f; -// ll1 = ( llx00 + llx0Z + llxY0 + llxYZ ) / 4.0f; -// ll2 = ( llx0z + llx00 + llxYz + llxY0 ) / 4.0f; -// ll3 = ( llxyz + llxy0 + llx0z + llx00 ) / 4.0f; -// } -// else -// { -// ll1 = ll2 = ll3 = ll4 = llx00; -// } -// c1r = c2r = c3r = c4r = ( tint4 ? pBaseRed : 1.0f ) * 0.6f; -// c1g = c2g = c3g = c4g = ( tint4 ? pBaseGreen : 1.0f ) * 0.6f; -// c1b = c2b = c3b = c4b = ( tint4 ? pBaseBlue : 1.0f ) * 0.6f; -// c1r *= ll1; -// c1g *= ll1; -// c1b *= ll1; -// c2r *= ll2; -// c2g *= ll2; -// c2b *= ll2; -// c3r *= ll3; -// c3g *= ll3; -// c3b *= ll3; -// c4r *= ll4; -// c4g *= ll4; -// c4b *= ll4; -// Icon_SPU *tex = getTexture(tt, level, pX, pY, pZ, 4); -// renderWest( tt, ( float )pX, ( float )pY, ( float )pZ, tex ); -// if ( fancy &&(tex->getName().compare(L"grass_side") == 0) && !hasFixedTexture() ) -// { -// c1r *= pBaseRed; -// c2r *= pBaseRed; -// c3r *= pBaseRed; -// c4r *= pBaseRed; -// c1g *= pBaseGreen; -// c2g *= pBaseGreen; -// c3g *= pBaseGreen; -// c4g *= pBaseGreen; -// c1b *= pBaseBlue; -// c2b *= pBaseBlue; -// c3b *= pBaseBlue; -// c4b *= pBaseBlue; -// renderWest( tt, ( float )pX, ( float )pY, ( float )pZ, getGrassSideTextureOverlay() ); -// } -// } -// if ( faceFlags & 0x20 ) -// { -// if ( blsmooth > 0 ) -// { -// pX++; -// llXy0 = tt->getBrightness( level, pX, pY - 1, pZ ); -// llX0z = tt->getBrightness( level, pX, pY, pZ - 1 ); -// llX0Z = tt->getBrightness( level, pX, pY, pZ + 1 ); -// llXY0 = tt->getBrightness( level, pX, pY + 1, pZ ); -// -// if ( llTransXy0 || llTransX0z ) -// { -// llXyz = tt->getBrightness( level, pX, pY - 1, pZ - 1 ); -// } -// else -// { -// llXyz = llX0z; -// } -// if ( llTransXy0 || llTransX0Z ) -// { -// llXyZ = tt->getBrightness( level, pX, pY - 1, pZ + 1 ); -// } -// else -// { -// llXyZ = llX0Z; -// } -// if ( llTransXY0 || llTransX0z ) -// { -// llXYz = tt->getBrightness( level, pX, pY + 1, pZ - 1 ); -// } -// else -// { -// llXYz = llX0z; -// } -// if ( llTransXY0 || llTransX0Z ) -// { -// llXYZ = tt->getBrightness( level, pX, pY + 1, pZ + 1 ); -// } -// else -// { -// llXYZ = llX0Z; -// } -// pX--; -// ll1 = ( llXy0 + llXyZ + llX00 + llX0Z ) / 4.0f; -// ll4 = ( llX00 + llX0Z + llXY0 + llXYZ ) / 4.0f; -// ll3 = ( llX0z + llX00 + llXYz + llXY0 ) / 4.0f; -// ll2 = ( llXyz + llXy0 + llX0z + llX00 ) / 4.0f; -// } -// else -// { -// ll1 = ll2 = ll3 = ll4 = llX00; -// } -// c1r = c2r = c3r = c4r = ( tint5 ? pBaseRed : 1.0f ) * 0.6f; -// c1g = c2g = c3g = c4g = ( tint5 ? pBaseGreen : 1.0f ) * 0.6f; -// c1b = c2b = c3b = c4b = ( tint5 ? pBaseBlue : 1.0f ) * 0.6f; -// c1r *= ll1; -// c1g *= ll1; -// c1b *= ll1; -// c2r *= ll2; -// c2g *= ll2; -// c2b *= ll2; -// c3r *= ll3; -// c3g *= ll3; -// c3b *= ll3; -// c4r *= ll4; -// c4g *= ll4; -// c4b *= ll4; -// -// Icon_SPU *tex = getTexture(tt, level, pX, pY, pZ, 5); -// renderEast( tt, ( float )pX, ( float )pY, ( float )pZ, tex ); -// if ( fancy && (tex->getName().compare(L"grass_side") == 0) && !hasFixedTexture() ) -// { -// c1r *= pBaseRed; -// c2r *= pBaseRed; -// c3r *= pBaseRed; -// c4r *= pBaseRed; -// c1g *= pBaseGreen; -// c2g *= pBaseGreen; -// c3g *= pBaseGreen; -// c4g *= pBaseGreen; -// c1b *= pBaseBlue; -// c2b *= pBaseBlue; -// c3b *= pBaseBlue; -// c4b *= pBaseBlue; -// renderEast( tt, ( float )pX, ( float )pY, ( float )pZ, getGrassSideTextureOverlay() ); -// } -// } -// applyAmbienceOcclusion = false; -// - return true; - +bool TileRenderer_SPU::tesselateBlockInWorldWithAmbienceOcclusionOldLighting( + Tile_SPU* tt, int pX, int pY, int pZ, float pBaseRed, float pBaseGreen, + float pBaseBlue) { + // + // // 4J - added these faceFlags so we can detect whether this block is + // going to have no visible faces and early out + // // the original code checked noCulling and shouldRenderFace directly + // where faceFlags is used now int faceFlags = 0; if ( noCulling ) + // { + // faceFlags = 0x3f; + // } + // else + // { + // faceFlags |= tt->shouldRenderFace( level, pX, pY - 1, pZ, 0 ) ? + // 0x01 : 0; faceFlags |= tt->shouldRenderFace( level, pX, pY + 1, pZ, 1 ) ? + // 0x02 : 0; faceFlags |= tt->shouldRenderFace( level, pX, pY, pZ - 1, 2 ) ? + // 0x04 : 0; faceFlags |= tt->shouldRenderFace( level, pX, pY, pZ + 1, 3 ) ? + // 0x08 : 0; faceFlags |= tt->shouldRenderFace( level, pX - 1, pY, pZ, 4 ) ? + // 0x10 : 0; faceFlags |= tt->shouldRenderFace( level, pX + 1, pY, pZ, 5 ) ? + // 0x20 : 0; + // } + // if ( faceFlags == 0 ) + // { + // return false; + // } + // + // applyAmbienceOcclusion = true; + // float ll1 = ll000; + // float ll2 = ll000; + // float ll3 = ll000; + // float ll4 = ll000; + // bool tint0 = true; + // bool tint1 = true; + // bool tint2 = true; + // bool tint3 = true; + // bool tint4 = true; + // bool tint5 = true; + // + // + // ll000 = tt->getBrightness( level, pX, pY, pZ ); + // llx00 = tt->getBrightness( level, pX - 1, pY, pZ ); + // ll0y0 = tt->getBrightness( level, pX, pY - 1, pZ ); + // ll00z = tt->getBrightness( level, pX, pY, pZ - 1 ); + // llX00 = tt->getBrightness( level, pX + 1, pY, pZ ); + // ll0Y0 = tt->getBrightness( level, pX, pY + 1, pZ ); + // ll00Z = tt->getBrightness( level, pX, pY, pZ + 1 ); + // + // llTransXY0 = level->m_tileData.transculent[level->getTile( pX + 1, pY + + // 1, pZ )]; llTransXy0 = level->m_tileData.transculent[level->getTile( pX + + // 1, pY - 1, pZ )]; llTransX0Z = + // level->m_tileData.transculent[level->getTile( pX + 1, pY, pZ + 1 )]; + // llTransX0z = level->m_tileData.transculent[level->getTile( pX + 1, pY, + // pZ - 1 )]; llTransxY0 = level->m_tileData.transculent[level->getTile( pX + // - 1, pY + 1, pZ )]; llTransxy0 = + // level->m_tileData.transculent[level->getTile( pX - 1, pY - 1, pZ )]; + // llTransx0z = level->m_tileData.transculent[level->getTile( pX - 1, pY, + // pZ - 1 )]; llTransx0Z = level->m_tileData.transculent[level->getTile( pX + // - 1, pY, pZ + 1 )]; llTrans0YZ = + // level->m_tileData.transculent[level->getTile( pX, pY + 1, pZ + 1 )]; + // llTrans0Yz = level->m_tileData.transculent[level->getTile( pX, pY + 1, + // pZ - 1 )]; llTrans0yZ = level->m_tileData.transculent[level->getTile( pX, + // pY - 1, pZ + 1 )]; llTrans0yz = + // level->m_tileData.transculent[level->getTile( pX, pY - 1, pZ - 1 )]; + // + // spu_print("Have to add texture name check here\n"); + // if ( getTexture(tt)->getName().compare(L"grass_top") == 0 ) tint0 = + // tint2 = tint3 = tint4 = tint5 = false; if ( hasFixedTexture() ) tint0 = + // tint2 = tint3 = tint4 = tint5 = false; + // + // if ( faceFlags & 0x01 ) + // { + // if ( blsmooth > 0 ) + // { + // pY--; + // + // llxy0 = tt->getBrightness( level, pX - 1, pY, pZ ); + // ll0yz = tt->getBrightness( level, pX, pY, pZ - 1 ); + // ll0yZ = tt->getBrightness( level, pX, pY, pZ + 1 ); + // llXy0 = tt->getBrightness( level, pX + 1, pY, pZ ); + // + // if ( llTrans0yz || llTransxy0 ) + // { + // llxyz = tt->getBrightness( level, pX - 1, pY, pZ + // - 1 ); + // } + // else + // { + // llxyz = llxy0; + // } + // if ( llTrans0yZ || llTransxy0 ) + // { + // llxyZ = tt->getBrightness( level, pX - 1, pY, pZ + // + 1 ); + // } + // else + // { + // llxyZ = llxy0; + // } + // if ( llTrans0yz || llTransXy0 ) + // { + // llXyz = tt->getBrightness( level, pX + 1, pY, pZ + // - 1 ); + // } + // else + // { + // llXyz = llXy0; + // } + // if ( llTrans0yZ || llTransXy0 ) + // { + // llXyZ = tt->getBrightness( level, pX + 1, pY, pZ + // + 1 ); + // } + // else + // { + // llXyZ = llXy0; + // } + // + // pY++; + // ll1 = ( llxyZ + llxy0 + ll0yZ + ll0y0 ) / 4.0f; + // ll4 = ( ll0yZ + ll0y0 + llXyZ + llXy0 ) / 4.0f; + // ll3 = ( ll0y0 + ll0yz + llXy0 + llXyz ) / 4.0f; + // ll2 = ( llxy0 + llxyz + ll0y0 + ll0yz ) / 4.0f; + // } + // else + // { + // ll1 = ll2 = ll3 = ll4 = ll0y0; + // } + // c1r = c2r = c3r = c4r = ( tint0 ? pBaseRed : 1.0f ) * 0.5f; + // c1g = c2g = c3g = c4g = ( tint0 ? pBaseGreen : 1.0f ) * 0.5f; + // c1b = c2b = c3b = c4b = ( tint0 ? pBaseBlue : 1.0f ) * 0.5f; + // c1r *= ll1; + // c1g *= ll1; + // c1b *= ll1; + // c2r *= ll2; + // c2g *= ll2; + // c2b *= ll2; + // c3r *= ll3; + // c3g *= ll3; + // c3b *= ll3; + // c4r *= ll4; + // c4g *= ll4; + // c4b *= ll4; + // + // renderFaceDown( tt, ( float )pX, ( float )pY, ( float )pZ, + // getTexture( tt, level, pX, pY, pZ, 0 ) ); + // } + // if ( faceFlags & 0x02 ) + // { + // if ( blsmooth > 0 ) + // { + // pY++; + // + // llxY0 = tt->getBrightness( level, pX - 1, pY, pZ ); + // llXY0 = tt->getBrightness( level, pX + 1, pY, pZ ); + // ll0Yz = tt->getBrightness( level, pX, pY, pZ - 1 ); + // ll0YZ = tt->getBrightness( level, pX, pY, pZ + 1 ); + // + // if ( llTrans0Yz || llTransxY0 ) + // { + // llxYz = tt->getBrightness( level, pX - 1, pY, pZ + // - 1 ); + // } + // else + // { + // llxYz = llxY0; + // } + // if ( llTrans0Yz || llTransXY0 ) + // { + // llXYz = tt->getBrightness( level, pX + 1, pY, pZ + // - 1 ); + // } + // else + // { + // llXYz = llXY0; + // } + // if ( llTrans0YZ || llTransxY0 ) + // { + // llxYZ = tt->getBrightness( level, pX - 1, pY, pZ + // + 1 ); + // } + // else + // { + // llxYZ = llxY0; + // } + // if ( llTrans0YZ || llTransXY0 ) + // { + // llXYZ = tt->getBrightness( level, pX + 1, pY, pZ + // + 1 ); + // } + // else + // { + // llXYZ = llXY0; + // } + // pY--; + // + // ll4 = ( llxYZ + llxY0 + ll0YZ + ll0Y0 ) / 4.0f; + // ll1 = ( ll0YZ + ll0Y0 + llXYZ + llXY0 ) / 4.0f; + // ll2 = ( ll0Y0 + ll0Yz + llXY0 + llXYz ) / 4.0f; + // ll3 = ( llxY0 + llxYz + ll0Y0 + ll0Yz ) / 4.0f; + // } + // else + // { + // ll1 = ll2 = ll3 = ll4 = ll0Y0; + // } + // c1r = c2r = c3r = c4r = ( tint1 ? pBaseRed : 1.0f ); + // c1g = c2g = c3g = c4g = ( tint1 ? pBaseGreen : 1.0f ); + // c1b = c2b = c3b = c4b = ( tint1 ? pBaseBlue : 1.0f ); + // c1r *= ll1; + // c1g *= ll1; + // c1b *= ll1; + // c2r *= ll2; + // c2g *= ll2; + // c2b *= ll2; + // c3r *= ll3; + // c3g *= ll3; + // c3b *= ll3; + // c4r *= ll4; + // c4g *= ll4; + // c4b *= ll4; + // renderFaceUp( tt, ( float )pX, ( float )pY, ( float )pZ, + // getTexture( tt, level, pX, pY, pZ, 1 ) ); + // } + // if ( faceFlags & 0x04 ) + // { + // if ( blsmooth > 0 ) + // { + // pZ--; + // llx0z = tt->getBrightness( level, pX - 1, pY, pZ ); + // ll0yz = tt->getBrightness( level, pX, pY - 1, pZ ); + // ll0Yz = tt->getBrightness( level, pX, pY + 1, pZ ); + // llX0z = tt->getBrightness( level, pX + 1, pY, pZ ); + // + // if ( llTransx0z || llTrans0yz ) + // { + // llxyz = tt->getBrightness( level, pX - 1, pY - + // 1, pZ ); + // } + // else + // { + // llxyz = llx0z; + // } + // if ( llTransx0z || llTrans0Yz ) + // { + // llxYz = tt->getBrightness( level, pX - 1, pY + + // 1, pZ ); + // } + // else + // { + // llxYz = llx0z; + // } + // if ( llTransX0z || llTrans0yz ) + // { + // llXyz = tt->getBrightness( level, pX + 1, pY - + // 1, pZ ); + // } + // else + // { + // llXyz = llX0z; + // } + // if ( llTransX0z || llTrans0Yz ) + // { + // llXYz = tt->getBrightness( level, pX + 1, pY + + // 1, pZ ); + // } + // else + // { + // llXYz = llX0z; + // } + // pZ++; + // ll1 = ( llx0z + llxYz + ll00z + ll0Yz ) / 4.0f; + // ll2 = ( ll00z + ll0Yz + llX0z + llXYz ) / 4.0f; + // ll3 = ( ll0yz + ll00z + llXyz + llX0z ) / 4.0f; + // ll4 = ( llxyz + llx0z + ll0yz + ll00z ) / 4.0f; + // } + // else + // { + // ll1 = ll2 = ll3 = ll4 = ll00z; + // } + // c1r = c2r = c3r = c4r = ( tint2 ? pBaseRed : 1.0f ) * 0.8f; + // c1g = c2g = c3g = c4g = ( tint2 ? pBaseGreen : 1.0f ) * 0.8f; + // c1b = c2b = c3b = c4b = ( tint2 ? pBaseBlue : 1.0f ) * 0.8f; + // c1r *= ll1; + // c1g *= ll1; + // c1b *= ll1; + // c2r *= ll2; + // c2g *= ll2; + // c2b *= ll2; + // c3r *= ll3; + // c3g *= ll3; + // c3b *= ll3; + // c4r *= ll4; + // c4g *= ll4; + // c4b *= ll4; + // + // Icon_SPU *tex = getTexture(tt, level, pX, pY, pZ, 2); + // renderNorth( tt, ( float )pX, ( float )pY, ( float )pZ, tex ); + // + // if ( fancy && (tex->getName().compare(L"grass_side") == 0) && + // !hasFixedTexture()) + // { + // c1r *= pBaseRed; + // c2r *= pBaseRed; + // c3r *= pBaseRed; + // c4r *= pBaseRed; + // c1g *= pBaseGreen; + // c2g *= pBaseGreen; + // c3g *= pBaseGreen; + // c4g *= pBaseGreen; + // c1b *= pBaseBlue; + // c2b *= pBaseBlue; + // c3b *= pBaseBlue; + // c4b *= pBaseBlue; + // renderNorth( tt, ( float )pX, ( float )pY, ( float )pZ, + // getGrassSideTextureOverlay() ); + // } + // } + // if ( faceFlags & 0x08 ) + // { + // if ( blsmooth > 0 ) + // { + // pZ++; + // + // llx0Z = tt->getBrightness( level, pX - 1, pY, pZ ); + // llX0Z = tt->getBrightness( level, pX + 1, pY, pZ ); + // ll0yZ = tt->getBrightness( level, pX, pY - 1, pZ ); + // ll0YZ = tt->getBrightness( level, pX, pY + 1, pZ ); + // + // if ( llTransx0Z || llTrans0yZ ) + // { + // llxyZ = tt->getBrightness( level, pX - 1, pY - + // 1, pZ ); + // } + // else + // { + // llxyZ = llx0Z; + // } + // if ( llTransx0Z || llTrans0YZ ) + // { + // llxYZ = tt->getBrightness( level, pX - 1, pY + + // 1, pZ ); + // } + // else + // { + // llxYZ = llx0Z; + // } + // if ( llTransX0Z || llTrans0yZ ) + // { + // llXyZ = tt->getBrightness( level, pX + 1, pY - + // 1, pZ ); + // } + // else + // { + // llXyZ = llX0Z; + // } + // if ( llTransX0Z || llTrans0YZ ) + // { + // llXYZ = tt->getBrightness( level, pX + 1, pY + + // 1, pZ ); + // } + // else + // { + // llXYZ = llX0Z; + // } + // pZ--; + // ll1 = ( llx0Z + llxYZ + ll00Z + ll0YZ ) / 4.0f; + // ll4 = ( ll00Z + ll0YZ + llX0Z + llXYZ ) / 4.0f; + // ll3 = ( ll0yZ + ll00Z + llXyZ + llX0Z ) / 4.0f; + // ll2 = ( llxyZ + llx0Z + ll0yZ + ll00Z ) / 4.0f; + // } + // else + // { + // ll1 = ll2 = ll3 = ll4 = ll00Z; + // } + // c1r = c2r = c3r = c4r = ( tint3 ? pBaseRed : 1.0f ) * 0.8f; + // c1g = c2g = c3g = c4g = ( tint3 ? pBaseGreen : 1.0f ) * 0.8f; + // c1b = c2b = c3b = c4b = ( tint3 ? pBaseBlue : 1.0f ) * 0.8f; + // c1r *= ll1; + // c1g *= ll1; + // c1b *= ll1; + // c2r *= ll2; + // c2g *= ll2; + // c2b *= ll2; + // c3r *= ll3; + // c3g *= ll3; + // c3b *= ll3; + // c4r *= ll4; + // c4g *= ll4; + // c4b *= ll4; + // Icon_SPU *tex = getTexture(tt, level, pX, pY, pZ, 3); + // renderSouth( tt, ( float )pX, ( float )pY, ( float )pZ, + // getTexture(tt, level, pX, pY, pZ, 3 ) ); if ( fancy && + // (tex->getName().compare(L"grass_side") == 0) && !hasFixedTexture() ) + // { + // c1r *= pBaseRed; + // c2r *= pBaseRed; + // c3r *= pBaseRed; + // c4r *= pBaseRed; + // c1g *= pBaseGreen; + // c2g *= pBaseGreen; + // c3g *= pBaseGreen; + // c4g *= pBaseGreen; + // c1b *= pBaseBlue; + // c2b *= pBaseBlue; + // c3b *= pBaseBlue; + // c4b *= pBaseBlue; + // renderSouth( tt, ( float )pX, ( float )pY, ( float )pZ, + // getGrassSideTextureOverlay() ); + // } + // } + // if ( faceFlags & 0x10 ) + // { + // if ( blsmooth > 0 ) + // { + // pX--; + // llxy0 = tt->getBrightness( level, pX, pY - 1, pZ ); + // llx0z = tt->getBrightness( level, pX, pY, pZ - 1 ); + // llx0Z = tt->getBrightness( level, pX, pY, pZ + 1 ); + // llxY0 = tt->getBrightness( level, pX, pY + 1, pZ ); + // + // if ( llTransx0z || llTransxy0 ) + // { + // llxyz = tt->getBrightness( level, pX, pY - 1, pZ + // - 1 ); + // } + // else + // { + // llxyz = llx0z; + // } + // if ( llTransx0Z || llTransxy0 ) + // { + // llxyZ = tt->getBrightness( level, pX, pY - 1, pZ + // + 1 ); + // } + // else + // { + // llxyZ = llx0Z; + // } + // if ( llTransx0z || llTransxY0 ) + // { + // llxYz = tt->getBrightness( level, pX, pY + 1, pZ + // - 1 ); + // } + // else + // { + // llxYz = llx0z; + // } + // if ( llTransx0Z || llTransxY0 ) + // { + // llxYZ = tt->getBrightness( level, pX, pY + 1, pZ + // + 1 ); + // } + // else + // { + // llxYZ = llx0Z; + // } + // pX++; + // ll4 = ( llxy0 + llxyZ + llx00 + llx0Z ) / 4.0f; + // ll1 = ( llx00 + llx0Z + llxY0 + llxYZ ) / 4.0f; + // ll2 = ( llx0z + llx00 + llxYz + llxY0 ) / 4.0f; + // ll3 = ( llxyz + llxy0 + llx0z + llx00 ) / 4.0f; + // } + // else + // { + // ll1 = ll2 = ll3 = ll4 = llx00; + // } + // c1r = c2r = c3r = c4r = ( tint4 ? pBaseRed : 1.0f ) * 0.6f; + // c1g = c2g = c3g = c4g = ( tint4 ? pBaseGreen : 1.0f ) * 0.6f; + // c1b = c2b = c3b = c4b = ( tint4 ? pBaseBlue : 1.0f ) * 0.6f; + // c1r *= ll1; + // c1g *= ll1; + // c1b *= ll1; + // c2r *= ll2; + // c2g *= ll2; + // c2b *= ll2; + // c3r *= ll3; + // c3g *= ll3; + // c3b *= ll3; + // c4r *= ll4; + // c4g *= ll4; + // c4b *= ll4; + // Icon_SPU *tex = getTexture(tt, level, pX, pY, pZ, 4); + // renderWest( tt, ( float )pX, ( float )pY, ( float )pZ, tex ); + // if ( fancy &&(tex->getName().compare(L"grass_side") == 0) && + // !hasFixedTexture() ) + // { + // c1r *= pBaseRed; + // c2r *= pBaseRed; + // c3r *= pBaseRed; + // c4r *= pBaseRed; + // c1g *= pBaseGreen; + // c2g *= pBaseGreen; + // c3g *= pBaseGreen; + // c4g *= pBaseGreen; + // c1b *= pBaseBlue; + // c2b *= pBaseBlue; + // c3b *= pBaseBlue; + // c4b *= pBaseBlue; + // renderWest( tt, ( float )pX, ( float )pY, ( float )pZ, + // getGrassSideTextureOverlay() ); + // } + // } + // if ( faceFlags & 0x20 ) + // { + // if ( blsmooth > 0 ) + // { + // pX++; + // llXy0 = tt->getBrightness( level, pX, pY - 1, pZ ); + // llX0z = tt->getBrightness( level, pX, pY, pZ - 1 ); + // llX0Z = tt->getBrightness( level, pX, pY, pZ + 1 ); + // llXY0 = tt->getBrightness( level, pX, pY + 1, pZ ); + // + // if ( llTransXy0 || llTransX0z ) + // { + // llXyz = tt->getBrightness( level, pX, pY - 1, pZ + // - 1 ); + // } + // else + // { + // llXyz = llX0z; + // } + // if ( llTransXy0 || llTransX0Z ) + // { + // llXyZ = tt->getBrightness( level, pX, pY - 1, pZ + // + 1 ); + // } + // else + // { + // llXyZ = llX0Z; + // } + // if ( llTransXY0 || llTransX0z ) + // { + // llXYz = tt->getBrightness( level, pX, pY + 1, pZ + // - 1 ); + // } + // else + // { + // llXYz = llX0z; + // } + // if ( llTransXY0 || llTransX0Z ) + // { + // llXYZ = tt->getBrightness( level, pX, pY + 1, pZ + // + 1 ); + // } + // else + // { + // llXYZ = llX0Z; + // } + // pX--; + // ll1 = ( llXy0 + llXyZ + llX00 + llX0Z ) / 4.0f; + // ll4 = ( llX00 + llX0Z + llXY0 + llXYZ ) / 4.0f; + // ll3 = ( llX0z + llX00 + llXYz + llXY0 ) / 4.0f; + // ll2 = ( llXyz + llXy0 + llX0z + llX00 ) / 4.0f; + // } + // else + // { + // ll1 = ll2 = ll3 = ll4 = llX00; + // } + // c1r = c2r = c3r = c4r = ( tint5 ? pBaseRed : 1.0f ) * 0.6f; + // c1g = c2g = c3g = c4g = ( tint5 ? pBaseGreen : 1.0f ) * 0.6f; + // c1b = c2b = c3b = c4b = ( tint5 ? pBaseBlue : 1.0f ) * 0.6f; + // c1r *= ll1; + // c1g *= ll1; + // c1b *= ll1; + // c2r *= ll2; + // c2g *= ll2; + // c2b *= ll2; + // c3r *= ll3; + // c3g *= ll3; + // c3b *= ll3; + // c4r *= ll4; + // c4g *= ll4; + // c4b *= ll4; + // + // Icon_SPU *tex = getTexture(tt, level, pX, pY, pZ, 5); + // renderEast( tt, ( float )pX, ( float )pY, ( float )pZ, tex ); + // if ( fancy && (tex->getName().compare(L"grass_side") == 0) && + // !hasFixedTexture() ) + // { + // c1r *= pBaseRed; + // c2r *= pBaseRed; + // c3r *= pBaseRed; + // c4r *= pBaseRed; + // c1g *= pBaseGreen; + // c2g *= pBaseGreen; + // c3g *= pBaseGreen; + // c4g *= pBaseGreen; + // c1b *= pBaseBlue; + // c2b *= pBaseBlue; + // c3b *= pBaseBlue; + // c4b *= pBaseBlue; + // renderEast( tt, ( float )pX, ( float )pY, ( float )pZ, + // getGrassSideTextureOverlay() ); + // } + // } + // applyAmbienceOcclusion = false; + // + return true; } // 4J - brought forward from 1.8.2 -int TileRenderer_SPU::blend( int a, int b, int c, int def ) -{ - if ( a == 0 ) a = def; - if ( b == 0 ) b = def; - if ( c == 0 ) c = def; - return ( ( a + b + c + def ) >> 2 ) & 0xff00ff; +int TileRenderer_SPU::blend(int a, int b, int c, int def) { + if (a == 0) a = def; + if (b == 0) b = def; + if (c == 0) c = def; + return ((a + b + c + def) >> 2) & 0xff00ff; } -int TileRenderer_SPU::blend(int a, int b, int c, int d, float fa, float fb, float fc, float fd) -{ - - int top = (int) ((float) ((a >> 16) & 0xff) * fa + (float) ((b >> 16) & 0xff) * fb + (float) ((c >> 16) & 0xff) * fc + (float) ((d >> 16) & 0xff) * fd) & 0xff; - int bottom = (int) ((float) (a & 0xff) * fa + (float) (b & 0xff) * fb + (float) (c & 0xff) * fc + (float) (d & 0xff) * fd) & 0xff; - return (top << 16) | bottom; +int TileRenderer_SPU::blend(int a, int b, int c, int d, float fa, float fb, + float fc, float fd) { + int top = + (int)((float)((a >> 16) & 0xff) * fa + (float)((b >> 16) & 0xff) * fb + + (float)((c >> 16) & 0xff) * fc + (float)((d >> 16) & 0xff) * fd) & + 0xff; + int bottom = (int)((float)(a & 0xff) * fa + (float)(b & 0xff) * fb + + (float)(c & 0xff) * fc + (float)(d & 0xff) * fd) & + 0xff; + return (top << 16) | bottom; } -bool TileRenderer_SPU::tesselateBlockInWorld( Tile_SPU* tt, int x, int y, int z, float r, float g, float b ) -{ - applyAmbienceOcclusion = false; +bool TileRenderer_SPU::tesselateBlockInWorld(Tile_SPU* tt, int x, int y, int z, + float r, float g, float b) { + applyAmbienceOcclusion = false; - Tesselator_SPU* t = getTesselator(); + Tesselator_SPU* t = getTesselator(); - bool changed = false; - float c10 = 0.5f; - float c11 = 1; - float c2 = 0.8f; - float c3 = 0.6f; + bool changed = false; + float c10 = 0.5f; + float c11 = 1; + float c2 = 0.8f; + float c3 = 0.6f; - float r11 = c11 * r; - float g11 = c11 * g; - float b11 = c11 * b; + float r11 = c11 * r; + float g11 = c11 * g; + float b11 = c11 * b; - float r10 = c10; - float r2 = c2; - float r3 = c3; + float r10 = c10; + float r2 = c2; + float r3 = c3; - float g10 = c10; - float g2 = c2; - float g3 = c3; + float g10 = c10; + float g2 = c2; + float g3 = c3; - float b10 = c10; - float b2 = c2; - float b3 = c3; + float b10 = c10; + float b2 = c2; + float b3 = c3; - if ( tt->id != Tile_SPU::grass_Id ) - { - r10 *= r; - r2 *= r; - r3 *= r; + if (tt->id != Tile_SPU::grass_Id) { + r10 *= r; + r2 *= r; + r3 *= r; - g10 *= g; - g2 *= g; - g3 *= g; + g10 *= g; + g2 *= g; + g3 *= g; - b10 *= b; - b2 *= b; - b3 *= b; - } + b10 *= b; + b2 *= b; + b3 *= b; + } - int centerColor = 0; - float centerBrightness = 0.0f; - if ( SharedConstants::TEXTURE_LIGHTING ) - { - centerColor = tt->getLightColor( level, x, y, z ); - } - else - { - centerBrightness = tt->getBrightness( level, x, y, z ); - } + int centerColor = 0; + float centerBrightness = 0.0f; + if (SharedConstants::TEXTURE_LIGHTING) { + centerColor = tt->getLightColor(level, x, y, z); + } else { + centerBrightness = tt->getBrightness(level, x, y, z); + } - if ( noCulling || tt->shouldRenderFace( level, x, y - 1, z, Facing::DOWN ) ) - { - if ( SharedConstants::TEXTURE_LIGHTING ) - { - t->tex2( tileShapeY0 > 0 ? centerColor : tt->getLightColor( level, x, y - 1, z ) ); - t->color( r10, g10, b10 ); - } - else - { - float br = tt->getBrightness( level, x, y - 1, z ); - t->color( r10 * br, g10 * br, b10 * br ); - } - renderFaceDown( tt, x, y, z, getTexture(tt, level, x, y, z, 0 ) ); - changed = true; - } + if (noCulling || tt->shouldRenderFace(level, x, y - 1, z, Facing::DOWN)) { + if (SharedConstants::TEXTURE_LIGHTING) { + t->tex2(tileShapeY0 > 0 ? centerColor + : tt->getLightColor(level, x, y - 1, z)); + t->color(r10, g10, b10); + } else { + float br = tt->getBrightness(level, x, y - 1, z); + t->color(r10 * br, g10 * br, b10 * br); + } + renderFaceDown(tt, x, y, z, getTexture(tt, level, x, y, z, 0)); + changed = true; + } - if ( noCulling || tt->shouldRenderFace( level, x, y + 1, z, Facing::UP ) ) - { - if ( SharedConstants::TEXTURE_LIGHTING ) - { - t->tex2( tileShapeY1 < 1 ? centerColor : tt->getLightColor( level, x, y + 1, z ) ); - t->color( r11, g11, b11 ); - } - else - { - float br = tt->getBrightness( level, x, y + 1, z ); - // spu_print("need to add material settings\n"); -// if ( tileShapeY1 != 1 && !tt->material->isLiquid() ) br = centerBrightness; - t->color( r11 * br, g11 * br, b11 * br ); - } - renderFaceUp( tt, x, y, z, getTexture(tt, level, x, y, z, 1 ) ); - changed = true; - } + if (noCulling || tt->shouldRenderFace(level, x, y + 1, z, Facing::UP)) { + if (SharedConstants::TEXTURE_LIGHTING) { + t->tex2(tileShapeY1 < 1 ? centerColor + : tt->getLightColor(level, x, y + 1, z)); + t->color(r11, g11, b11); + } else { + float br = tt->getBrightness(level, x, y + 1, z); + // spu_print("need to add material settings\n"); + // if ( tileShapeY1 != 1 && + //!tt->material->isLiquid() ) br = centerBrightness; + t->color(r11 * br, g11 * br, b11 * br); + } + renderFaceUp(tt, x, y, z, getTexture(tt, level, x, y, z, 1)); + changed = true; + } - if ( noCulling || tt->shouldRenderFace( level, x, y, z - 1, Facing::NORTH ) ) - { - if ( SharedConstants::TEXTURE_LIGHTING ) - { - t->tex2( tileShapeZ0 > 0 ? centerColor : tt->getLightColor( level, x, y, z - 1 ) ); - t->color( r2, g2, b2 ); - } - else - { - float br = tt->getBrightness( level, x, y, z - 1 ); - if ( tileShapeZ0 > 0 ) br = centerBrightness; - t->color( r2 * br, g2 * br, b2 * br ); - } + if (noCulling || tt->shouldRenderFace(level, x, y, z - 1, Facing::NORTH)) { + if (SharedConstants::TEXTURE_LIGHTING) { + t->tex2(tileShapeZ0 > 0 ? centerColor + : tt->getLightColor(level, x, y, z - 1)); + t->color(r2, g2, b2); + } else { + float br = tt->getBrightness(level, x, y, z - 1); + if (tileShapeZ0 > 0) br = centerBrightness; + t->color(r2 * br, g2 * br, b2 * br); + } - Icon_SPU *tex = getTexture(tt, level, x, y, z, 2); - renderNorth( tt, x, y, z, tex ); + Icon_SPU* tex = getTexture(tt, level, x, y, z, 2); + renderNorth(tt, x, y, z, tex); - if ( fancy && (tex == &Tile_SPU::ms_pTileData->iconData[Tile_SPU::grass_Id] && !hasFixedTexture() )) - { - t->color( r2 * r, g2 * g, b2 * b ); - renderNorth( tt, x, y, z, GrassTile_SPU::getSideTextureOverlay() ); - } - changed = true; - } + if (fancy && + (tex == &Tile_SPU::ms_pTileData->iconData[Tile_SPU::grass_Id] && + !hasFixedTexture())) { + t->color(r2 * r, g2 * g, b2 * b); + renderNorth(tt, x, y, z, GrassTile_SPU::getSideTextureOverlay()); + } + changed = true; + } - if ( noCulling || tt->shouldRenderFace( level, x, y, z + 1, Facing::SOUTH ) ) - { - if ( SharedConstants::TEXTURE_LIGHTING ) - { - t->tex2( tileShapeZ1 < 1 ? centerColor : tt->getLightColor( level, x, y, z + 1 ) ); - t->color( r2, g2, b2 ); - } - else - { - float br = tt->getBrightness( level, x, y, z + 1 ); - if ( tileShapeZ1 < 1 ) br = centerBrightness; - t->color( r2 * br, g2 * br, b2 * br ); - } - Icon_SPU *tex = getTexture(tt, level, x, y, z, 3); - renderSouth( tt, x, y, z, tex ); + if (noCulling || tt->shouldRenderFace(level, x, y, z + 1, Facing::SOUTH)) { + if (SharedConstants::TEXTURE_LIGHTING) { + t->tex2(tileShapeZ1 < 1 ? centerColor + : tt->getLightColor(level, x, y, z + 1)); + t->color(r2, g2, b2); + } else { + float br = tt->getBrightness(level, x, y, z + 1); + if (tileShapeZ1 < 1) br = centerBrightness; + t->color(r2 * br, g2 * br, b2 * br); + } + Icon_SPU* tex = getTexture(tt, level, x, y, z, 3); + renderSouth(tt, x, y, z, tex); - if ( fancy && (tex == &Tile_SPU::ms_pTileData->iconData[Tile_SPU::grass_Id] && !hasFixedTexture() )) - { - t->color( r2 * r, g2 * g, b2 * b ); - renderSouth( tt, x, y, z, GrassTile_SPU::getSideTextureOverlay() ); - } - changed = true; - } + if (fancy && + (tex == &Tile_SPU::ms_pTileData->iconData[Tile_SPU::grass_Id] && + !hasFixedTexture())) { + t->color(r2 * r, g2 * g, b2 * b); + renderSouth(tt, x, y, z, GrassTile_SPU::getSideTextureOverlay()); + } + changed = true; + } - if ( noCulling || tt->shouldRenderFace( level, x - 1, y, z, Facing::WEST ) ) - { - if ( SharedConstants::TEXTURE_LIGHTING ) - { - t->tex2( tileShapeX0 > 0 ? centerColor : tt->getLightColor( level, x - 1, y, z ) ); - t->color( r3, g3, b3 ); - } - else - { - float br = tt->getBrightness( level, x - 1, y, z ); - if ( tileShapeX0 > 0 ) br = centerBrightness; - t->color( r3 * br, g3 * br, b3 * br ); - } - Icon_SPU *tex = getTexture(tt, level, x, y, z, 4); - renderWest( tt, x, y, z, tex ); + if (noCulling || tt->shouldRenderFace(level, x - 1, y, z, Facing::WEST)) { + if (SharedConstants::TEXTURE_LIGHTING) { + t->tex2(tileShapeX0 > 0 ? centerColor + : tt->getLightColor(level, x - 1, y, z)); + t->color(r3, g3, b3); + } else { + float br = tt->getBrightness(level, x - 1, y, z); + if (tileShapeX0 > 0) br = centerBrightness; + t->color(r3 * br, g3 * br, b3 * br); + } + Icon_SPU* tex = getTexture(tt, level, x, y, z, 4); + renderWest(tt, x, y, z, tex); - if ( fancy && (tex == &Tile_SPU::ms_pTileData->iconData[Tile_SPU::grass_Id] && !hasFixedTexture() )) - { - t->color( r3 * r, g3 * g, b3 * b ); - renderWest( tt, x, y, z, GrassTile_SPU::getSideTextureOverlay() ); - } - changed = true; - } + if (fancy && + (tex == &Tile_SPU::ms_pTileData->iconData[Tile_SPU::grass_Id] && + !hasFixedTexture())) { + t->color(r3 * r, g3 * g, b3 * b); + renderWest(tt, x, y, z, GrassTile_SPU::getSideTextureOverlay()); + } + changed = true; + } - if ( noCulling || tt->shouldRenderFace( level, x + 1, y, z, Facing::EAST ) ) - { - if ( SharedConstants::TEXTURE_LIGHTING ) - { - t->tex2( tileShapeX1 < 1 ? centerColor : tt->getLightColor( level, x + 1, y, z ) ); - t->color( r3, g3, b3 ); - } - else - { - float br = tt->getBrightness( level, x + 1, y, z ); - if ( tileShapeX1 < 1 ) br = centerBrightness; - t->color( r3 * br, g3 * br, b3 * br ); - } - Icon_SPU *tex = getTexture(tt, level, x, y, z, 5); - renderEast( tt, x, y, z, tex ); + if (noCulling || tt->shouldRenderFace(level, x + 1, y, z, Facing::EAST)) { + if (SharedConstants::TEXTURE_LIGHTING) { + t->tex2(tileShapeX1 < 1 ? centerColor + : tt->getLightColor(level, x + 1, y, z)); + t->color(r3, g3, b3); + } else { + float br = tt->getBrightness(level, x + 1, y, z); + if (tileShapeX1 < 1) br = centerBrightness; + t->color(r3 * br, g3 * br, b3 * br); + } + Icon_SPU* tex = getTexture(tt, level, x, y, z, 5); + renderEast(tt, x, y, z, tex); - if ( fancy && (tex == &Tile_SPU::ms_pTileData->iconData[Tile_SPU::grass_Id] && !hasFixedTexture() )) - { - t->color( r3 * r, g3 * g, b3 * b ); - renderEast( tt, x, y, z, GrassTile_SPU::getSideTextureOverlay() ); - } - changed = true; - } - - return changed; + if (fancy && + (tex == &Tile_SPU::ms_pTileData->iconData[Tile_SPU::grass_Id] && + !hasFixedTexture())) { + t->color(r3 * r, g3 * g, b3 * b); + renderEast(tt, x, y, z, GrassTile_SPU::getSideTextureOverlay()); + } + changed = true; + } + return changed; } -bool TileRenderer_SPU::tesselateCactusInWorld( Tile_SPU* tt, int x, int y, int z ) -{ - int col = tt->getColor( level, x, y, z ); - float r = ( ( col >> 16 ) & 0xff ) / 255.0f; - float g = ( ( col >> 8 ) & 0xff ) / 255.0f; - float b = ( ( col )& 0xff ) / 255.0f; +bool TileRenderer_SPU::tesselateCactusInWorld(Tile_SPU* tt, int x, int y, + int z) { + int col = tt->getColor(level, x, y, z); + float r = ((col >> 16) & 0xff) / 255.0f; + float g = ((col >> 8) & 0xff) / 255.0f; + float b = ((col) & 0xff) / 255.0f; - if ( isAnaglyph3d() ) - { - float cr = ( r * 30 + g * 59 + b * 11 ) / 100; - float cg = ( r * 30 + g * 70 ) / ( 100 ); - float cb = ( r * 30 + b * 70 ) / ( 100 ); + if (isAnaglyph3d()) { + float cr = (r * 30 + g * 59 + b * 11) / 100; + float cg = (r * 30 + g * 70) / (100); + float cb = (r * 30 + b * 70) / (100); - r = cr; - g = cg; - b = cb; - } - return tesselateCactusInWorld( tt, x, y, z, r, g, b ); + r = cr; + g = cg; + b = cb; + } + return tesselateCactusInWorld(tt, x, y, z, r, g, b); } -bool TileRenderer_SPU::tesselateCactusInWorld( Tile_SPU* tt, int x, int y, int z, float r, float g, float b ) -{ - Tesselator_SPU* t = getTesselator(); +bool TileRenderer_SPU::tesselateCactusInWorld(Tile_SPU* tt, int x, int y, int z, + float r, float g, float b) { + Tesselator_SPU* t = getTesselator(); - bool changed = false; - float c10 = 0.5f; - float c11 = 1; - float c2 = 0.8f; - float c3 = 0.6f; + bool changed = false; + float c10 = 0.5f; + float c11 = 1; + float c2 = 0.8f; + float c3 = 0.6f; - float r10 = c10 * r; - float r11 = c11 * r; - float r2 = c2 * r; - float r3 = c3 * r; + float r10 = c10 * r; + float r11 = c11 * r; + float r2 = c2 * r; + float r3 = c3 * r; - float g10 = c10 * g; - float g11 = c11 * g; - float g2 = c2 * g; - float g3 = c3 * g; + float g10 = c10 * g; + float g11 = c11 * g; + float g2 = c2 * g; + float g3 = c3 * g; - float b10 = c10 * b; - float b11 = c11 * b; - float b2 = c2 * b; - float b3 = c3 * b; + float b10 = c10 * b; + float b11 = c11 * b; + float b2 = c2 * b; + float b3 = c3 * b; - float s = 1 / 16.0f; + float s = 1 / 16.0f; - float centerBrightness = 0.0f; - int centerColor = 0; - if ( SharedConstants::TEXTURE_LIGHTING ) - { - centerColor = tt->getLightColor( level, x, y, z ); - } - else - { - centerBrightness = tt->getBrightness( level, x, y, z ); - } + float centerBrightness = 0.0f; + int centerColor = 0; + if (SharedConstants::TEXTURE_LIGHTING) { + centerColor = tt->getLightColor(level, x, y, z); + } else { + centerBrightness = tt->getBrightness(level, x, y, z); + } - if ( noCulling || tt->shouldRenderFace( level, x, y - 1, z, 0 ) ) - { - if ( SharedConstants::TEXTURE_LIGHTING ) - { - t->tex2( tileShapeY0 > 0 ? centerColor : tt->getLightColor( level, x, y - 1, z ) ); - t->color( r10, g10, b10 ); - } - else - { - float br = tt->getBrightness( level, x, y - 1, z ); - t->color( r10 * br, g10 * br, b10 * br ); - } - renderFaceDown( tt, x, y, z, getTexture( tt, level, x, y, z, 0 ) ); - changed = true; - } + if (noCulling || tt->shouldRenderFace(level, x, y - 1, z, 0)) { + if (SharedConstants::TEXTURE_LIGHTING) { + t->tex2(tileShapeY0 > 0 ? centerColor + : tt->getLightColor(level, x, y - 1, z)); + t->color(r10, g10, b10); + } else { + float br = tt->getBrightness(level, x, y - 1, z); + t->color(r10 * br, g10 * br, b10 * br); + } + renderFaceDown(tt, x, y, z, getTexture(tt, level, x, y, z, 0)); + changed = true; + } - if ( noCulling || tt->shouldRenderFace( level, x, y + 1, z, 1 ) ) - { - if ( SharedConstants::TEXTURE_LIGHTING ) - { - t->tex2( tileShapeY1 < 1 ? centerColor : tt->getLightColor( level, x, y + 1, z ) ); - t->color( r11, g11, b11 ); - } - else - { - float br = tt->getBrightness( level, x, y + 1, z ); - if ( tileShapeY1 != 1 && !tt->getMaterial()->isLiquid() ) br = centerBrightness; - t->color( r11 * br, g11 * br, b11 * br ); - } - renderFaceUp( tt, x, y, z, getTexture( tt, level, x, y, z, 1 ) ); - changed = true; - } + if (noCulling || tt->shouldRenderFace(level, x, y + 1, z, 1)) { + if (SharedConstants::TEXTURE_LIGHTING) { + t->tex2(tileShapeY1 < 1 ? centerColor + : tt->getLightColor(level, x, y + 1, z)); + t->color(r11, g11, b11); + } else { + float br = tt->getBrightness(level, x, y + 1, z); + if (tileShapeY1 != 1 && !tt->getMaterial()->isLiquid()) + br = centerBrightness; + t->color(r11 * br, g11 * br, b11 * br); + } + renderFaceUp(tt, x, y, z, getTexture(tt, level, x, y, z, 1)); + changed = true; + } - if ( noCulling || tt->shouldRenderFace( level, x, y, z - 1, 2 ) ) - { - if ( SharedConstants::TEXTURE_LIGHTING ) - { - t->tex2( tileShapeZ0 > 0 ? centerColor : tt->getLightColor( level, x, y, z - 1 ) ); - t->color( r2, g2, b2 ); - } - else - { - float br = tt->getBrightness( level, x, y, z - 1 ); - if ( tileShapeZ0 > 0 ) br = centerBrightness; - t->color( r2 * br, g2 * br, b2 * br ); - } - t->addOffset( 0, 0, s ); - renderNorth( tt, x, y, z, getTexture(tt, level, x, y, z, 2 ) ); - t->addOffset( 0, 0, -s ); - changed = true; - } + if (noCulling || tt->shouldRenderFace(level, x, y, z - 1, 2)) { + if (SharedConstants::TEXTURE_LIGHTING) { + t->tex2(tileShapeZ0 > 0 ? centerColor + : tt->getLightColor(level, x, y, z - 1)); + t->color(r2, g2, b2); + } else { + float br = tt->getBrightness(level, x, y, z - 1); + if (tileShapeZ0 > 0) br = centerBrightness; + t->color(r2 * br, g2 * br, b2 * br); + } + t->addOffset(0, 0, s); + renderNorth(tt, x, y, z, getTexture(tt, level, x, y, z, 2)); + t->addOffset(0, 0, -s); + changed = true; + } - if ( noCulling || tt->shouldRenderFace( level, x, y, z + 1, 3 ) ) - { - if ( SharedConstants::TEXTURE_LIGHTING ) - { - t->tex2( tileShapeZ1 < 1 ? centerColor : tt->getLightColor( level, x, y, z + 1 ) ); - t->color( r2, g2, b2 ); - } - else - { - float br = tt->getBrightness( level, x, y, z + 1 ); - if ( tileShapeZ1 < 1 ) br = centerBrightness; - t->color( r2 * br, g2 * br, b2 * br ); - } + if (noCulling || tt->shouldRenderFace(level, x, y, z + 1, 3)) { + if (SharedConstants::TEXTURE_LIGHTING) { + t->tex2(tileShapeZ1 < 1 ? centerColor + : tt->getLightColor(level, x, y, z + 1)); + t->color(r2, g2, b2); + } else { + float br = tt->getBrightness(level, x, y, z + 1); + if (tileShapeZ1 < 1) br = centerBrightness; + t->color(r2 * br, g2 * br, b2 * br); + } - t->addOffset( 0, 0, -s ); - renderSouth( tt, x, y, z, getTexture(tt, level, x, y, z, 3 ) ); - t->addOffset( 0, 0, s ); - changed = true; - } + t->addOffset(0, 0, -s); + renderSouth(tt, x, y, z, getTexture(tt, level, x, y, z, 3)); + t->addOffset(0, 0, s); + changed = true; + } - if ( noCulling || tt->shouldRenderFace( level, x - 1, y, z, 4 ) ) - { - if ( SharedConstants::TEXTURE_LIGHTING ) - { - t->tex2( tileShapeX0 > 0 ? centerColor : tt->getLightColor( level, x - 1, y, z ) ); - t->color( r3, g3, b3 ); - } - else - { - float br = tt->getBrightness( level, x - 1, y, z ); - if ( tileShapeX0 > 0 ) br = centerBrightness; - t->color( r3 * br, g3 * br, b3 * br ); - } - t->addOffset( s, 0, 0 ); - renderWest( tt, x, y, z, getTexture(tt, level, x, y, z, 4 ) ); - t->addOffset( -s, 0, 0 ); - changed = true; - } + if (noCulling || tt->shouldRenderFace(level, x - 1, y, z, 4)) { + if (SharedConstants::TEXTURE_LIGHTING) { + t->tex2(tileShapeX0 > 0 ? centerColor + : tt->getLightColor(level, x - 1, y, z)); + t->color(r3, g3, b3); + } else { + float br = tt->getBrightness(level, x - 1, y, z); + if (tileShapeX0 > 0) br = centerBrightness; + t->color(r3 * br, g3 * br, b3 * br); + } + t->addOffset(s, 0, 0); + renderWest(tt, x, y, z, getTexture(tt, level, x, y, z, 4)); + t->addOffset(-s, 0, 0); + changed = true; + } - if ( noCulling || tt->shouldRenderFace( level, x + 1, y, z, 5 ) ) - { - if ( SharedConstants::TEXTURE_LIGHTING ) - { - t->tex2( tileShapeX1 < 1 ? centerColor : tt->getLightColor( level, x + 1, y, z ) ); - t->color( r3, g3, b3 ); - } - else - { - float br = tt->getBrightness( level, x + 1, y, z ); - if ( tileShapeX1 < 1 ) br = centerBrightness; - t->color( r3 * br, g3 * br, b3 * br ); - } - t->addOffset( -s, 0, 0 ); - renderEast( tt, x, y, z, getTexture(tt, level, x, y, z, 5 ) ); - t->addOffset( s, 0, 0 ); - changed = true; - } + if (noCulling || tt->shouldRenderFace(level, x + 1, y, z, 5)) { + if (SharedConstants::TEXTURE_LIGHTING) { + t->tex2(tileShapeX1 < 1 ? centerColor + : tt->getLightColor(level, x + 1, y, z)); + t->color(r3, g3, b3); + } else { + float br = tt->getBrightness(level, x + 1, y, z); + if (tileShapeX1 < 1) br = centerBrightness; + t->color(r3 * br, g3 * br, b3 * br); + } + t->addOffset(-s, 0, 0); + renderEast(tt, x, y, z, getTexture(tt, level, x, y, z, 5)); + t->addOffset(s, 0, 0); + changed = true; + } - return changed; + return changed; } -bool TileRenderer_SPU::tesselateFenceInWorld( FenceTile_SPU* tt, int x, int y, int z ) -{ -// #ifdef DISABLE_TESS_FUNCS - bool changed = false; +bool TileRenderer_SPU::tesselateFenceInWorld(FenceTile_SPU* tt, int x, int y, + int z) { + // #ifdef DISABLE_TESS_FUNCS + bool changed = false; - float a = 6 / 16.0f; - float b = 10 / 16.0f; -// EnterCriticalSection( &Tile_SPU::m_csShape ); - setShape( a, 0, a, b, 1, b ); - tesselateBlockInWorld( tt, x, y, z ); - changed = true; + float a = 6 / 16.0f; + float b = 10 / 16.0f; + // EnterCriticalSection( &Tile_SPU::m_csShape ); + setShape(a, 0, a, b, 1, b); + tesselateBlockInWorld(tt, x, y, z); + changed = true; - bool vertical = false; - bool horizontal = false; + bool vertical = false; + bool horizontal = false; - if (tt->connectsTo(level, x - 1, y, z) || tt->connectsTo(level, x + 1, y, z)) vertical = true; - if (tt->connectsTo(level, x, y, z - 1) || tt->connectsTo(level, x, y, z + 1)) horizontal = true; + if (tt->connectsTo(level, x - 1, y, z) || + tt->connectsTo(level, x + 1, y, z)) + vertical = true; + if (tt->connectsTo(level, x, y, z - 1) || + tt->connectsTo(level, x, y, z + 1)) + horizontal = true; - bool l = tt->connectsTo(level, x - 1, y, z); - bool r = tt->connectsTo(level, x + 1, y, z); - bool u = tt->connectsTo(level, x, y, z - 1); - bool d = tt->connectsTo(level, x, y, z + 1); + bool l = tt->connectsTo(level, x - 1, y, z); + bool r = tt->connectsTo(level, x + 1, y, z); + bool u = tt->connectsTo(level, x, y, z - 1); + bool d = tt->connectsTo(level, x, y, z + 1); - if ( !vertical && !horizontal ) vertical = true; + if (!vertical && !horizontal) vertical = true; - a = 7 / 16.0f; - b = 9 / 16.0f; - float h0 = 12 / 16.0f; - float h1 = 15 / 16.0f; + a = 7 / 16.0f; + b = 9 / 16.0f; + float h0 = 12 / 16.0f; + float h1 = 15 / 16.0f; - float x0 = l ? 0 : a; - float x1 = r ? 1 : b; - float z0 = u ? 0 : a; - float z1 = d ? 1 : b; - if ( vertical ) - { - setShape( x0, h0, a, x1, h1, b ); - tesselateBlockInWorld( tt, x, y, z ); - changed = true; - } - if ( horizontal ) - { - setShape( a, h0, z0, b, h1, z1 ); - tesselateBlockInWorld( tt, x, y, z ); - changed = true; - } + float x0 = l ? 0 : a; + float x1 = r ? 1 : b; + float z0 = u ? 0 : a; + float z1 = d ? 1 : b; + if (vertical) { + setShape(x0, h0, a, x1, h1, b); + tesselateBlockInWorld(tt, x, y, z); + changed = true; + } + if (horizontal) { + setShape(a, h0, z0, b, h1, z1); + tesselateBlockInWorld(tt, x, y, z); + changed = true; + } - h0 = 6 / 16.0f; - h1 = 9 / 16.0f; - if ( vertical ) - { - setShape( x0, h0, a, x1, h1, b ); - tesselateBlockInWorld( tt, x, y, z ); - changed = true; - } - if ( horizontal ) - { - setShape( a, h0, z0, b, h1, z1 ); - tesselateBlockInWorld( tt, x, y, z ); - changed = true; - } + h0 = 6 / 16.0f; + h1 = 9 / 16.0f; + if (vertical) { + setShape(x0, h0, a, x1, h1, b); + tesselateBlockInWorld(tt, x, y, z); + changed = true; + } + if (horizontal) { + setShape(a, h0, z0, b, h1, z1); + tesselateBlockInWorld(tt, x, y, z); + changed = true; + } - tt->updateShape(level, x, y, z); -// LeaveCriticalSection( &Tile_SPU::m_csShape ); - return changed; -// #endif // #ifdef DISABLE_TESS_FUNCS - return false; + tt->updateShape(level, x, y, z); + // LeaveCriticalSection( &Tile_SPU::m_csShape ); + return changed; + // #endif // #ifdef DISABLE_TESS_FUNCS + return false; } -bool TileRenderer_SPU::tesselateWallInWorld(WallTile_SPU *tt, int x, int y, int z) -{ - bool w = tt->connectsTo(level, x - 1, y, z); - bool e = tt->connectsTo(level, x + 1, y, z); - bool n = tt->connectsTo(level, x, y, z - 1); - bool s = tt->connectsTo(level, x, y, z + 1); +bool TileRenderer_SPU::tesselateWallInWorld(WallTile_SPU* tt, int x, int y, + int z) { + bool w = tt->connectsTo(level, x - 1, y, z); + bool e = tt->connectsTo(level, x + 1, y, z); + bool n = tt->connectsTo(level, x, y, z - 1); + bool s = tt->connectsTo(level, x, y, z + 1); - bool vertical = (n && s && !w && !e); - bool horizontal = (!n && !s && w && e); - bool emptyAbove = level->isEmptyTile(x, y + 1, z); + bool vertical = (n && s && !w && !e); + bool horizontal = (!n && !s && w && e); + bool emptyAbove = level->isEmptyTile(x, y + 1, z); - if ((!vertical && !horizontal) || !emptyAbove) - { - // center post - setShape(.5f - WallTile_SPU::POST_WIDTH, 0, .5f - WallTile_SPU::POST_WIDTH, .5f + WallTile_SPU::POST_WIDTH, WallTile_SPU::POST_HEIGHT, .5f + WallTile_SPU::POST_WIDTH); - tesselateBlockInWorld(tt, x, y, z); + if ((!vertical && !horizontal) || !emptyAbove) { + // center post + setShape(.5f - WallTile_SPU::POST_WIDTH, 0, + .5f - WallTile_SPU::POST_WIDTH, .5f + WallTile_SPU::POST_WIDTH, + WallTile_SPU::POST_HEIGHT, .5f + WallTile_SPU::POST_WIDTH); + tesselateBlockInWorld(tt, x, y, z); - if (w) - { - setShape(0, 0, .5f - WallTile_SPU::WALL_WIDTH, .5f - WallTile_SPU::POST_WIDTH, WallTile_SPU::WALL_HEIGHT, .5f + WallTile_SPU::WALL_WIDTH); - tesselateBlockInWorld(tt, x, y, z); - } - if (e) - { - setShape(.5f + WallTile_SPU::POST_WIDTH, 0, .5f - WallTile_SPU::WALL_WIDTH, 1, WallTile_SPU::WALL_HEIGHT, .5f + WallTile_SPU::WALL_WIDTH); - tesselateBlockInWorld(tt, x, y, z); - } - if (n) - { - setShape(.5f - WallTile_SPU::WALL_WIDTH, 0, 0, .5f + WallTile_SPU::WALL_WIDTH, WallTile_SPU::WALL_HEIGHT, .5f - WallTile_SPU::POST_WIDTH); - tesselateBlockInWorld(tt, x, y, z); - } - if (s) - { - setShape(.5f - WallTile_SPU::WALL_WIDTH, 0, .5f + WallTile_SPU::POST_WIDTH, .5f + WallTile_SPU::WALL_WIDTH, WallTile_SPU::WALL_HEIGHT, 1); - tesselateBlockInWorld(tt, x, y, z); - } - } - else if (vertical) - { - // north-south wall - setShape(.5f - WallTile_SPU::WALL_WIDTH, 0, 0, .5f + WallTile_SPU::WALL_WIDTH, WallTile_SPU::WALL_HEIGHT, 1); - tesselateBlockInWorld(tt, x, y, z); - } - else - { - // west-east wall - setShape(0, 0, .5f - WallTile_SPU::WALL_WIDTH, 1, WallTile_SPU::WALL_HEIGHT, .5f + WallTile_SPU::WALL_WIDTH); - tesselateBlockInWorld(tt, x, y, z); - } + if (w) { + setShape(0, 0, .5f - WallTile_SPU::WALL_WIDTH, + .5f - WallTile_SPU::POST_WIDTH, WallTile_SPU::WALL_HEIGHT, + .5f + WallTile_SPU::WALL_WIDTH); + tesselateBlockInWorld(tt, x, y, z); + } + if (e) { + setShape(.5f + WallTile_SPU::POST_WIDTH, 0, + .5f - WallTile_SPU::WALL_WIDTH, 1, + WallTile_SPU::WALL_HEIGHT, .5f + WallTile_SPU::WALL_WIDTH); + tesselateBlockInWorld(tt, x, y, z); + } + if (n) { + setShape(.5f - WallTile_SPU::WALL_WIDTH, 0, 0, + .5f + WallTile_SPU::WALL_WIDTH, WallTile_SPU::WALL_HEIGHT, + .5f - WallTile_SPU::POST_WIDTH); + tesselateBlockInWorld(tt, x, y, z); + } + if (s) { + setShape(.5f - WallTile_SPU::WALL_WIDTH, 0, + .5f + WallTile_SPU::POST_WIDTH, + .5f + WallTile_SPU::WALL_WIDTH, WallTile_SPU::WALL_HEIGHT, + 1); + tesselateBlockInWorld(tt, x, y, z); + } + } else if (vertical) { + // north-south wall + setShape(.5f - WallTile_SPU::WALL_WIDTH, 0, 0, + .5f + WallTile_SPU::WALL_WIDTH, WallTile_SPU::WALL_HEIGHT, 1); + tesselateBlockInWorld(tt, x, y, z); + } else { + // west-east wall + setShape(0, 0, .5f - WallTile_SPU::WALL_WIDTH, 1, + WallTile_SPU::WALL_HEIGHT, .5f + WallTile_SPU::WALL_WIDTH); + tesselateBlockInWorld(tt, x, y, z); + } - tt->updateShape(level, x, y, z); - return true; + tt->updateShape(level, x, y, z); + return true; } - -bool TileRenderer_SPU::tesselateEggInWorld(EggTile_SPU *tt, int x, int y, int z) -{ - bool changed = false; -// EnterCriticalSection( &Tile_SPU::m_csShape ); +bool TileRenderer_SPU::tesselateEggInWorld(EggTile_SPU* tt, int x, int y, + int z) { + bool changed = false; + // EnterCriticalSection( &Tile_SPU::m_csShape ); int y0 = 0; - for (int i = 0; i < 8; i++) - { + for (int i = 0; i < 8; i++) { int ww = 0; int hh = 1; if (i == 0) ww = 2; if (i == 1) ww = 3; if (i == 2) ww = 4; - if (i == 3) - { + if (i == 3) { ww = 5; hh = 2; } - if (i == 4) - { + if (i == 4) { ww = 6; hh = 3; } - if (i == 5) - { + if (i == 5) { ww = 7; hh = 5; } - if (i == 6) - { + if (i == 6) { ww = 6; hh = 2; } @@ -6539,12 +6513,12 @@ bool TileRenderer_SPU::tesselateEggInWorld(EggTile_SPU *tt, int x, int y, int z) changed = true; setShape(0, 0, 0, 1, 1, 1); -// LeaveCriticalSection( &Tile_SPU::m_csShape ); + // LeaveCriticalSection( &Tile_SPU::m_csShape ); return changed; } -bool TileRenderer_SPU::tesselateFenceGateInWorld(FenceGateTile_SPU *tt, int x, int y, int z) -{ +bool TileRenderer_SPU::tesselateFenceGateInWorld(FenceGateTile_SPU* tt, int x, + int y, int z) { bool changed = true; #ifdef DISABLE_TESS_FUNCS @@ -6559,25 +6533,28 @@ bool TileRenderer_SPU::tesselateFenceGateInWorld(FenceGateTile_SPU *tt, int x, i float h20 = 5 / 16.0f; float h21 = 16 / 16.0f; - //if (((direction == Direction::NORTH || direction == Direction::SOUTH) && level->getTile(x - 1, y, z) == Tile_SPU::cobbleWall_Id && level->getTile(x + 1, y, z) == Tile_SPU::cobbleWall_Id) - // || ((direction == Direction::EAST || direction == Direction::WEST) && level->getTile(x, y, z - 1) == Tile_SPU::cobbleWall_Id && level->getTile(x, y, z + 1) == Tile_SPU::cobbleWall_Id)) - //{ - // h00 -= 3.0f / 16.0f; - // h01 -= 3.0f / 16.0f; - // h10 -= 3.0f / 16.0f; - // h11 -= 3.0f / 16.0f; - // h20 -= 3.0f / 16.0f; - // h21 -= 3.0f / 16.0f; - //} + // if (((direction == Direction::NORTH || direction == Direction::SOUTH) && + // level->getTile(x - 1, y, z) == Tile_SPU::cobbleWall_Id && + // level->getTile(x + 1, y, z) == Tile_SPU::cobbleWall_Id) + // || ((direction == Direction::EAST || direction == Direction::WEST) && + //level->getTile(x, y, z - 1) == Tile_SPU::cobbleWall_Id && + //level->getTile(x, y, z + 1) == Tile_SPU::cobbleWall_Id)) + //{ + // h00 -= 3.0f / 16.0f; + // h01 -= 3.0f / 16.0f; + // h10 -= 3.0f / 16.0f; + // h11 -= 3.0f / 16.0f; + // h20 -= 3.0f / 16.0f; + // h21 -= 3.0f / 16.0f; + // } - noCulling = true; + noCulling = true; -// EnterCriticalSection( &Tile_SPU::m_csShape ); + // EnterCriticalSection( &Tile_SPU::m_csShape ); // edge sticks - if (direction == Direction::EAST || direction == Direction::WEST) - { - upFlip = FLIP_CW; + if (direction == Direction::EAST || direction == Direction::WEST) { + upFlip = FLIP_CW; float x0 = 7 / 16.0f; float x1 = 9 / 16.0f; float z0 = 0 / 16.0f; @@ -6589,10 +6566,8 @@ bool TileRenderer_SPU::tesselateFenceGateInWorld(FenceGateTile_SPU *tt, int x, i z1 = 16 / 16.0f; setShape(x0, h20, z0, x1, h21, z1); tesselateBlockInWorld(tt, x, y, z); - upFlip = FLIP_NONE; - } - else - { + upFlip = FLIP_NONE; + } else { float x0 = 0 / 16.0f; float x1 = 2 / 16.0f; float z0 = 7 / 16.0f; @@ -6605,1031 +6580,1009 @@ bool TileRenderer_SPU::tesselateFenceGateInWorld(FenceGateTile_SPU *tt, int x, i setShape(x0, h20, z0, x1, h21, z1); tesselateBlockInWorld(tt, x, y, z); } - if (isOpen) - { - if (direction == Direction::NORTH || direction == Direction::SOUTH) - { - upFlip = FLIP_CW; - } - if (direction == Direction::EAST) - { + if (isOpen) { + if (direction == Direction::NORTH || direction == Direction::SOUTH) { + upFlip = FLIP_CW; + } + if (direction == Direction::EAST) { + const float z00 = 0 / 16.0f; + const float z01 = 2 / 16.0f; + const float z10 = 14 / 16.0f; + const float z11 = 16 / 16.0f; - const float z00 = 0 / 16.0f; - const float z01 = 2 / 16.0f; - const float z10 = 14 / 16.0f; - const float z11 = 16 / 16.0f; + const float x0 = 9 / 16.0f; + const float x1 = 13 / 16.0f; + const float x2 = 15 / 16.0f; - const float x0 = 9 / 16.0f; - const float x1 = 13 / 16.0f; - const float x2 = 15 / 16.0f; + setShape(x1, h00, z00, x2, h11, z01); + tesselateBlockInWorld(tt, x, y, z); + setShape(x1, h00, z10, x2, h11, z11); + tesselateBlockInWorld(tt, x, y, z); - setShape(x1, h00, z00, x2, h11, z01); - tesselateBlockInWorld(tt, x, y, z); - setShape(x1, h00, z10, x2, h11, z11); - tesselateBlockInWorld(tt, x, y, z); + setShape(x0, h00, z00, x1, h01, z01); + tesselateBlockInWorld(tt, x, y, z); + setShape(x0, h00, z10, x1, h01, z11); + tesselateBlockInWorld(tt, x, y, z); - setShape(x0, h00, z00, x1, h01, z01); - tesselateBlockInWorld(tt, x, y, z); - setShape(x0, h00, z10, x1, h01, z11); - tesselateBlockInWorld(tt, x, y, z); + setShape(x0, h10, z00, x1, h11, z01); + tesselateBlockInWorld(tt, x, y, z); + setShape(x0, h10, z10, x1, h11, z11); + tesselateBlockInWorld(tt, x, y, z); + } else if (direction == Direction::WEST) { + const float z00 = 0 / 16.0f; + const float z01 = 2 / 16.0f; + const float z10 = 14 / 16.0f; + const float z11 = 16 / 16.0f; - setShape(x0, h10, z00, x1, h11, z01); - tesselateBlockInWorld(tt, x, y, z); - setShape(x0, h10, z10, x1, h11, z11); - tesselateBlockInWorld(tt, x, y, z); - } - else if (direction == Direction::WEST) - { - const float z00 = 0 / 16.0f; - const float z01 = 2 / 16.0f; - const float z10 = 14 / 16.0f; - const float z11 = 16 / 16.0f; + const float x0 = 1 / 16.0f; + const float x1 = 3 / 16.0f; + const float x2 = 7 / 16.0f; - const float x0 = 1 / 16.0f; - const float x1 = 3 / 16.0f; - const float x2 = 7 / 16.0f; + setShape(x0, h00, z00, x1, h11, z01); + tesselateBlockInWorld(tt, x, y, z); + setShape(x0, h00, z10, x1, h11, z11); + tesselateBlockInWorld(tt, x, y, z); - setShape(x0, h00, z00, x1, h11, z01); - tesselateBlockInWorld(tt, x, y, z); - setShape(x0, h00, z10, x1, h11, z11); - tesselateBlockInWorld(tt, x, y, z); + setShape(x1, h00, z00, x2, h01, z01); + tesselateBlockInWorld(tt, x, y, z); + setShape(x1, h00, z10, x2, h01, z11); + tesselateBlockInWorld(tt, x, y, z); - setShape(x1, h00, z00, x2, h01, z01); - tesselateBlockInWorld(tt, x, y, z); - setShape(x1, h00, z10, x2, h01, z11); - tesselateBlockInWorld(tt, x, y, z); + setShape(x1, h10, z00, x2, h11, z01); + tesselateBlockInWorld(tt, x, y, z); + setShape(x1, h10, z10, x2, h11, z11); + tesselateBlockInWorld(tt, x, y, z); + } else if (direction == Direction::SOUTH) { + const float x00 = 0 / 16.0f; + const float x01 = 2 / 16.0f; + const float x10 = 14 / 16.0f; + const float x11 = 16 / 16.0f; - setShape(x1, h10, z00, x2, h11, z01); - tesselateBlockInWorld(tt, x, y, z); - setShape(x1, h10, z10, x2, h11, z11); - tesselateBlockInWorld(tt, x, y, z); - } - else if (direction == Direction::SOUTH) - { + const float z0 = 9 / 16.0f; + const float z1 = 13 / 16.0f; + const float z2 = 15 / 16.0f; - const float x00 = 0 / 16.0f; - const float x01 = 2 / 16.0f; - const float x10 = 14 / 16.0f; - const float x11 = 16 / 16.0f; + setShape(x00, h00, z1, x01, h11, z2); + tesselateBlockInWorld(tt, x, y, z); + setShape(x10, h00, z1, x11, h11, z2); + tesselateBlockInWorld(tt, x, y, z); - const float z0 = 9 / 16.0f; - const float z1 = 13 / 16.0f; - const float z2 = 15 / 16.0f; + setShape(x00, h00, z0, x01, h01, z1); + tesselateBlockInWorld(tt, x, y, z); + setShape(x10, h00, z0, x11, h01, z1); + tesselateBlockInWorld(tt, x, y, z); - setShape(x00, h00, z1, x01, h11, z2); - tesselateBlockInWorld(tt, x, y, z); - setShape(x10, h00, z1, x11, h11, z2); - tesselateBlockInWorld(tt, x, y, z); + setShape(x00, h10, z0, x01, h11, z1); + tesselateBlockInWorld(tt, x, y, z); + setShape(x10, h10, z0, x11, h11, z1); + tesselateBlockInWorld(tt, x, y, z); + } else if (direction == Direction::NORTH) { + const float x00 = 0 / 16.0f; + const float x01 = 2 / 16.0f; + const float x10 = 14 / 16.0f; + const float x11 = 16 / 16.0f; - setShape(x00, h00, z0, x01, h01, z1); - tesselateBlockInWorld(tt, x, y, z); - setShape(x10, h00, z0, x11, h01, z1); - tesselateBlockInWorld(tt, x, y, z); + const float z0 = 1 / 16.0f; + const float z1 = 3 / 16.0f; + const float z2 = 7 / 16.0f; - setShape(x00, h10, z0, x01, h11, z1); - tesselateBlockInWorld(tt, x, y, z); - setShape(x10, h10, z0, x11, h11, z1); - tesselateBlockInWorld(tt, x, y, z); - } - else if (direction == Direction::NORTH) - { - const float x00 = 0 / 16.0f; - const float x01 = 2 / 16.0f; - const float x10 = 14 / 16.0f; - const float x11 = 16 / 16.0f; + setShape(x00, h00, z0, x01, h11, z1); + tesselateBlockInWorld(tt, x, y, z); + setShape(x10, h00, z0, x11, h11, z1); + tesselateBlockInWorld(tt, x, y, z); - const float z0 = 1 / 16.0f; - const float z1 = 3 / 16.0f; - const float z2 = 7 / 16.0f; + setShape(x00, h00, z1, x01, h01, z2); + tesselateBlockInWorld(tt, x, y, z); + setShape(x10, h00, z1, x11, h01, z2); + tesselateBlockInWorld(tt, x, y, z); - setShape(x00, h00, z0, x01, h11, z1); - tesselateBlockInWorld(tt, x, y, z); - setShape(x10, h00, z0, x11, h11, z1); - tesselateBlockInWorld(tt, x, y, z); - - setShape(x00, h00, z1, x01, h01, z2); - tesselateBlockInWorld(tt, x, y, z); - setShape(x10, h00, z1, x11, h01, z2); - tesselateBlockInWorld(tt, x, y, z); - - setShape(x00, h10, z1, x01, h11, z2); - tesselateBlockInWorld(tt, x, y, z); - setShape(x10, h10, z1, x11, h11, z2); - tesselateBlockInWorld(tt, x, y, z); - } - } - else - { - if (direction == Direction::EAST || direction == Direction::WEST) - { - upFlip = FLIP_CW; - float x0 = 7 / 16.0f; - float x1 = 9 / 16.0f; - float z0 = 6 / 16.0f; - float z1 = 8 / 16.0f; - setShape(x0, h00, z0, x1, h11, z1); - tesselateBlockInWorld(tt, x, y, z); - z0 = 8 / 16.0f; - z1 = 10 / 16.0f; - setShape(x0, h00, z0, x1, h11, z1); - tesselateBlockInWorld(tt, x, y, z); - z0 = 10 / 16.0f; - z1 = 14 / 16.0f; - setShape(x0, h00, z0, x1, h01, z1); - tesselateBlockInWorld(tt, x, y, z); - setShape(x0, h10, z0, x1, h11, z1); - tesselateBlockInWorld(tt, x, y, z); - z0 = 2 / 16.0f; - z1 = 6 / 16.0f; - setShape(x0, h00, z0, x1, h01, z1); - tesselateBlockInWorld(tt, x, y, z); - setShape(x0, h10, z0, x1, h11, z1); - tesselateBlockInWorld(tt, x, y, z); - } - else - { - float x0 = 6 / 16.0f; - float x1 = 8 / 16.0f; - float z0 = 7 / 16.0f; - float z1 = 9 / 16.0f; - setShape(x0, h00, z0, x1, h11, z1); - tesselateBlockInWorld(tt, x, y, z); - x0 = 8 / 16.0f; - x1 = 10 / 16.0f; - setShape(x0, h00, z0, x1, h11, z1); - tesselateBlockInWorld(tt, x, y, z); - x0 = 10 / 16.0f; - x1 = 14 / 16.0f; - setShape(x0, h00, z0, x1, h01, z1); - tesselateBlockInWorld(tt, x, y, z); - setShape(x0, h10, z0, x1, h11, z1); - tesselateBlockInWorld(tt, x, y, z); - x0 = 2 / 16.0f; - x1 = 6 / 16.0f; - setShape(x0, h00, z0, x1, h01, z1); - tesselateBlockInWorld(tt, x, y, z); - setShape(x0, h10, z0, x1, h11, z1); - tesselateBlockInWorld(tt, x, y, z); - - } - } - noCulling = false; - upFlip = FLIP_NONE; + setShape(x00, h10, z1, x01, h11, z2); + tesselateBlockInWorld(tt, x, y, z); + setShape(x10, h10, z1, x11, h11, z2); + tesselateBlockInWorld(tt, x, y, z); + } + } else { + if (direction == Direction::EAST || direction == Direction::WEST) { + upFlip = FLIP_CW; + float x0 = 7 / 16.0f; + float x1 = 9 / 16.0f; + float z0 = 6 / 16.0f; + float z1 = 8 / 16.0f; + setShape(x0, h00, z0, x1, h11, z1); + tesselateBlockInWorld(tt, x, y, z); + z0 = 8 / 16.0f; + z1 = 10 / 16.0f; + setShape(x0, h00, z0, x1, h11, z1); + tesselateBlockInWorld(tt, x, y, z); + z0 = 10 / 16.0f; + z1 = 14 / 16.0f; + setShape(x0, h00, z0, x1, h01, z1); + tesselateBlockInWorld(tt, x, y, z); + setShape(x0, h10, z0, x1, h11, z1); + tesselateBlockInWorld(tt, x, y, z); + z0 = 2 / 16.0f; + z1 = 6 / 16.0f; + setShape(x0, h00, z0, x1, h01, z1); + tesselateBlockInWorld(tt, x, y, z); + setShape(x0, h10, z0, x1, h11, z1); + tesselateBlockInWorld(tt, x, y, z); + } else { + float x0 = 6 / 16.0f; + float x1 = 8 / 16.0f; + float z0 = 7 / 16.0f; + float z1 = 9 / 16.0f; + setShape(x0, h00, z0, x1, h11, z1); + tesselateBlockInWorld(tt, x, y, z); + x0 = 8 / 16.0f; + x1 = 10 / 16.0f; + setShape(x0, h00, z0, x1, h11, z1); + tesselateBlockInWorld(tt, x, y, z); + x0 = 10 / 16.0f; + x1 = 14 / 16.0f; + setShape(x0, h00, z0, x1, h01, z1); + tesselateBlockInWorld(tt, x, y, z); + setShape(x0, h10, z0, x1, h11, z1); + tesselateBlockInWorld(tt, x, y, z); + x0 = 2 / 16.0f; + x1 = 6 / 16.0f; + setShape(x0, h00, z0, x1, h01, z1); + tesselateBlockInWorld(tt, x, y, z); + setShape(x0, h10, z0, x1, h11, z1); + tesselateBlockInWorld(tt, x, y, z); + } + } + noCulling = false; + upFlip = FLIP_NONE; setShape(0, 0, 0, 1, 1, 1); // LeaveCriticalSection( &Tile_SPU::m_csShape ); -#endif // #ifdef DISABLE_TESS_FUNCS +#endif // #ifdef DISABLE_TESS_FUNCS return changed; } -bool TileRenderer_SPU::tesselateStairsInWorld( StairTile_SPU* tt, int x, int y, int z ) -{ +bool TileRenderer_SPU::tesselateStairsInWorld(StairTile_SPU* tt, int x, int y, + int z) { #ifdef DISABLE_TESS_FUNCS - // EnterCriticalSection( &Tile_SPU::m_csShape ); - tt->setBaseShape(level, x, y, z); - setShape(tt); - tesselateBlockInWorld(tt, x, y, z); + // EnterCriticalSection( &Tile_SPU::m_csShape ); + tt->setBaseShape(level, x, y, z); + setShape(tt); + tesselateBlockInWorld(tt, x, y, z); - bool checkInnerPiece = tt->setStepShape(level, x, y, z); - setShape(tt); - tesselateBlockInWorld(tt, x, y, z); + bool checkInnerPiece = tt->setStepShape(level, x, y, z); + setShape(tt); + tesselateBlockInWorld(tt, x, y, z); - if (checkInnerPiece) - { - if (tt->setInnerPieceShape(level, x, y, z)) - { - setShape(tt); - tesselateBlockInWorld(tt, x, y, z); - } - } + if (checkInnerPiece) { + if (tt->setInnerPieceShape(level, x, y, z)) { + setShape(tt); + tesselateBlockInWorld(tt, x, y, z); + } + } // LeaveCriticalSection( &Tile_SPU::m_csShape ); -#endif // #ifdef DISABLE_TESS_FUNCS - return true; +#endif // #ifdef DISABLE_TESS_FUNCS + return true; } -bool TileRenderer_SPU::tesselateDoorInWorld( Tile_SPU* tt, int x, int y, int z ) -{ - Tesselator_SPU* t = getTesselator(); +bool TileRenderer_SPU::tesselateDoorInWorld(Tile_SPU* tt, int x, int y, int z) { + Tesselator_SPU* t = getTesselator(); - // skip rendering if the other half of the door is missing, - // to avoid rendering doors that are about to be removed - int data = level->getData(x, y, z); - if ((data & DoorTile_SPU::UPPER_BIT) != 0) - { - if (level->getTile(x, y - 1, z) != tt->id) - { - return false; - } - } - else { - if (level->getTile(x, y + 1, z) != tt->id) - { - return false; - } - } + // skip rendering if the other half of the door is missing, + // to avoid rendering doors that are about to be removed + int data = level->getData(x, y, z); + if ((data & DoorTile_SPU::UPPER_BIT) != 0) { + if (level->getTile(x, y - 1, z) != tt->id) { + return false; + } + } else { + if (level->getTile(x, y + 1, z) != tt->id) { + return false; + } + } - bool changed = false; - float c10 = 0.5f; - float c11 = 1; - float c2 = 0.8f; - float c3 = 0.6f; + bool changed = false; + float c10 = 0.5f; + float c11 = 1; + float c2 = 0.8f; + float c3 = 0.6f; - int centerColor = 0; - float centerBrightness = 0.0f; + int centerColor = 0; + float centerBrightness = 0.0f; - if ( SharedConstants::TEXTURE_LIGHTING ) - { - centerColor = tt->getLightColor( level, x, y, z ); - } - else - { - centerBrightness = tt->getBrightness( level, x, y, z ); - } + if (SharedConstants::TEXTURE_LIGHTING) { + centerColor = tt->getLightColor(level, x, y, z); + } else { + centerBrightness = tt->getBrightness(level, x, y, z); + } + if (SharedConstants::TEXTURE_LIGHTING) { + t->tex2(tileShapeY0 > 0 ? centerColor + : tt->getLightColor(level, x, y - 1, z)); + t->color(c10, c10, c10); + } else { + float br = tt->getBrightness(level, x, y - 1, z); + if (tileShapeY0 > 0) br = centerBrightness; + if (level->m_tileData.lightEmission[tt->id] > 0) br = 1.0f; + t->color(c10 * br, c10 * br, c10 * br); + } + renderFaceDown(tt, x, y, z, getTexture(tt, level, x, y, z, 0)); + changed = true; - if ( SharedConstants::TEXTURE_LIGHTING ) - { - t->tex2( tileShapeY0 > 0 ? centerColor : tt->getLightColor( level, x, y - 1, z ) ); - t->color( c10, c10, c10 ); - } - else - { - float br = tt->getBrightness( level, x, y - 1, z ); - if ( tileShapeY0 > 0 ) br = centerBrightness; - if (level->m_tileData.lightEmission[tt->id] > 0 ) br = 1.0f; - t->color( c10 * br, c10 * br, c10 * br ); - } - renderFaceDown( tt, x, y, z, getTexture(tt, level, x, y, z, 0 ) ); - changed = true; + if (SharedConstants::TEXTURE_LIGHTING) { + t->tex2(tileShapeY1 < 1 ? centerColor + : tt->getLightColor(level, x, y + 1, z)); + t->color(c11, c11, c11); + } else { + float br = tt->getBrightness(level, x, y + 1, z); + if (tileShapeY1 < 1) br = centerBrightness; + if (level->m_tileData.lightEmission[tt->id] > 0) br = 1.0f; + t->color(c11 * br, c11 * br, c11 * br); + } + renderFaceUp(tt, x, y, z, getTexture(tt, level, x, y, z, 1)); + changed = true; - if ( SharedConstants::TEXTURE_LIGHTING ) - { - t->tex2( tileShapeY1 < 1 ? centerColor : tt->getLightColor( level, x, y + 1, z ) ); - t->color( c11, c11, c11 ); - } - else - { - float br = tt->getBrightness( level, x, y + 1, z ); - if ( tileShapeY1 < 1 ) br = centerBrightness; - if ( level->m_tileData.lightEmission[tt->id] > 0 ) br = 1.0f; - t->color( c11 * br, c11 * br, c11 * br ); - } - renderFaceUp( tt, x, y, z, getTexture(tt, level, x, y, z, 1 ) ); - changed = true; - - { - if ( SharedConstants::TEXTURE_LIGHTING ) - { - t->tex2( tileShapeZ0 > 0 ? centerColor : tt->getLightColor( level, x, y, z - 1 ) ); - t->color( c2, c2, c2 ); - } - else - { - float br = tt->getBrightness( level, x, y, z - 1 ); - if ( tileShapeZ0 > 0 ) br = centerBrightness; - if ( level->m_tileData.lightEmission[tt->id] > 0 ) br = 1.0f; - t->color( c2 * br, c2 * br, c2 * br ); - } - Icon_SPU *tex = getTexture(tt, level, x, y, z, 2 ); - renderNorth( tt, x, y, z, tex ); - changed = true; - xFlipTexture = false; - } - { - if ( SharedConstants::TEXTURE_LIGHTING ) - { - t->tex2( tileShapeZ1 < 1 ? centerColor : tt->getLightColor( level, x, y, z + 1 ) ); - t->color( c2, c2, c2 ); - } - else - { - float br = tt->getBrightness( level, x, y, z + 1 ); - if ( tileShapeZ1 < 1 ) br = centerBrightness; - if ( level->m_tileData.lightEmission[tt->id] > 0 ) br = 1.0f; - t->color( c2 * br, c2 * br, c2 * br ); - } - Icon_SPU *tex = getTexture( tt, level, x, y, z, 3 ); - renderSouth( tt, x, y, z, tex ); - changed = true; - xFlipTexture = false; - } - { - if ( SharedConstants::TEXTURE_LIGHTING ) - { - t->tex2( tileShapeX0 > 0 ? centerColor : tt->getLightColor( level, x - 1, y, z ) ); - t->color( c3, c3, c3 ); - } - else - { - float br = tt->getBrightness( level, x - 1, y, z ); - if ( tileShapeX0 > 0 ) br = centerBrightness; - if ( level->m_tileData.lightEmission[tt->id] > 0 ) br = 1.0f; - t->color( c3 * br, c3 * br, c3 * br ); - } - Icon_SPU *tex = getTexture(tt, level, x, y, z, 4 ); - renderWest( tt, x, y, z, tex ); - changed = true; - xFlipTexture = false; - } - { - if ( SharedConstants::TEXTURE_LIGHTING ) - { - t->tex2( tileShapeX1 < 1 ? centerColor : tt->getLightColor( level, x + 1, y, z ) ); - t->color( c3, c3, c3 ); - } - else - { - float br = tt->getBrightness( level, x + 1, y, z ); - if ( tileShapeX1 < 1 ) br = centerBrightness; - if ( level->m_tileData.lightEmission[tt->id] > 0 ) br = 1.0f; - t->color( c3 * br, c3 * br, c3 * br ); - } - Icon_SPU *tex = getTexture(tt, level, x, y, z, 5 ); - renderEast( tt, x, y, z, tex ); - changed = true; - xFlipTexture = false; - } - return changed; + { + if (SharedConstants::TEXTURE_LIGHTING) { + t->tex2(tileShapeZ0 > 0 ? centerColor + : tt->getLightColor(level, x, y, z - 1)); + t->color(c2, c2, c2); + } else { + float br = tt->getBrightness(level, x, y, z - 1); + if (tileShapeZ0 > 0) br = centerBrightness; + if (level->m_tileData.lightEmission[tt->id] > 0) br = 1.0f; + t->color(c2 * br, c2 * br, c2 * br); + } + Icon_SPU* tex = getTexture(tt, level, x, y, z, 2); + renderNorth(tt, x, y, z, tex); + changed = true; + xFlipTexture = false; + } + { + if (SharedConstants::TEXTURE_LIGHTING) { + t->tex2(tileShapeZ1 < 1 ? centerColor + : tt->getLightColor(level, x, y, z + 1)); + t->color(c2, c2, c2); + } else { + float br = tt->getBrightness(level, x, y, z + 1); + if (tileShapeZ1 < 1) br = centerBrightness; + if (level->m_tileData.lightEmission[tt->id] > 0) br = 1.0f; + t->color(c2 * br, c2 * br, c2 * br); + } + Icon_SPU* tex = getTexture(tt, level, x, y, z, 3); + renderSouth(tt, x, y, z, tex); + changed = true; + xFlipTexture = false; + } + { + if (SharedConstants::TEXTURE_LIGHTING) { + t->tex2(tileShapeX0 > 0 ? centerColor + : tt->getLightColor(level, x - 1, y, z)); + t->color(c3, c3, c3); + } else { + float br = tt->getBrightness(level, x - 1, y, z); + if (tileShapeX0 > 0) br = centerBrightness; + if (level->m_tileData.lightEmission[tt->id] > 0) br = 1.0f; + t->color(c3 * br, c3 * br, c3 * br); + } + Icon_SPU* tex = getTexture(tt, level, x, y, z, 4); + renderWest(tt, x, y, z, tex); + changed = true; + xFlipTexture = false; + } + { + if (SharedConstants::TEXTURE_LIGHTING) { + t->tex2(tileShapeX1 < 1 ? centerColor + : tt->getLightColor(level, x + 1, y, z)); + t->color(c3, c3, c3); + } else { + float br = tt->getBrightness(level, x + 1, y, z); + if (tileShapeX1 < 1) br = centerBrightness; + if (level->m_tileData.lightEmission[tt->id] > 0) br = 1.0f; + t->color(c3 * br, c3 * br, c3 * br); + } + Icon_SPU* tex = getTexture(tt, level, x, y, z, 5); + renderEast(tt, x, y, z, tex); + changed = true; + xFlipTexture = false; + } + return changed; } -void TileRenderer_SPU::renderFaceDown( Tile_SPU* tt, float x, float y, float z, Icon_SPU *tex ) -{ - Tesselator_SPU* t = getTesselator(); +void TileRenderer_SPU::renderFaceDown(Tile_SPU* tt, float x, float y, float z, + Icon_SPU* tex) { + Tesselator_SPU* t = getTesselator(); - if (hasFixedTexture()) tex = fixedTexture; - float u00 = tex->getU(tileShapeX0 * 16.0f); - float u11 = tex->getU(tileShapeX1 * 16.0f); - float v00 = tex->getV(tileShapeZ0 * 16.0f); - float v11 = tex->getV(tileShapeZ1 * 16.0f); + if (hasFixedTexture()) tex = fixedTexture; + float u00 = tex->getU(tileShapeX0 * 16.0f); + float u11 = tex->getU(tileShapeX1 * 16.0f); + float v00 = tex->getV(tileShapeZ0 * 16.0f); + float v11 = tex->getV(tileShapeZ1 * 16.0f); - if ( tileShapeX0 < 0 || tileShapeX1 > 1 ) - { - u00 = tex->getU0(); - u11 = tex->getU1(); - } - if ( tileShapeZ0 < 0 || tileShapeZ1 > 1 ) - { - v00 = tex->getV0(); - v11 = tex->getV1(); - } + if (tileShapeX0 < 0 || tileShapeX1 > 1) { + u00 = tex->getU0(); + u11 = tex->getU1(); + } + if (tileShapeZ0 < 0 || tileShapeZ1 > 1) { + v00 = tex->getV0(); + v11 = tex->getV1(); + } - float u01 = u11, u10 = u00, v01 = v00, v10 = v11; - if ( downFlip == FLIP_CCW ) - { - u00 = tex->getU(tileShapeZ0 * 16.0f); - v00 = tex->getV(SharedConstants::WORLD_RESOLUTION - tileShapeX1 * 16.0f); - u11 = tex->getU(tileShapeZ1 * 16.0f); - v11 = tex->getV(SharedConstants::WORLD_RESOLUTION - tileShapeX0 * 16.0f); + float u01 = u11, u10 = u00, v01 = v00, v10 = v11; + if (downFlip == FLIP_CCW) { + u00 = tex->getU(tileShapeZ0 * 16.0f); + v00 = + tex->getV(SharedConstants::WORLD_RESOLUTION - tileShapeX1 * 16.0f); + u11 = tex->getU(tileShapeZ1 * 16.0f); + v11 = + tex->getV(SharedConstants::WORLD_RESOLUTION - tileShapeX0 * 16.0f); - u01 = u11; - u10 = u00; - v01 = v00; - v10 = v11; - u01 = u00; - u10 = u11; - v00 = v11; - v11 = v01; - } - else if ( downFlip == FLIP_CW ) - { - // reshape - u00 = tex->getU(SharedConstants::WORLD_RESOLUTION - tileShapeZ1 * 16.0f); - v00 = tex->getV(tileShapeX0 * 16.0f); - u11 = tex->getU(SharedConstants::WORLD_RESOLUTION - tileShapeZ0 * 16.0f); - v11 = tex->getV(tileShapeX1 * 16.0f); + u01 = u11; + u10 = u00; + v01 = v00; + v10 = v11; + u01 = u00; + u10 = u11; + v00 = v11; + v11 = v01; + } else if (downFlip == FLIP_CW) { + // reshape + u00 = + tex->getU(SharedConstants::WORLD_RESOLUTION - tileShapeZ1 * 16.0f); + v00 = tex->getV(tileShapeX0 * 16.0f); + u11 = + tex->getU(SharedConstants::WORLD_RESOLUTION - tileShapeZ0 * 16.0f); + v11 = tex->getV(tileShapeX1 * 16.0f); - // rotate - u01 = u11; - u10 = u00; - v01 = v00; - v10 = v11; - u00 = u01; - u11 = u10; - v01 = v11; - v10 = v00; - } - else if ( downFlip == FLIP_180 ) - { - u00 = tex->getU(SharedConstants::WORLD_RESOLUTION - tileShapeX0 * 16.0f); - u11 = tex->getU(SharedConstants::WORLD_RESOLUTION - tileShapeX1 * 16.0f); - v00 = tex->getV(SharedConstants::WORLD_RESOLUTION - tileShapeZ0 * 16.0f); - v11 = tex->getV(SharedConstants::WORLD_RESOLUTION - tileShapeZ1 * 16.0f); + // rotate + u01 = u11; + u10 = u00; + v01 = v00; + v10 = v11; + u00 = u01; + u11 = u10; + v01 = v11; + v10 = v00; + } else if (downFlip == FLIP_180) { + u00 = + tex->getU(SharedConstants::WORLD_RESOLUTION - tileShapeX0 * 16.0f); + u11 = + tex->getU(SharedConstants::WORLD_RESOLUTION - tileShapeX1 * 16.0f); + v00 = + tex->getV(SharedConstants::WORLD_RESOLUTION - tileShapeZ0 * 16.0f); + v11 = + tex->getV(SharedConstants::WORLD_RESOLUTION - tileShapeZ1 * 16.0f); - u01 = u11; - u10 = u00; - v01 = v00; - v10 = v11; - } + u01 = u11; + u10 = u00; + v01 = v00; + v10 = v11; + } - float x0 = x + tileShapeX0; - float x1 = x + tileShapeX1; - float y0 = y + tileShapeY0; - float z0 = z + tileShapeZ0; - float z1 = z + tileShapeZ1; + float x0 = x + tileShapeX0; + float x1 = x + tileShapeX1; + float y0 = y + tileShapeY0; + float z0 = z + tileShapeZ0; + float z1 = z + tileShapeZ1; - if ( applyAmbienceOcclusion ) - { - t->color( c1r, c1g, c1b ); - if ( SharedConstants::TEXTURE_LIGHTING ) t->tex2( tc1 ); - t->vertexUV( ( float )( x0 ), ( float )( y0 ), ( float )( z1 ), ( float )( u10 ), ( float )( v10 ) ); - t->color( c2r, c2g, c2b ); - if ( SharedConstants::TEXTURE_LIGHTING ) t->tex2( tc2 ); - t->vertexUV( ( float )( x0 ), ( float )( y0 ), ( float )( z0 ), ( float )( u00 ), ( float )( v00 ) ); - t->color( c3r, c3g, c3b ); - if ( SharedConstants::TEXTURE_LIGHTING ) t->tex2( tc3 ); - t->vertexUV( ( float )( x1 ), ( float )( y0 ), ( float )( z0 ), ( float )( u01 ), ( float )( v01 ) ); - t->color( c4r, c4g, c4b ); - if ( SharedConstants::TEXTURE_LIGHTING ) t->tex2( tc4 ); - t->vertexUV( ( float )( x1 ), ( float )( y0 ), ( float )( z1 ), ( float )( u11 ), ( float )( v11 ) ); - } - else - { - t->vertexUV( ( float )( x0 ), ( float )( y0 ), ( float )( z1 ), ( float )( u10 ), ( float )( v10 ) ); - t->vertexUV( ( float )( x0 ), ( float )( y0 ), ( float )( z0 ), ( float )( u00 ), ( float )( v00 ) ); - t->vertexUV( ( float )( x1 ), ( float )( y0 ), ( float )( z0 ), ( float )( u01 ), ( float )( v01 ) ); - t->vertexUV( ( float )( x1 ), ( float )( y0 ), ( float )( z1 ), ( float )( u11 ), ( float )( v11 ) ); - } + if (applyAmbienceOcclusion) { + t->color(c1r, c1g, c1b); + if (SharedConstants::TEXTURE_LIGHTING) t->tex2(tc1); + t->vertexUV((float)(x0), (float)(y0), (float)(z1), (float)(u10), + (float)(v10)); + t->color(c2r, c2g, c2b); + if (SharedConstants::TEXTURE_LIGHTING) t->tex2(tc2); + t->vertexUV((float)(x0), (float)(y0), (float)(z0), (float)(u00), + (float)(v00)); + t->color(c3r, c3g, c3b); + if (SharedConstants::TEXTURE_LIGHTING) t->tex2(tc3); + t->vertexUV((float)(x1), (float)(y0), (float)(z0), (float)(u01), + (float)(v01)); + t->color(c4r, c4g, c4b); + if (SharedConstants::TEXTURE_LIGHTING) t->tex2(tc4); + t->vertexUV((float)(x1), (float)(y0), (float)(z1), (float)(u11), + (float)(v11)); + } else { + t->vertexUV((float)(x0), (float)(y0), (float)(z1), (float)(u10), + (float)(v10)); + t->vertexUV((float)(x0), (float)(y0), (float)(z0), (float)(u00), + (float)(v00)); + t->vertexUV((float)(x1), (float)(y0), (float)(z0), (float)(u01), + (float)(v01)); + t->vertexUV((float)(x1), (float)(y0), (float)(z1), (float)(u11), + (float)(v11)); + } } -void TileRenderer_SPU::renderFaceUp( Tile_SPU* tt, float x, float y, float z, Icon_SPU *tex ) -{ - Tesselator_SPU* t = getTesselator(); +void TileRenderer_SPU::renderFaceUp(Tile_SPU* tt, float x, float y, float z, + Icon_SPU* tex) { + Tesselator_SPU* t = getTesselator(); - if (hasFixedTexture()) tex = fixedTexture; - float u00 = tex->getU(tileShapeX0 * 16.0f); - float u11 = tex->getU(tileShapeX1 * 16.0f); - float v00 = tex->getV(tileShapeZ0 * 16.0f); - float v11 = tex->getV(tileShapeZ1 * 16.0f); + if (hasFixedTexture()) tex = fixedTexture; + float u00 = tex->getU(tileShapeX0 * 16.0f); + float u11 = tex->getU(tileShapeX1 * 16.0f); + float v00 = tex->getV(tileShapeZ0 * 16.0f); + float v11 = tex->getV(tileShapeZ1 * 16.0f); - if ( tileShapeX0 < 0 || tileShapeX1 > 1 ) - { - u00 = tex->getU0(); - u11 = tex->getU1(); - } - if ( tileShapeZ0 < 0 || tileShapeZ1 > 1 ) - { - v00 = tex->getV0(); - v11 = tex->getV1(); - } + if (tileShapeX0 < 0 || tileShapeX1 > 1) { + u00 = tex->getU0(); + u11 = tex->getU1(); + } + if (tileShapeZ0 < 0 || tileShapeZ1 > 1) { + v00 = tex->getV0(); + v11 = tex->getV1(); + } - float u01 = u11, u10 = u00, v01 = v00, v10 = v11; + float u01 = u11, u10 = u00, v01 = v00, v10 = v11; - if ( upFlip == FLIP_CW ) - { - u00 = tex->getU(tileShapeZ0 * 16.0f); - v00 = tex->getV(SharedConstants::WORLD_RESOLUTION - tileShapeX1 * 16.0f); - u11 = tex->getU(tileShapeZ1 * 16.0f); - v11 = tex->getV(SharedConstants::WORLD_RESOLUTION - tileShapeX0 * 16.0f); + if (upFlip == FLIP_CW) { + u00 = tex->getU(tileShapeZ0 * 16.0f); + v00 = + tex->getV(SharedConstants::WORLD_RESOLUTION - tileShapeX1 * 16.0f); + u11 = tex->getU(tileShapeZ1 * 16.0f); + v11 = + tex->getV(SharedConstants::WORLD_RESOLUTION - tileShapeX0 * 16.0f); - u01 = u11; - u10 = u00; - v01 = v00; - v10 = v11; - u01 = u00; - u10 = u11; - v00 = v11; - v11 = v01; - } - else if ( upFlip == FLIP_CCW ) - { - // reshape - u00 = tex->getU(SharedConstants::WORLD_RESOLUTION - tileShapeZ1 * 16.0f); - v00 = tex->getV(tileShapeX0 * 16.0f); - u11 = tex->getU(SharedConstants::WORLD_RESOLUTION - tileShapeZ0 * 16.0f); - v11 = tex->getV(tileShapeX1 * 16.0f); + u01 = u11; + u10 = u00; + v01 = v00; + v10 = v11; + u01 = u00; + u10 = u11; + v00 = v11; + v11 = v01; + } else if (upFlip == FLIP_CCW) { + // reshape + u00 = + tex->getU(SharedConstants::WORLD_RESOLUTION - tileShapeZ1 * 16.0f); + v00 = tex->getV(tileShapeX0 * 16.0f); + u11 = + tex->getU(SharedConstants::WORLD_RESOLUTION - tileShapeZ0 * 16.0f); + v11 = tex->getV(tileShapeX1 * 16.0f); - // rotate - u01 = u11; - u10 = u00; - v01 = v00; - v10 = v11; - u00 = u01; - u11 = u10; - v01 = v11; - v10 = v00; - } - else if ( upFlip == FLIP_180 ) - { - u00 = tex->getU(SharedConstants::WORLD_RESOLUTION - tileShapeX0 * 16.0f); - u11 = tex->getU(SharedConstants::WORLD_RESOLUTION - tileShapeX1 * 16.0f); - v00 = tex->getV(SharedConstants::WORLD_RESOLUTION - tileShapeZ0 * 16.0f); - v11 = tex->getV(SharedConstants::WORLD_RESOLUTION - tileShapeZ1 * 16.0f); + // rotate + u01 = u11; + u10 = u00; + v01 = v00; + v10 = v11; + u00 = u01; + u11 = u10; + v01 = v11; + v10 = v00; + } else if (upFlip == FLIP_180) { + u00 = + tex->getU(SharedConstants::WORLD_RESOLUTION - tileShapeX0 * 16.0f); + u11 = + tex->getU(SharedConstants::WORLD_RESOLUTION - tileShapeX1 * 16.0f); + v00 = + tex->getV(SharedConstants::WORLD_RESOLUTION - tileShapeZ0 * 16.0f); + v11 = + tex->getV(SharedConstants::WORLD_RESOLUTION - tileShapeZ1 * 16.0f); - u01 = u11; - u10 = u00; - v01 = v00; - v10 = v11; - } + u01 = u11; + u10 = u00; + v01 = v00; + v10 = v11; + } + float x0 = x + tileShapeX0; + float x1 = x + tileShapeX1; + float y1 = y + tileShapeY1; + float z0 = z + tileShapeZ0; + float z1 = z + tileShapeZ1; - float x0 = x + tileShapeX0; - float x1 = x + tileShapeX1; - float y1 = y + tileShapeY1; - float z0 = z + tileShapeZ0; - float z1 = z + tileShapeZ1; - - if ( applyAmbienceOcclusion ) - { - t->color( c1r, c1g, c1b ); - if ( SharedConstants::TEXTURE_LIGHTING ) t->tex2( tc1 ); - t->vertexUV( ( float )( x1 ), ( float )( y1 ), ( float )( z1 ), ( float )( u11 ), ( float )( v11 ) ); - t->color( c2r, c2g, c2b ); - if ( SharedConstants::TEXTURE_LIGHTING ) t->tex2( tc2 ); - t->vertexUV( ( float )( x1 ), ( float )( y1 ), ( float )( z0 ), ( float )( u01 ), ( float )( v01 ) ); - t->color( c3r, c3g, c3b ); - if ( SharedConstants::TEXTURE_LIGHTING ) t->tex2( tc3 ); - t->vertexUV( ( float )( x0 ), ( float )( y1 ), ( float )( z0 ), ( float )( u00 ), ( float )( v00 ) ); - t->color( c4r, c4g, c4b ); - if ( SharedConstants::TEXTURE_LIGHTING ) t->tex2( tc4 ); - t->vertexUV( ( float )( x0 ), ( float )( y1 ), ( float )( z1 ), ( float )( u10 ), ( float )( v10 ) ); - } - else - { - t->vertexUV( ( float )( x1 ), ( float )( y1 ), ( float )( z1 ), ( float )( u11 ), ( float )( v11 ) ); - t->vertexUV( ( float )( x1 ), ( float )( y1 ), ( float )( z0 ), ( float )( u01 ), ( float )( v01 ) ); - t->vertexUV( ( float )( x0 ), ( float )( y1 ), ( float )( z0 ), ( float )( u00 ), ( float )( v00 ) ); - t->vertexUV( ( float )( x0 ), ( float )( y1 ), ( float )( z1 ), ( float )( u10 ), ( float )( v10 ) ); - } - + if (applyAmbienceOcclusion) { + t->color(c1r, c1g, c1b); + if (SharedConstants::TEXTURE_LIGHTING) t->tex2(tc1); + t->vertexUV((float)(x1), (float)(y1), (float)(z1), (float)(u11), + (float)(v11)); + t->color(c2r, c2g, c2b); + if (SharedConstants::TEXTURE_LIGHTING) t->tex2(tc2); + t->vertexUV((float)(x1), (float)(y1), (float)(z0), (float)(u01), + (float)(v01)); + t->color(c3r, c3g, c3b); + if (SharedConstants::TEXTURE_LIGHTING) t->tex2(tc3); + t->vertexUV((float)(x0), (float)(y1), (float)(z0), (float)(u00), + (float)(v00)); + t->color(c4r, c4g, c4b); + if (SharedConstants::TEXTURE_LIGHTING) t->tex2(tc4); + t->vertexUV((float)(x0), (float)(y1), (float)(z1), (float)(u10), + (float)(v10)); + } else { + t->vertexUV((float)(x1), (float)(y1), (float)(z1), (float)(u11), + (float)(v11)); + t->vertexUV((float)(x1), (float)(y1), (float)(z0), (float)(u01), + (float)(v01)); + t->vertexUV((float)(x0), (float)(y1), (float)(z0), (float)(u00), + (float)(v00)); + t->vertexUV((float)(x0), (float)(y1), (float)(z1), (float)(u10), + (float)(v10)); + } } -void TileRenderer_SPU::renderNorth( Tile_SPU* tt, float x, float y, float z, Icon_SPU *tex ) -{ - Tesselator_SPU* t = getTesselator(); +void TileRenderer_SPU::renderNorth(Tile_SPU* tt, float x, float y, float z, + Icon_SPU* tex) { + Tesselator_SPU* t = getTesselator(); - if (hasFixedTexture()) tex = fixedTexture; - float u00 = tex->getU(tileShapeX0 * 16.0f); - float u11 = tex->getU(tileShapeX1 * 16.0f); - float v00 = tex->getV(SharedConstants::WORLD_RESOLUTION - tileShapeY1 * 16.0f); - float v11 = tex->getV(SharedConstants::WORLD_RESOLUTION - tileShapeY0 * 16.0f); - if ( xFlipTexture ) - { - float tmp = u00; - u00 = u11; - u11 = tmp; - } + if (hasFixedTexture()) tex = fixedTexture; + float u00 = tex->getU(tileShapeX0 * 16.0f); + float u11 = tex->getU(tileShapeX1 * 16.0f); + float v00 = + tex->getV(SharedConstants::WORLD_RESOLUTION - tileShapeY1 * 16.0f); + float v11 = + tex->getV(SharedConstants::WORLD_RESOLUTION - tileShapeY0 * 16.0f); + if (xFlipTexture) { + float tmp = u00; + u00 = u11; + u11 = tmp; + } - if ( tileShapeX0 < 0 || tileShapeX1 > 1 ) - { - u00 = tex->getU0(); - u11 = tex->getU1(); - } - if ( tileShapeY0 < 0 || tileShapeY1 > 1 ) - { - v00 = tex->getV0(); - v11 = tex->getV1(); - } + if (tileShapeX0 < 0 || tileShapeX1 > 1) { + u00 = tex->getU0(); + u11 = tex->getU1(); + } + if (tileShapeY0 < 0 || tileShapeY1 > 1) { + v00 = tex->getV0(); + v11 = tex->getV1(); + } - float u01 = u11, u10 = u00, v01 = v00, v10 = v11; + float u01 = u11, u10 = u00, v01 = v00, v10 = v11; - if ( northFlip == FLIP_CCW ) - { - u00 = tex->getU(tileShapeY0 * 16.0f); - v00 = tex->getV(SharedConstants::WORLD_RESOLUTION - tileShapeX0 * 16.0f); - u11 = tex->getU(tileShapeY1 * 16.0f); - v11 = tex->getV(SharedConstants::WORLD_RESOLUTION - tileShapeX1 * 16.0f); + if (northFlip == FLIP_CCW) { + u00 = tex->getU(tileShapeY0 * 16.0f); + v00 = + tex->getV(SharedConstants::WORLD_RESOLUTION - tileShapeX0 * 16.0f); + u11 = tex->getU(tileShapeY1 * 16.0f); + v11 = + tex->getV(SharedConstants::WORLD_RESOLUTION - tileShapeX1 * 16.0f); - u01 = u11; - u10 = u00; - v01 = v00; - v10 = v11; - u01 = u00; - u10 = u11; - v00 = v11; - v11 = v01; - } - else if ( northFlip == FLIP_CW ) - { - // reshape - u00 = tex->getU(SharedConstants::WORLD_RESOLUTION - tileShapeY1 * 16.0f); - v00 = tex->getV(tileShapeX1 * 16.0f); - u11 = tex->getU(SharedConstants::WORLD_RESOLUTION - tileShapeY0 * 16.0f); - v11 = tex->getV(tileShapeX0 * 16.0f); + u01 = u11; + u10 = u00; + v01 = v00; + v10 = v11; + u01 = u00; + u10 = u11; + v00 = v11; + v11 = v01; + } else if (northFlip == FLIP_CW) { + // reshape + u00 = + tex->getU(SharedConstants::WORLD_RESOLUTION - tileShapeY1 * 16.0f); + v00 = tex->getV(tileShapeX1 * 16.0f); + u11 = + tex->getU(SharedConstants::WORLD_RESOLUTION - tileShapeY0 * 16.0f); + v11 = tex->getV(tileShapeX0 * 16.0f); - // rotate - u01 = u11; - u10 = u00; - v01 = v00; - v10 = v11; - u00 = u01; - u11 = u10; - v01 = v11; - v10 = v00; - } - else if ( northFlip == FLIP_180 ) - { - u00 = tex->getU(SharedConstants::WORLD_RESOLUTION - tileShapeX0 * 16.0f); - u11 = tex->getU(SharedConstants::WORLD_RESOLUTION - tileShapeX1 * 16.0f); - v00 = tex->getV(tileShapeY1 * 16.0f); - v11 = tex->getV(tileShapeY0 * 16.0f); + // rotate + u01 = u11; + u10 = u00; + v01 = v00; + v10 = v11; + u00 = u01; + u11 = u10; + v01 = v11; + v10 = v00; + } else if (northFlip == FLIP_180) { + u00 = + tex->getU(SharedConstants::WORLD_RESOLUTION - tileShapeX0 * 16.0f); + u11 = + tex->getU(SharedConstants::WORLD_RESOLUTION - tileShapeX1 * 16.0f); + v00 = tex->getV(tileShapeY1 * 16.0f); + v11 = tex->getV(tileShapeY0 * 16.0f); - u01 = u11; - u10 = u00; - v01 = v00; - v10 = v11; - } + u01 = u11; + u10 = u00; + v01 = v00; + v10 = v11; + } + float x0 = x + tileShapeX0; + float x1 = x + tileShapeX1; + float y0 = y + tileShapeY0; + float y1 = y + tileShapeY1; + float z0 = z + tileShapeZ0; - float x0 = x + tileShapeX0; - float x1 = x + tileShapeX1; - float y0 = y + tileShapeY0; - float y1 = y + tileShapeY1; - float z0 = z + tileShapeZ0; - - if ( applyAmbienceOcclusion ) - { - t->color( c1r, c1g, c1b ); - if ( SharedConstants::TEXTURE_LIGHTING ) t->tex2( tc1 ); - t->vertexUV( ( float )( x0 ), ( float )( y1 ), ( float )( z0 ), ( float )( u01 ), ( float )( v01 ) ); - t->color( c2r, c2g, c2b ); - if ( SharedConstants::TEXTURE_LIGHTING ) t->tex2( tc2 ); - t->vertexUV( ( float )( x1 ), ( float )( y1 ), ( float )( z0 ), ( float )( u00 ), ( float )( v00 ) ); - t->color( c3r, c3g, c3b ); - if ( SharedConstants::TEXTURE_LIGHTING ) t->tex2( tc3 ); - t->vertexUV( ( float )( x1 ), ( float )( y0 ), ( float )( z0 ), ( float )( u10 ), ( float )( v10 ) ); - t->color( c4r, c4g, c4b ); - if ( SharedConstants::TEXTURE_LIGHTING ) t->tex2( tc4 ); - t->vertexUV( ( float )( x0 ), ( float )( y0 ), ( float )( z0 ), ( float )( u11 ), ( float )( v11 ) ); - } - else - { - t->vertexUV( ( float )( x0 ), ( float )( y1 ), ( float )( z0 ), ( float )( u01 ), ( float )( v01 ) ); - t->vertexUV( ( float )( x1 ), ( float )( y1 ), ( float )( z0 ), ( float )( u00 ), ( float )( v00 ) ); - t->vertexUV( ( float )( x1 ), ( float )( y0 ), ( float )( z0 ), ( float )( u10 ), ( float )( v10 ) ); - t->vertexUV( ( float )( x0 ), ( float )( y0 ), ( float )( z0 ), ( float )( u11 ), ( float )( v11 ) ); - } - + if (applyAmbienceOcclusion) { + t->color(c1r, c1g, c1b); + if (SharedConstants::TEXTURE_LIGHTING) t->tex2(tc1); + t->vertexUV((float)(x0), (float)(y1), (float)(z0), (float)(u01), + (float)(v01)); + t->color(c2r, c2g, c2b); + if (SharedConstants::TEXTURE_LIGHTING) t->tex2(tc2); + t->vertexUV((float)(x1), (float)(y1), (float)(z0), (float)(u00), + (float)(v00)); + t->color(c3r, c3g, c3b); + if (SharedConstants::TEXTURE_LIGHTING) t->tex2(tc3); + t->vertexUV((float)(x1), (float)(y0), (float)(z0), (float)(u10), + (float)(v10)); + t->color(c4r, c4g, c4b); + if (SharedConstants::TEXTURE_LIGHTING) t->tex2(tc4); + t->vertexUV((float)(x0), (float)(y0), (float)(z0), (float)(u11), + (float)(v11)); + } else { + t->vertexUV((float)(x0), (float)(y1), (float)(z0), (float)(u01), + (float)(v01)); + t->vertexUV((float)(x1), (float)(y1), (float)(z0), (float)(u00), + (float)(v00)); + t->vertexUV((float)(x1), (float)(y0), (float)(z0), (float)(u10), + (float)(v10)); + t->vertexUV((float)(x0), (float)(y0), (float)(z0), (float)(u11), + (float)(v11)); + } } -void TileRenderer_SPU::renderSouth( Tile_SPU* tt, float x, float y, float z, Icon_SPU *tex ) -{ - Tesselator_SPU* t = getTesselator(); +void TileRenderer_SPU::renderSouth(Tile_SPU* tt, float x, float y, float z, + Icon_SPU* tex) { + Tesselator_SPU* t = getTesselator(); - if (hasFixedTexture()) tex = fixedTexture; - float u00 = tex->getU(tileShapeX0 * 16.0f); - float u11 = tex->getU(tileShapeX1 * 16.0f); - float v00 = tex->getV(SharedConstants::WORLD_RESOLUTION - tileShapeY1 * 16.0f); - float v11 = tex->getV(SharedConstants::WORLD_RESOLUTION - tileShapeY0 * 16.0f); - if ( xFlipTexture ) - { - float tmp = u00; - u00 = u11; - u11 = tmp; - } + if (hasFixedTexture()) tex = fixedTexture; + float u00 = tex->getU(tileShapeX0 * 16.0f); + float u11 = tex->getU(tileShapeX1 * 16.0f); + float v00 = + tex->getV(SharedConstants::WORLD_RESOLUTION - tileShapeY1 * 16.0f); + float v11 = + tex->getV(SharedConstants::WORLD_RESOLUTION - tileShapeY0 * 16.0f); + if (xFlipTexture) { + float tmp = u00; + u00 = u11; + u11 = tmp; + } - if ( tileShapeX0 < 0 || tileShapeX1 > 1 ) - { - u00 = tex->getU0(); - u11 = tex->getU1(); - } - if ( tileShapeY0 < 0 || tileShapeY1 > 1 ) - { - v00 = tex->getV0(); - v11 = tex->getV1(); - } + if (tileShapeX0 < 0 || tileShapeX1 > 1) { + u00 = tex->getU0(); + u11 = tex->getU1(); + } + if (tileShapeY0 < 0 || tileShapeY1 > 1) { + v00 = tex->getV0(); + v11 = tex->getV1(); + } - float u01 = u11, u10 = u00, v01 = v00, v10 = v11; + float u01 = u11, u10 = u00, v01 = v00, v10 = v11; - if ( southFlip == FLIP_CW ) - { - u00 = tex->getU(tileShapeY0 * 16.0f); - v11 = tex->getV(SharedConstants::WORLD_RESOLUTION - tileShapeX0 * 16.0f); - u11 = tex->getU(tileShapeY1 * 16.0f); - v00 = tex->getV(SharedConstants::WORLD_RESOLUTION - tileShapeX1 * 16.0f); + if (southFlip == FLIP_CW) { + u00 = tex->getU(tileShapeY0 * 16.0f); + v11 = + tex->getV(SharedConstants::WORLD_RESOLUTION - tileShapeX0 * 16.0f); + u11 = tex->getU(tileShapeY1 * 16.0f); + v00 = + tex->getV(SharedConstants::WORLD_RESOLUTION - tileShapeX1 * 16.0f); - u01 = u11; - u10 = u00; - v01 = v00; - v10 = v11; - u01 = u00; - u10 = u11; - v00 = v11; - v11 = v01; - } - else if ( southFlip == FLIP_CCW ) - { - // reshape - u00 = tex->getU(SharedConstants::WORLD_RESOLUTION - tileShapeY1 * 16.0f); - v00 = tex->getV(tileShapeX0 * 16.0f); - u11 = tex->getU(SharedConstants::WORLD_RESOLUTION - tileShapeY0 * 16.0f); - v11 = tex->getV(tileShapeX1 * 16.0f); + u01 = u11; + u10 = u00; + v01 = v00; + v10 = v11; + u01 = u00; + u10 = u11; + v00 = v11; + v11 = v01; + } else if (southFlip == FLIP_CCW) { + // reshape + u00 = + tex->getU(SharedConstants::WORLD_RESOLUTION - tileShapeY1 * 16.0f); + v00 = tex->getV(tileShapeX0 * 16.0f); + u11 = + tex->getU(SharedConstants::WORLD_RESOLUTION - tileShapeY0 * 16.0f); + v11 = tex->getV(tileShapeX1 * 16.0f); - // rotate - u01 = u11; - u10 = u00; - v01 = v00; - v10 = v11; - u00 = u01; - u11 = u10; - v01 = v11; - v10 = v00; - } - else if ( southFlip == FLIP_180 ) - { - u00 = tex->getU(SharedConstants::WORLD_RESOLUTION - tileShapeX0 * 16.0f); - u11 = tex->getU(SharedConstants::WORLD_RESOLUTION - tileShapeX1 * 16.0f); - v00 = tex->getV(tileShapeY1 * 16.0f); - v11 = tex->getV(tileShapeY0 * 16.0f); + // rotate + u01 = u11; + u10 = u00; + v01 = v00; + v10 = v11; + u00 = u01; + u11 = u10; + v01 = v11; + v10 = v00; + } else if (southFlip == FLIP_180) { + u00 = + tex->getU(SharedConstants::WORLD_RESOLUTION - tileShapeX0 * 16.0f); + u11 = + tex->getU(SharedConstants::WORLD_RESOLUTION - tileShapeX1 * 16.0f); + v00 = tex->getV(tileShapeY1 * 16.0f); + v11 = tex->getV(tileShapeY0 * 16.0f); - u01 = u11; - u10 = u00; - v01 = v00; - v10 = v11; - } + u01 = u11; + u10 = u00; + v01 = v00; + v10 = v11; + } + float x0 = x + tileShapeX0; + float x1 = x + tileShapeX1; + float y0 = y + tileShapeY0; + float y1 = y + tileShapeY1; + float z1 = z + tileShapeZ1; - float x0 = x + tileShapeX0; - float x1 = x + tileShapeX1; - float y0 = y + tileShapeY0; - float y1 = y + tileShapeY1; - float z1 = z + tileShapeZ1; - - if ( applyAmbienceOcclusion ) - { - t->color( c1r, c1g, c1b ); - if ( SharedConstants::TEXTURE_LIGHTING ) t->tex2( tc1 ); - t->vertexUV( ( float )( x0 ), ( float )( y1 ), ( float )( z1 ), ( float )( u00 ), ( float )( v00 ) ); - t->color( c2r, c2g, c2b ); - if ( SharedConstants::TEXTURE_LIGHTING ) t->tex2( tc2 ); - t->vertexUV( ( float )( x0 ), ( float )( y0 ), ( float )( z1 ), ( float )( u10 ), ( float )( v10 ) ); - t->color( c3r, c3g, c3b ); - if ( SharedConstants::TEXTURE_LIGHTING ) t->tex2( tc3 ); - t->vertexUV( ( float )( x1 ), ( float )( y0 ), ( float )( z1 ), ( float )( u11 ), ( float )( v11 ) ); - t->color( c4r, c4g, c4b ); - if ( SharedConstants::TEXTURE_LIGHTING ) t->tex2( tc4 ); - t->vertexUV( ( float )( x1 ), ( float )( y1 ), ( float )( z1 ), ( float )( u01 ), ( float )( v01 ) ); - } - else - { - t->vertexUV( ( float )( x0 ), ( float )( y1 ), ( float )( z1 ), ( float )( u00 ), ( float )( v00 ) ); - t->vertexUV( ( float )( x0 ), ( float )( y0 ), ( float )( z1 ), ( float )( u10 ), ( float )( v10 ) ); - t->vertexUV( ( float )( x1 ), ( float )( y0 ), ( float )( z1 ), ( float )( u11 ), ( float )( v11 ) ); - t->vertexUV( ( float )( x1 ), ( float )( y1 ), ( float )( z1 ), ( float )( u01 ), ( float )( v01 ) ); - } - + if (applyAmbienceOcclusion) { + t->color(c1r, c1g, c1b); + if (SharedConstants::TEXTURE_LIGHTING) t->tex2(tc1); + t->vertexUV((float)(x0), (float)(y1), (float)(z1), (float)(u00), + (float)(v00)); + t->color(c2r, c2g, c2b); + if (SharedConstants::TEXTURE_LIGHTING) t->tex2(tc2); + t->vertexUV((float)(x0), (float)(y0), (float)(z1), (float)(u10), + (float)(v10)); + t->color(c3r, c3g, c3b); + if (SharedConstants::TEXTURE_LIGHTING) t->tex2(tc3); + t->vertexUV((float)(x1), (float)(y0), (float)(z1), (float)(u11), + (float)(v11)); + t->color(c4r, c4g, c4b); + if (SharedConstants::TEXTURE_LIGHTING) t->tex2(tc4); + t->vertexUV((float)(x1), (float)(y1), (float)(z1), (float)(u01), + (float)(v01)); + } else { + t->vertexUV((float)(x0), (float)(y1), (float)(z1), (float)(u00), + (float)(v00)); + t->vertexUV((float)(x0), (float)(y0), (float)(z1), (float)(u10), + (float)(v10)); + t->vertexUV((float)(x1), (float)(y0), (float)(z1), (float)(u11), + (float)(v11)); + t->vertexUV((float)(x1), (float)(y1), (float)(z1), (float)(u01), + (float)(v01)); + } } -void TileRenderer_SPU::renderWest( Tile_SPU* tt, float x, float y, float z, Icon_SPU *tex ) -{ - Tesselator_SPU* t = getTesselator(); +void TileRenderer_SPU::renderWest(Tile_SPU* tt, float x, float y, float z, + Icon_SPU* tex) { + Tesselator_SPU* t = getTesselator(); - if (hasFixedTexture()) tex = fixedTexture; - float u00 = tex->getU(tileShapeZ0 * 16.0f); - float u11 = tex->getU(tileShapeZ1 * 16.0f); - float v00 = tex->getV(SharedConstants::WORLD_RESOLUTION - tileShapeY1 * 16.0f); - float v11 = tex->getV(SharedConstants::WORLD_RESOLUTION - tileShapeY0 * 16.0f); - if ( xFlipTexture ) - { - float tmp = u00; - u00 = u11; - u11 = tmp; - } + if (hasFixedTexture()) tex = fixedTexture; + float u00 = tex->getU(tileShapeZ0 * 16.0f); + float u11 = tex->getU(tileShapeZ1 * 16.0f); + float v00 = + tex->getV(SharedConstants::WORLD_RESOLUTION - tileShapeY1 * 16.0f); + float v11 = + tex->getV(SharedConstants::WORLD_RESOLUTION - tileShapeY0 * 16.0f); + if (xFlipTexture) { + float tmp = u00; + u00 = u11; + u11 = tmp; + } - if ( tileShapeZ0 < 0 || tileShapeZ1 > 1 ) - { - u00 = tex->getU0(); - u11 = tex->getU1(); - } - if ( tileShapeY0 < 0 || tileShapeY1 > 1 ) - { - v00 = tex->getV0(); - v11 = tex->getV1(); - } + if (tileShapeZ0 < 0 || tileShapeZ1 > 1) { + u00 = tex->getU0(); + u11 = tex->getU1(); + } + if (tileShapeY0 < 0 || tileShapeY1 > 1) { + v00 = tex->getV0(); + v11 = tex->getV1(); + } - float u01 = u11, u10 = u00, v01 = v00, v10 = v11; + float u01 = u11, u10 = u00, v01 = v00, v10 = v11; - if ( westFlip == FLIP_CW ) - { - u00 = tex->getU(tileShapeY0 * 16.0f); - v00 = tex->getV(SharedConstants::WORLD_RESOLUTION - tileShapeZ1 * 16.0f); - u11 = tex->getU(tileShapeY1 * 16.0f); - v11 = tex->getV(SharedConstants::WORLD_RESOLUTION - tileShapeZ0 * 16.0f); + if (westFlip == FLIP_CW) { + u00 = tex->getU(tileShapeY0 * 16.0f); + v00 = + tex->getV(SharedConstants::WORLD_RESOLUTION - tileShapeZ1 * 16.0f); + u11 = tex->getU(tileShapeY1 * 16.0f); + v11 = + tex->getV(SharedConstants::WORLD_RESOLUTION - tileShapeZ0 * 16.0f); - u01 = u11; - u10 = u00; - v01 = v00; - v10 = v11; - u01 = u00; - u10 = u11; - v00 = v11; - v11 = v01; - } - else if ( westFlip == FLIP_CCW ) - { - // reshape - u00 = tex->getU(SharedConstants::WORLD_RESOLUTION - tileShapeY1 * 16.0f); - v00 = tex->getV(tileShapeZ0 * 16.0f); - u11 = tex->getU(SharedConstants::WORLD_RESOLUTION - tileShapeY0 * 16.0f); - v11 = tex->getV(tileShapeZ1 * 16.0f); + u01 = u11; + u10 = u00; + v01 = v00; + v10 = v11; + u01 = u00; + u10 = u11; + v00 = v11; + v11 = v01; + } else if (westFlip == FLIP_CCW) { + // reshape + u00 = + tex->getU(SharedConstants::WORLD_RESOLUTION - tileShapeY1 * 16.0f); + v00 = tex->getV(tileShapeZ0 * 16.0f); + u11 = + tex->getU(SharedConstants::WORLD_RESOLUTION - tileShapeY0 * 16.0f); + v11 = tex->getV(tileShapeZ1 * 16.0f); - // rotate - u01 = u11; - u10 = u00; - v01 = v00; - v10 = v11; - u00 = u01; - u11 = u10; - v01 = v11; - v10 = v00; - } - else if ( westFlip == FLIP_180 ) - { - u00 = tex->getU(SharedConstants::WORLD_RESOLUTION - tileShapeZ0 * 16.0f); - u11 = tex->getU(SharedConstants::WORLD_RESOLUTION - tileShapeZ1 * 16.0f); - v00 = tex->getV(tileShapeY1 * 16.0f); - v11 = tex->getV(tileShapeY0 * 16.0f); + // rotate + u01 = u11; + u10 = u00; + v01 = v00; + v10 = v11; + u00 = u01; + u11 = u10; + v01 = v11; + v10 = v00; + } else if (westFlip == FLIP_180) { + u00 = + tex->getU(SharedConstants::WORLD_RESOLUTION - tileShapeZ0 * 16.0f); + u11 = + tex->getU(SharedConstants::WORLD_RESOLUTION - tileShapeZ1 * 16.0f); + v00 = tex->getV(tileShapeY1 * 16.0f); + v11 = tex->getV(tileShapeY0 * 16.0f); + u01 = u11; + u10 = u00; + v01 = v00; + v10 = v11; + } - u01 = u11; - u10 = u00; - v01 = v00; - v10 = v11; - } - - float x0 = x + tileShapeX0; - float y0 = y + tileShapeY0; - float y1 = y + tileShapeY1; - float z0 = z + tileShapeZ0; - float z1 = z + tileShapeZ1; - - if ( applyAmbienceOcclusion ) - { - t->color( c1r, c1g, c1b ); - if ( SharedConstants::TEXTURE_LIGHTING ) t->tex2( tc1 ); - t->vertexUV( ( float )( x0 ), ( float )( y1 ), ( float )( z1 ), ( float )( u01 ), ( float )( v01 ) ); - t->color( c2r, c2g, c2b ); - if ( SharedConstants::TEXTURE_LIGHTING ) t->tex2( tc2 ); - t->vertexUV( ( float )( x0 ), ( float )( y1 ), ( float )( z0 ), ( float )( u00 ), ( float )( v00 ) ); - t->color( c3r, c3g, c3b ); - if ( SharedConstants::TEXTURE_LIGHTING ) t->tex2( tc3 ); - t->vertexUV( ( float )( x0 ), ( float )( y0 ), ( float )( z0 ), ( float )( u10 ), ( float )( v10 ) ); - t->color( c4r, c4g, c4b ); - if ( SharedConstants::TEXTURE_LIGHTING ) t->tex2( tc4 ); - t->vertexUV( ( float )( x0 ), ( float )( y0 ), ( float )( z1 ), ( float )( u11 ), ( float )( v11 ) ); - } - else - { - t->vertexUV( ( float )( x0 ), ( float )( y1 ), ( float )( z1 ), ( float )( u01 ), ( float )( v01 ) ); - t->vertexUV( ( float )( x0 ), ( float )( y1 ), ( float )( z0 ), ( float )( u00 ), ( float )( v00 ) ); - t->vertexUV( ( float )( x0 ), ( float )( y0 ), ( float )( z0 ), ( float )( u10 ), ( float )( v10 ) ); - t->vertexUV( ( float )( x0 ), ( float )( y0 ), ( float )( z1 ), ( float )( u11 ), ( float )( v11 ) ); - } + float x0 = x + tileShapeX0; + float y0 = y + tileShapeY0; + float y1 = y + tileShapeY1; + float z0 = z + tileShapeZ0; + float z1 = z + tileShapeZ1; + if (applyAmbienceOcclusion) { + t->color(c1r, c1g, c1b); + if (SharedConstants::TEXTURE_LIGHTING) t->tex2(tc1); + t->vertexUV((float)(x0), (float)(y1), (float)(z1), (float)(u01), + (float)(v01)); + t->color(c2r, c2g, c2b); + if (SharedConstants::TEXTURE_LIGHTING) t->tex2(tc2); + t->vertexUV((float)(x0), (float)(y1), (float)(z0), (float)(u00), + (float)(v00)); + t->color(c3r, c3g, c3b); + if (SharedConstants::TEXTURE_LIGHTING) t->tex2(tc3); + t->vertexUV((float)(x0), (float)(y0), (float)(z0), (float)(u10), + (float)(v10)); + t->color(c4r, c4g, c4b); + if (SharedConstants::TEXTURE_LIGHTING) t->tex2(tc4); + t->vertexUV((float)(x0), (float)(y0), (float)(z1), (float)(u11), + (float)(v11)); + } else { + t->vertexUV((float)(x0), (float)(y1), (float)(z1), (float)(u01), + (float)(v01)); + t->vertexUV((float)(x0), (float)(y1), (float)(z0), (float)(u00), + (float)(v00)); + t->vertexUV((float)(x0), (float)(y0), (float)(z0), (float)(u10), + (float)(v10)); + t->vertexUV((float)(x0), (float)(y0), (float)(z1), (float)(u11), + (float)(v11)); + } } -void TileRenderer_SPU::renderEast( Tile_SPU* tt, float x, float y, float z, Icon_SPU *tex ) -{ - Tesselator_SPU* t = getTesselator(); +void TileRenderer_SPU::renderEast(Tile_SPU* tt, float x, float y, float z, + Icon_SPU* tex) { + Tesselator_SPU* t = getTesselator(); - if (hasFixedTexture()) tex = fixedTexture; - float u00 = tex->getU(tileShapeZ0 * 16.0f); - float u11 = tex->getU(tileShapeZ1 * 16.0f); - float v00 = tex->getV(SharedConstants::WORLD_RESOLUTION - tileShapeY1 * 16.0f); - float v11 = tex->getV(SharedConstants::WORLD_RESOLUTION - tileShapeY0 * 16.0f); - if ( xFlipTexture ) - { - float tmp = u00; - u00 = u11; - u11 = tmp; - } + if (hasFixedTexture()) tex = fixedTexture; + float u00 = tex->getU(tileShapeZ0 * 16.0f); + float u11 = tex->getU(tileShapeZ1 * 16.0f); + float v00 = + tex->getV(SharedConstants::WORLD_RESOLUTION - tileShapeY1 * 16.0f); + float v11 = + tex->getV(SharedConstants::WORLD_RESOLUTION - tileShapeY0 * 16.0f); + if (xFlipTexture) { + float tmp = u00; + u00 = u11; + u11 = tmp; + } - if ( tileShapeZ0 < 0 || tileShapeZ1 > 1 ) - { - u00 = tex->getU0(); - u11 = tex->getU1(); - } - if ( tileShapeY0 < 0 || tileShapeY1 > 1 ) - { - v00 = tex->getV0(); - v11 = tex->getV1(); - } + if (tileShapeZ0 < 0 || tileShapeZ1 > 1) { + u00 = tex->getU0(); + u11 = tex->getU1(); + } + if (tileShapeY0 < 0 || tileShapeY1 > 1) { + v00 = tex->getV0(); + v11 = tex->getV1(); + } - float u01 = u11, u10 = u00, v01 = v00, v10 = v11; + float u01 = u11, u10 = u00, v01 = v00, v10 = v11; - if ( eastFlip == FLIP_CCW ) - { - u00 = tex->getU(tileShapeY0 * 16.0f); - v00 = tex->getV(SharedConstants::WORLD_RESOLUTION - tileShapeZ0 * 16.0f); - u11 = tex->getU(tileShapeY1 * 16.0f); - v11 = tex->getV(SharedConstants::WORLD_RESOLUTION - tileShapeZ1 * 16.0f); + if (eastFlip == FLIP_CCW) { + u00 = tex->getU(tileShapeY0 * 16.0f); + v00 = + tex->getV(SharedConstants::WORLD_RESOLUTION - tileShapeZ0 * 16.0f); + u11 = tex->getU(tileShapeY1 * 16.0f); + v11 = + tex->getV(SharedConstants::WORLD_RESOLUTION - tileShapeZ1 * 16.0f); - u01 = u11; - u10 = u00; - v01 = v00; - v10 = v11; - u01 = u00; - u10 = u11; - v00 = v11; - v11 = v01; - } - else if ( eastFlip == FLIP_CW ) - { - // reshape - u00 = tex->getU(SharedConstants::WORLD_RESOLUTION - tileShapeY1 * 16.0f); - v00 = tex->getV(tileShapeZ1 * 16.0f); - u11 = tex->getU(SharedConstants::WORLD_RESOLUTION - tileShapeY0 * 16.0f); - v11 = tex->getV(tileShapeZ0 * 16.0f); + u01 = u11; + u10 = u00; + v01 = v00; + v10 = v11; + u01 = u00; + u10 = u11; + v00 = v11; + v11 = v01; + } else if (eastFlip == FLIP_CW) { + // reshape + u00 = + tex->getU(SharedConstants::WORLD_RESOLUTION - tileShapeY1 * 16.0f); + v00 = tex->getV(tileShapeZ1 * 16.0f); + u11 = + tex->getU(SharedConstants::WORLD_RESOLUTION - tileShapeY0 * 16.0f); + v11 = tex->getV(tileShapeZ0 * 16.0f); - // rotate - u01 = u11; - u10 = u00; - v01 = v00; - v10 = v11; - u00 = u01; - u11 = u10; - v01 = v11; - v10 = v00; - } - else if ( eastFlip == FLIP_180 ) - { - u00 = tex->getU(SharedConstants::WORLD_RESOLUTION - tileShapeZ0 * 16.0f); - u11 = tex->getU(SharedConstants::WORLD_RESOLUTION - tileShapeZ1 * 16.0f); - v00 = tex->getV(tileShapeY1 * 16.0f); - v11 = tex->getV(tileShapeY0 * 16.0f); + // rotate + u01 = u11; + u10 = u00; + v01 = v00; + v10 = v11; + u00 = u01; + u11 = u10; + v01 = v11; + v10 = v00; + } else if (eastFlip == FLIP_180) { + u00 = + tex->getU(SharedConstants::WORLD_RESOLUTION - tileShapeZ0 * 16.0f); + u11 = + tex->getU(SharedConstants::WORLD_RESOLUTION - tileShapeZ1 * 16.0f); + v00 = tex->getV(tileShapeY1 * 16.0f); + v11 = tex->getV(tileShapeY0 * 16.0f); - u01 = u11; - u10 = u00; - v01 = v00; - v10 = v11; - } + u01 = u11; + u10 = u00; + v01 = v00; + v10 = v11; + } - float x1 = x + tileShapeX1; - float y0 = y + tileShapeY0; - float y1 = y + tileShapeY1; - float z0 = z + tileShapeZ0; - float z1 = z + tileShapeZ1; - - if ( applyAmbienceOcclusion ) - { - t->color( c1r, c1g, c1b ); - if ( SharedConstants::TEXTURE_LIGHTING ) t->tex2( tc1 ); - t->vertexUV( ( float )( x1 ), ( float )( y0 ), ( float )( z1 ), ( float )( u10 ), ( float )( v10 ) ); - t->color( c2r, c2g, c2b ); - if ( SharedConstants::TEXTURE_LIGHTING ) t->tex2( tc2 ); - t->vertexUV( ( float )( x1 ), ( float )( y0 ), ( float )( z0 ), ( float )( u11 ), ( float )( v11 ) ); - t->color( c3r, c3g, c3b ); - if ( SharedConstants::TEXTURE_LIGHTING ) t->tex2( tc3 ); - t->vertexUV( ( float )( x1 ), ( float )( y1 ), ( float )( z0 ), ( float )( u01 ), ( float )( v01 ) ); - t->color( c4r, c4g, c4b ); - if ( SharedConstants::TEXTURE_LIGHTING ) t->tex2( tc4 ); - t->vertexUV( ( float )( x1 ), ( float )( y1 ), ( float )( z1 ), ( float )( u00 ), ( float )( v00 ) ); - } - else - { - t->vertexUV( ( float )( x1 ), ( float )( y0 ), ( float )( z1 ), ( float )( u10 ), ( float )( v10 ) ); - t->vertexUV( ( float )( x1 ), ( float )( y0 ), ( float )( z0 ), ( float )( u11 ), ( float )( v11 ) ); - t->vertexUV( ( float )( x1 ), ( float )( y1 ), ( float )( z0 ), ( float )( u01 ), ( float )( v01 ) ); - t->vertexUV( ( float )( x1 ), ( float )( y1 ), ( float )( z1 ), ( float )( u00 ), ( float )( v00 ) ); - } + float x1 = x + tileShapeX1; + float y0 = y + tileShapeY0; + float y1 = y + tileShapeY1; + float z0 = z + tileShapeZ0; + float z1 = z + tileShapeZ1; + if (applyAmbienceOcclusion) { + t->color(c1r, c1g, c1b); + if (SharedConstants::TEXTURE_LIGHTING) t->tex2(tc1); + t->vertexUV((float)(x1), (float)(y0), (float)(z1), (float)(u10), + (float)(v10)); + t->color(c2r, c2g, c2b); + if (SharedConstants::TEXTURE_LIGHTING) t->tex2(tc2); + t->vertexUV((float)(x1), (float)(y0), (float)(z0), (float)(u11), + (float)(v11)); + t->color(c3r, c3g, c3b); + if (SharedConstants::TEXTURE_LIGHTING) t->tex2(tc3); + t->vertexUV((float)(x1), (float)(y1), (float)(z0), (float)(u01), + (float)(v01)); + t->color(c4r, c4g, c4b); + if (SharedConstants::TEXTURE_LIGHTING) t->tex2(tc4); + t->vertexUV((float)(x1), (float)(y1), (float)(z1), (float)(u00), + (float)(v00)); + } else { + t->vertexUV((float)(x1), (float)(y0), (float)(z1), (float)(u10), + (float)(v10)); + t->vertexUV((float)(x1), (float)(y0), (float)(z0), (float)(u11), + (float)(v11)); + t->vertexUV((float)(x1), (float)(y1), (float)(z0), (float)(u01), + (float)(v01)); + t->vertexUV((float)(x1), (float)(y1), (float)(z1), (float)(u00), + (float)(v00)); + } } -bool TileRenderer_SPU::canRender( int renderShape ) -{ - if ( renderShape == Tile_SPU::SHAPE_BLOCK ) return true; - if ( renderShape == Tile_SPU::SHAPE_TREE ) return true; - if ( renderShape == Tile_SPU::SHAPE_QUARTZ) return true; - if ( renderShape == Tile_SPU::SHAPE_CACTUS ) return true; - if ( renderShape == Tile_SPU::SHAPE_STAIRS ) return true; - if ( renderShape == Tile_SPU::SHAPE_FENCE ) return true; - if ( renderShape == Tile_SPU::SHAPE_EGG) return true; - if ( renderShape == Tile_SPU::SHAPE_ENTITYTILE_ANIMATED) return true; - if ( renderShape == Tile_SPU::SHAPE_FENCE_GATE) return true; - if ( renderShape == Tile_SPU::SHAPE_PISTON_BASE ) return true; - if ( renderShape == Tile_SPU::SHAPE_PORTAL_FRAME ) return true; - if ( renderShape == Tile_SPU::SHAPE_WALL) return true; - if ( renderShape == Tile_SPU::SHAPE_ANVIL) return true; - return false; +bool TileRenderer_SPU::canRender(int renderShape) { + if (renderShape == Tile_SPU::SHAPE_BLOCK) return true; + if (renderShape == Tile_SPU::SHAPE_TREE) return true; + if (renderShape == Tile_SPU::SHAPE_QUARTZ) return true; + if (renderShape == Tile_SPU::SHAPE_CACTUS) return true; + if (renderShape == Tile_SPU::SHAPE_STAIRS) return true; + if (renderShape == Tile_SPU::SHAPE_FENCE) return true; + if (renderShape == Tile_SPU::SHAPE_EGG) return true; + if (renderShape == Tile_SPU::SHAPE_ENTITYTILE_ANIMATED) return true; + if (renderShape == Tile_SPU::SHAPE_FENCE_GATE) return true; + if (renderShape == Tile_SPU::SHAPE_PISTON_BASE) return true; + if (renderShape == Tile_SPU::SHAPE_PORTAL_FRAME) return true; + if (renderShape == Tile_SPU::SHAPE_WALL) return true; + if (renderShape == Tile_SPU::SHAPE_ANVIL) return true; + return false; } -Icon_SPU *TileRenderer_SPU::getTexture(Tile_SPU *tile, ChunkRebuildData *level, int x, int y, int z, int face) -{ - return getTextureOrMissing(tile->getTexture(level, x, y, z, face)); +Icon_SPU* TileRenderer_SPU::getTexture(Tile_SPU* tile, ChunkRebuildData* level, + int x, int y, int z, int face) { + return getTextureOrMissing(tile->getTexture(level, x, y, z, face)); } -Icon_SPU *TileRenderer_SPU::getTexture(Tile_SPU *tile, int face, int data) -{ - return getTextureOrMissing(tile->getTexture(face, data)); +Icon_SPU* TileRenderer_SPU::getTexture(Tile_SPU* tile, int face, int data) { + return getTextureOrMissing(tile->getTexture(face, data)); } -Icon_SPU *TileRenderer_SPU::getTexture(Tile_SPU *tile, int face) -{ - return getTextureOrMissing(tile->getTexture(face)); +Icon_SPU* TileRenderer_SPU::getTexture(Tile_SPU* tile, int face) { + return getTextureOrMissing(tile->getTexture(face)); } -Icon_SPU *TileRenderer_SPU::getTexture(Tile_SPU *tile) -{ - return getTextureOrMissing(tile->getTexture(Facing::UP)); +Icon_SPU* TileRenderer_SPU::getTexture(Tile_SPU* tile) { + return getTextureOrMissing(tile->getTexture(Facing::UP)); } -Icon_SPU *TileRenderer_SPU::getTextureOrMissing(Icon_SPU *Icon_SPU) -{ - if (Icon_SPU == NULL) - { - assert(0); - // return minecraft->textures->getMissingIcon_SPU(Icon_SPU::TYPE_TERRAIN); - } - return Icon_SPU; -} \ No newline at end of file +Icon_SPU* TileRenderer_SPU::getTextureOrMissing(Icon_SPU* Icon_SPU) { + if (Icon_SPU == NULL) { + assert(0); + // return + //minecraft->textures->getMissingIcon_SPU(Icon_SPU::TYPE_TERRAIN); + } + return Icon_SPU; +} diff --git a/Minecraft.Client/Rendering/Camera.cpp b/Minecraft.Client/Rendering/Camera.cpp index 0b77091af..fdfbb1dad 100644 --- a/Minecraft.Client/Rendering/Camera.cpp +++ b/Minecraft.Client/Rendering/Camera.cpp @@ -121,4 +121,4 @@ int Camera::getBlockAt(Level* level, std::shared_ptr player, } } return t; -} \ No newline at end of file +} diff --git a/Minecraft.Client/Rendering/EntityRenderers/FishingHookRenderer.cpp b/Minecraft.Client/Rendering/EntityRenderers/FishingHookRenderer.cpp index 9d4b7e0f1..b43acd1dd 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/FishingHookRenderer.cpp +++ b/Minecraft.Client/Rendering/EntityRenderers/FishingHookRenderer.cpp @@ -58,22 +58,22 @@ void FishingHookRenderer::render(std::shared_ptr _hook, double x, float swing = hook->owner->getAttackAnim(a); float swing2 = (float)Mth::sin(sqrt(swing) * PI); - Vec3* vv = Vec3::newTemp(-0.5, 0.03, 0.8); - vv->xRot(-(hook->owner->xRotO + + Vec3 vv(-0.5, 0.03, 0.8); + vv.xRot(-(hook->owner->xRotO + (hook->owner->xRot - hook->owner->xRotO) * a) * PI / 180); - vv->yRot(-(hook->owner->yRotO + + vv.yRot(-(hook->owner->yRotO + (hook->owner->yRot - hook->owner->yRotO) * a) * PI / 180); - vv->yRot(swing2 * 0.5f); - vv->xRot(-swing2 * 0.7f); + vv.yRot(swing2 * 0.5f); + vv.xRot(-swing2 * 0.7f); double xp = - hook->owner->xo + (hook->owner->x - hook->owner->xo) * a + vv->x; + hook->owner->xo + (hook->owner->x - hook->owner->xo) * a + vv.x; double yp = - hook->owner->yo + (hook->owner->y - hook->owner->yo) * a + vv->y; + hook->owner->yo + (hook->owner->y - hook->owner->yo) * a + vv.y; double zp = - hook->owner->zo + (hook->owner->z - hook->owner->zo) * a + vv->z; + hook->owner->zo + (hook->owner->z - hook->owner->zo) * a + vv.z; double yOffset = hook->owner == std::dynamic_pointer_cast( Minecraft::GetInstance()->player) ? 0 diff --git a/Minecraft.Client/Rendering/EntityRenderers/MinecartRenderer.cpp b/Minecraft.Client/Rendering/EntityRenderers/MinecartRenderer.cpp index 83f81f10a..f5ed5b766 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/MinecartRenderer.cpp +++ b/Minecraft.Client/Rendering/EntityRenderers/MinecartRenderer.cpp @@ -54,13 +54,13 @@ void MinecartRenderer::render(std::shared_ptr _cart, double x, double y, y += (p0->y + p1->y) / 2 - yy; z += p->z - zz; - Vec3* dir = Vec3::newTemp(-p0->x, -p0->y, -p0->z); - *dir = dir->add(p1->x, p1->y, p1->z); - if (dir->length() == 0) { + Vec3 dir(-p0->x, -p0->y, -p0->z); + dir = dir.add(p1->x, p1->y, p1->z); + if (dir.length() == 0) { } else { - *dir = dir->normalize(); - rot = (float)(atan2(dir->z, dir->x) * 180 / PI); - xRot = (float)(atan(dir->y) * 73); + dir = dir.normalize(); + rot = (float)(atan2(dir.z, dir.x) * 180 / PI); + xRot = (float)(atan(dir.y) * 73); } } glTranslatef((float)x, (float)y, (float)z); diff --git a/Minecraft.Client/Rendering/EntityRenderers/TileRenderer.cpp b/Minecraft.Client/Rendering/EntityRenderers/TileRenderer.cpp index e78b97a3d..08ae72935 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/TileRenderer.cpp +++ b/Minecraft.Client/Rendering/EntityRenderers/TileRenderer.cpp @@ -1045,9 +1045,8 @@ bool TileRenderer::tesselateAnvilInWorld(AnvilTile* tt, int x, int y, int z, float TileRenderer::tesselateAnvilPiece(AnvilTile* tt, int x, int y, int z, int part, float bottom, float width, - float height, float length, - bool rotate, bool render, - int data) { + float height, float length, bool rotate, + bool render, int data) { if (rotate) { float swap = width; width = length; @@ -4068,9 +4067,11 @@ bool TileRenderer::tesselateCrossInWorld(Tile* tt, int x, int y, int z) { float zt = (float)z; if (tt == Tile::tallgrass) { - // 4jcraft add a bunch of casts to prevent overflow (i pray to god) - int64_t seed = ((int64_t)x * 3129871) ^ ((int64_t)z * 116129781L) ^ ((int64_t)y); - seed = (int64_t)(((uint64_t)seed * (uint64_t)seed * 42317861ULL) + ((uint64_t)seed * 11ULL)); + // 4jcraft add a bunch of casts to prevent overflow (i pray to god) + int64_t seed = + ((int64_t)x * 3129871) ^ ((int64_t)z * 116129781L) ^ ((int64_t)y); + seed = (int64_t)(((uint64_t)seed * (uint64_t)seed * 42317861ULL) + + ((uint64_t)seed * 11ULL)); xt += ((((seed >> 16) & 0xf) / 15.0f) - 0.5f) * 0.5f; yt += ((((seed >> 20) & 0xf) / 15.0f) - 1.0f) * 0.2f; @@ -4326,8 +4327,10 @@ bool TileRenderer::tesselateLilypadInWorld(Tile* tt, int x, int y, int z) { float v1 = tex->getV1(true); // 4jcraft add a bunch of casts to prevent overflow (i pray to god) - int64_t seed = ((int64_t)x * 3129871) ^ ((int64_t)z * 116129781L) ^ ((int64_t)y); - seed = (int64_t)(((uint64_t)seed * (uint64_t)seed * 42317861ULL) + ((uint64_t)seed * 11ULL)); + int64_t seed = + ((int64_t)x * 3129871) ^ ((int64_t)z * 116129781L) ^ ((int64_t)y); + seed = (int64_t)(((uint64_t)seed * (uint64_t)seed * 42317861ULL) + + ((uint64_t)seed * 11ULL)); int dir = (int)((seed >> 16) & 0x3); diff --git a/Minecraft.Client/Rendering/GameRenderer.cpp b/Minecraft.Client/Rendering/GameRenderer.cpp index 0946c50b9..2938a092f 100644 --- a/Minecraft.Client/Rendering/GameRenderer.cpp +++ b/Minecraft.Client/Rendering/GameRenderer.cpp @@ -305,8 +305,8 @@ void GameRenderer::pick(float a) { } Vec3* b = mc->cameraTargetPlayer->getViewVector(a); - Vec3* to = Vec3::newTemp(b->x * range, b->y * range, b->z * range); - *to = to->add(from->x, from->y, from->z); + Vec3 to(b->x * range, b->y * range, b->z * range); + to = to.add(from->x, from->y, from->z); hovered = nullptr; float overlap = 1; std::vector >* objects = mc->level->getEntities( @@ -323,7 +323,7 @@ void GameRenderer::pick(float a) { float rr = e->getPickRadius(); AABB* bb = e->bb->grow(rr, rr, rr); - HitResult* p = bb->clip(from, to); + HitResult* p = bb->clip(from, &to); if (bb->contains(from)) { if (0 < nearest || nearest == 0) { hovered = e; @@ -524,11 +524,12 @@ void GameRenderer::moveCameraToPlayer(float a) { // 4J - corrected bug here where zo was also added to x // component - HitResult* hr = mc->level->clip( - Vec3::newTemp(x + xo, y + yo, z + zo), - Vec3::newTemp(x - xd + xo, y - yd + yo, z - zd + zo)); + Vec3 a(x + xo, y + yo, z + zo); + Vec3 b(x - xd + xo, y - yd + yo, z - zd + zo); + HitResult* hr = mc->level->clip(&a, &b); if (hr != NULL) { - double dist = hr->pos.distanceTo(*Vec3::newTemp(x, y, z)); + Vec3 p(x, y, z); + double dist = hr->pos.distanceTo(p); if (dist < cameraDist) cameraDist = dist; delete hr; } @@ -1865,10 +1866,10 @@ void GameRenderer::setupClearColor(float a) { fb = (float)fogColor->z; if (mc->options->viewDistance < 2) { - Vec3* sunAngle = Mth::sin(level->getSunAngle(a)) > 0 - ? Vec3::newTemp(-1, 0, 0) - : Vec3::newTemp(1, 0, 0); - float d = (float)player->getViewVector(a)->dot(*sunAngle); + Vec3 sunAngle = Mth::sin(level->getSunAngle(a)) > 0 + ? Vec3(-1, 0, 0) + : Vec3(1, 0, 0); + float d = (float)player->getViewVector(a)->dot(sunAngle); if (d < 0) d = 0; if (d > 0) { float* c = diff --git a/Minecraft.Client/Rendering/Lighting.cpp b/Minecraft.Client/Rendering/Lighting.cpp index 73e700837..4182a9fe3 100644 --- a/Minecraft.Client/Rendering/Lighting.cpp +++ b/Minecraft.Client/Rendering/Lighting.cpp @@ -22,16 +22,16 @@ void Lighting::turnOn() { float d = 0.6f; float s = 0.0f; - Vec3* l = Vec3::newTemp(0.2f, 1.0f, -0.7f); - *l = l->normalize(); - glLight(GL_LIGHT0, GL_POSITION, getBuffer(l->x, l->y, l->z, 0)); + Vec3 l(0.2f, 1.0f, -0.7f); + l = l.normalize(); + glLight(GL_LIGHT0, GL_POSITION, getBuffer(l.x, l.y, l.z, 0)); glLight(GL_LIGHT0, GL_DIFFUSE, getBuffer(d, d, d, 1)); glLight(GL_LIGHT0, GL_AMBIENT, getBuffer(0.0f, 0.0f, 0.0f, 1.0f)); glLight(GL_LIGHT0, GL_SPECULAR, getBuffer(s, s, s, 1.0f)); - l = Vec3::newTemp(-0.2f, 1.0f, 0.7f); - *l = l->normalize(); - glLight(GL_LIGHT1, GL_POSITION, getBuffer(l->x, l->y, l->z, 0)); + l = Vec3(-0.2f, 1.0f, 0.7f); + l = l.normalize(); + glLight(GL_LIGHT1, GL_POSITION, getBuffer(l.x, l.y, l.z, 0)); glLight(GL_LIGHT1, GL_DIFFUSE, getBuffer(d, d, d, 1)); glLight(GL_LIGHT1, GL_AMBIENT, getBuffer(0.0f, 0.0f, 0.0f, 1.0f)); glLight(GL_LIGHT1, GL_SPECULAR, getBuffer(s, s, s, 1.0f)); diff --git a/Minecraft.Client/Rendering/Vertex.cpp b/Minecraft.Client/Rendering/Vertex.cpp index b4c70ae19..0145619e5 100644 --- a/Minecraft.Client/Rendering/Vertex.cpp +++ b/Minecraft.Client/Rendering/Vertex.cpp @@ -19,4 +19,4 @@ Vertex::Vertex(Vec3* pos, float u, float v) { this->pos = pos; this->u = u; this->v = v; -} \ No newline at end of file +} diff --git a/Minecraft.World/AI/Goals/AvoidPlayerGoal.cpp b/Minecraft.World/AI/Goals/AvoidPlayerGoal.cpp index 59a6e84f4..ab5af98d0 100644 --- a/Minecraft.World/AI/Goals/AvoidPlayerGoal.cpp +++ b/Minecraft.World/AI/Goals/AvoidPlayerGoal.cpp @@ -64,10 +64,10 @@ bool AvoidPlayerGoal::canUse() { delete entities; } + Vec3 avoid_pos(toAvoid.lock()->x, toAvoid.lock()->y, toAvoid.lock()->z); Vec3* pos = RandomPos::getPosAvoid( std::dynamic_pointer_cast(mob->shared_from_this()), 16, - 7, - Vec3::newTemp(toAvoid.lock()->x, toAvoid.lock()->y, toAvoid.lock()->z)); + 7, &avoid_pos); if (pos == NULL) return false; if (toAvoid.lock()->distanceToSqr(pos->x, pos->y, pos->z) < toAvoid.lock()->distanceToSqr(mob->shared_from_this())) diff --git a/Minecraft.World/AI/Goals/MoveIndoorsGoal.cpp b/Minecraft.World/AI/Goals/MoveIndoorsGoal.cpp index 01b7b6cba..6ebcef842 100644 --- a/Minecraft.World/AI/Goals/MoveIndoorsGoal.cpp +++ b/Minecraft.World/AI/Goals/MoveIndoorsGoal.cpp @@ -44,12 +44,11 @@ void MoveIndoorsGoal::start() { } if (mob->distanceToSqr(_doorInfo->getIndoorX(), _doorInfo->y, _doorInfo->getIndoorZ()) > 16 * 16) { + Vec3 towards(_doorInfo->getIndoorX() + 0.5, _doorInfo->getIndoorY(), + _doorInfo->getIndoorZ() + 0.5); Vec3* pos = RandomPos::getPosTowards( std::dynamic_pointer_cast(mob->shared_from_this()), - 14, 3, - Vec3::newTemp(_doorInfo->getIndoorX() + 0.5, - _doorInfo->getIndoorY(), - _doorInfo->getIndoorZ() + 0.5)); + 14, 3, &towards); if (pos != NULL) mob->getNavigation()->moveTo(pos->x, pos->y, pos->z, 1.0f); } else diff --git a/Minecraft.World/AI/Goals/MoveThroughVillageGoal.cpp b/Minecraft.World/AI/Goals/MoveThroughVillageGoal.cpp index a5c511525..82f0308ff 100644 --- a/Minecraft.World/AI/Goals/MoveThroughVillageGoal.cpp +++ b/Minecraft.World/AI/Goals/MoveThroughVillageGoal.cpp @@ -47,9 +47,10 @@ bool MoveThroughVillageGoal::canUse() { mob->getNavigation()->setCanOpenDoors(oldCanOpenDoors); if (path != NULL) return true; + Vec3 towards(_doorInfo->x, _doorInfo->y, _doorInfo->z); Vec3* pos = RandomPos::getPosTowards( std::dynamic_pointer_cast(mob->shared_from_this()), 10, - 7, Vec3::newTemp(_doorInfo->x, _doorInfo->y, _doorInfo->z)); + 7, &towards); if (pos == NULL) return false; mob->getNavigation()->setCanOpenDoors(false); delete path; diff --git a/Minecraft.World/AI/Goals/MoveTowardsRestrictionGoal.cpp b/Minecraft.World/AI/Goals/MoveTowardsRestrictionGoal.cpp index b8c2f9de6..5b8efe271 100644 --- a/Minecraft.World/AI/Goals/MoveTowardsRestrictionGoal.cpp +++ b/Minecraft.World/AI/Goals/MoveTowardsRestrictionGoal.cpp @@ -17,10 +17,11 @@ MoveTowardsRestrictionGoal::MoveTowardsRestrictionGoal(PathfinderMob* mob, bool MoveTowardsRestrictionGoal::canUse() { if (mob->isWithinRestriction()) return false; - Pos* towards = mob->getRestrictCenter(); + Pos* toward = mob->getRestrictCenter(); + Vec3 towards(toward->x, toward->y, toward->z); Vec3* pos = RandomPos::getPosTowards( std::dynamic_pointer_cast(mob->shared_from_this()), 16, - 7, Vec3::newTemp(towards->x, towards->y, towards->z)); + 7, &towards); if (pos == NULL) return false; wantedX = pos->x; wantedY = pos->y; @@ -34,4 +35,4 @@ bool MoveTowardsRestrictionGoal::canContinueToUse() { void MoveTowardsRestrictionGoal::start() { mob->getNavigation()->moveTo(wantedX, wantedY, wantedZ, speedModifier); -} \ No newline at end of file +} diff --git a/Minecraft.World/AI/Goals/MoveTowardsTargetGoal.cpp b/Minecraft.World/AI/Goals/MoveTowardsTargetGoal.cpp index a218b78f3..bc3be03d8 100644 --- a/Minecraft.World/AI/Goals/MoveTowardsTargetGoal.cpp +++ b/Minecraft.World/AI/Goals/MoveTowardsTargetGoal.cpp @@ -20,9 +20,10 @@ bool MoveTowardsTargetGoal::canUse() { if (target.lock() == NULL) return false; if (target.lock()->distanceToSqr(mob->shared_from_this()) > within * within) return false; + Vec3 towards(target.lock()->x, target.lock()->y, target.lock()->z); Vec3* pos = RandomPos::getPosTowards( std::dynamic_pointer_cast(mob->shared_from_this()), 16, - 7, Vec3::newTemp(target.lock()->x, target.lock()->y, target.lock()->z)); + 7, &towards); if (pos == NULL) return false; wantedX = pos->x; wantedY = pos->y; diff --git a/Minecraft.World/Entities/LivingEntity.cpp b/Minecraft.World/Entities/LivingEntity.cpp index 571f69273..47a004096 100644 --- a/Minecraft.World/Entities/LivingEntity.cpp +++ b/Minecraft.World/Entities/LivingEntity.cpp @@ -792,18 +792,18 @@ void LivingEntity::breakItem(std::shared_ptr itemInstance) { 0.8f + level->random->nextFloat() * 0.4f); for (int i = 0; i < 5; i++) { - Vec3* d = Vec3::newTemp((random->nextFloat() - 0.5) * 0.1, + Vec3 d = Vec3((random->nextFloat() - 0.5) * 0.1, Math::random() * 0.1 + 0.1, 0); - d->xRot(-xRot * PI / 180); - d->yRot(-yRot * PI / 180); + d.xRot(-xRot * PI / 180); + d.yRot(-yRot * PI / 180); - Vec3* p = Vec3::newTemp((random->nextFloat() - 0.5) * 0.3, + Vec3 p = Vec3((random->nextFloat() - 0.5) * 0.3, -random->nextFloat() * 0.6 - 0.3, 0.6); - p->xRot(-xRot * PI / 180); - p->yRot(-yRot * PI / 180); - *p = p->add(x, y + getHeadHeight(), z); + p.xRot(-xRot * PI / 180); + p.yRot(-yRot * PI / 180); + p = p.add(x, y + getHeadHeight(), z); level->addParticle(PARTICLE_ICONCRACK(itemInstance->getItem()->id, 0), - p->x, p->y, p->z, d->x, d->y + 0.05, d->z); + p.x, p.y, p.z, d.x, d.y + 0.05, d.z); } } @@ -1641,10 +1641,10 @@ void LivingEntity::take(std::shared_ptr e, int orgCount) { } bool LivingEntity::canSee(std::shared_ptr target) { - HitResult* hres = level->clip( - Vec3::newTemp(x, y + getHeadHeight(), z), - Vec3::newTemp(target->x, target->y + target->getHeadHeight(), - target->z)); + Vec3 a{x, y + getHeadHeight(), z}; + Vec3 b{target->x, target->y + target->getHeadHeight(), target->z}; + + HitResult* hres = level->clip(&a, &b); bool retVal = (hres == NULL); delete hres; return retVal; @@ -1690,11 +1690,11 @@ Vec3* LivingEntity::getPos(float a) { } HitResult* LivingEntity::pick(double range, float a) { - Vec3* from = getPos(a); - Vec3* b = getViewVector(a); - Vec3* to = Vec3::newTemp(b->x * range, b->y * range, b->z * range); - *to = to->add(from->x, from->y, from->z); - return level->clip(from, to); + Vec3 from = *getPos(a); + Vec3 b = *getViewVector(a); + Vec3 to{b.x * range, b.y * range, b.z * range}; + to = to.add(from.x, from.y, from.z); + return level->clip(&from, &to); } bool LivingEntity::isEffectiveAi() { return !level->isClientSide; } diff --git a/Minecraft.World/Entities/Mobs/Arrow.cpp b/Minecraft.World/Entities/Mobs/Arrow.cpp index 1a5db2c82..5de30c9a4 100644 --- a/Minecraft.World/Entities/Mobs/Arrow.cpp +++ b/Minecraft.World/Entities/Mobs/Arrow.cpp @@ -184,7 +184,8 @@ void Arrow::tick() { if (t > 0) { Tile::tiles[t]->updateShape(level, xTile, yTile, zTile); AABB* aabb = Tile::tiles[t]->getAABB(level, xTile, yTile, zTile); - if (aabb != NULL && aabb->contains(Vec3::newTemp(x, y, z))) { + Vec3 pos{x, y, z}; + if (aabb != NULL && aabb->contains(&pos)) { inGround = true; } } @@ -217,15 +218,17 @@ void Arrow::tick() { flightTime++; } - Vec3* from = Vec3::newTemp(x, y, z); - Vec3* to = Vec3::newTemp(x + xd, y + yd, z + zd); - HitResult* res = level->clip(from, to, false, true); + Vec3 from{x, y, z}; + Vec3 to{x + xd, y + yd, z + zd}; + HitResult* res = level->clip(&from, &to, false, true); + + from = Vec3{x, y, z}; + to = Vec3{x + xd, y + yd, z + zd}; - from = Vec3::newTemp(x, y, z); - to = Vec3::newTemp(x + xd, y + yd, z + zd); if (res != NULL) { - to = Vec3::newTemp(res->pos.x, res->pos.y, res->pos.z); + to = Vec3{res->pos.x, res->pos.y, res->pos.z}; } + std::shared_ptr hitEntity = nullptr; std::vector >* objects = level->getEntities( shared_from_this(), this->bb->expand(xd, yd, zd)->grow(1, 1, 1)); @@ -237,9 +240,9 @@ void Arrow::tick() { float rr = 0.3f; AABB* bb = e->bb->grow(rr, rr, rr); - HitResult* p = bb->clip(from, to); + HitResult* p = bb->clip(&from, &to); if (p != NULL) { - double dd = from->distanceTo(p->pos); + double dd = from.distanceTo(p->pos); if (dd < nearest || nearest == 0) { hitEntity = e; nearest = dd; diff --git a/Minecraft.World/Entities/Mobs/EnderDragon.cpp b/Minecraft.World/Entities/Mobs/EnderDragon.cpp index b2726950b..5ef66d371 100644 --- a/Minecraft.World/Entities/Mobs/EnderDragon.cpp +++ b/Minecraft.World/Entities/Mobs/EnderDragon.cpp @@ -314,9 +314,9 @@ void EnderDragon::aiStep() { // v->y, v->z, lSteps); unsigned int d = 0; for(unsigned int d = 1; // d < 3; ++d) { - Vec3* vN = Vec3::newTemp(v->x, v->y, v->z); - *vN = v->normalize(); - vN->yRot(-PI / 4); + Vec3 vN = Vec3{v->x, v->y, v->z}.normalize(); + vN.yRot(-PI / 4); + for (unsigned int i = 0; i < 8; ++i) { if (getSynchedAction() == e_EnderdragonAction_Landing) { // for(unsigned int j = 0; j < 6; ++j) @@ -335,9 +335,9 @@ void EnderDragon::aiStep() { zP += (level->random->nextBoolean() ? 1 : -1) * level->random->nextFloat() / 2; level->addParticle(eParticleType_dragonbreath, xP, - yP, zP, (-vN->x * 0.08) + xd, - (-vN->y * 0.3) + yd, - (-vN->z * 0.08) + zd); + yP, zP, (-vN.x * 0.08) + xd, + (-vN.y * 0.3) + yd, + (-vN.z * 0.08) + zd); } } else { double yVelocity = 0.6; @@ -357,12 +357,12 @@ void EnderDragon::aiStep() { zP += (level->random->nextBoolean() ? 1 : -1) * level->random->nextFloat() / 2; level->addParticle(eParticleType_dragonbreath, xP, - yP, zP, -vN->x * xzVelocity * j, - -vN->y * yVelocity, - -vN->z * xzVelocity * j); + yP, zP, -vN.x * xzVelocity * j, + -vN.y * yVelocity, + -vN.z * xzVelocity * j); } } - vN->yRot(PI / (2 * 8)); + vN.yRot(PI / (2 * 8)); } } } else if (getSynchedAction() == @@ -478,15 +478,13 @@ void EnderDragon::aiStep() { // No movement } else if (getSynchedAction() == e_EnderdragonAction_Sitting_Scanning) { if (attackTarget != NULL) { - Vec3* aim = Vec3::newTemp((attackTarget->x - x), 0, - (attackTarget->z - z)); - *aim = aim->normalize(); + Vec3 aim = Vec3((attackTarget->x - x), 0, (attackTarget->z - z)) + .normalize(); - Vec3* dir = Vec3::newTemp(sin(yRot * PI / 180), 0, - -cos(yRot * PI / 180)); + Vec3 dir = Vec3(sin(yRot * PI / 180), 0, -cos(yRot * PI / 180)) + .normalize(); - *dir = dir->normalize(); - float dot = (float)dir->dot(*aim); + float dot = (float)dir.dot(aim); float angleDegs = acos(dot) * 180 / PI; angleDegs = angleDegs + 0.5f; @@ -564,14 +562,12 @@ void EnderDragon::aiStep() { if (yRotD > 50) yRotD = 50; if (yRotD < -50) yRotD = -50; - Vec3* aim = - Vec3::newTemp((xTarget - x), (yTarget - y), (zTarget - z)); - *aim = aim->normalize(); + Vec3 aim = + Vec3((xTarget - x), (yTarget - y), (zTarget - z)).normalize(); - Vec3* dir = - Vec3::newTemp(sin(yRot * PI / 180), yd, -cos(yRot * PI / 180)); - *dir = dir->normalize(); - float dot = (float)(dir->dot(*aim) + 0.5f) / 1.5f; + Vec3 dir = Vec3(sin(yRot * PI / 180), yd, -cos(yRot * PI / 180)) + .normalize(); + float dot = (float)(dir.dot(aim) + 0.5f) / 1.5f; if (dot < 0) dot = 0; yRotA *= 0.80f; @@ -595,9 +591,8 @@ void EnderDragon::aiStep() { move(xd, yd, zd); } - Vec3* actual = Vec3::newTemp(xd, yd, zd); - *actual = actual->normalize(); - float slide = (float)(actual->dot(*dir) + 1) / 2.0f; + Vec3 actual = Vec3(xd, yd, zd).normalize(); + float slide = (float)(actual.dot(dir) + 1) / 2.0f; slide = 0.8f + 0.15f * slide; xd *= slide; @@ -738,15 +733,13 @@ void EnderDragon::aiStep() { maxDist * maxDist) { if (this->canSee(attackTarget)) { m_fireballCharge++; - Vec3* aim = Vec3::newTemp((attackTarget->x - x), 0, - (attackTarget->z - z)); - *aim = aim->normalize(); + Vec3 aim = Vec3((attackTarget->x - x), 0, (attackTarget->z - z)) + .normalize(); - Vec3* dir = Vec3::newTemp(sin(yRot * PI / 180), 0, - -cos(yRot * PI / 180)); - *dir = dir->normalize(); + Vec3 dir = Vec3(sin(yRot * PI / 180), 0, -cos(yRot * PI / 180)) + .normalize(); - float dot = (float)dir->dot(*aim); + float dot = (float)dir.dot(aim); float angleDegs = acos(dot) * 180 / PI; angleDegs = angleDegs + 0.5f; @@ -985,13 +978,13 @@ void EnderDragon::findNewTarget() { int targetNodeIndex = 0; if (playerNearestToEgg != NULL) { - Vec3* aim = Vec3::newTemp(playerNearestToEgg->x, 0, - playerNearestToEgg->z); - *aim = aim->normalize(); + Vec3 aim = Vec3(playerNearestToEgg->x, 0, playerNearestToEgg->z) + .normalize(); + // app.DebugPrintf("Final marker node near (%f,%d,%f)\n", // -aim->x*40,105,-aim->z*40 ); targetNodeIndex = - findClosestNode(-aim->x * 40, 105.0, -aim->z * 40); + findClosestNode(-aim.x * 40, 105.0, -aim.z * 40); } else { targetNodeIndex = findClosestNode(40.0, eggHeight, 0.0); } diff --git a/Minecraft.World/Entities/Mobs/EnderMan.cpp b/Minecraft.World/Entities/Mobs/EnderMan.cpp index 3e2586874..d559c2056 100644 --- a/Minecraft.World/Entities/Mobs/EnderMan.cpp +++ b/Minecraft.World/Entities/Mobs/EnderMan.cpp @@ -117,13 +117,13 @@ bool EnderMan::isLookingAtMe(std::shared_ptr player) { Vec3* look = player->getViewVector(1); *look = look->normalize(); - Vec3* dir = Vec3::newTemp( - x - player->x, - (bb->y0 + bbHeight / 2) - (player->y + player->getHeadHeight()), - z - player->z); - double dist = dir->length(); - *dir = dir->normalize(); - double dot = look->dot(*dir); + Vec3 dir{x - player->x, + (bb->y0 + bbHeight / 2) - (player->y + player->getHeadHeight()), + z - player->z}; + + double dist = dir.length(); + dir = dir.normalize(); + double dot = look->dot(dir); if (dot > 1 - 0.025 / dist) { return player->canSee(shared_from_this()); } @@ -251,13 +251,13 @@ bool EnderMan::teleport() { } bool EnderMan::teleportTowards(std::shared_ptr e) { - Vec3* dir = Vec3::newTemp( - x - e->x, bb->y0 + bbHeight / 2 - e->y + e->getHeadHeight(), z - e->z); - *dir = dir->normalize(); + Vec3 dir{x - e->x, bb->y0 + bbHeight / 2 - e->y + e->getHeadHeight(), + z - e->z}; + dir = dir.normalize(); double d = 16; - double xx = x + (random->nextDouble() - 0.5) * 8 - dir->x * d; - double yy = y + (random->nextInt(16) - 8) - dir->y * d; - double zz = z + (random->nextDouble() - 0.5) * 8 - dir->z * d; + double xx = x + (random->nextDouble() - 0.5) * 8 - dir.x * d; + double yy = y + (random->nextInt(16) - 8) - dir.y * d; + double zz = z + (random->nextDouble() - 0.5) * 8 - dir.z * d; return teleport(xx, yy, zz); } diff --git a/Minecraft.World/Entities/Mobs/Fireball.cpp b/Minecraft.World/Entities/Mobs/Fireball.cpp index c7e1a805d..68b12a435 100644 --- a/Minecraft.World/Entities/Mobs/Fireball.cpp +++ b/Minecraft.World/Entities/Mobs/Fireball.cpp @@ -166,14 +166,14 @@ void Fireball::tick() { } MemSect(41); - Vec3* from = Vec3::newTemp(x, y, z); - Vec3* to = Vec3::newTemp(x + xd, y + yd, z + zd); - HitResult* res = level->clip(from, to); + Vec3 from(x, y, z); + Vec3 to(x + xd, y + yd, z + zd); + HitResult* res = level->clip(&from, &to); - from = Vec3::newTemp(x, y, z); - to = Vec3::newTemp(x + xd, y + yd, z + zd); + from = Vec3(x, y, z); + to = Vec3(x + xd, y + yd, z + zd); if (res != NULL) { - *to = Vec3{res->pos.x, res->pos.y, res->pos.z}; + to = Vec3{res->pos.x, res->pos.y, res->pos.z}; } std::shared_ptr hitEntity = nullptr; std::vector >* objects = level->getEntities( @@ -188,9 +188,9 @@ void Fireball::tick() { float rr = 0.3f; AABB* bb = e->bb->grow(rr, rr, rr); - HitResult* p = bb->clip(from, to); + HitResult* p = bb->clip(&from, &to); if (p != NULL) { - double dd = from->distanceTo(p->pos); + double dd = from.distanceTo(p->pos); if (dd < nearest || nearest == 0) { hitEntity = e; nearest = dd; diff --git a/Minecraft.World/Entities/Mobs/FishingHook.cpp b/Minecraft.World/Entities/Mobs/FishingHook.cpp index 74351cc06..b8cc293bf 100644 --- a/Minecraft.World/Entities/Mobs/FishingHook.cpp +++ b/Minecraft.World/Entities/Mobs/FishingHook.cpp @@ -203,14 +203,14 @@ void FishingHook::tick() { flightTime++; } - Vec3* from = Vec3::newTemp(x, y, z); - Vec3* to = Vec3::newTemp(x + xd, y + yd, z + zd); - HitResult* res = level->clip(from, to); + Vec3 from(x, y, z); + Vec3 to(x + xd, y + yd, z + zd); + HitResult* res = level->clip(&from, &to); - from = Vec3::newTemp(x, y, z); - to = Vec3::newTemp(x + xd, y + yd, z + zd); + from = Vec3(x, y, z); + to = Vec3(x + xd, y + yd, z + zd); if (res != NULL) { - to = Vec3::newTemp(res->pos.x, res->pos.y, res->pos.z); + to = Vec3(res->pos.x, res->pos.y, res->pos.z); } std::shared_ptr hitEntity = nullptr; std::vector >* objects = level->getEntities( @@ -223,9 +223,9 @@ void FishingHook::tick() { float rr = 0.3f; AABB* bb = e->bb->grow(rr, rr, rr); - HitResult* p = bb->clip(from, to); + HitResult* p = bb->clip(&from, &to); if (p != NULL) { - double dd = from->distanceTo(p->pos); + double dd = from.distanceTo(p->pos); if (dd < nearest || nearest == 0) { hitEntity = e; nearest = dd; diff --git a/Minecraft.World/Entities/Mobs/Minecart.cpp b/Minecraft.World/Entities/Mobs/Minecart.cpp index 182a7c5dd..273845676 100644 --- a/Minecraft.World/Entities/Mobs/Minecart.cpp +++ b/Minecraft.World/Entities/Mobs/Minecart.cpp @@ -724,13 +724,13 @@ void Minecart::push(std::shared_ptr e) { // other // Fix for #38882 - TU5: Gameplay: Minecart with furnace is not // able to move another minecart on the rail. - Vec3* dir = Vec3::newTemp(xo, 0, zo); - *dir = dir->normalize(); - Vec3* facing = - Vec3::newTemp(cos(yRot * PI / 180), 0, sin(yRot * PI / 180)); - *facing = facing->normalize(); + Vec3 dir(xo, 0, zo); + dir = dir.normalize(); - double dot = abs(dir->dot(*facing)); + Vec3 facing(cos(yRot * PI / 180), 0, sin(yRot * PI / 180)); + facing = facing.normalize(); + + double dot = abs(dir.dot(facing)); if (dot < 0.8f) { return; diff --git a/Minecraft.World/Entities/Throwable.cpp b/Minecraft.World/Entities/Throwable.cpp index 316b08313..93e9a9701 100644 --- a/Minecraft.World/Entities/Throwable.cpp +++ b/Minecraft.World/Entities/Throwable.cpp @@ -135,14 +135,14 @@ void Throwable::tick() { flightTime++; } - Vec3* from = Vec3::newTemp(x, y, z); - Vec3* to = Vec3::newTemp(x + xd, y + yd, z + zd); - HitResult* res = level->clip(from, to); + Vec3 from(x, y, z); + Vec3 to(x + xd, y + yd, z + zd); + HitResult* res = level->clip(&from, &to); - from = Vec3::newTemp(x, y, z); - to = Vec3::newTemp(x + xd, y + yd, z + zd); + from = Vec3(x, y, z); + to = Vec3(x + xd, y + yd, z + zd); if (res != NULL) { - to = Vec3::newTemp(res->pos.x, res->pos.y, res->pos.z); + to = Vec3(res->pos.x, res->pos.y, res->pos.z); } if (!level->isClientSide) { @@ -157,9 +157,9 @@ void Throwable::tick() { float rr = 0.3f; AABB* bb = e->bb->grow(rr, rr, rr); - HitResult* p = bb->clip(from, to); + HitResult* p = bb->clip(&from, &to); if (p != NULL) { - double dd = from->distanceTo(p->pos); + double dd = from.distanceTo(p->pos); delete p; if (dd < nearest || nearest == 0) { hitEntity = e; diff --git a/Minecraft.World/Items/BoatItem.cpp b/Minecraft.World/Items/BoatItem.cpp index b7ed93864..6e0b358b1 100644 --- a/Minecraft.World/Items/BoatItem.cpp +++ b/Minecraft.World/Items/BoatItem.cpp @@ -62,7 +62,7 @@ std::shared_ptr BoatItem::use( player->yo + (player->y - player->yo) * a + 1.62 - player->heightOffset; double z = player->zo + (player->z - player->zo) * a; - Vec3* from = Vec3::newTemp(x, y, z); + Vec3 from(x, y, z); float yCos = Mth::cos(-yRot * Mth::RAD_TO_GRAD - PI); float ySin = Mth::sin(-yRot * Mth::RAD_TO_GRAD - PI); @@ -74,9 +74,9 @@ std::shared_ptr BoatItem::use( float za = yCos * xCos; double range = 5; - Vec3* to = Vec3::newTemp(xa * range, ya * range, za * range); - *to = to->add(from->x, from->y, from->z); - HitResult* hr = level->clip(from, to, true); + Vec3 to(xa * range, ya * range, za * range); + to = to.add(from.x, from.y, from.z); + HitResult* hr = level->clip(&from, &to, true); if (hr == NULL) return itemInstance; // check entity collision @@ -94,7 +94,7 @@ std::shared_ptr BoatItem::use( float rr = e->getPickRadius(); AABB* bb = e->bb->grow(rr, rr, rr); - if (bb->contains(from)) { + if (bb->contains(&from)) { hitEntity = true; } } diff --git a/Minecraft.World/Items/Item.cpp b/Minecraft.World/Items/Item.cpp index 85124b3fa..788e9b475 100644 --- a/Minecraft.World/Items/Item.cpp +++ b/Minecraft.World/Items/Item.cpp @@ -1603,7 +1603,7 @@ HitResult* Item::getPlayerPOVHitResult(Level* level, player->yo + (player->y - player->yo) * a + 1.62 - player->heightOffset; double z = player->zo + (player->z - player->zo) * a; - Vec3* from = Vec3::newTemp(x, y, z); + Vec3 from(x, y, z); float yCos = (float)cos(-yRot * Mth::RAD_TO_GRAD - PI); float ySin = (float)sin(-yRot * Mth::RAD_TO_GRAD - PI); @@ -1615,9 +1615,9 @@ HitResult* Item::getPlayerPOVHitResult(Level* level, float za = yCos * xCos; double range = 5; - Vec3* to = Vec3::newTemp(xa * range, ya * range, za * range); - *to = to->add(from->x, from->y, from->z); - return level->clip(from, to, alsoPickLiquid, !alsoPickLiquid); + Vec3 to(xa * range, ya * range, za * range); + to = to.add(from.x, from.y, from.z); + return level->clip(&from, &to, alsoPickLiquid, !alsoPickLiquid); } int Item::getEnchantmentValue() { return 0; } diff --git a/Minecraft.World/Level/Dimensions/TheEndDimension.cpp b/Minecraft.World/Level/Dimensions/TheEndDimension.cpp index 9ffba3f97..28fa68ba2 100644 --- a/Minecraft.World/Level/Dimensions/TheEndDimension.cpp +++ b/Minecraft.World/Level/Dimensions/TheEndDimension.cpp @@ -60,4 +60,4 @@ Pos* TheEndDimension::getSpawnPos() { return new Pos(100, 50, 0); } bool TheEndDimension::isFoggyAt(int x, int z) { return true; } -int TheEndDimension::getSpawnYPosition() { return 50; } \ No newline at end of file +int TheEndDimension::getSpawnYPosition() { return 50; } diff --git a/Minecraft.World/Level/Events/VillageSiege.cpp b/Minecraft.World/Level/Events/VillageSiege.cpp index 3b623da8c..67410f7b3 100644 --- a/Minecraft.World/Level/Events/VillageSiege.cpp +++ b/Minecraft.World/Level/Events/VillageSiege.cpp @@ -157,4 +157,4 @@ Vec3* VillageSiege::findRandomSpawnPos(int x, int y, int z) { return Vec3::newTemp(xx, yy, zz); } return NULL; -} \ No newline at end of file +} diff --git a/Minecraft.World/Level/Explosion.cpp b/Minecraft.World/Level/Explosion.cpp index e3718a552..1b3686a4b 100644 --- a/Minecraft.World/Level/Explosion.cpp +++ b/Minecraft.World/Level/Explosion.cpp @@ -108,7 +108,7 @@ void Explosion::explode() { level->getEntities(source, AABB::newTemp(x0, y0, z0, x1, y1, z1)); std::vector > entities(levelEntities->begin(), levelEntities->end()); - Vec3* center = Vec3::newTemp(x, y, z); + Vec3 center(x, y, z); AUTO_VAR(itEnd, entities.end()); for (AUTO_VAR(it, entities.begin()); it != itEnd; it++) { @@ -146,7 +146,7 @@ void Explosion::explode() { za /= da; } - double sp = level->getSeenPercent(center, e->bb); + double sp = level->getSeenPercent(¢er, e->bb); double pow = (1 - dist) * sp; if (canDamage) e->hurt(DamageSource::explosion(this), @@ -298,4 +298,4 @@ std::shared_ptr Explosion::getSourceMob() { if (source->instanceof(eTYPE_LIVINGENTITY)) return std::dynamic_pointer_cast(source); return nullptr; -} \ No newline at end of file +} diff --git a/Minecraft.World/Level/Level.cpp b/Minecraft.World/Level/Level.cpp index 8e72c6f05..82317c5c5 100644 --- a/Minecraft.World/Level/Level.cpp +++ b/Minecraft.World/Level/Level.cpp @@ -1478,21 +1478,21 @@ HitResult* Level::clip(Vec3* a, Vec3* b, bool liquid, bool solidOnly) { a->z = zClip; } - Vec3* tPos = Vec3::newTemp(a->x, a->y, a->z); - xTile0 = (int)(tPos->x = floor(a->x)); + Vec3 tPos(a->x, a->y, a->z); + xTile0 = (int)(tPos.x = floor(a->x)); if (face == 5) { xTile0--; - tPos->x++; + tPos.x++; } - yTile0 = (int)(tPos->y = floor(a->y)); + yTile0 = (int)(tPos.y = floor(a->y)); if (face == 1) { yTile0--; - tPos->y++; + tPos.y++; } - zTile0 = (int)(tPos->z = floor(a->z)); + zTile0 = (int)(tPos.z = floor(a->z)); if (face == 3) { zTile0--; - tPos->z++; + tPos.z++; } int t = getTile(xTile0, yTile0, zTile0); @@ -2473,7 +2473,7 @@ bool Level::checkAndHandleWater(AABB* box, Material* material, } bool ok = false; - Vec3* current = Vec3::newTemp(0, 0, 0); + Vec3 current(0, 0, 0); for (int x = x0; x < x1; x++) { for (int y = y0; y < y1; y++) { for (int z = z0; z < z1; z++) { @@ -2483,18 +2483,18 @@ bool Level::checkAndHandleWater(AABB* box, Material* material, y + 1 - LiquidTile::getHeight(getData(x, y, z)); if (y1 >= yt0) { ok = true; - tile->handleEntityInside(this, x, y, z, e, current); + tile->handleEntityInside(this, x, y, z, e, ¤t); } } } } } - if (current->length() > 0 && e->isPushedByWater()) { - *current = current->normalize(); + if (current.length() > 0 && e->isPushedByWater()) { + current = current.normalize(); double pow = 0.014; - e->xd += current->x * pow; - e->yd += current->y * pow; - e->zd += current->z * pow; + e->xd += current.x * pow; + e->yd += current.y * pow; + e->zd += current.z * pow; } return ok; } @@ -2580,7 +2580,8 @@ float Level::getSeenPercent(Vec3* center, AABB* bb) { double x = bb->x0 + (bb->x1 - bb->x0) * xx; double y = bb->y0 + (bb->y1 - bb->y0) * yy; double z = bb->z0 + (bb->z1 - bb->z0) * zz; - HitResult* res = clip(Vec3::newTemp(x, y, z), center); + Vec3 a(x, y, z); + HitResult* res = clip(&a, center); if (res == NULL) hits++; delete res; count++; diff --git a/Minecraft.World/Level/RandomLevelSource.cpp b/Minecraft.World/Level/RandomLevelSource.cpp index 6db10eaea..420324bad 100644 --- a/Minecraft.World/Level/RandomLevelSource.cpp +++ b/Minecraft.World/Level/RandomLevelSource.cpp @@ -109,32 +109,34 @@ int RandomLevelSource::getMinDistanceToEdge(int xxx, int zzz, int worldSize, // // only check if either x or z values are within the falloff // if(xxx > (min - falloffStart) - Vec3* topLeft = Vec3::newTemp(min, 0, min); - Vec3* topRight = Vec3::newTemp(max, 0, min); - Vec3* bottomLeft = Vec3::newTemp(min, 0, max); - Vec3* bottomRight = Vec3::newTemp(max, 0, max); + Vec3 topLeft(min, 0, min); + Vec3 topRight(max, 0, min); + Vec3 bottomLeft(min, 0, max); + Vec3 bottomRight(max, 0, max); float closest = falloffStart; float dist; // make sure we're in range of the edges before we do a full distance check if ((xxx > (min - falloffStart) && xxx < (min + falloffStart)) || (xxx > (max - falloffStart) && xxx < (max + falloffStart))) { - Vec3* point = Vec3::newTemp(xxx, 0, zzz); + Vec3 point(xxx, 0, zzz); + if (xxx > 0) - dist = point->distanceFromLine(*topRight, *bottomRight); + dist = point.distanceFromLine(topRight, bottomRight); else - dist = point->distanceFromLine(*topLeft, *bottomLeft); + dist = point.distanceFromLine(topLeft, bottomLeft); closest = dist; } // make sure we're in range of the edges before we do a full distance check if ((zzz > (min - falloffStart) && zzz < (min + falloffStart)) || (zzz > (max - falloffStart) && zzz < (max + falloffStart))) { - Vec3* point = Vec3::newTemp(xxx, 0, zzz); + Vec3 point(xxx, 0, zzz); + if (zzz > 0) - dist = point->distanceFromLine(*bottomLeft, *bottomRight); + dist = point.distanceFromLine(bottomLeft, bottomRight); else - dist = point->distanceFromLine(*topLeft, *topRight); + dist = point.distanceFromLine(topLeft, topRight); if (dist < closest) closest = dist; } diff --git a/Minecraft.World/Player/Player.cpp b/Minecraft.World/Player/Player.cpp index 7253d1633..64e17333a 100644 --- a/Minecraft.World/Player/Player.cpp +++ b/Minecraft.World/Player/Player.cpp @@ -527,20 +527,20 @@ void Player::spawnEatParticles(std::shared_ptr useItem, } if (useItem->getUseAnimation() == UseAnim_eat) { for (int i = 0; i < count; i++) { - Vec3* d = Vec3::newTemp((random->nextFloat() - 0.5) * 0.1, - Math::random() * 0.1 + 0.1, 0); + Vec3 d{(random->nextFloat() - 0.5) * 0.1, + Math::random() * 0.1 + 0.1, 0}; - d->xRot(-xRot * PI / 180); - d->yRot(-yRot * PI / 180); + d.xRot(-xRot * PI / 180); + d.yRot(-yRot * PI / 180); - Vec3* p = Vec3::newTemp((random->nextFloat() - 0.5) * 0.3, - -random->nextFloat() * 0.6 - 0.3, 0.6); - p->xRot(-xRot * PI / 180); - p->yRot(-yRot * PI / 180); - *p = p->add(x, y + getHeadHeight(), z); + Vec3 p{(random->nextFloat() - 0.5) * 0.3, + -random->nextFloat() * 0.6 - 0.3, 0.6}; + p.xRot(-xRot * PI / 180); + p.yRot(-yRot * PI / 180); + p = p.add(x, y + getHeadHeight(), z); level->addParticle(PARTICLE_ICONCRACK(useItem->getItem()->id, 0), - p->x, p->y, p->z, d->x, d->y + 0.05, d->z); + p.x, p.y, p.z, d.x, d.y + 0.05, d.z); } // 4J Stu - Was L"mob.eat" which doesnt exist diff --git a/Minecraft.World/Util/Vec3.cpp b/Minecraft.World/Util/Vec3.cpp index 0262d2e17..eb9dededa 100644 --- a/Minecraft.World/Util/Vec3.cpp +++ b/Minecraft.World/Util/Vec3.cpp @@ -1,7 +1,8 @@ -#include "../Platform/stdafx.h" #include "Vec3.h" + #include #include + #include "AABB.h" unsigned int Vec3::tlsIdx = 0; diff --git a/Minecraft.World/Util/Vec3.h b/Minecraft.World/Util/Vec3.h index 9b424305a..92b3610a8 100644 --- a/Minecraft.World/Util/Vec3.h +++ b/Minecraft.World/Util/Vec3.h @@ -1,6 +1,8 @@ #pragma once #include +#include + class AABB; class Vec3 { From e887c8cf453566fe030a15de5532e799bf47a476 Mon Sep 17 00:00:00 2001 From: orng Date: Thu, 26 Mar 2026 13:29:05 -0500 Subject: [PATCH 013/170] refactor: remove calls to `Vec3::newTemp` and `Vec3::newPermanent` --- Minecraft.Client/Level/ServerLevel.cpp | 6 +- .../ApplySchematicRuleDefinition.cpp | 2 +- .../Common/GameRules/ConsoleSchematicFile.cpp | 2 +- .../Common/Tutorial/AreaConstraint.cpp | 4 +- .../Platform/Common/Tutorial/AreaHint.cpp | 4 +- .../Common/Tutorial/ChangeStateConstraint.cpp | 5 +- .../Common/UI/UIScene_DebugSetCamera.cpp | 8 +- Minecraft.Client/Player/LocalPlayer.cpp | 14 +- Minecraft.Client/Rendering/Camera.cpp | 13 +- Minecraft.Client/Rendering/Camera.h | 4 +- .../EntityRenderers/MinecartRenderer.cpp | 13 +- .../EntityRenderers/TileRenderer.cpp | 185 +++++++++--------- Minecraft.Client/Rendering/GameRenderer.cpp | 54 ++--- Minecraft.Client/Rendering/LevelRenderer.cpp | 34 ++-- Minecraft.Client/Rendering/Vertex.cpp | 2 +- Minecraft.World/AI/Goals/AvoidPlayerGoal.cpp | 6 +- Minecraft.World/AI/Goals/FleeSunGoal.cpp | 13 +- Minecraft.World/AI/Goals/FleeSunGoal.h | 7 +- Minecraft.World/AI/Goals/MoveIndoorsGoal.cpp | 4 +- .../AI/Goals/MoveThroughVillageGoal.cpp | 4 +- .../AI/Goals/MoveTowardsRestrictionGoal.cpp | 4 +- .../AI/Goals/MoveTowardsTargetGoal.cpp | 4 +- Minecraft.World/AI/Goals/PanicGoal.cpp | 6 +- Minecraft.World/AI/Goals/PlayGoal.cpp | 8 +- Minecraft.World/AI/Goals/RandomStrollGoal.cpp | 10 +- .../AI/Goals/RunAroundLikeCrazyGoal.cpp | 6 +- Minecraft.World/AI/Navigation/Path.cpp | 12 +- Minecraft.World/AI/Navigation/Path.h | 6 +- .../AI/Navigation/PathNavigation.cpp | 38 ++-- .../AI/Navigation/PathNavigation.h | 4 +- Minecraft.World/AI/Navigation/RandomPos.cpp | 17 +- Minecraft.World/AI/Navigation/RandomPos.h | 12 +- Minecraft.World/Blocks/LiquidTile.cpp | 34 ++-- Minecraft.World/Blocks/LiquidTile.h | 4 +- Minecraft.World/Entities/Entity.cpp | 3 +- Minecraft.World/Entities/Entity.h | 3 +- Minecraft.World/Entities/LivingEntity.cpp | 19 +- Minecraft.World/Entities/LivingEntity.h | 7 +- Minecraft.World/Entities/Mobs/EnderDragon.cpp | 36 ++-- Minecraft.World/Entities/Mobs/EnderDragon.h | 2 +- Minecraft.World/Entities/Mobs/EnderMan.cpp | 5 +- Minecraft.World/Entities/Mobs/Fireball.cpp | 5 +- Minecraft.World/Entities/Mobs/Ghast.cpp | 6 +- Minecraft.World/Entities/Mobs/Minecart.cpp | 20 +- Minecraft.World/Entities/Mobs/Minecart.h | 5 +- Minecraft.World/Entities/PathfinderMob.cpp | 9 +- Minecraft.World/Items/BoatItem.cpp | 12 +- .../Level/Dimensions/Dimension.cpp | 4 +- Minecraft.World/Level/Dimensions/Dimension.h | 2 +- .../Level/Dimensions/HellDimension.cpp | 4 +- .../Level/Dimensions/HellDimension.h | 2 +- .../Level/Dimensions/SkyIslandDimension.cpp | 6 +- .../Level/Dimensions/TheEndDimension.cpp | 4 +- .../Level/Dimensions/TheEndDimension.h | 2 +- Minecraft.World/Level/Events/VillageSiege.cpp | 18 +- Minecraft.World/Level/Events/VillageSiege.h | 6 +- Minecraft.World/Level/Explosion.cpp | 9 +- Minecraft.World/Level/Explosion.h | 6 +- Minecraft.World/Level/Level.cpp | 10 +- Minecraft.World/Level/Level.h | 6 +- Minecraft.World/Util/Vec3.cpp | 2 + .../WorldGen/Structures/Village.cpp | 14 +- Minecraft.World/WorldGen/Structures/Village.h | 5 +- 63 files changed, 407 insertions(+), 374 deletions(-) diff --git a/Minecraft.Client/Level/ServerLevel.cpp b/Minecraft.Client/Level/ServerLevel.cpp index 025190b7f..1b8ec2782 100644 --- a/Minecraft.Client/Level/ServerLevel.cpp +++ b/Minecraft.Client/Level/ServerLevel.cpp @@ -1112,13 +1112,13 @@ std::shared_ptr ServerLevel::explode(std::shared_ptr source, } if (player->distanceToSqr(x, y, z) < 64 * 64) { - Vec3* knockbackVec = explosion->getHitPlayerKnockback(player); + Vec3 knockbackVec = explosion->getHitPlayerKnockback(player); // app.DebugPrintf("Sending %s with knockback (%f,%f,%f)\n", // knockbackOnly?"knockbackOnly":"allExplosion",knockbackVec->x,knockbackVec->y,knockbackVec->z); // If the player is not the primary on the system, then we only // want to send info for the knockback player->connection->send(std::shared_ptr( - new ExplodePacket(x, y, z, r, &explosion->toBlow, knockbackVec, + new ExplodePacket(x, y, z, r, &explosion->toBlow, &knockbackVec, knockbackOnly))); sentTo.push_back(player); } @@ -1584,4 +1584,4 @@ void ServerLevel::flagEntitiesToBeRemoved(unsigned int* flags, if (chunkMap) { chunkMap->flagEntitiesToBeRemoved(flags, removedFound); } -} \ No newline at end of file +} diff --git a/Minecraft.Client/Platform/Common/GameRules/ApplySchematicRuleDefinition.cpp b/Minecraft.Client/Platform/Common/GameRules/ApplySchematicRuleDefinition.cpp index 9139bfce7..c7b2c0230 100644 --- a/Minecraft.Client/Platform/Common/GameRules/ApplySchematicRuleDefinition.cpp +++ b/Minecraft.Client/Platform/Common/GameRules/ApplySchematicRuleDefinition.cpp @@ -12,7 +12,7 @@ ApplySchematicRuleDefinition::ApplySchematicRuleDefinition( LevelGenerationOptions* levelGenOptions) { m_levelGenOptions = levelGenOptions; - m_location = Vec3::newPermanent(0, 0, 0); + m_location = new Vec3(0, 0, 0); m_locationBox = NULL; m_totalBlocksChanged = 0; m_totalBlocksChangedLighting = 0; diff --git a/Minecraft.Client/Platform/Common/GameRules/ConsoleSchematicFile.cpp b/Minecraft.Client/Platform/Common/GameRules/ConsoleSchematicFile.cpp index 62476d8ab..b9fec3328 100644 --- a/Minecraft.Client/Platform/Common/GameRules/ConsoleSchematicFile.cpp +++ b/Minecraft.Client/Platform/Common/GameRules/ConsoleSchematicFile.cpp @@ -156,7 +156,7 @@ void ConsoleSchematicFile::load(DataInputStream* dis) { // (%f,%f,%f)\n",(int)type,x,y,z); #endif m_entities.push_back(std::pair( - Vec3::newPermanent(x, y, z), (CompoundTag*)eTag->copy())); + new Vec3(x, y, z), (CompoundTag*)eTag->copy())); } } delete tag; diff --git a/Minecraft.Client/Platform/Common/Tutorial/AreaConstraint.cpp b/Minecraft.Client/Platform/Common/Tutorial/AreaConstraint.cpp index 2057080b5..016cc71ff 100644 --- a/Minecraft.Client/Platform/Common/Tutorial/AreaConstraint.cpp +++ b/Minecraft.Client/Platform/Common/Tutorial/AreaConstraint.cpp @@ -25,8 +25,8 @@ AreaConstraint::~AreaConstraint() { bool AreaConstraint::isConstraintSatisfied(int iPad) { Minecraft* minecraft = Minecraft::GetInstance(); - return messageArea->contains(minecraft->localplayers[iPad]->getPos(1)) == - contains; + Vec3 ipad_player = minecraft->localplayers[iPad]->getPos(1); + return messageArea->contains(&ipad_player) == contains; } bool AreaConstraint::isConstraintRestrictive(int iPad) { diff --git a/Minecraft.Client/Platform/Common/Tutorial/AreaHint.cpp b/Minecraft.Client/Platform/Common/Tutorial/AreaHint.cpp index 729b361d0..ced909db9 100644 --- a/Minecraft.Client/Platform/Common/Tutorial/AreaHint.cpp +++ b/Minecraft.Client/Platform/Common/Tutorial/AreaHint.cpp @@ -24,10 +24,12 @@ AreaHint::~AreaHint() { delete area; } int AreaHint::tick() { Minecraft* minecraft = Minecraft::GetInstance(); + Vec3 player_pos = minecraft->player->getPos(1); + if ((m_displayState == e_Tutorial_State_Any || m_tutorial->getCurrentState() == m_displayState) && m_hintNeeded && - area->contains(minecraft->player->getPos(1)) == contains) { + area->contains(&player_pos) == contains) { if (m_completeState == e_Tutorial_State_None) { m_hintNeeded = false; } else if (m_tutorial->isStateCompleted(m_completeState)) { diff --git a/Minecraft.Client/Platform/Common/Tutorial/ChangeStateConstraint.cpp b/Minecraft.Client/Platform/Common/Tutorial/ChangeStateConstraint.cpp index 9d8d75e1d..252d85f7d 100644 --- a/Minecraft.Client/Platform/Common/Tutorial/ChangeStateConstraint.cpp +++ b/Minecraft.Client/Platform/Common/Tutorial/ChangeStateConstraint.cpp @@ -85,8 +85,9 @@ void ChangeStateConstraint::tick(int iPad) { break; } } + Vec3 ipad_player = minecraft->localplayers[iPad]->getPos(1); if (!m_bHasChanged && inASourceState && - movementArea->contains(minecraft->localplayers[iPad]->getPos(1)) == + movementArea->contains(&ipad_player) == contains) { m_bHasChanged = true; m_changedFromState = m_tutorial->getCurrentState(); @@ -126,7 +127,7 @@ void ChangeStateConstraint::tick(int iPad) { } } else if (m_bHasChanged && movementArea->contains( - minecraft->localplayers[iPad]->getPos(1)) != contains) { + &ipad_player) != contains) { m_bHasChanged = false; m_tutorial->changeTutorialState(m_changedFromState); diff --git a/Minecraft.Client/Platform/Common/UI/UIScene_DebugSetCamera.cpp b/Minecraft.Client/Platform/Common/UI/UIScene_DebugSetCamera.cpp index 89e872eb9..af850cb67 100644 --- a/Minecraft.Client/Platform/Common/UI/UIScene_DebugSetCamera.cpp +++ b/Minecraft.Client/Platform/Common/UI/UIScene_DebugSetCamera.cpp @@ -19,13 +19,13 @@ UIScene_DebugSetCamera::UIScene_DebugSetCamera(int iPad, void* initData, Minecraft* pMinecraft = Minecraft::GetInstance(); if (pMinecraft != NULL) { - Vec3* vec = pMinecraft->localplayers[playerNo]->getPos(1.0); + Vec3 vec = pMinecraft->localplayers[playerNo]->getPos(1.0); - currentPosition->m_camX = vec->x; + currentPosition->m_camX = vec.x; currentPosition->m_camY = - vec->y - + vec.y - 1.62; // pMinecraft->localplayers[playerNo]->getHeadHeight(); - currentPosition->m_camZ = vec->z; + currentPosition->m_camZ = vec.z; currentPosition->m_yRot = pMinecraft->localplayers[playerNo]->yRot; currentPosition->m_elev = pMinecraft->localplayers[playerNo]->xRot; diff --git a/Minecraft.Client/Player/LocalPlayer.cpp b/Minecraft.Client/Player/LocalPlayer.cpp index f264a55af..1f6e17a08 100644 --- a/Minecraft.Client/Player/LocalPlayer.cpp +++ b/Minecraft.Client/Player/LocalPlayer.cpp @@ -404,25 +404,25 @@ void LocalPlayer::aiStep() { if (abilities.flying) // minecraft->options->isFlying ) { - Vec3* viewVector = getViewVector(1.0f); + Vec3 viewVector = getViewVector(1.0f); // 4J-PB - To let the player build easily while flying, we need to // change this #ifdef _DEBUG_MENUS_ENABLED if (abilities.debugflying) { - flyX = (float)viewVector->x * input->ya; - flyY = (float)viewVector->y * input->ya; - flyZ = (float)viewVector->z * input->ya; + flyX = (float)viewVector.x * input->ya; + flyY = (float)viewVector.y * input->ya; + flyZ = (float)viewVector.z * input->ya; } else #endif { if (isSprinting()) { // Accelrate up to full speed if we are sprinting, moving in the // direction of the view vector - flyX = (float)viewVector->x * input->ya; - flyY = (float)viewVector->y * input->ya; - flyZ = (float)viewVector->z * input->ya; + flyX = (float)viewVector.x * input->ya; + flyY = (float)viewVector.y * input->ya; + flyZ = (float)viewVector.z * input->ya; float scale = ((float)(SPRINT_DURATION - sprintTime)) / 10.0f; scale = scale * scale; diff --git a/Minecraft.Client/Rendering/Camera.cpp b/Minecraft.Client/Rendering/Camera.cpp index fdfbb1dad..f728f3f09 100644 --- a/Minecraft.Client/Rendering/Camera.cpp +++ b/Minecraft.Client/Rendering/Camera.cpp @@ -91,10 +91,11 @@ zPlayerOffs = position->get(2); TilePos* Camera::getCameraTilePos(std::shared_ptr player, double alpha) { - return new TilePos(getCameraPos(player, alpha)); + Vec3 cam_pos = getCameraPos(player, alpha); + return new TilePos(&cam_pos); } -Vec3* Camera::getCameraPos(std::shared_ptr player, double alpha) { +Vec3 Camera::getCameraPos(std::shared_ptr player, double alpha) { double xx = player->xo + (player->x - player->xo) * alpha; double yy = player->yo + (player->y - player->yo) * alpha + player->getHeadHeight(); @@ -104,19 +105,19 @@ Vec3* Camera::getCameraPos(std::shared_ptr player, double alpha) { double yt = yy + Camera::yPlayerOffs * 1; double zt = zz + Camera::zPlayerOffs * 1; - return Vec3::newTemp(xt, yt, zt); + return Vec3(xt, yt, zt); } int Camera::getBlockAt(Level* level, std::shared_ptr player, float alpha) { - Vec3* p = Camera::getCameraPos(player, alpha); - TilePos tp = TilePos(p); + Vec3 p = Camera::getCameraPos(player, alpha); + TilePos tp = TilePos(&p); int t = level->getTile(tp.x, tp.y, tp.z); if (t != 0 && Tile::tiles[t]->material->isLiquid()) { float hh = LiquidTile::getHeight(level->getData(tp.x, tp.y, tp.z)) - 1 / 9.0f; float h = tp.y + 1 - hh; - if (p->y >= h) { + if (p.y >= h) { t = level->getTile(tp.x, tp.y + 1, tp.z); } } diff --git a/Minecraft.Client/Rendering/Camera.h b/Minecraft.Client/Rendering/Camera.h index ce2dcb6ce..4ce2d8419 100644 --- a/Minecraft.Client/Rendering/Camera.h +++ b/Minecraft.Client/Rendering/Camera.h @@ -26,8 +26,8 @@ public: static TilePos* getCameraTilePos(std::shared_ptr player, double alpha); - static Vec3* getCameraPos(std::shared_ptr player, + static Vec3 getCameraPos(std::shared_ptr player, double alpha); static int getBlockAt(Level* level, std::shared_ptr player, float alpha); -}; \ No newline at end of file +}; diff --git a/Minecraft.Client/Rendering/EntityRenderers/MinecartRenderer.cpp b/Minecraft.Client/Rendering/EntityRenderers/MinecartRenderer.cpp index f5ed5b766..5868a654e 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/MinecartRenderer.cpp +++ b/Minecraft.Client/Rendering/EntityRenderers/MinecartRenderer.cpp @@ -1,5 +1,6 @@ #include "../../Platform/stdafx.h" #include "MinecartRenderer.h" +#include #include "../Models/MinecartModel.h" #include "../../Textures/TextureAtlas.h" #include "../../../Minecraft.World/Headers/net.minecraft.world.entity.item.h" @@ -40,15 +41,15 @@ void MinecartRenderer::render(std::shared_ptr _cart, double x, double y, double r = 0.3f; - Vec3* p = cart->getPos(xx, yy, zz); + std::optional p = cart->getPos(xx, yy, zz); float xRot = cart->xRotO + (cart->xRot - cart->xRotO) * a; - if (p != NULL) { - Vec3* p0 = cart->getPosOffs(xx, yy, zz, r); - Vec3* p1 = cart->getPosOffs(xx, yy, zz, -r); - if (p0 == NULL) p0 = p; - if (p1 == NULL) p1 = p; + if (p.has_value()) { + auto p0 = cart->getPosOffs(xx, yy, zz, r); + auto p1 = cart->getPosOffs(xx, yy, zz, -r); + if (!p0.has_value()) p0 = p; + if (!p1.has_value()) p1 = p; x += p->x - xx; y += (p0->y + p1->y) / 2 - yy; diff --git a/Minecraft.Client/Rendering/EntityRenderers/TileRenderer.cpp b/Minecraft.Client/Rendering/EntityRenderers/TileRenderer.cpp index 08ae72935..3ee4ff71a 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/TileRenderer.cpp +++ b/Minecraft.Client/Rendering/EntityRenderers/TileRenderer.cpp @@ -1,6 +1,7 @@ #include "../../Platform/stdafx.h" #include "TileRenderer.h" +#include #include "../GameRenderer.h" #include "../../Minecraft.h" #include "../../Textures/Textures.h" @@ -1817,58 +1818,58 @@ bool TileRenderer::tesselateLeverInWorld(Tile* tt, int x, int y, int z) { float u1 = tex->getU1(true); float v1 = tex->getV1(true); - Vec3* corners[8]; + std::array corners; float xv = 1.0f / 16.0f; float zv = 1.0f / 16.0f; float yv = 10.0f / 16.0f; - corners[0] = Vec3::newTemp(-xv, -0, -zv); - corners[1] = Vec3::newTemp(+xv, -0, -zv); - corners[2] = Vec3::newTemp(+xv, -0, +zv); - corners[3] = Vec3::newTemp(-xv, -0, +zv); - corners[4] = Vec3::newTemp(-xv, +yv, -zv); - corners[5] = Vec3::newTemp(+xv, +yv, -zv); - corners[6] = Vec3::newTemp(+xv, +yv, +zv); - corners[7] = Vec3::newTemp(-xv, +yv, +zv); + corners[0] = Vec3(-xv, -0, -zv); + corners[1] = Vec3(+xv, -0, -zv); + corners[2] = Vec3(+xv, -0, +zv); + corners[3] = Vec3(-xv, -0, +zv); + corners[4] = Vec3(-xv, +yv, -zv); + corners[5] = Vec3(+xv, +yv, -zv); + corners[6] = Vec3(+xv, +yv, +zv); + corners[7] = Vec3(-xv, +yv, +zv); for (int i = 0; i < 8; i++) { if (flipped) { - corners[i]->z -= 1 / 16.0f; - corners[i]->xRot(40 * PI / 180); + corners[i].z -= 1 / 16.0f; + corners[i].xRot(40 * PI / 180); } else { - corners[i]->z += 1 / 16.0f; - corners[i]->xRot(-40 * PI / 180); + corners[i].z += 1 / 16.0f; + corners[i].xRot(-40 * PI / 180); } if (dir == 0 || dir == 7) { - corners[i]->zRot(180 * PI / 180); + corners[i].zRot(180 * PI / 180); } if (dir == 6 || dir == 0) { - corners[i]->yRot(90 * PI / 180); + corners[i].yRot(90 * PI / 180); } if (dir > 0 && dir < 5) { - corners[i]->y -= 6 / 16.0f; - corners[i]->xRot(90 * PI / 180); + corners[i].y -= 6 / 16.0f; + corners[i].xRot(90 * PI / 180); - if (dir == 4) corners[i]->yRot(0 * PI / 180); - if (dir == 3) corners[i]->yRot(180 * PI / 180); - if (dir == 2) corners[i]->yRot(90 * PI / 180); - if (dir == 1) corners[i]->yRot(-90 * PI / 180); + if (dir == 4) corners[i].yRot(0 * PI / 180); + if (dir == 3) corners[i].yRot(180 * PI / 180); + if (dir == 2) corners[i].yRot(90 * PI / 180); + if (dir == 1) corners[i].yRot(-90 * PI / 180); - corners[i]->x += x + 0.5; - corners[i]->y += y + 8 / 16.0f; - corners[i]->z += z + 0.5; + corners[i].x += x + 0.5; + corners[i].y += y + 8 / 16.0f; + corners[i].z += z + 0.5; } else if (dir == 0 || dir == 7) { - corners[i]->x += x + 0.5; - corners[i]->y += y + 14 / 16.0f; - corners[i]->z += z + 0.5; + corners[i].x += x + 0.5; + corners[i].y += y + 14 / 16.0f; + corners[i].z += z + 0.5; } else { - corners[i]->x += x + 0.5; - corners[i]->y += y + 2 / 16.0f; - corners[i]->z += z + 0.5; + corners[i].x += x + 0.5; + corners[i].y += y + 2 / 16.0f; + corners[i].z += z + 0.5; } } - Vec3 *c0 = NULL, *c1 = NULL, *c2 = NULL, *c3 = NULL; + Vec3 c0, c1, c2, c3; for (int i = 0; i < 6; i++) { if (i == 0) { u0 = tex->getU(7, true); @@ -1912,13 +1913,13 @@ bool TileRenderer::tesselateLeverInWorld(Tile* tt, int x, int y, int z) { c2 = corners[7]; c3 = corners[4]; } - t->vertexUV((float)(c0->x), (float)(c0->y), (float)(c0->z), (float)(u0), + t->vertexUV((float)(c0.x), (float)(c0.y), (float)(c0.z), (float)(u0), (float)(v1)); - t->vertexUV((float)(c1->x), (float)(c1->y), (float)(c1->z), (float)(u1), + t->vertexUV((float)(c1.x), (float)(c1.y), (float)(c1.z), (float)(u1), (float)(v1)); - t->vertexUV((float)(c2->x), (float)(c2->y), (float)(c2->z), (float)(u1), + t->vertexUV((float)(c2.x), (float)(c2.y), (float)(c2.z), (float)(u1), (float)(v0)); - t->vertexUV((float)(c3->x), (float)(c3->y), (float)(c3->z), (float)(u0), + t->vertexUV((float)(c3.x), (float)(c3.y), (float)(c3.z), (float)(u0), (float)(v0)); } return true; @@ -1976,46 +1977,46 @@ bool TileRenderer::tesselateTripwireSourceInWorld(Tile* tt, int x, int y, double u1 = tex->getU1(); double v1 = tex->getV1(); - Vec3* corners[8]; + std::array corners; float stickWidth = 0.75f / 16.0f; float stickHeight = 0.75f / 16.0f; float stickLength = 5 / 16.0f; - corners[0] = Vec3::newTemp(-stickWidth, -0, -stickHeight); - corners[1] = Vec3::newTemp(+stickWidth, -0, -stickHeight); - corners[2] = Vec3::newTemp(+stickWidth, -0, +stickHeight); - corners[3] = Vec3::newTemp(-stickWidth, -0, +stickHeight); - corners[4] = Vec3::newTemp(-stickWidth, +stickLength, -stickHeight); - corners[5] = Vec3::newTemp(+stickWidth, +stickLength, -stickHeight); - corners[6] = Vec3::newTemp(+stickWidth, +stickLength, +stickHeight); - corners[7] = Vec3::newTemp(-stickWidth, +stickLength, +stickHeight); + corners[0] = Vec3(-stickWidth, -0, -stickHeight); + corners[1] = Vec3(+stickWidth, -0, -stickHeight); + corners[2] = Vec3(+stickWidth, -0, +stickHeight); + corners[3] = Vec3(-stickWidth, -0, +stickHeight); + corners[4] = Vec3(-stickWidth, +stickLength, -stickHeight); + corners[5] = Vec3(+stickWidth, +stickLength, -stickHeight); + corners[6] = Vec3(+stickWidth, +stickLength, +stickHeight); + corners[7] = Vec3(-stickWidth, +stickLength, +stickHeight); for (int i = 0; i < 8; i++) { - corners[i]->z += 1 / 16.0f; + corners[i].z += 1 / 16.0f; if (powered) { - corners[i]->xRot(30 * PI / 180); - corners[i]->y -= 7 / 16.0f; + corners[i].xRot(30 * PI / 180); + corners[i].y -= 7 / 16.0f; } else if (attached) { - corners[i]->xRot(5 * PI / 180); - corners[i]->y -= 7 / 16.0f; + corners[i].xRot(5 * PI / 180); + corners[i].y -= 7 / 16.0f; } else { - corners[i]->xRot(-40 * PI / 180); - corners[i]->y -= 6 / 16.0f; + corners[i].xRot(-40 * PI / 180); + corners[i].y -= 6 / 16.0f; } - corners[i]->xRot(90 * PI / 180); + corners[i].xRot(90 * PI / 180); - if (dir == Direction::NORTH) corners[i]->yRot(0 * PI / 180); - if (dir == Direction::SOUTH) corners[i]->yRot(180 * PI / 180); - if (dir == Direction::WEST) corners[i]->yRot(90 * PI / 180); - if (dir == Direction::EAST) corners[i]->yRot(-90 * PI / 180); + if (dir == Direction::NORTH) corners[i].yRot(0 * PI / 180); + if (dir == Direction::SOUTH) corners[i].yRot(180 * PI / 180); + if (dir == Direction::WEST) corners[i].yRot(90 * PI / 180); + if (dir == Direction::EAST) corners[i].yRot(-90 * PI / 180); - corners[i]->x += x + 0.5; - corners[i]->y += y + 5 / 16.0f; - corners[i]->z += z + 0.5; + corners[i].x += x + 0.5; + corners[i].y += y + 5 / 16.0f; + corners[i].z += z + 0.5; } - Vec3 *c0 = NULL, *c1 = NULL, *c2 = NULL, *c3 = NULL; + Vec3 c0, c1, c2, c3; int stickX0 = 7; int stickX1 = 9; int stickY0 = 9; @@ -2061,47 +2062,47 @@ bool TileRenderer::tesselateTripwireSourceInWorld(Tile* tt, int x, int y, c2 = corners[7]; c3 = corners[4]; } - t->vertexUV(c0->x, c0->y, c0->z, u0, v1); - t->vertexUV(c1->x, c1->y, c1->z, u1, v1); - t->vertexUV(c2->x, c2->y, c2->z, u1, v0); - t->vertexUV(c3->x, c3->y, c3->z, u0, v0); + t->vertexUV(c0.x, c0.y, c0.z, u0, v1); + t->vertexUV(c1.x, c1.y, c1.z, u1, v1); + t->vertexUV(c2.x, c2.y, c2.z, u1, v0); + t->vertexUV(c3.x, c3.y, c3.z, u0, v0); } float hoopWidth = 1.5f / 16.0f; float hoopHeight = 1.5f / 16.0f; float hoopLength = 0.5f / 16.0f; - corners[0] = Vec3::newTemp(-hoopWidth, -0, -hoopHeight); - corners[1] = Vec3::newTemp(+hoopWidth, -0, -hoopHeight); - corners[2] = Vec3::newTemp(+hoopWidth, -0, +hoopHeight); - corners[3] = Vec3::newTemp(-hoopWidth, -0, +hoopHeight); - corners[4] = Vec3::newTemp(-hoopWidth, +hoopLength, -hoopHeight); - corners[5] = Vec3::newTemp(+hoopWidth, +hoopLength, -hoopHeight); - corners[6] = Vec3::newTemp(+hoopWidth, +hoopLength, +hoopHeight); - corners[7] = Vec3::newTemp(-hoopWidth, +hoopLength, +hoopHeight); + corners[0] = Vec3(-hoopWidth, -0, -hoopHeight); + corners[1] = Vec3(+hoopWidth, -0, -hoopHeight); + corners[2] = Vec3(+hoopWidth, -0, +hoopHeight); + corners[3] = Vec3(-hoopWidth, -0, +hoopHeight); + corners[4] = Vec3(-hoopWidth, +hoopLength, -hoopHeight); + corners[5] = Vec3(+hoopWidth, +hoopLength, -hoopHeight); + corners[6] = Vec3(+hoopWidth, +hoopLength, +hoopHeight); + corners[7] = Vec3(-hoopWidth, +hoopLength, +hoopHeight); for (int i = 0; i < 8; i++) { - corners[i]->z += 3.5f / 16.0f; + corners[i].z += 3.5f / 16.0f; if (powered) { - corners[i]->y -= 1.5 / 16.0f; - corners[i]->z -= 2.6 / 16.0f; - corners[i]->xRot(0 * PI / 180); + corners[i].y -= 1.5 / 16.0f; + corners[i].z -= 2.6 / 16.0f; + corners[i].xRot(0 * PI / 180); } else if (attached) { - corners[i]->y += 0.25 / 16.0f; - corners[i]->z -= 2.75 / 16.0f; - corners[i]->xRot(10 * PI / 180); + corners[i].y += 0.25 / 16.0f; + corners[i].z -= 2.75 / 16.0f; + corners[i].xRot(10 * PI / 180); } else { - corners[i]->xRot(50 * PI / 180); + corners[i].xRot(50 * PI / 180); } - if (dir == Direction::NORTH) corners[i]->yRot(0 * PI / 180); - if (dir == Direction::SOUTH) corners[i]->yRot(180 * PI / 180); - if (dir == Direction::WEST) corners[i]->yRot(90 * PI / 180); - if (dir == Direction::EAST) corners[i]->yRot(-90 * PI / 180); + if (dir == Direction::NORTH) corners[i].yRot(0 * PI / 180); + if (dir == Direction::SOUTH) corners[i].yRot(180 * PI / 180); + if (dir == Direction::WEST) corners[i].yRot(90 * PI / 180); + if (dir == Direction::EAST) corners[i].yRot(-90 * PI / 180); - corners[i]->x += x + 0.5; - corners[i]->y += y + 5 / 16.0f; - corners[i]->z += z + 0.5; + corners[i].x += x + 0.5; + corners[i].y += y + 5 / 16.0f; + corners[i].z += z + 0.5; } int hoopX0 = 5; @@ -2149,14 +2150,14 @@ bool TileRenderer::tesselateTripwireSourceInWorld(Tile* tt, int x, int y, c2 = corners[7]; c3 = corners[4]; } - t->vertexUV(c0->x, c0->y, c0->z, u0, v1); - t->vertexUV(c1->x, c1->y, c1->z, u1, v1); - t->vertexUV(c2->x, c2->y, c2->z, u1, v0); - t->vertexUV(c3->x, c3->y, c3->z, u0, v0); + t->vertexUV(c0.x, c0.y, c0.z, u0, v1); + t->vertexUV(c1.x, c1.y, c1.z, u1, v1); + t->vertexUV(c2.x, c2.y, c2.z, u1, v0); + t->vertexUV(c3.x, c3.y, c3.z, u0, v0); } if (attached) { - double hoopBottomY = corners[0]->y; + double hoopBottomY = corners[0].y; float width = 0.5f / 16.0f; float top = 0.5f - (width / 2); float bottom = top + width; diff --git a/Minecraft.Client/Rendering/GameRenderer.cpp b/Minecraft.Client/Rendering/GameRenderer.cpp index 2938a092f..30137286f 100644 --- a/Minecraft.Client/Rendering/GameRenderer.cpp +++ b/Minecraft.Client/Rendering/GameRenderer.cpp @@ -90,7 +90,7 @@ GameRenderer::GameRenderer(Minecraft* mc) { tickSmoothYO = 0; lastTickA = 0; - cameraPos = Vec3::newPermanent(0.0f, 0.0f, 0.0f); + cameraPos = new Vec3(0.0f, 0.0f, 0.0f); fovOffset = 0; fovOffsetO = 0; @@ -291,7 +291,7 @@ void GameRenderer::pick(float a) { } double dist = range; - Vec3* from = mc->cameraTargetPlayer->getPos(a); + Vec3 from = mc->cameraTargetPlayer->getPos(a); if (mc->gameMode->hasFarPickRange()) { dist = range = 6; @@ -301,18 +301,18 @@ void GameRenderer::pick(float a) { } if (mc->hitResult != NULL) { - dist = mc->hitResult->pos.distanceTo(*from); + dist = mc->hitResult->pos.distanceTo(from); } - Vec3* b = mc->cameraTargetPlayer->getViewVector(a); - Vec3 to(b->x * range, b->y * range, b->z * range); - to = to.add(from->x, from->y, from->z); + Vec3 b = mc->cameraTargetPlayer->getViewVector(a); + Vec3 to(b.x * range, b.y * range, b.z * range); + to = to.add(from.x, from.y, from.z); hovered = nullptr; float overlap = 1; std::vector >* objects = mc->level->getEntities( mc->cameraTargetPlayer, mc->cameraTargetPlayer->bb - ->expand(b->x * (range), b->y * (range), b->z * (range)) + ->expand(b.x * (range), b.y * (range), b.z * (range)) ->grow(overlap, overlap, overlap)); double nearest = dist; @@ -323,14 +323,14 @@ void GameRenderer::pick(float a) { float rr = e->getPickRadius(); AABB* bb = e->bb->grow(rr, rr, rr); - HitResult* p = bb->clip(from, &to); - if (bb->contains(from)) { + HitResult* p = bb->clip(&from, &to); + if (bb->contains(&from)) { if (0 < nearest || nearest == 0) { hovered = e; nearest = 0; } } else if (p != NULL) { - double dd = from->distanceTo(p->pos); + double dd = from.distanceTo(p->pos); std::shared_ptr ridingEntity = mc->cameraTargetPlayer->riding; // 4jcraft: compare the mounted entity explicitly so riding the hit @@ -1371,10 +1371,10 @@ void GameRenderer::renderLevel(float a, int64_t until) { // storing the camera position Fix for #77745 - TU9: Content: // Gameplay: Items and mobs not belonging to end world are // disappearing when Enderdragon is damaged. - Vec3* cameraPosTemp = cameraEntity->getPos(a); - cameraPos->x = cameraPosTemp->x; - cameraPos->y = cameraPosTemp->y; - cameraPos->z = cameraPosTemp->z; + Vec3 cameraPosTemp = cameraEntity->getPos(a); + cameraPos->x = cameraPosTemp.x; + cameraPos->y = cameraPosTemp.y; + cameraPos->z = cameraPosTemp.z; levelRenderer->renderEntities(cameraPos, frustum, a); #ifdef __PSVITA__ // AP - make sure we're using the Alpha cut out effect for particles @@ -1855,21 +1855,21 @@ void GameRenderer::setupClearColor(float a) { float whiteness = 1.0f / (4 - mc->options->viewDistance); whiteness = 1 - (float)pow((double)whiteness, 0.25); - Vec3* skyColor = level->getSkyColor(mc->cameraTargetPlayer, a); - float sr = (float)skyColor->x; - float sg = (float)skyColor->y; - float sb = (float)skyColor->z; + Vec3 skyColor = level->getSkyColor(mc->cameraTargetPlayer, a); + float sr = (float)skyColor.x; + float sg = (float)skyColor.y; + float sb = (float)skyColor.z; - Vec3* fogColor = level->getFogColor(a); - fr = (float)fogColor->x; - fg = (float)fogColor->y; - fb = (float)fogColor->z; + Vec3 fogColor = level->getFogColor(a); + fr = (float)fogColor.x; + fg = (float)fogColor.y; + fb = (float)fogColor.z; if (mc->options->viewDistance < 2) { Vec3 sunAngle = Mth::sin(level->getSunAngle(a)) > 0 ? Vec3(-1, 0, 0) : Vec3(1, 0, 0); - float d = (float)player->getViewVector(a)->dot(sunAngle); + float d = (float)player->getViewVector(a).dot(sunAngle); if (d < 0) d = 0; if (d > 0) { float* c = @@ -1905,10 +1905,10 @@ void GameRenderer::setupClearColor(float a) { int t = Camera::getBlockAt(mc->level, player, a); if (isInClouds) { - Vec3* cc = level->getCloudColor(a); - fr = (float)cc->x; - fg = (float)cc->y; - fb = (float)cc->z; + Vec3 cc = level->getCloudColor(a); + fr = (float)cc.x; + fg = (float)cc.y; + fb = (float)cc.z; } else if (t != 0 && Tile::tiles[t]->material == Material::water) { float clearness = EnchantmentHelper::getOxygenBonus(player) * 0.2f; diff --git a/Minecraft.Client/Rendering/LevelRenderer.cpp b/Minecraft.Client/Rendering/LevelRenderer.cpp index 2554b3532..902cee656 100644 --- a/Minecraft.Client/Rendering/LevelRenderer.cpp +++ b/Minecraft.Client/Rendering/LevelRenderer.cpp @@ -1035,10 +1035,10 @@ void LevelRenderer::renderSky(float alpha) { glDisable(GL_TEXTURE_2D); int playerIndex = mc->player->GetXboxPad(); - Vec3* sc = level[playerIndex]->getSkyColor(mc->cameraTargetPlayer, alpha); - float sr = (float)sc->x; - float sg = (float)sc->y; - float sb = (float)sc->z; + Vec3 sc = level[playerIndex]->getSkyColor(mc->cameraTargetPlayer, alpha); + float sr = (float)sc.x; + float sg = (float)sc.y; + float sb = (float)sc.z; if (mc->options->anaglyph3d) { float srr = (sr * 30 + sg * 59 + sb * 11) / 100; @@ -1185,7 +1185,7 @@ void LevelRenderer::renderSky(float alpha) { glColor3f(0, 0, 0); double yy = - mc->player->getPos(alpha)->y - + mc->player->getPos(alpha).y - level[playerIndex]->getHorizonHeight(); // 4J - getHorizonHeight moved // forward from 1.2.3 if (yy < 0) { @@ -1259,10 +1259,10 @@ void LevelRenderer::renderHaloRing(float alpha) { int playerIndex = mc->player->GetXboxPad(); - Vec3* sc = level[playerIndex]->getSkyColor(mc->cameraTargetPlayer, alpha); - float sr = (float)sc->x; - float sg = (float)sc->y; - float sb = (float)sc->z; + Vec3 sc = level[playerIndex]->getSkyColor(mc->cameraTargetPlayer, alpha); + float sr = (float)sc.x; + float sg = (float)sc.y; + float sb = (float)sc.z; // Rough lumninance calculation float Y = (sr + sr + sb + sg + sg + sg) / 6; @@ -1335,10 +1335,10 @@ void LevelRenderer::renderClouds(float alpha) { glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - Vec3* cc = level[playerIndex]->getCloudColor(alpha); - float cr = (float)cc->x; - float cg = (float)cc->y; - float cb = (float)cc->z; + Vec3 cc = level[playerIndex]->getCloudColor(alpha); + float cr = (float)cc.x; + float cg = (float)cc.y; + float cb = (float)cc.z; if (mc->options->anaglyph3d) { float crr = (cr * 30 + cg * 59 + cb * 11) / 100; @@ -1632,10 +1632,10 @@ void LevelRenderer::renderAdvancedClouds(float alpha) { glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - Vec3* cc = level[playerIndex]->getCloudColor(alpha); - float cr = (float)cc->x; - float cg = (float)cc->y; - float cb = (float)cc->z; + Vec3 cc = level[playerIndex]->getCloudColor(alpha); + float cr = (float)cc.x; + float cg = (float)cc.y; + float cb = (float)cc.z; if (mc->options->anaglyph3d) { float crr = (cr * 30 + cg * 59 + cb * 11) / 100; diff --git a/Minecraft.Client/Rendering/Vertex.cpp b/Minecraft.Client/Rendering/Vertex.cpp index 0145619e5..aaf37cc93 100644 --- a/Minecraft.Client/Rendering/Vertex.cpp +++ b/Minecraft.Client/Rendering/Vertex.cpp @@ -2,7 +2,7 @@ #include "Vertex.h" Vertex::Vertex(float x, float y, float z, float u, float v) { - this->pos = Vec3::newPermanent(x, y, z); + this->pos = new Vec3(x, y, z); this->u = u; this->v = v; } diff --git a/Minecraft.World/AI/Goals/AvoidPlayerGoal.cpp b/Minecraft.World/AI/Goals/AvoidPlayerGoal.cpp index ab5af98d0..59045d029 100644 --- a/Minecraft.World/AI/Goals/AvoidPlayerGoal.cpp +++ b/Minecraft.World/AI/Goals/AvoidPlayerGoal.cpp @@ -65,17 +65,17 @@ bool AvoidPlayerGoal::canUse() { } Vec3 avoid_pos(toAvoid.lock()->x, toAvoid.lock()->y, toAvoid.lock()->z); - Vec3* pos = RandomPos::getPosAvoid( + auto pos = RandomPos::getPosAvoid( std::dynamic_pointer_cast(mob->shared_from_this()), 16, 7, &avoid_pos); - if (pos == NULL) return false; + if (!pos.has_value()) return false; if (toAvoid.lock()->distanceToSqr(pos->x, pos->y, pos->z) < toAvoid.lock()->distanceToSqr(mob->shared_from_this())) return false; delete path; path = pathNav->createPath(pos->x, pos->y, pos->z); if (path == NULL) return false; - if (!path->endsInXZ(pos)) return false; + if (!path->endsInXZ(&*pos)) return false; return true; } diff --git a/Minecraft.World/AI/Goals/FleeSunGoal.cpp b/Minecraft.World/AI/Goals/FleeSunGoal.cpp index 70a77fe77..fdddfd6e0 100644 --- a/Minecraft.World/AI/Goals/FleeSunGoal.cpp +++ b/Minecraft.World/AI/Goals/FleeSunGoal.cpp @@ -5,6 +5,7 @@ #include "../../Headers/net.minecraft.world.level.h" #include "../../Headers/net.minecraft.world.phys.h" #include "FleeSunGoal.h" +#include FleeSunGoal::FleeSunGoal(PathfinderMob* mob, double speedModifier) { this->mob = mob; @@ -20,8 +21,8 @@ bool FleeSunGoal::canUse() { Mth::floor(mob->z))) return false; - Vec3* pos = getHidePos(); - if (pos == NULL) return false; + auto pos = getHidePos(); + if (!pos.has_value()) return false; wantedX = pos->x; wantedY = pos->y; wantedZ = pos->z; @@ -34,7 +35,7 @@ void FleeSunGoal::start() { mob->getNavigation()->moveTo(wantedX, wantedY, wantedZ, speedModifier); } -Vec3* FleeSunGoal::getHidePos() { +std::optional FleeSunGoal::getHidePos() { Random* random = mob->getRandom(); for (int i = 0; i < 10; i++) { int xt = Mth::floor(mob->x + random->nextInt(20) - 10); @@ -42,7 +43,7 @@ Vec3* FleeSunGoal::getHidePos() { int zt = Mth::floor(mob->z + random->nextInt(20) - 10); if (!level->canSeeSky(xt, yt, zt) && mob->getWalkTargetValue(xt, yt, zt) < 0) - return Vec3::newTemp(xt, yt, zt); + return Vec3(xt, yt, zt); } - return NULL; -} \ No newline at end of file + return std::nullopt; +} diff --git a/Minecraft.World/AI/Goals/FleeSunGoal.h b/Minecraft.World/AI/Goals/FleeSunGoal.h index cdd6f8612..e9cce5983 100644 --- a/Minecraft.World/AI/Goals/FleeSunGoal.h +++ b/Minecraft.World/AI/Goals/FleeSunGoal.h @@ -1,5 +1,8 @@ #pragma once +#include + +#include "../../Util/Vec3.h" #include "Goal.h" class FleeSunGoal : public Goal { @@ -17,10 +20,10 @@ public: virtual void start(); private: - Vec3* getHidePos(); + std::optional getHidePos(); public: // 4J Added override to update ai elements when loading entity from // schematics virtual void setLevel(Level* level) { this->level = level; } -}; \ No newline at end of file +}; diff --git a/Minecraft.World/AI/Goals/MoveIndoorsGoal.cpp b/Minecraft.World/AI/Goals/MoveIndoorsGoal.cpp index 6ebcef842..6451e21e4 100644 --- a/Minecraft.World/AI/Goals/MoveIndoorsGoal.cpp +++ b/Minecraft.World/AI/Goals/MoveIndoorsGoal.cpp @@ -46,10 +46,10 @@ void MoveIndoorsGoal::start() { _doorInfo->getIndoorZ()) > 16 * 16) { Vec3 towards(_doorInfo->getIndoorX() + 0.5, _doorInfo->getIndoorY(), _doorInfo->getIndoorZ() + 0.5); - Vec3* pos = RandomPos::getPosTowards( + auto pos = RandomPos::getPosTowards( std::dynamic_pointer_cast(mob->shared_from_this()), 14, 3, &towards); - if (pos != NULL) + if (pos.has_value()) mob->getNavigation()->moveTo(pos->x, pos->y, pos->z, 1.0f); } else mob->getNavigation()->moveTo(_doorInfo->getIndoorX() + 0.5, diff --git a/Minecraft.World/AI/Goals/MoveThroughVillageGoal.cpp b/Minecraft.World/AI/Goals/MoveThroughVillageGoal.cpp index 82f0308ff..03fe6795a 100644 --- a/Minecraft.World/AI/Goals/MoveThroughVillageGoal.cpp +++ b/Minecraft.World/AI/Goals/MoveThroughVillageGoal.cpp @@ -48,10 +48,10 @@ bool MoveThroughVillageGoal::canUse() { if (path != NULL) return true; Vec3 towards(_doorInfo->x, _doorInfo->y, _doorInfo->z); - Vec3* pos = RandomPos::getPosTowards( + auto pos = RandomPos::getPosTowards( std::dynamic_pointer_cast(mob->shared_from_this()), 10, 7, &towards); - if (pos == NULL) return false; + if (!pos.has_value()) return false; mob->getNavigation()->setCanOpenDoors(false); delete path; path = mob->getNavigation()->createPath(pos->x, pos->y, pos->z); diff --git a/Minecraft.World/AI/Goals/MoveTowardsRestrictionGoal.cpp b/Minecraft.World/AI/Goals/MoveTowardsRestrictionGoal.cpp index 5b8efe271..cb52d4c3b 100644 --- a/Minecraft.World/AI/Goals/MoveTowardsRestrictionGoal.cpp +++ b/Minecraft.World/AI/Goals/MoveTowardsRestrictionGoal.cpp @@ -19,10 +19,10 @@ bool MoveTowardsRestrictionGoal::canUse() { if (mob->isWithinRestriction()) return false; Pos* toward = mob->getRestrictCenter(); Vec3 towards(toward->x, toward->y, toward->z); - Vec3* pos = RandomPos::getPosTowards( + auto pos = RandomPos::getPosTowards( std::dynamic_pointer_cast(mob->shared_from_this()), 16, 7, &towards); - if (pos == NULL) return false; + if (!pos.has_value()) return false; wantedX = pos->x; wantedY = pos->y; wantedZ = pos->z; diff --git a/Minecraft.World/AI/Goals/MoveTowardsTargetGoal.cpp b/Minecraft.World/AI/Goals/MoveTowardsTargetGoal.cpp index bc3be03d8..22babe6ca 100644 --- a/Minecraft.World/AI/Goals/MoveTowardsTargetGoal.cpp +++ b/Minecraft.World/AI/Goals/MoveTowardsTargetGoal.cpp @@ -21,10 +21,10 @@ bool MoveTowardsTargetGoal::canUse() { if (target.lock()->distanceToSqr(mob->shared_from_this()) > within * within) return false; Vec3 towards(target.lock()->x, target.lock()->y, target.lock()->z); - Vec3* pos = RandomPos::getPosTowards( + auto pos = RandomPos::getPosTowards( std::dynamic_pointer_cast(mob->shared_from_this()), 16, 7, &towards); - if (pos == NULL) return false; + if (!pos.has_value()) return false; wantedX = pos->x; wantedY = pos->y; wantedZ = pos->z; diff --git a/Minecraft.World/AI/Goals/PanicGoal.cpp b/Minecraft.World/AI/Goals/PanicGoal.cpp index 9c32c1c6e..a05d0fcfc 100644 --- a/Minecraft.World/AI/Goals/PanicGoal.cpp +++ b/Minecraft.World/AI/Goals/PanicGoal.cpp @@ -14,10 +14,10 @@ PanicGoal::PanicGoal(PathfinderMob* mob, double speedModifier) { bool PanicGoal::canUse() { if (mob->getLastHurtByMob() == NULL && !mob->isOnFire()) return false; - Vec3* pos = RandomPos::getPos( + auto pos = RandomPos::getPos( std::dynamic_pointer_cast(mob->shared_from_this()), 5, 4); - if (pos == NULL) return false; + if (!pos.has_value()) return false; posX = pos->x; posY = pos->y; posZ = pos->z; @@ -28,4 +28,4 @@ void PanicGoal::start() { mob->getNavigation()->moveTo(posX, posY, posZ, speedModifier); } -bool PanicGoal::canContinueToUse() { return !mob->getNavigation()->isDone(); } \ No newline at end of file +bool PanicGoal::canContinueToUse() { return !mob->getNavigation()->isDone(); } diff --git a/Minecraft.World/AI/Goals/PlayGoal.cpp b/Minecraft.World/AI/Goals/PlayGoal.cpp index 4c933d513..0259d5c93 100644 --- a/Minecraft.World/AI/Goals/PlayGoal.cpp +++ b/Minecraft.World/AI/Goals/PlayGoal.cpp @@ -43,10 +43,10 @@ bool PlayGoal::canUse() { delete children; if (followFriend.lock() == NULL) { - Vec3* pos = RandomPos::getPos( + auto pos = RandomPos::getPos( std::dynamic_pointer_cast(mob->shared_from_this()), 16, 3); - if (pos == NULL) return false; + if (!pos.has_value()) return false; } return true; } @@ -72,11 +72,11 @@ void PlayGoal::tick() { mob->getNavigation()->moveTo(followFriend.lock(), speedModifier); } else { if (mob->getNavigation()->isDone()) { - Vec3* pos = + auto pos = RandomPos::getPos(std::dynamic_pointer_cast( mob->shared_from_this()), 16, 3); - if (pos == NULL) return; + if (!pos.has_value()) return; mob->getNavigation()->moveTo(pos->x, pos->y, pos->z, speedModifier); } } diff --git a/Minecraft.World/AI/Goals/RandomStrollGoal.cpp b/Minecraft.World/AI/Goals/RandomStrollGoal.cpp index ba81c5442..2e95918bd 100644 --- a/Minecraft.World/AI/Goals/RandomStrollGoal.cpp +++ b/Minecraft.World/AI/Goals/RandomStrollGoal.cpp @@ -20,11 +20,11 @@ bool RandomStrollGoal::canUse() { // fenced-off region far enough to determine we can despawn them if (mob->getNoActionTime() < SharedConstants::TICKS_PER_SECOND * 5) { if (mob->getRandom()->nextInt(120) == 0) { - Vec3* pos = + auto pos = RandomPos::getPos(std::dynamic_pointer_cast( mob->shared_from_this()), 10, 7); - if (pos == NULL) return false; + if (!pos.has_value()) return false; wantedX = pos->x; wantedY = pos->y; wantedZ = pos->z; @@ -38,11 +38,11 @@ bool RandomStrollGoal::canUse() { // a given area and so waiting around is just wasting time if (mob->isExtraWanderingEnabled()) { - Vec3* pos = + auto pos = RandomPos::getPos(std::dynamic_pointer_cast( mob->shared_from_this()), 10, 7, mob->getWanderingQuadrant()); - if (pos == NULL) return false; + if (!pos.has_value()) return false; wantedX = pos->x; wantedY = pos->y; wantedZ = pos->z; @@ -58,4 +58,4 @@ bool RandomStrollGoal::canContinueToUse() { void RandomStrollGoal::start() { mob->getNavigation()->moveTo(wantedX, wantedY, wantedZ, speedModifier); -} \ No newline at end of file +} diff --git a/Minecraft.World/AI/Goals/RunAroundLikeCrazyGoal.cpp b/Minecraft.World/AI/Goals/RunAroundLikeCrazyGoal.cpp index 84c35dd41..c24d376cd 100644 --- a/Minecraft.World/AI/Goals/RunAroundLikeCrazyGoal.cpp +++ b/Minecraft.World/AI/Goals/RunAroundLikeCrazyGoal.cpp @@ -17,10 +17,10 @@ RunAroundLikeCrazyGoal::RunAroundLikeCrazyGoal(EntityHorse* mob, bool RunAroundLikeCrazyGoal::canUse() { if (horse->isTamed() || horse->rider.lock() == NULL) return false; - Vec3* pos = RandomPos::getPos( + auto pos = RandomPos::getPos( std::dynamic_pointer_cast(horse->shared_from_this()), 5, 4); - if (pos == NULL) return false; + if (!pos.has_value()) return false; posX = pos->x; posY = pos->y; posZ = pos->z; @@ -57,4 +57,4 @@ void RunAroundLikeCrazyGoal::tick() { horse->level->broadcastEntityEvent(horse->shared_from_this(), EntityEvent::TAMING_FAILED); } -} \ No newline at end of file +} diff --git a/Minecraft.World/AI/Navigation/Path.cpp b/Minecraft.World/AI/Navigation/Path.cpp index eaef6b8a9..672839665 100644 --- a/Minecraft.World/AI/Navigation/Path.cpp +++ b/Minecraft.World/AI/Navigation/Path.cpp @@ -48,17 +48,17 @@ int Path::getIndex() { return index; } void Path::setIndex(int index) { this->index = index; } -Vec3* Path::getPos(std::shared_ptr e, int index) { +Vec3 Path::getPos(std::shared_ptr e, int index) { double x = nodes[index]->x + (int)(e->bbWidth + 1) * 0.5; double y = nodes[index]->y; double z = nodes[index]->z + (int)(e->bbWidth + 1) * 0.5; - return Vec3::newTemp(x, y, z); + return Vec3(x, y, z); } -Vec3* Path::currentPos(std::shared_ptr e) { return getPos(e, index); } +Vec3 Path::currentPos(std::shared_ptr e) { return getPos(e, index); } -Vec3* Path::currentPos() { - return Vec3::newTemp(nodes[index]->x, nodes[index]->y, nodes[index]->z); +Vec3 Path::currentPos() { + return Vec3(nodes[index]->x, nodes[index]->y, nodes[index]->z); } bool Path::sameAs(Path* path) { @@ -83,4 +83,4 @@ bool Path::endsInXZ(Vec3* pos) { Node* lastNode = last(); if (lastNode == NULL) return false; return lastNode->x == (int)pos->x && lastNode->z == (int)pos->z; -} \ No newline at end of file +} diff --git a/Minecraft.World/AI/Navigation/Path.h b/Minecraft.World/AI/Navigation/Path.h index 0e5697959..ab0a013be 100644 --- a/Minecraft.World/AI/Navigation/Path.h +++ b/Minecraft.World/AI/Navigation/Path.h @@ -20,10 +20,10 @@ public: void setSize(int length); int getIndex(); void setIndex(int index); - Vec3* getPos(std::shared_ptr e, int index); + Vec3 getPos(std::shared_ptr e, int index); NodeArray Getarray(); - Vec3* currentPos(std::shared_ptr e); - Vec3* currentPos(); + Vec3 currentPos(std::shared_ptr e); + Vec3 currentPos(); bool sameAs(Path* path); bool endsIn(Vec3* pos); bool endsInXZ(Vec3* pos); diff --git a/Minecraft.World/AI/Navigation/PathNavigation.cpp b/Minecraft.World/AI/Navigation/PathNavigation.cpp index 0160d92f0..5b670ec7d 100644 --- a/Minecraft.World/AI/Navigation/PathNavigation.cpp +++ b/Minecraft.World/AI/Navigation/PathNavigation.cpp @@ -20,7 +20,7 @@ PathNavigation::PathNavigation(Mob* mob, Level* level) { avoidSun = false; _tick = 0; lastStuckCheck = 0; - lastStuckCheckPos = Vec3::newPermanent(0, 0, 0); + lastStuckCheckPos = new Vec3(0, 0, 0); _canPassDoors = true; _canOpenDoors = false; avoidWater = false; @@ -110,11 +110,11 @@ bool PathNavigation::moveTo(Path* newPath, double speedModifier) { if (path->getSize() == 0) return false; this->speedModifier = speedModifier; - Vec3* mobPos = getTempMobPos(); + Vec3 mobPos = getTempMobPos(); lastStuckCheck = _tick; - lastStuckCheckPos->x = mobPos->x; - lastStuckCheckPos->y = mobPos->y; - lastStuckCheckPos->z = mobPos->z; + lastStuckCheckPos->x = mobPos.x; + lastStuckCheckPos->y = mobPos.y; + lastStuckCheckPos->z = mobPos.z; return true; } @@ -127,20 +127,19 @@ void PathNavigation::tick() { if (canUpdatePath()) updatePath(); if (isDone()) return; - Vec3* target = path->currentPos(mob->shared_from_this()); - if (target == NULL) return; + Vec3 target = path->currentPos(mob->shared_from_this()); - mob->getMoveControl()->setWantedPosition(target->x, target->y, target->z, + mob->getMoveControl()->setWantedPosition(target.x, target.y, target.z, speedModifier); } void PathNavigation::updatePath() { - Vec3* mobPos = getTempMobPos(); + Vec3 mobPos = getTempMobPos(); // find first elevations in path int firstElevation = path->getSize(); for (int i = path->getIndex(); path != NULL && i < path->getSize(); ++i) { - if ((int)path->get(i)->y != (int)mobPos->y) { + if ((int)path->get(i)->y != (int)mobPos.y) { firstElevation = i; break; } @@ -150,8 +149,8 @@ void PathNavigation::updatePath() { // check canWalkDirectly also) possibly only check next as well float waypointRadiusSqr = mob->bbWidth * mob->bbWidth; for (int i = path->getIndex(); i < firstElevation; ++i) { - Vec3* pathPos = path->getPos(mob->shared_from_this(), i); - if (mobPos->distanceToSqr(*pathPos) < waypointRadiusSqr) { + Vec3 pathPos = path->getPos(mob->shared_from_this(), i); + if (mobPos.distanceToSqr(pathPos) < waypointRadiusSqr) { path->setIndex(i + 1); } } @@ -161,7 +160,8 @@ void PathNavigation::updatePath() { int sy = (int)mob->bbHeight + 1; int sz = sx; for (int i = firstElevation - 1; i >= path->getIndex(); --i) { - if (canMoveDirectly(mobPos, path->getPos(mob->shared_from_this(), i), + Vec3 mob_pos = path->getPos(mob->shared_from_this(), i); + if (canMoveDirectly(&mobPos, &mob_pos, sx, sy, sz)) { path->setIndex(i); break; @@ -170,11 +170,11 @@ void PathNavigation::updatePath() { // stuck detection (probably pushed off path) if (_tick - lastStuckCheck > 100) { - if (mobPos->distanceToSqr(*lastStuckCheckPos) < 1.5 * 1.5) stop(); + if (mobPos.distanceToSqr(*lastStuckCheckPos) < 1.5 * 1.5) stop(); lastStuckCheck = _tick; - lastStuckCheckPos->x = mobPos->x; - lastStuckCheckPos->y = mobPos->y; - lastStuckCheckPos->z = mobPos->z; + lastStuckCheckPos->x = mobPos.x; + lastStuckCheckPos->y = mobPos.y; + lastStuckCheckPos->z = mobPos.z; } } @@ -185,8 +185,8 @@ void PathNavigation::stop() { path = NULL; } -Vec3* PathNavigation::getTempMobPos() { - return Vec3::newTemp(mob->x, getSurfaceY(), mob->z); +Vec3 PathNavigation::getTempMobPos() { + return Vec3(mob->x, getSurfaceY(), mob->z); } int PathNavigation::getSurfaceY() { diff --git a/Minecraft.World/AI/Navigation/PathNavigation.h b/Minecraft.World/AI/Navigation/PathNavigation.h index d9d731532..25130e1b0 100644 --- a/Minecraft.World/AI/Navigation/PathNavigation.h +++ b/Minecraft.World/AI/Navigation/PathNavigation.h @@ -52,7 +52,7 @@ public: void stop(); private: - Vec3* getTempMobPos(); + Vec3 getTempMobPos(); int getSurfaceY(); bool canUpdatePath(); bool isInLiquid(); @@ -67,4 +67,4 @@ public: // 4J Added override to update ai elements when loading entity from // schematics void setLevel(Level* level); -}; \ No newline at end of file +}; diff --git a/Minecraft.World/AI/Navigation/RandomPos.cpp b/Minecraft.World/AI/Navigation/RandomPos.cpp index d092d0e82..1a804fbb9 100644 --- a/Minecraft.World/AI/Navigation/RandomPos.cpp +++ b/Minecraft.World/AI/Navigation/RandomPos.cpp @@ -2,16 +2,17 @@ #include "../../Headers/net.minecraft.world.entity.h" #include "../../Headers/net.minecraft.world.phys.h" #include "RandomPos.h" +#include -Vec3* RandomPos::tempDir = Vec3::newPermanent(0, 0, 0); +Vec3* RandomPos::tempDir = new Vec3(0, 0, 0); -Vec3* RandomPos::getPos(std::shared_ptr mob, int xzDist, +std::optional RandomPos::getPos(std::shared_ptr mob, int xzDist, int yDist, int quadrant /*=-1*/) // 4J - added quadrant { return generateRandomPos(mob, xzDist, yDist, NULL, quadrant); } -Vec3* RandomPos::getPosTowards(std::shared_ptr mob, int xzDist, +std::optional RandomPos::getPosTowards(std::shared_ptr mob, int xzDist, int yDist, Vec3* towardsPos) { tempDir->x = towardsPos->x - mob->x; tempDir->y = towardsPos->y - mob->y; @@ -19,7 +20,7 @@ Vec3* RandomPos::getPosTowards(std::shared_ptr mob, int xzDist, return generateRandomPos(mob, xzDist, yDist, tempDir); } -Vec3* RandomPos::getPosAvoid(std::shared_ptr mob, int xzDist, +std::optional RandomPos::getPosAvoid(std::shared_ptr mob, int xzDist, int yDist, Vec3* avoidPos) { tempDir->x = mob->x - avoidPos->x; tempDir->y = mob->y - avoidPos->y; @@ -27,7 +28,7 @@ Vec3* RandomPos::getPosAvoid(std::shared_ptr mob, int xzDist, return generateRandomPos(mob, xzDist, yDist, tempDir); } -Vec3* RandomPos::generateRandomPos(std::shared_ptr mob, +std::optional RandomPos::generateRandomPos(std::shared_ptr mob, int xzDist, int yDist, Vec3* dir, int quadrant /*=-1*/) // 4J - added quadrant { @@ -81,8 +82,8 @@ Vec3* RandomPos::generateRandomPos(std::shared_ptr mob, } } if (hasBest) { - return Vec3::newTemp(xBest, yBest, zBest); + return Vec3(xBest, yBest, zBest); } - return NULL; -} \ No newline at end of file + return std::nullopt; +} diff --git a/Minecraft.World/AI/Navigation/RandomPos.h b/Minecraft.World/AI/Navigation/RandomPos.h index 8baa8e50f..48e278ad0 100644 --- a/Minecraft.World/AI/Navigation/RandomPos.h +++ b/Minecraft.World/AI/Navigation/RandomPos.h @@ -1,5 +1,6 @@ #pragma once +#include class PathfinderMob; class RandomPos { @@ -7,15 +8,14 @@ private: static Vec3* tempDir; public: - static Vec3* getPos(std::shared_ptr mob, int xzDist, + static std::optional getPos(std::shared_ptr mob, int xzDist, int yDist, int quadrant = -1); // 4J added quadrant - static Vec3* getPosTowards(std::shared_ptr mob, int xzDist, + static std::optional getPosTowards(std::shared_ptr mob, int xzDist, int yDist, Vec3* towardsPos); - static Vec3* getPosAvoid(std::shared_ptr mob, int xzDist, + static std::optional getPosAvoid(std::shared_ptr mob, int xzDist, int yDist, Vec3* avoidPos); - private: - static Vec3* generateRandomPos(std::shared_ptr mob, + static std::optional generateRandomPos(std::shared_ptr mob, int xzDist, int yDist, Vec3* dir, int quadrant = -1); // 4J added quadrant -}; \ No newline at end of file +}; diff --git a/Minecraft.World/Blocks/LiquidTile.cpp b/Minecraft.World/Blocks/LiquidTile.cpp index 348982c5f..2b3cda562 100644 --- a/Minecraft.World/Blocks/LiquidTile.cpp +++ b/Minecraft.World/Blocks/LiquidTile.cpp @@ -7,6 +7,7 @@ #include "LiquidTile.h" #include "../Util/Facing.h" #include "../Util/SoundTypes.h" +#include "Blocks/Material.h" const std::wstring LiquidTile::TEXTURE_LAVA_STILL = L"lava"; const std::wstring LiquidTile::TEXTURE_WATER_STILL = L"water"; @@ -116,8 +117,8 @@ int LiquidTile::getResource(int data, Random* random, int playerBonusLevel) { int LiquidTile::getResourceCount(Random* random) { return 0; } -Vec3* LiquidTile::getFlow(LevelSource* level, int x, int y, int z) { - Vec3* flow = Vec3::newTemp(0, 0, 0); +Vec3 LiquidTile::getFlow(LevelSource* level, int x, int y, int z) { + Vec3 flow(0, 0, 0); int mid = getRenderedDepth(level, x, y, z); for (int d = 0; d < 4; d++) { int xt = x; @@ -135,15 +136,15 @@ Vec3* LiquidTile::getFlow(LevelSource* level, int x, int y, int z) { t = getRenderedDepth(level, xt, yt - 1, zt); if (t >= 0) { int dir = t - (mid - 8); - *flow = flow->add((xt - x) * dir, (yt - y) * dir, + flow = flow.add((xt - x) * dir, (yt - y) * dir, (zt - z) * dir); } } } else { if (t >= 0) { int dir = t - mid; - *flow = - flow->add((xt - x) * dir, (yt - y) * dir, (zt - z) * dir); + flow = + flow.add((xt - x) * dir, (yt - y) * dir, (zt - z) * dir); } } } @@ -157,18 +158,19 @@ Vec3* LiquidTile::getFlow(LevelSource* level, int x, int y, int z) { if (ok || isSolidFace(level, x, y + 1, z + 1, 3)) ok = true; if (ok || isSolidFace(level, x - 1, y + 1, z, 4)) ok = true; if (ok || isSolidFace(level, x + 1, y + 1, z, 5)) ok = true; - if (ok) *flow = flow->normalize().add(0, -6, 0); + if (ok) flow = flow.normalize().add(0, -6, 0); } - *flow = flow->normalize(); + flow = flow.normalize(); + return flow; } void LiquidTile::handleEntityInside(Level* level, int x, int y, int z, std::shared_ptr e, Vec3* current) { - Vec3* flow = getFlow(level, x, y, z); - current->x += flow->x; - current->y += flow->y; - current->z += flow->z; + Vec3 flow = getFlow(level, x, y, z); + current->x += flow.x; + current->y += flow.y; + current->z += flow.z; } int LiquidTile::getTickDelay(Level* level) { @@ -305,13 +307,13 @@ void LiquidTile::animateTick(Level* level, int x, int y, int z, double LiquidTile::getSlopeAngle(LevelSource* level, int x, int y, int z, Material* m) { - Vec3* flow = NULL; + Vec3 flow; if (m == Material::water) - flow = ((LiquidTile*)Tile::water)->getFlow(level, x, y, z); + flow = Tile::water->getFlow(level, x, y, z); if (m == Material::lava) - flow = ((LiquidTile*)Tile::lava)->getFlow(level, x, y, z); - if (flow->x == 0 && flow->z == 0) return -1000; - return atan2(flow->z, flow->x) - PI / 2; + flow = Tile::lava->getFlow(level, x, y, z); + if (flow.x == 0 && flow.z == 0) return -1000; + return atan2(flow.z, flow.x) - PI / 2; } void LiquidTile::onPlace(Level* level, int x, int y, int z) { diff --git a/Minecraft.World/Blocks/LiquidTile.h b/Minecraft.World/Blocks/LiquidTile.h index 24c3d8f17..1d59d274a 100644 --- a/Minecraft.World/Blocks/LiquidTile.h +++ b/Minecraft.World/Blocks/LiquidTile.h @@ -46,7 +46,7 @@ public: virtual int getResourceCount(Random* random); private: - virtual Vec3* getFlow(LevelSource* level, int x, int y, int z); + virtual Vec3 getFlow(LevelSource* level, int x, int y, int z); public: virtual void handleEntityInside(Level* level, int x, int y, int z, @@ -72,4 +72,4 @@ protected: public: void registerIcons(IconRegister* iconRegister); static Icon* getTexture(const std::wstring& name); -}; \ No newline at end of file +}; diff --git a/Minecraft.World/Entities/Entity.cpp b/Minecraft.World/Entities/Entity.cpp index dc3ee4dd7..51ed60e8f 100644 --- a/Minecraft.World/Entities/Entity.cpp +++ b/Minecraft.World/Entities/Entity.cpp @@ -23,6 +23,7 @@ #include "../../Minecraft.Client/Level/MultiPlayerLevel.h" #include "../../Minecraft.Client/Player/MultiPlayerLocalPlayer.h" #include +#include #include "../../Minecraft.Client/Level/ServerLevel.h" #include "../../Minecraft.Client/Network/PlayerList.h" @@ -1533,7 +1534,7 @@ void Entity::lerpTo(double x, double y, double z, float yRot, float xRot, float Entity::getPickRadius() { return 0.1f; } -Vec3* Entity::getLookAngle() { return NULL; } +std::optional Entity::getLookAngle() { return std::nullopt; } void Entity::handleInsidePortal() { if (changingDimensionDelay > 0) { diff --git a/Minecraft.World/Entities/Entity.h b/Minecraft.World/Entities/Entity.h index bc7d0a4dc..df348f5cd 100644 --- a/Minecraft.World/Entities/Entity.h +++ b/Minecraft.World/Entities/Entity.h @@ -6,6 +6,7 @@ #include "../Util/Vec3.h" #include "../Util/Definitions.h" #include +#include class LivingEntity; class LightningBolt; @@ -342,7 +343,7 @@ public: virtual void lerpTo(double x, double y, double z, float yRot, float xRot, int steps); virtual float getPickRadius(); - virtual Vec3* getLookAngle(); + virtual std::optional getLookAngle(); virtual void handleInsidePortal(); virtual int getDimensionChangingDelay(); virtual void lerpMotion(double xd, double yd, double zd); diff --git a/Minecraft.World/Entities/LivingEntity.cpp b/Minecraft.World/Entities/LivingEntity.cpp index 47a004096..00a5de704 100644 --- a/Minecraft.World/Entities/LivingEntity.cpp +++ b/Minecraft.World/Entities/LivingEntity.cpp @@ -24,6 +24,7 @@ #include "../Headers/net.minecraft.world.scores.h" #include "../Headers/com.mojang.nbt.h" #include "LivingEntity.h" +#include #include "../../Minecraft.Client/Textures/Textures.h" #include "../../Minecraft.Client/Level/ServerLevel.h" #include "../../Minecraft.Client/Player/EntityTracker.h" @@ -1650,16 +1651,16 @@ bool LivingEntity::canSee(std::shared_ptr target) { return retVal; } -Vec3* LivingEntity::getLookAngle() { return getViewVector(1); } +std::optional LivingEntity::getLookAngle() { return getViewVector(1); } -Vec3* LivingEntity::getViewVector(float a) { +Vec3 LivingEntity::getViewVector(float a) { if (a == 1) { float yCos = Mth::cos(-yRot * Mth::RAD_TO_GRAD - PI); float ySin = Mth::sin(-yRot * Mth::RAD_TO_GRAD - PI); float xCos = -Mth::cos(-xRot * Mth::RAD_TO_GRAD); float xSin = Mth::sin(-xRot * Mth::RAD_TO_GRAD); - return Vec3::newTemp(ySin * xCos, xSin, yCos * xCos); + return Vec3(ySin * xCos, xSin, yCos * xCos); } float xRot = xRotO + (this->xRot - xRotO) * a; float yRot = yRotO + (this->yRot - yRotO) * a; @@ -1669,7 +1670,7 @@ Vec3* LivingEntity::getViewVector(float a) { float xCos = -Mth::cos(-xRot * Mth::RAD_TO_GRAD); float xSin = Mth::sin(-xRot * Mth::RAD_TO_GRAD); - return Vec3::newTemp(ySin * xCos, xSin, yCos * xCos); + return Vec3(ySin * xCos, xSin, yCos * xCos); } float LivingEntity::getAttackAnim(float a) { @@ -1678,20 +1679,20 @@ float LivingEntity::getAttackAnim(float a) { return oAttackAnim + diff * a; } -Vec3* LivingEntity::getPos(float a) { +Vec3 LivingEntity::getPos(float a) { if (a == 1) { - return Vec3::newTemp(x, y, z); + return Vec3(x, y, z); } double x = xo + (this->x - xo) * a; double y = yo + (this->y - yo) * a; double z = zo + (this->z - zo) * a; - return Vec3::newTemp(x, y, z); + return Vec3(x, y, z); } HitResult* LivingEntity::pick(double range, float a) { - Vec3 from = *getPos(a); - Vec3 b = *getViewVector(a); + Vec3 from = getPos(a); + Vec3 b = getViewVector(a); Vec3 to{b.x * range, b.y * range, b.z * range}; to = to.add(from.x, from.y, from.z); return level->clip(&from, &to); diff --git a/Minecraft.World/Entities/LivingEntity.h b/Minecraft.World/Entities/LivingEntity.h index ead873ce3..30ad389b3 100644 --- a/Minecraft.World/Entities/LivingEntity.h +++ b/Minecraft.World/Entities/LivingEntity.h @@ -1,5 +1,6 @@ #pragma once +#include #include "Entity.h" #include "MobType.h" #include "../AI/Goals/GoalSelector.h" @@ -304,10 +305,10 @@ public: virtual bool canSee(std::shared_ptr target); public: - virtual Vec3* getLookAngle(); - virtual Vec3* getViewVector(float a); + virtual std::optional getLookAngle(); + virtual Vec3 getViewVector(float a); virtual float getAttackAnim(float a); - virtual Vec3* getPos(float a); + virtual Vec3 getPos(float a); virtual HitResult* pick(double range, float a); virtual bool isEffectiveAi(); diff --git a/Minecraft.World/Entities/Mobs/EnderDragon.cpp b/Minecraft.World/Entities/Mobs/EnderDragon.cpp index 5ef66d371..828eeb982 100644 --- a/Minecraft.World/Entities/Mobs/EnderDragon.cpp +++ b/Minecraft.World/Entities/Mobs/EnderDragon.cpp @@ -14,6 +14,7 @@ #include "../../Util/SharedConstants.h" #include "EnderDragon.h" #include +#include #define PRINT_DRAGON_STATE_CHANGE_MESSAGES 1 @@ -309,12 +310,12 @@ void EnderDragon::aiStep() { double xP = 0.0; double yP = 0.0; double zP = 0.0; - Vec3* v = getHeadLookVector(1); // getViewVector(1); + Vec3 v = getHeadLookVector(1); // getViewVector(1); // app.DebugPrintf("View vector is (%f,%f,%f) - lsteps %d\n", v->x, // v->y, v->z, lSteps); unsigned int d = 0; for(unsigned int d = 1; // d < 3; ++d) { - Vec3 vN = Vec3{v->x, v->y, v->z}.normalize(); + Vec3 vN = Vec3{v.x, v.y, v.z}.normalize(); vN.yRot(-PI / 4); for (unsigned int i = 0; i < 8; ++i) { @@ -746,10 +747,10 @@ void EnderDragon::aiStep() { if (m_fireballCharge >= 20 && (angleDegs >= 0 && angleDegs < 10)) { double d = 1; - Vec3* v = getViewVector(1); - float startingX = head->x - v->x * d; + Vec3 v = getViewVector(1); + float startingX = head->x - v.x * d; float startingY = head->y + head->bbHeight / 2 + 0.5f; - float startingZ = head->z - v->z * d; + float startingZ = head->z - v.z * d; double xdd = attackTarget->x - startingX; double ydd = @@ -1022,9 +1023,9 @@ void EnderDragon::findNewTarget() { // !m_holdingPatternClockwise; if (getSynchedAction() == e_EnderdragonAction_Takeoff) { - Vec3* v = getHeadLookVector(1); + Vec3 v = getHeadLookVector(1); targetNodeIndex = - findClosestNode(-v->x * 40, 105.0, -v->z * 40); + findClosestNode(-v.x * 40, 105.0, -v.z * 40); } else { if (random->nextInt(8) == 0) { m_holdingPatternClockwise = !m_holdingPatternClockwise; @@ -1488,24 +1489,24 @@ void EnderDragon::strafeAttackTarget() { void EnderDragon::navigateToNextPathNode() { if (m_currentPath != NULL && !m_currentPath->isDone()) { - Vec3* curr = m_currentPath->currentPos(); + Vec3 curr = m_currentPath->currentPos(); m_currentPath->next(); - xTarget = curr->x; + xTarget = curr.x; if (getSynchedAction() == e_EnderdragonAction_LandingApproach && m_currentPath->isDone()) { // When heading to the last node on the landing approach, we want // the yCoord to be exact - yTarget = curr->y; + yTarget = curr.y; } else { do { - yTarget = curr->y + random->nextFloat() * 20; - } while (yTarget < (curr->y)); + yTarget = curr.y + random->nextFloat() * 20; + } while (yTarget < (curr.y)); } - zTarget = curr->z; - app.DebugPrintf("Path node pos is (%f,%f,%f)\n", curr->x, curr->y, - curr->z); + zTarget = curr.z; + app.DebugPrintf("Path node pos is (%f,%f,%f)\n", curr.x, curr.y, + curr.z); app.DebugPrintf("Setting new target to (%f,%f,%f)\n", xTarget, yTarget, zTarget); } @@ -1846,8 +1847,8 @@ double EnderDragon::getHeadPartYRotDiff(int partIndex, doubleArray bodyPos, return result; } -Vec3* EnderDragon::getHeadLookVector(float a) { - Vec3* result = NULL; +Vec3 EnderDragon::getHeadLookVector(float a) { + Vec3 result; if (getSynchedAction() == e_EnderdragonAction_Landing || getSynchedAction() == e_EnderdragonAction_Takeoff) { @@ -1888,5 +1889,6 @@ Vec3* EnderDragon::getHeadLookVector(float a) { } else { result = getViewVector(a); } + return result; } diff --git a/Minecraft.World/Entities/Mobs/EnderDragon.h b/Minecraft.World/Entities/Mobs/EnderDragon.h index 90056ce63..e8270dcae 100644 --- a/Minecraft.World/Entities/Mobs/EnderDragon.h +++ b/Minecraft.World/Entities/Mobs/EnderDragon.h @@ -188,7 +188,7 @@ public: doubleArray partPos); double getHeadPartYRotDiff(int partIndex, doubleArray bodyPos, doubleArray partPos); - Vec3* getHeadLookVector(float a); + Vec3 getHeadLookVector(float a); virtual std::wstring getAName() { return app.GetString(IDS_ENDERDRAGON); }; virtual float getHealth() { return LivingEntity::getHealth(); }; diff --git a/Minecraft.World/Entities/Mobs/EnderMan.cpp b/Minecraft.World/Entities/Mobs/EnderMan.cpp index d559c2056..9762254f9 100644 --- a/Minecraft.World/Entities/Mobs/EnderMan.cpp +++ b/Minecraft.World/Entities/Mobs/EnderMan.cpp @@ -114,8 +114,7 @@ bool EnderMan::isLookingAtMe(std::shared_ptr player) { std::shared_ptr helmet = player->inventory->armor[3]; if (helmet != NULL && helmet->id == Tile::pumpkin_Id) return false; - Vec3* look = player->getViewVector(1); - *look = look->normalize(); + Vec3 look = player->getViewVector(1).normalize(); Vec3 dir{x - player->x, (bb->y0 + bbHeight / 2) - (player->y + player->getHeadHeight()), @@ -123,7 +122,7 @@ bool EnderMan::isLookingAtMe(std::shared_ptr player) { double dist = dir.length(); dir = dir.normalize(); - double dot = look->dot(dir); + double dot = look.dot(dir); if (dot > 1 - 0.025 / dist) { return player->canSee(shared_from_this()); } diff --git a/Minecraft.World/Entities/Mobs/Fireball.cpp b/Minecraft.World/Entities/Mobs/Fireball.cpp index 68b12a435..91bfe34f7 100644 --- a/Minecraft.World/Entities/Mobs/Fireball.cpp +++ b/Minecraft.World/Entities/Mobs/Fireball.cpp @@ -300,8 +300,8 @@ bool Fireball::hurt(DamageSource* source, float damage) { markHurt(); if (source->getEntity() != NULL) { - Vec3* lookAngle = source->getEntity()->getLookAngle(); - if (lookAngle != NULL) { + auto lookAngle = source->getEntity()->getLookAngle(); + if (lookAngle.has_value()) { xd = lookAngle->x; yd = lookAngle->y; zd = lookAngle->z; @@ -309,6 +309,7 @@ bool Fireball::hurt(DamageSource* source, float damage) { yPower = yd * 0.1; zPower = zd * 0.1; } + if (source->getEntity()->instanceof(eTYPE_LIVINGENTITY)) { owner = std::dynamic_pointer_cast(source->getEntity()); diff --git a/Minecraft.World/Entities/Mobs/Ghast.cpp b/Minecraft.World/Entities/Mobs/Ghast.cpp index a44e29e60..6dedd39ef 100644 --- a/Minecraft.World/Entities/Mobs/Ghast.cpp +++ b/Minecraft.World/Entities/Mobs/Ghast.cpp @@ -141,10 +141,10 @@ void Ghast::serverAiStep() { ydd, zdd)); ie->explosionPower = explosionPower; double d = 4; - Vec3* v = getViewVector(1); - ie->x = x + v->x * d; + Vec3 v = getViewVector(1); + ie->x = x + v.x * d; ie->y = y + bbHeight / 2 + 0.5f; - ie->z = z + v->z * d; + ie->z = z + v.z * d; level->addEntity(ie); charge = -40; } diff --git a/Minecraft.World/Entities/Mobs/Minecart.cpp b/Minecraft.World/Entities/Mobs/Minecart.cpp index 273845676..511764cb6 100644 --- a/Minecraft.World/Entities/Mobs/Minecart.cpp +++ b/Minecraft.World/Entities/Mobs/Minecart.cpp @@ -13,6 +13,8 @@ #include "../../../Minecraft.Client/Level/ServerLevel.h" #include "../../Headers/com.mojang.nbt.h" #include "Minecart.h" +#include +#include #include "../../Util/SharedConstants.h" const int Minecart::EXITS[][2][3] = { @@ -361,7 +363,7 @@ void Minecart::moveAlongTrack(int xt, int yt, int zt, double maxSpeed, double slideSpeed, int tile, int data) { fallDistance = 0; - Vec3* oldPos = getPos(x, y, z); + auto oldPos = getPos(x, y, z); y = yt; bool powerTrack = false; @@ -489,8 +491,8 @@ void Minecart::moveAlongTrack(int xt, int yt, int zt, double maxSpeed, applyNaturalSlowdown(); - Vec3* newPos = getPos(x, y, z); - if (newPos != NULL && oldPos != NULL) { + auto newPos = getPos(x, y, z); + if (newPos.has_value() && oldPos.has_value()) { double speed = (oldPos->y - newPos->y) * 0.05; pow = sqrt(xd * xd + zd * zd); @@ -549,7 +551,7 @@ void Minecart::applyNaturalSlowdown() { } } -Vec3* Minecart::getPosOffs(double x, double y, double z, double offs) { +std::optional Minecart::getPosOffs(double x, double y, double z, double offs) { int xt = Mth::floor(x); int yt = Mth::floor(y); int zt = Mth::floor(z); @@ -594,10 +596,11 @@ Vec3* Minecart::getPosOffs(double x, double y, double z, double offs) { return getPos(x, y, z); } - return NULL; + + return std::nullopt; } -Vec3* Minecart::getPos(double x, double y, double z) { +std::optional Minecart::getPos(double x, double y, double z) { int xt = Mth::floor(x); int yt = Mth::floor(y); int zt = Mth::floor(z); @@ -653,9 +656,10 @@ Vec3* Minecart::getPos(double x, double y, double z) { z = z0 + zD * progress; if (yD < 0) y += 1; if (yD > 0) y += 0.5; - return Vec3::newTemp(x, y, z); + return Vec3(x, y, z); } - return NULL; + + return std::nullopt; } void Minecart::readAdditionalSaveData(CompoundTag* tag) { diff --git a/Minecraft.World/Entities/Mobs/Minecart.h b/Minecraft.World/Entities/Mobs/Minecart.h index 353df82dc..3e96f1fc3 100644 --- a/Minecraft.World/Entities/Mobs/Minecart.h +++ b/Minecraft.World/Entities/Mobs/Minecart.h @@ -1,4 +1,5 @@ #pragma once +#include #include "../Entity.h" class DamageSource; @@ -77,8 +78,8 @@ protected: virtual void moveAlongTrack(int xt, int yt, int zt, double maxSpeed, double slideSpeed, int tile, int data); virtual void applyNaturalSlowdown(); - virtual Vec3* getPosOffs(double x, double y, double z, double offs); - virtual Vec3* getPos(double x, double y, double z); + virtual std::optional getPosOffs(double x, double y, double z, double offs); + virtual std::optional getPos(double x, double y, double z); protected: virtual void addAdditonalSaveData(CompoundTag* base); diff --git a/Minecraft.World/Entities/PathfinderMob.cpp b/Minecraft.World/Entities/PathfinderMob.cpp index 6abf6a2ac..aec748483 100644 --- a/Minecraft.World/Entities/PathfinderMob.cpp +++ b/Minecraft.World/Entities/PathfinderMob.cpp @@ -120,18 +120,20 @@ void PathfinderMob::serverAiStep() { return; } - Vec3* target = path->currentPos(shared_from_this()); + Vec3 target = path->currentPos(shared_from_this()); double r = bbWidth * 2; - while (target != NULL && target->distanceToSqr(x, target->y, z) < r * r) { + while (target.distanceToSqr(x, target.y, z) < r * r) { path->next(); if (path->isDone()) { - target = NULL; setPath(NULL); // 4J - changed to setPath from path = + break; } else target = path->currentPos(shared_from_this()); } jumping = false; + // 4jcraft - refactoring Vec3 shows this branch never hits + /* if (target != NULL) { double xd = target->x - x; double zd = target->z - z; @@ -165,6 +167,7 @@ void PathfinderMob::serverAiStep() { jumping = true; } } + */ if (attackTarget != NULL) { lookAt(attackTarget, 30, 30); diff --git a/Minecraft.World/Items/BoatItem.cpp b/Minecraft.World/Items/BoatItem.cpp index 6e0b358b1..0d3b1749c 100644 --- a/Minecraft.World/Items/BoatItem.cpp +++ b/Minecraft.World/Items/BoatItem.cpp @@ -25,7 +25,7 @@ bool BoatItem::TestUse(std::shared_ptr itemInstance, Level* level, player->yo + (player->y - player->yo) + 1.62 - player->heightOffset; double z = player->zo + (player->z - player->zo); - Vec3* from = Vec3::newTemp(x, y, z); + Vec3 from(x, y, z); float yCos = Mth::cos(-yRot * Mth::RAD_TO_GRAD - PI); float ySin = Mth::sin(-yRot * Mth::RAD_TO_GRAD - PI); @@ -37,9 +37,9 @@ bool BoatItem::TestUse(std::shared_ptr itemInstance, Level* level, float za = yCos * xCos; double range = 5; - Vec3* to = Vec3::newTemp(xa * range, ya * range, za * range); - *to = to->add(from->x, from->y, from->z); - HitResult* hr = level->clip(from, to, true); + Vec3 to(xa * range, ya * range, za * range); + to = to.add(from.x, from.y, from.z); + HitResult* hr = level->clip(&from, &to, true); if (hr == NULL) return false; if (hr->type == HitResult::TILE) { @@ -80,12 +80,12 @@ std::shared_ptr BoatItem::use( if (hr == NULL) return itemInstance; // check entity collision - Vec3* b = player->getViewVector(a); + Vec3 b = player->getViewVector(a); bool hitEntity = false; float overlap = 1; std::vector >* objects = level->getEntities( player, - player->bb->expand(b->x * (range), b->y * (range), b->z * (range)) + player->bb->expand(b.x * (range), b.y * (range), b.z * (range)) ->grow(overlap, overlap, overlap)); // for (int i = 0; i < objects.size(); i++) { for (AUTO_VAR(it, objects->begin()); it != objects->end(); ++it) { diff --git a/Minecraft.World/Level/Dimensions/Dimension.cpp b/Minecraft.World/Level/Dimensions/Dimension.cpp index a4447878c..0af723d87 100644 --- a/Minecraft.World/Level/Dimensions/Dimension.cpp +++ b/Minecraft.World/Level/Dimensions/Dimension.cpp @@ -157,7 +157,7 @@ float* Dimension::getSunriseColor(float td, float a) { return NULL; } -Vec3* Dimension::getFogColor(float td, float a) const { +Vec3 Dimension::getFogColor(float td, float a) const { float br = Mth::cos(td * PI * 2) * 2 + 0.5f; if (br < 0.0f) br = 0.0f; if (br > 1.0f) br = 1.0f; @@ -172,7 +172,7 @@ Vec3* Dimension::getFogColor(float td, float a) const { g *= br * 0.94f + 0.06f; b *= br * 0.91f + 0.09f; - return Vec3::newTemp(r, g, b); + return Vec3(r, g, b); } bool Dimension::mayRespawn() const { return true; } diff --git a/Minecraft.World/Level/Dimensions/Dimension.h b/Minecraft.World/Level/Dimensions/Dimension.h index b5d1f4674..0aea9e38c 100644 --- a/Minecraft.World/Level/Dimensions/Dimension.h +++ b/Minecraft.World/Level/Dimensions/Dimension.h @@ -48,7 +48,7 @@ private: public: virtual float* getSunriseColor(float td, float a); - virtual Vec3* getFogColor(float td, float a) const; + virtual Vec3 getFogColor(float td, float a) const; virtual bool mayRespawn() const; static Dimension* getNew(int id); virtual float getCloudHeight(); diff --git a/Minecraft.World/Level/Dimensions/HellDimension.cpp b/Minecraft.World/Level/Dimensions/HellDimension.cpp index f2869a58b..87d8ae155 100644 --- a/Minecraft.World/Level/Dimensions/HellDimension.cpp +++ b/Minecraft.World/Level/Dimensions/HellDimension.cpp @@ -15,7 +15,7 @@ void HellDimension::init() { id = -1; } -Vec3* HellDimension::getFogColor(float td, float a) const { +Vec3 HellDimension::getFogColor(float td, float a) const { int colour = Minecraft::GetInstance()->getColourTable()->getColor( eMinecraftColour_Nether_Fog_Colour); uint8_t redComponent = ((colour >> 16) & 0xFF); @@ -25,7 +25,7 @@ Vec3* HellDimension::getFogColor(float td, float a) const { float rr = (float)redComponent / 256; // 0.2f; float gg = (float)greenComponent / 256; // 0.03f; float bb = (float)blueComponent / 256; // 0.03f; - return Vec3::newTemp(rr, gg, bb); + return Vec3(rr, gg, bb); } void HellDimension::updateLightRamp() { diff --git a/Minecraft.World/Level/Dimensions/HellDimension.h b/Minecraft.World/Level/Dimensions/HellDimension.h index 93f374687..caa6ff55f 100644 --- a/Minecraft.World/Level/Dimensions/HellDimension.h +++ b/Minecraft.World/Level/Dimensions/HellDimension.h @@ -4,7 +4,7 @@ class HellDimension : public Dimension { public: virtual void init(); - virtual Vec3* getFogColor(float td, float a) const; + virtual Vec3 getFogColor(float td, float a) const; protected: virtual void updateLightRamp(); diff --git a/Minecraft.World/Level/Dimensions/SkyIslandDimension.cpp b/Minecraft.World/Level/Dimensions/SkyIslandDimension.cpp index 74ebb817a..07cb4fe4b 100644 --- a/Minecraft.World/Level/Dimensions/SkyIslandDimension.cpp +++ b/Minecraft.World/Level/Dimensions/SkyIslandDimension.cpp @@ -20,7 +20,7 @@ float SkyIslandDimension::getTimeOfDay(int64_t time, float a) const { float* SkyIslandDimension::getSunriseColor(float td, float a) { return NULL; } -Vec3* SkyIslandDimension::getFogColor(float td, float a) const { +Vec3 SkyIslandDimension::getFogColor(float td, float a) const { int fogColor = 0x8080a0; float br = Mth::cos(td * PI * 2) * 2 + 0.5f; if (br < 0.0f) br = 0.0f; @@ -33,7 +33,7 @@ Vec3* SkyIslandDimension::getFogColor(float td, float a) const { g *= br * 0.94f + 0.06f; b *= br * 0.91f + 0.09f; - return Vec3::newTemp(r, g, b); + return Vec3(r, g, b); } bool SkyIslandDimension::hasGround() { return false; } @@ -46,4 +46,4 @@ bool SkyIslandDimension::isValidSpawn(int x, int z) const { if (topTile == 0) return false; return Tile::tiles[topTile]->material->blocksMotion(); -} \ No newline at end of file +} diff --git a/Minecraft.World/Level/Dimensions/TheEndDimension.cpp b/Minecraft.World/Level/Dimensions/TheEndDimension.cpp index 28fa68ba2..d1b40addb 100644 --- a/Minecraft.World/Level/Dimensions/TheEndDimension.cpp +++ b/Minecraft.World/Level/Dimensions/TheEndDimension.cpp @@ -23,7 +23,7 @@ float TheEndDimension::getTimeOfDay(int64_t time, float a) const { float* TheEndDimension::getSunriseColor(float td, float a) { return NULL; } -Vec3* TheEndDimension::getFogColor(float td, float a) const { +Vec3 TheEndDimension::getFogColor(float td, float a) const { int fogColor = Minecraft::GetInstance()->getColourTable()->getColor( eMinecraftColour_End_Fog_Colour); // 0xa080a0; float br = Mth::cos(td * PI * 2) * 2 + 0.5f; @@ -37,7 +37,7 @@ Vec3* TheEndDimension::getFogColor(float td, float a) const { g *= br * 0.0f + 0.15f; b *= br * 0.0f + 0.15f; - return Vec3::newTemp(r, g, b); + return Vec3(r, g, b); } bool TheEndDimension::hasGround() { return false; } diff --git a/Minecraft.World/Level/Dimensions/TheEndDimension.h b/Minecraft.World/Level/Dimensions/TheEndDimension.h index c6c601e99..304974106 100644 --- a/Minecraft.World/Level/Dimensions/TheEndDimension.h +++ b/Minecraft.World/Level/Dimensions/TheEndDimension.h @@ -7,7 +7,7 @@ public: virtual ChunkSource* createRandomLevelSource() const; virtual float getTimeOfDay(int64_t time, float a) const; virtual float* getSunriseColor(float td, float a); - virtual Vec3* getFogColor(float td, float a) const; + virtual Vec3 getFogColor(float td, float a) const; virtual bool hasGround(); virtual bool mayRespawn() const; virtual bool isNaturalDimension(); diff --git a/Minecraft.World/Level/Events/VillageSiege.cpp b/Minecraft.World/Level/Events/VillageSiege.cpp index 67410f7b3..abf2dc517 100644 --- a/Minecraft.World/Level/Events/VillageSiege.cpp +++ b/Minecraft.World/Level/Events/VillageSiege.cpp @@ -4,6 +4,7 @@ #include "../../Headers/net.minecraft.world.entity.monster.h" #include "../../Headers/net.minecraft.world.level.h" #include "VillageSiege.h" +#include VillageSiege::VillageSiege(Level* level) { hasSetupSiege = false; @@ -108,8 +109,8 @@ bool VillageSiege::tryToSetupSiege() { } if (overlaps) return false; - Vec3* spawnPos = findRandomSpawnPos(spawnX, spawnY, spawnZ); - if (spawnPos == NULL) continue; + auto spawnPos = findRandomSpawnPos(spawnX, spawnY, spawnZ); + if (!spawnPos.has_value()) continue; nextSpawnTime = 0; siegeCount = 20; @@ -119,8 +120,8 @@ bool VillageSiege::tryToSetupSiege() { } bool VillageSiege::trySpawn() { - Vec3* spawnPos = findRandomSpawnPos(spawnX, spawnY, spawnZ); - if (spawnPos == NULL) return false; + auto spawnPos = findRandomSpawnPos(spawnX, spawnY, spawnZ); + if (!spawnPos.has_value()) return false; std::shared_ptr mob; // try { @@ -143,9 +144,9 @@ bool VillageSiege::trySpawn() { return true; } -Vec3* VillageSiege::findRandomSpawnPos(int x, int y, int z) { +std::optional VillageSiege::findRandomSpawnPos(int x, int y, int z) { std::shared_ptr _village = village.lock(); - if (_village == NULL) return NULL; + if (_village == NULL) return std::nullopt; for (int i = 0; i < 10; ++i) { int xx = x + level->random->nextInt(16) - 8; @@ -154,7 +155,8 @@ Vec3* VillageSiege::findRandomSpawnPos(int x, int y, int z) { if (!_village->isInside(xx, yy, zz)) continue; if (MobSpawner::isSpawnPositionOk(MobCategory::monster, level, xx, yy, zz)) - return Vec3::newTemp(xx, yy, zz); + return Vec3(xx, yy, zz); } - return NULL; + + return std::nullopt; } diff --git a/Minecraft.World/Level/Events/VillageSiege.h b/Minecraft.World/Level/Events/VillageSiege.h index f6a978824..35456c3aa 100644 --- a/Minecraft.World/Level/Events/VillageSiege.h +++ b/Minecraft.World/Level/Events/VillageSiege.h @@ -1,5 +1,7 @@ #pragma once +#include + class VillageSiege { private: Level* level; @@ -23,5 +25,5 @@ public: private: bool tryToSetupSiege(); bool trySpawn(); - Vec3* findRandomSpawnPos(int x, int y, int z); -}; \ No newline at end of file + std::optional findRandomSpawnPos(int x, int y, int z); +}; diff --git a/Minecraft.World/Level/Explosion.cpp b/Minecraft.World/Level/Explosion.cpp index 1b3686a4b..752586bd6 100644 --- a/Minecraft.World/Level/Explosion.cpp +++ b/Minecraft.World/Level/Explosion.cpp @@ -28,9 +28,6 @@ Explosion::Explosion(Level* level, std::shared_ptr source, double x, Explosion::~Explosion() { delete random; - for (AUTO_VAR(it, hitPlayers.begin()); it != hitPlayers.end(); ++it) { - delete it->second; - } } void Explosion::explode() { @@ -165,7 +162,7 @@ void Explosion::explode() { // app.DebugPrintf("Adding player knockback (%f,%f,%f)\n", xa * // pow, ya * pow, za * pow); hitPlayers.insert(playerVec3Map::value_type( - player, Vec3::newPermanent(xa * pow, ya * pow, za * pow))); + player, Vec3(xa * pow, ya * pow, za * pow))); } } } @@ -283,10 +280,10 @@ void Explosion::finalizeExplosion( Explosion::playerVec3Map* Explosion::getHitPlayers() { return &hitPlayers; } -Vec3* Explosion::getHitPlayerKnockback(std::shared_ptr player) { +Vec3 Explosion::getHitPlayerKnockback(std::shared_ptr player) { AUTO_VAR(it, hitPlayers.find(player)); - if (it == hitPlayers.end()) return Vec3::newTemp(0.0, 0.0, 0.0); + if (it == hitPlayers.end()) return Vec3(0.0, 0.0, 0.0); return it->second; } diff --git a/Minecraft.World/Level/Explosion.h b/Minecraft.World/Level/Explosion.h index 46c67f272..1c250e6b3 100644 --- a/Minecraft.World/Level/Explosion.h +++ b/Minecraft.World/Level/Explosion.h @@ -24,7 +24,7 @@ public: std::unordered_set toBlow; private: - typedef std::unordered_map, Vec3*, PlayerKeyHash, + typedef std::unordered_map, Vec3, PlayerKeyHash, PlayerKeyEq> playerVec3Map; playerVec3Map hitPlayers; @@ -42,6 +42,6 @@ public: std::vector* toBlowDirect = NULL); // 4J - added toBlow parameter playerVec3Map* getHitPlayers(); - Vec3* getHitPlayerKnockback(std::shared_ptr player); + Vec3 getHitPlayerKnockback(std::shared_ptr player); std::shared_ptr getSourceMob(); -}; \ No newline at end of file +}; diff --git a/Minecraft.World/Level/Level.cpp b/Minecraft.World/Level/Level.cpp index 82317c5c5..f61f88c8b 100644 --- a/Minecraft.World/Level/Level.cpp +++ b/Minecraft.World/Level/Level.cpp @@ -1884,7 +1884,7 @@ float Level::getSkyDarken(float a) { return br * 0.8f + 0.2f; } -Vec3* Level::getSkyColor(std::shared_ptr source, float a) { +Vec3 Level::getSkyColor(std::shared_ptr source, float a) { float td = getTimeOfDay(a); float br = Mth::cos(td * PI * 2) * 2 + 0.5f; @@ -1932,7 +1932,7 @@ Vec3* Level::getSkyColor(std::shared_ptr source, float a) { b = b * (1 - f) + 1 * f; } - return Vec3::newTemp(r, g, b); + return Vec3(r, g, b); } float Level::getTimeOfDay(float a) { @@ -1963,7 +1963,7 @@ float Level::getSunAngle(float a) { return td * PI * 2; } -Vec3* Level::getCloudColor(float a) { +Vec3 Level::getCloudColor(float a) { float td = getTimeOfDay(a); float br = Mth::cos(td * PI * 2) * 2.0f + 0.5f; @@ -2001,10 +2001,10 @@ Vec3* Level::getCloudColor(float a) { b = b * ba + mid * (1 - ba); } - return Vec3::newTemp(r, g, b); + return Vec3(r, g, b); } -Vec3* Level::getFogColor(float a) { +Vec3 Level::getFogColor(float a) { float td = getTimeOfDay(a); return dimension->getFogColor(td, a); } diff --git a/Minecraft.World/Level/Level.h b/Minecraft.World/Level/Level.h index 840e3ae1d..d28d1cda5 100644 --- a/Minecraft.World/Level/Level.h +++ b/Minecraft.World/Level/Level.h @@ -365,13 +365,13 @@ public: false); // 4J: Added noEntities & blockAtEdge parameters int getOldSkyDarken(float a); // 4J - change brought forward from 1.8.2 float getSkyDarken(float a); // 4J - change brought forward from 1.8.2 - Vec3* getSkyColor(std::shared_ptr source, float a); + Vec3 getSkyColor(std::shared_ptr source, float a); float getTimeOfDay(float a); int getMoonPhase(); float getMoonBrightness(); float getSunAngle(float a); - Vec3* getCloudColor(float a); - Vec3* getFogColor(float a); + Vec3 getCloudColor(float a); + Vec3 getFogColor(float a); int getTopRainBlock(int x, int z); int getTopSolidBlock(int x, int z); bool biomeHasRain(int x, int z); // 4J added diff --git a/Minecraft.World/Util/Vec3.cpp b/Minecraft.World/Util/Vec3.cpp index eb9dededa..7017db739 100644 --- a/Minecraft.World/Util/Vec3.cpp +++ b/Minecraft.World/Util/Vec3.cpp @@ -34,6 +34,7 @@ void Vec3::ReleaseThreadStorage() { } Vec3* Vec3::newPermanent(double x, double y, double z) { + assert(0); return new Vec3(x, y, z); }; @@ -42,6 +43,7 @@ void Vec3::clearPool() {} void Vec3::resetPool() {} Vec3* Vec3::newTemp(double x, double y, double z) { + assert(0); ThreadStorage* tls = (ThreadStorage*)TlsGetValue(tlsIdx); Vec3* thisVec = &tls->pool[tls->poolPointer]; thisVec->set(x, y, z); diff --git a/Minecraft.World/WorldGen/Structures/Village.cpp b/Minecraft.World/WorldGen/Structures/Village.cpp index 07e505908..16a6a2283 100644 --- a/Minecraft.World/WorldGen/Structures/Village.cpp +++ b/Minecraft.World/WorldGen/Structures/Village.cpp @@ -7,6 +7,7 @@ #include "../../Headers/net.minecraft.world.phys.h" #include "Village.h" #include +#include Village::Aggressor::Aggressor(std::shared_ptr mob, int timeStamp) { @@ -60,9 +61,9 @@ void Village::tick(int tick) { int idealGolemCount = populationSize / 10; if (golemCount < idealGolemCount && doorInfos.size() > 20 && level->random->nextInt(7000) == 0) { - Vec3* spawnPos = + auto spawnPos = findRandomSpawnPos(center->x, center->y, center->z, 2, 4, 2); - if (spawnPos != NULL) { + if (spawnPos.has_value()) { std::shared_ptr vg = std::shared_ptr(new VillagerGolem(level)); vg->setPos(spawnPos->x, spawnPos->y, spawnPos->z); @@ -88,16 +89,17 @@ void Village::tick(int tick) { // } } -Vec3* Village::findRandomSpawnPos(int x, int y, int z, int sx, int sy, int sz) { +std::optional Village::findRandomSpawnPos(int x, int y, int z, int sx, + int sy, int sz) { for (int i = 0; i < 10; ++i) { int xx = x + level->random->nextInt(16) - 8; int yy = y + level->random->nextInt(6) - 3; int zz = z + level->random->nextInt(16) - 8; if (!isInside(xx, yy, zz)) continue; - if (canSpawnAt(xx, yy, zz, sx, sy, sz)) - return Vec3::newTemp(xx, yy, zz); + if (canSpawnAt(xx, yy, zz, sx, sy, sz)) return Vec3(xx, yy, zz); } - return NULL; + + return std::nullopt; } bool Village::canSpawnAt(int x, int y, int z, int sx, int sy, int sz) { diff --git a/Minecraft.World/WorldGen/Structures/Village.h b/Minecraft.World/WorldGen/Structures/Village.h index fb35335f7..b63f3e8e9 100644 --- a/Minecraft.World/WorldGen/Structures/Village.h +++ b/Minecraft.World/WorldGen/Structures/Village.h @@ -1,5 +1,6 @@ #pragma once +#include class Village { private: Level* level; @@ -36,7 +37,7 @@ public: void tick(int tick); private: - Vec3* findRandomSpawnPos(int x, int y, int z, int sx, int sy, int sz); + std::optional findRandomSpawnPos(int x, int y, int z, int sx, int sy, int sz); bool canSpawnAt(int x, int y, int z, int sx, int sy, int sz); void countGolem(); void countPopulation(); @@ -78,4 +79,4 @@ public: void resetNoBreedTimer(); bool isBreedTimerOk(); void rewardAllPlayers(int amount); -}; \ No newline at end of file +}; From 9fe33151128b1ae34d33a0fe4dde87d89908e412 Mon Sep 17 00:00:00 2001 From: orng Date: Thu, 26 Mar 2026 13:37:01 -0500 Subject: [PATCH 014/170] refactor: remove vec3 tls --- Minecraft.Client/Minecraft.cpp | 4 -- Minecraft.Client/MinecraftServer.cpp | 3 -- .../Platform/Common/Consoles_App.cpp | 2 - .../Common/Network/GameNetworkManager.cpp | 5 -- .../Platform/Common/UI/IUIScene_PauseMenu.cpp | 2 - .../Platform/Common/XUI/XUI_Death.cpp | 1 - .../Platform/Common/XUI/XUI_PauseMenu.cpp | 2 - .../Platform/Durango/Durango_Minecraft.cpp | 4 -- .../Platform/Linux/Linux_Minecraft.cpp | 5 -- .../Platform/Orbis/Orbis_Minecraft.cpp | 5 -- .../Platform/PS3/PS3_Minecraft.cpp | 2 - .../ChunkUpdate/TileRenderer_SPU.cpp | 44 ++++++++------- .../Platform/PS3/Xbox_Minecraft.cpp | 4 -- .../Platform/PSVita/PSVita_Minecraft.cpp | 4 -- .../Windows64/Windows64_Minecraft.cpp | 4 -- .../Platform/Xbox/Xbox_Minecraft.cpp | 4 -- Minecraft.Client/Rendering/GameRenderer.cpp | 7 +-- Minecraft.Client/Rendering/LevelRenderer.cpp | 1 - Minecraft.World/Util/Vec3.cpp | 53 ------------------- Minecraft.World/Util/Vec3.h | 27 ---------- 20 files changed, 26 insertions(+), 157 deletions(-) diff --git a/Minecraft.Client/Minecraft.cpp b/Minecraft.Client/Minecraft.cpp index c8d90e7db..d939bafc6 100644 --- a/Minecraft.Client/Minecraft.cpp +++ b/Minecraft.Client/Minecraft.cpp @@ -724,7 +724,6 @@ void Minecraft::run() // try { // 4J - removed try/catch // if (minecraftApplet != null && !minecraftApplet.isActive()) break; // 4J - removed AABB::resetPool(); - Vec3::resetPool(); // if (parent == NULL && Display.isCloseRequested()) { // 4J - removed // stop(); @@ -1281,7 +1280,6 @@ void Minecraft::run_middle() { // if (minecraftApplet != null && // !minecraftApplet.isActive()) break; // 4J - removed AABB::resetPool(); - Vec3::resetPool(); // if (parent == NULL && Display.isCloseRequested()) { // // 4J - removed @@ -2223,7 +2221,6 @@ void Minecraft::emergencySave() { // 4J - lots of try/catches removed here, and garbage collector things levelRenderer->clear(); AABB::clearPool(); - Vec3::clearPool(); setLevel(NULL); } @@ -2400,7 +2397,6 @@ void Minecraft::levelTickUpdateFunc(void* pParam) { void Minecraft::levelTickThreadInitFunc() { AABB::CreateNewThreadStorage(); - Vec3::CreateNewThreadStorage(); Compression::UseDefaultThreadStorage(); } diff --git a/Minecraft.Client/MinecraftServer.cpp b/Minecraft.Client/MinecraftServer.cpp index a08f48ac9..17019e984 100644 --- a/Minecraft.Client/MinecraftServer.cpp +++ b/Minecraft.Client/MinecraftServer.cpp @@ -315,7 +315,6 @@ int MinecraftServer::runPostUpdate(void* lpParam) { Entity::useSmallIds(); // This thread can end up spawning entities as // resources AABB::CreateNewThreadStorage(); - Vec3::CreateNewThreadStorage(); Compression::UseDefaultThreadStorage(); Level::enableLightingCache(); Tile::CreateNewThreadStorage(); @@ -365,7 +364,6 @@ int MinecraftServer::runPostUpdate(void* lpParam) { // #endif //__PS3__ Tile::ReleaseThreadStorage(); AABB::ReleaseThreadStorage(); - Vec3::ReleaseThreadStorage(); Level::destroyLightingCache(); ShutdownManager::HasFinished(ShutdownManager::ePostProcessThread); @@ -1651,7 +1649,6 @@ void MinecraftServer::tick() { } AABB::resetPool(); - Vec3::resetPool(); tickCount++; diff --git a/Minecraft.Client/Platform/Common/Consoles_App.cpp b/Minecraft.Client/Platform/Common/Consoles_App.cpp index 7ec88c75b..34bec9010 100644 --- a/Minecraft.Client/Platform/Common/Consoles_App.cpp +++ b/Minecraft.Client/Platform/Common/Consoles_App.cpp @@ -4706,7 +4706,6 @@ int CMinecraftApp::SignoutExitWorldThreadProc(void* lpParameter) { // Share AABB & Vec3 pools with default (main thread) - should be ok as long // as we don't tick the main thread whilst this thread is running AABB::UseDefaultThreadStorage(); - Vec3::UseDefaultThreadStorage(); Compression::UseDefaultThreadStorage(); // app.SetGameStarted(false); @@ -7698,7 +7697,6 @@ int CMinecraftApp::RemoteSaveThreadProc(void* lpParameter) { // The game should be stopped while we are doing this, but the connections // ticks may try to create some AABB's or Vec3's AABB::UseDefaultThreadStorage(); - Vec3::UseDefaultThreadStorage(); Compression::UseDefaultThreadStorage(); // 4J-PB - Xbox 360 - 163153 - [CRASH] TU17: Code: Multiplayer: During the diff --git a/Minecraft.Client/Platform/Common/Network/GameNetworkManager.cpp b/Minecraft.Client/Platform/Common/Network/GameNetworkManager.cpp index a26addc80..3b18a50e4 100644 --- a/Minecraft.Client/Platform/Common/Network/GameNetworkManager.cpp +++ b/Minecraft.Client/Platform/Common/Network/GameNetworkManager.cpp @@ -948,7 +948,6 @@ int CGameNetworkManager::RunNetworkGameThreadProc(void* lpParameter) { // Share AABB & Vec3 pools with default (main thread) - should be ok as long // as we don't tick the main thread whilst this thread is running AABB::UseDefaultThreadStorage(); - Vec3::UseDefaultThreadStorage(); Compression::UseDefaultThreadStorage(); Tile::CreateNewThreadStorage(); @@ -1008,7 +1007,6 @@ int CGameNetworkManager::ServerThreadProc(void* lpParameter) { SetThreadName(-1, "Minecraft Server thread"); AABB::CreateNewThreadStorage(); - Vec3::CreateNewThreadStorage(); Compression::UseDefaultThreadStorage(); OldChunkStorage::UseDefaultThreadStorage(); Entity::useSmallIds(); @@ -1022,7 +1020,6 @@ int CGameNetworkManager::ServerThreadProc(void* lpParameter) { Tile::ReleaseThreadStorage(); AABB::ReleaseThreadStorage(); - Vec3::ReleaseThreadStorage(); Level::destroyLightingCache(); if (lpParameter != NULL) delete (NetworkGameInitData*)lpParameter; @@ -1034,7 +1031,6 @@ int CGameNetworkManager::ExitAndJoinFromInviteThreadProc(void* lpParam) { // Share AABB & Vec3 pools with default (main thread) - should be ok as long // as we don't tick the main thread whilst this thread is running AABB::UseDefaultThreadStorage(); - Vec3::UseDefaultThreadStorage(); Compression::UseDefaultThreadStorage(); // app.SetGameStarted(false); @@ -1187,7 +1183,6 @@ int CGameNetworkManager::ChangeSessionTypeThreadProc(void* lpParam) { // Share AABB & Vec3 pools with default (main thread) - should be ok as long // as we don't tick the main thread whilst this thread is running AABB::UseDefaultThreadStorage(); - Vec3::UseDefaultThreadStorage(); Compression::UseDefaultThreadStorage(); Minecraft* pMinecraft = Minecraft::GetInstance(); diff --git a/Minecraft.Client/Platform/Common/UI/IUIScene_PauseMenu.cpp b/Minecraft.Client/Platform/Common/UI/IUIScene_PauseMenu.cpp index 65d52d39a..f5c3d4d11 100644 --- a/Minecraft.Client/Platform/Common/UI/IUIScene_PauseMenu.cpp +++ b/Minecraft.Client/Platform/Common/UI/IUIScene_PauseMenu.cpp @@ -381,7 +381,6 @@ int IUIScene_PauseMenu::SaveWorldThreadProc(void* lpParameter) { // Share AABB & Vec3 pools with default (main thread) - should be ok as long // as we don't tick the main thread whilst this thread is running AABB::UseDefaultThreadStorage(); - Vec3::UseDefaultThreadStorage(); Compression::UseDefaultThreadStorage(); Minecraft* pMinecraft = Minecraft::GetInstance(); @@ -419,7 +418,6 @@ int IUIScene_PauseMenu::ExitWorldThreadProc(void* lpParameter) { // Share AABB & Vec3 pools with default (main thread) - should be ok as long // as we don't tick the main thread whilst this thread is running AABB::UseDefaultThreadStorage(); - Vec3::UseDefaultThreadStorage(); Compression::UseDefaultThreadStorage(); // app.SetGameStarted(false); diff --git a/Minecraft.Client/Platform/Common/XUI/XUI_Death.cpp b/Minecraft.Client/Platform/Common/XUI/XUI_Death.cpp index d073d2e98..20dff7cae 100644 --- a/Minecraft.Client/Platform/Common/XUI/XUI_Death.cpp +++ b/Minecraft.Client/Platform/Common/XUI/XUI_Death.cpp @@ -220,7 +220,6 @@ HRESULT CScene_Death::OnKeyDown(XUIMessageInput* pInputData, BOOL& rfHandled) { int CScene_Death::RespawnThreadProc(void* lpParameter) { AABB::UseDefaultThreadStorage(); - Vec3::UseDefaultThreadStorage(); Compression::UseDefaultThreadStorage(); size_t iPad = (size_t)lpParameter; diff --git a/Minecraft.Client/Platform/Common/XUI/XUI_PauseMenu.cpp b/Minecraft.Client/Platform/Common/XUI/XUI_PauseMenu.cpp index 7e2d611ea..5ce88755d 100644 --- a/Minecraft.Client/Platform/Common/XUI/XUI_PauseMenu.cpp +++ b/Minecraft.Client/Platform/Common/XUI/XUI_PauseMenu.cpp @@ -1074,7 +1074,6 @@ int UIScene_PauseMenu::SaveWorldThreadProc(LPVOID lpParameter) { // Share AABB & Vec3 pools with default (main thread) - should be ok as long // as we don't tick the main thread whilst this thread is running AABB::UseDefaultThreadStorage(); - Vec3::UseDefaultThreadStorage(); Compression::UseDefaultThreadStorage(); Minecraft* pMinecraft = Minecraft::GetInstance(); @@ -1107,7 +1106,6 @@ int UIScene_PauseMenu::ExitWorldThreadProc(void* lpParameter) { // Share AABB & Vec3 pools with default (main thread) - should be ok as long // as we don't tick the main thread whilst this thread is running AABB::UseDefaultThreadStorage(); - Vec3::UseDefaultThreadStorage(); Compression::UseDefaultThreadStorage(); // app.SetGameStarted(false); diff --git a/Minecraft.Client/Platform/Durango/Durango_Minecraft.cpp b/Minecraft.Client/Platform/Durango/Durango_Minecraft.cpp index dff64785d..e7f5179c4 100644 --- a/Minecraft.Client/Platform/Durango/Durango_Minecraft.cpp +++ b/Minecraft.Client/Platform/Durango/Durango_Minecraft.cpp @@ -795,7 +795,6 @@ void oldWinMainInit() { Tesselator::CreateNewThreadStorage(1024 * 1024); // Initialise TLS for AABB and Vec3 pools, for this main thread AABB::CreateNewThreadStorage(); - Vec3::CreateNewThreadStorage(); OldChunkStorage::CreateNewThreadStorage(); Level::enableLightingCache(); Tile::CreateNewThreadStorage(); @@ -1143,9 +1142,6 @@ void oldWinMainTick() { } // Fix for #7318 - Title crashes after short soak in the leaderboards menu - // A memory leak was caused because the icon renderer kept creating new - // Vec3's because the pool wasn't reset - Vec3::resetPool(); } #ifdef MEMORY_TRACKING diff --git a/Minecraft.Client/Platform/Linux/Linux_Minecraft.cpp b/Minecraft.Client/Platform/Linux/Linux_Minecraft.cpp index 852dbb58c..968bbe9be 100644 --- a/Minecraft.Client/Platform/Linux/Linux_Minecraft.cpp +++ b/Minecraft.Client/Platform/Linux/Linux_Minecraft.cpp @@ -711,7 +711,6 @@ void CleanupDevice() { #endif int StartMinecraftThreadProc(void* lpParameter) { - Vec3::UseDefaultThreadStorage(); AABB::UseDefaultThreadStorage(); Tesselator::CreateNewThreadStorage(1024 * 1024); RenderManager.InitialiseContext(); @@ -868,7 +867,6 @@ return -1; Tesselator::CreateNewThreadStorage(1024 * 1024); // Initialise TLS for AABB and Vec3 pools, for this main thread AABB::CreateNewThreadStorage(); - Vec3::CreateNewThreadStorage(); Compression::CreateNewThreadStorage(); OldChunkStorage::CreateNewThreadStorage(); Level::enableLightingCache(); @@ -1103,9 +1101,6 @@ PIXEndNamedEvent(); } // Fix for #7318 - Title crashes after short soak in the leaderboards - // menu A memory leak was caused because the icon renderer kept creating - // new Vec3's because the pool wasn't reset - Vec3::resetPool(); } // end game loop // Graceful shutdown: destroy GL context and GLFW before any C++ dtors run. diff --git a/Minecraft.Client/Platform/Orbis/Orbis_Minecraft.cpp b/Minecraft.Client/Platform/Orbis/Orbis_Minecraft.cpp index 7dfd2c385..84e6fbf12 100644 --- a/Minecraft.Client/Platform/Orbis/Orbis_Minecraft.cpp +++ b/Minecraft.Client/Platform/Orbis/Orbis_Minecraft.cpp @@ -1040,7 +1040,6 @@ void RegisterAwardsWithProfileManager() { } int StartMinecraftThreadProc(void* lpParameter) { - Vec3::UseDefaultThreadStorage(); AABB::UseDefaultThreadStorage(); Tesselator::CreateNewThreadStorage(1024 * 1024); RenderManager.InitialiseContext(); @@ -1378,7 +1377,6 @@ int main(int argc, const char* argv[]) { Tesselator::CreateNewThreadStorage(1024 * 1024); // Initialise TLS for AABB and Vec3 pools, for this main thread AABB::CreateNewThreadStorage(); - Vec3::CreateNewThreadStorage(); Compression::CreateNewThreadStorage(); OldChunkStorage::CreateNewThreadStorage(); Level::enableLightingCache(); @@ -1737,9 +1735,6 @@ int main(int argc, const char* argv[]) { app.PatchAvailableDialogTick(); // Fix for #7318 - Title crashes after short soak in the leaderboards - // menu A memory leak was caused because the icon renderer kept creating - // new Vec3's because the pool wasn't reset - Vec3::resetPool(); } // Free resources, unregister custom classes, and exit. diff --git a/Minecraft.Client/Platform/PS3/PS3_Minecraft.cpp b/Minecraft.Client/Platform/PS3/PS3_Minecraft.cpp index 2582fd0cc..e2200c8a8 100644 --- a/Minecraft.Client/Platform/PS3/PS3_Minecraft.cpp +++ b/Minecraft.Client/Platform/PS3/PS3_Minecraft.cpp @@ -1211,7 +1211,6 @@ int main() { Tesselator::CreateNewThreadStorage(1024 * 1024); // Initialise TLS for AABB and Vec3 pools, for this main thread AABB::CreateNewThreadStorage(); - Vec3::CreateNewThreadStorage(); OldChunkStorage::CreateNewThreadStorage(); Level::enableLightingCache(); Tile::CreateNewThreadStorage(); @@ -1547,7 +1546,6 @@ int main() { // Fix for #7318 - Title crashes after short soak in the leaderboards // menu A memory leak was caused because the icon renderer kept creating // new Vec3's because the pool wasn't reset - Vec3::resetPool(); } // Free resources, unregister custom classes, and exit. diff --git a/Minecraft.Client/Platform/PS3/SPU_Tasks/ChunkUpdate/TileRenderer_SPU.cpp b/Minecraft.Client/Platform/PS3/SPU_Tasks/ChunkUpdate/TileRenderer_SPU.cpp index a0193a671..efe51f37a 100644 --- a/Minecraft.Client/Platform/PS3/SPU_Tasks/ChunkUpdate/TileRenderer_SPU.cpp +++ b/Minecraft.Client/Platform/PS3/SPU_Tasks/ChunkUpdate/TileRenderer_SPU.cpp @@ -5413,19 +5413,20 @@ bool TileRenderer_SPU::tesselateBlockInWorldWithAmbienceOcclusionOldLighting( // // 4J - added these faceFlags so we can detect whether this block is // going to have no visible faces and early out // // the original code checked noCulling and shouldRenderFace directly - // where faceFlags is used now int faceFlags = 0; if ( noCulling ) + // where faceFlags is used now int faceFlags = 0; if ( + // noCulling ) // { // faceFlags = 0x3f; // } // else // { // faceFlags |= tt->shouldRenderFace( level, pX, pY - 1, pZ, 0 ) ? - // 0x01 : 0; faceFlags |= tt->shouldRenderFace( level, pX, pY + 1, pZ, 1 ) ? - // 0x02 : 0; faceFlags |= tt->shouldRenderFace( level, pX, pY, pZ - 1, 2 ) ? - // 0x04 : 0; faceFlags |= tt->shouldRenderFace( level, pX, pY, pZ + 1, 3 ) ? - // 0x08 : 0; faceFlags |= tt->shouldRenderFace( level, pX - 1, pY, pZ, 4 ) ? - // 0x10 : 0; faceFlags |= tt->shouldRenderFace( level, pX + 1, pY, pZ, 5 ) ? - // 0x20 : 0; + // 0x01 : 0; faceFlags |= tt->shouldRenderFace( level, pX, pY + // + 1, pZ, 1 ) ? 0x02 : 0; faceFlags |= + // tt->shouldRenderFace( level, pX, pY, pZ - 1, 2 ) ? 0x04 : 0; + // faceFlags |= tt->shouldRenderFace( level, pX, pY, pZ + 1, 3 ) ? 0x08 : 0; + // faceFlags |= tt->shouldRenderFace( level, pX - 1, pY, pZ, 4 ) ? 0x10 : 0; + // faceFlags |= tt->shouldRenderFace( level, pX + 1, pY, pZ, 5 ) ? 0x20 : 0; // } // if ( faceFlags == 0 ) // { @@ -5454,21 +5455,24 @@ bool TileRenderer_SPU::tesselateBlockInWorldWithAmbienceOcclusionOldLighting( // ll00Z = tt->getBrightness( level, pX, pY, pZ + 1 ); // // llTransXY0 = level->m_tileData.transculent[level->getTile( pX + 1, pY + - // 1, pZ )]; llTransXy0 = level->m_tileData.transculent[level->getTile( pX + - // 1, pY - 1, pZ )]; llTransX0Z = - // level->m_tileData.transculent[level->getTile( pX + 1, pY, pZ + 1 )]; - // llTransX0z = level->m_tileData.transculent[level->getTile( pX + 1, pY, - // pZ - 1 )]; llTransxY0 = level->m_tileData.transculent[level->getTile( pX + // 1, pZ )]; llTransXy0 = + // level->m_tileData.transculent[level->getTile( pX + 1, pY - 1, pZ )]; + // llTransX0Z = level->m_tileData.transculent[level->getTile( pX + 1, pY, pZ + // + 1 )]; llTransX0z = level->m_tileData.transculent[level->getTile( pX + + // 1, pY, pZ - 1 )]; llTransxY0 = + // level->m_tileData.transculent[level->getTile( pX // - 1, pY + 1, pZ )]; llTransxy0 = // level->m_tileData.transculent[level->getTile( pX - 1, pY - 1, pZ )]; // llTransx0z = level->m_tileData.transculent[level->getTile( pX - 1, pY, - // pZ - 1 )]; llTransx0Z = level->m_tileData.transculent[level->getTile( pX + // pZ - 1 )]; llTransx0Z = + // level->m_tileData.transculent[level->getTile( pX // - 1, pY, pZ + 1 )]; llTrans0YZ = // level->m_tileData.transculent[level->getTile( pX, pY + 1, pZ + 1 )]; // llTrans0Yz = level->m_tileData.transculent[level->getTile( pX, pY + 1, - // pZ - 1 )]; llTrans0yZ = level->m_tileData.transculent[level->getTile( pX, - // pY - 1, pZ + 1 )]; llTrans0yz = - // level->m_tileData.transculent[level->getTile( pX, pY - 1, pZ - 1 )]; + // pZ - 1 )]; llTrans0yZ = + // level->m_tileData.transculent[level->getTile( pX, pY - 1, pZ + 1 )]; + // llTrans0yz = level->m_tileData.transculent[level->getTile( pX, pY - 1, pZ + // - 1 )]; // // spu_print("Have to add texture name check here\n"); // if ( getTexture(tt)->getName().compare(L"grass_top") == 0 ) tint0 = @@ -6097,7 +6101,7 @@ bool TileRenderer_SPU::tesselateBlockInWorld(Tile_SPU* tt, int x, int y, int z, float br = tt->getBrightness(level, x, y + 1, z); // spu_print("need to add material settings\n"); // if ( tileShapeY1 != 1 && - //!tt->material->isLiquid() ) br = centerBrightness; + //! tt->material->isLiquid() ) br = centerBrightness; t->color(r11 * br, g11 * br, b11 * br); } renderFaceUp(tt, x, y, z, getTexture(tt, level, x, y, z, 1)); @@ -6537,8 +6541,8 @@ bool TileRenderer_SPU::tesselateFenceGateInWorld(FenceGateTile_SPU* tt, int x, // level->getTile(x - 1, y, z) == Tile_SPU::cobbleWall_Id && // level->getTile(x + 1, y, z) == Tile_SPU::cobbleWall_Id) // || ((direction == Direction::EAST || direction == Direction::WEST) && - //level->getTile(x, y, z - 1) == Tile_SPU::cobbleWall_Id && - //level->getTile(x, y, z + 1) == Tile_SPU::cobbleWall_Id)) + // level->getTile(x, y, z - 1) == Tile_SPU::cobbleWall_Id && + // level->getTile(x, y, z + 1) == Tile_SPU::cobbleWall_Id)) //{ // h00 -= 3.0f / 16.0f; // h01 -= 3.0f / 16.0f; @@ -7582,7 +7586,7 @@ Icon_SPU* TileRenderer_SPU::getTextureOrMissing(Icon_SPU* Icon_SPU) { if (Icon_SPU == NULL) { assert(0); // return - //minecraft->textures->getMissingIcon_SPU(Icon_SPU::TYPE_TERRAIN); + // minecraft->textures->getMissingIcon_SPU(Icon_SPU::TYPE_TERRAIN); } return Icon_SPU; } diff --git a/Minecraft.Client/Platform/PS3/Xbox_Minecraft.cpp b/Minecraft.Client/Platform/PS3/Xbox_Minecraft.cpp index fb8e88016..90c153b8d 100644 --- a/Minecraft.Client/Platform/PS3/Xbox_Minecraft.cpp +++ b/Minecraft.Client/Platform/PS3/Xbox_Minecraft.cpp @@ -661,7 +661,6 @@ int APIENTRY _tWinMain(_In_ HINSTANCE hInstance, Tesselator::CreateNewThreadStorage(1024 * 1024); // Initialise TLS for AABB and Vec3 pools, for this main thread AABB::CreateNewThreadStorage(); - Vec3::CreateNewThreadStorage(); Level::enableLightingCache(); Minecraft::main(); @@ -961,9 +960,6 @@ int APIENTRY _tWinMain(_In_ HINSTANCE hInstance, #endif // Fix for #7318 - Title crashes after short soak in the leaderboards - // menu A memory leak was caused because the icon renderer kept creating - // new Vec3's because the pool wasn't reset - Vec3::resetPool(); } // Free resources, unregister custom classes, and exit. diff --git a/Minecraft.Client/Platform/PSVita/PSVita_Minecraft.cpp b/Minecraft.Client/Platform/PSVita/PSVita_Minecraft.cpp index 1ee98dd99..9065eccb7 100644 --- a/Minecraft.Client/Platform/PSVita/PSVita_Minecraft.cpp +++ b/Minecraft.Client/Platform/PSVita/PSVita_Minecraft.cpp @@ -896,7 +896,6 @@ int main() { Tesselator::CreateNewThreadStorage(1024 * 1024); // Initialise TLS for AABB and Vec3 pools, for this main thread AABB::CreateNewThreadStorage(); - Vec3::CreateNewThreadStorage(); Compression::CreateNewThreadStorage(); OldChunkStorage::CreateNewThreadStorage(); Level::enableLightingCache(); @@ -1250,9 +1249,6 @@ int main() { app.SaveDataTick(); // Fix for #7318 - Title crashes after short soak in the leaderboards - // menu A memory leak was caused because the icon renderer kept creating - // new Vec3's because the pool wasn't reset - Vec3::resetPool(); // sceRazorCpuSync(); #ifndef _CONTENT_PACKAGE diff --git a/Minecraft.Client/Platform/Windows64/Windows64_Minecraft.cpp b/Minecraft.Client/Platform/Windows64/Windows64_Minecraft.cpp index e64afe754..0e009e4ce 100644 --- a/Minecraft.Client/Platform/Windows64/Windows64_Minecraft.cpp +++ b/Minecraft.Client/Platform/Windows64/Windows64_Minecraft.cpp @@ -941,7 +941,6 @@ int APIENTRY _tWinMain(_In_ HINSTANCE hInstance, Tesselator::CreateNewThreadStorage(1024 * 1024); // Initialise TLS for AABB and Vec3 pools, for this main thread AABB::CreateNewThreadStorage(); - Vec3::CreateNewThreadStorage(); Compression::CreateNewThreadStorage(); OldChunkStorage::CreateNewThreadStorage(); Level::enableLightingCache(); @@ -1269,9 +1268,6 @@ int APIENTRY _tWinMain(_In_ HINSTANCE hInstance, } // Fix for #7318 - Title crashes after short soak in the leaderboards - // menu A memory leak was caused because the icon renderer kept creating - // new Vec3's because the pool wasn't reset - Vec3::resetPool(); } // Free resources, unregister custom classes, and exit. diff --git a/Minecraft.Client/Platform/Xbox/Xbox_Minecraft.cpp b/Minecraft.Client/Platform/Xbox/Xbox_Minecraft.cpp index 822fd717c..1b2cdd997 100644 --- a/Minecraft.Client/Platform/Xbox/Xbox_Minecraft.cpp +++ b/Minecraft.Client/Platform/Xbox/Xbox_Minecraft.cpp @@ -700,7 +700,6 @@ int __cdecl main() { Tesselator::CreateNewThreadStorage(1024 * 1024); // Initialise TLS for AABB and Vec3 pools, for this main thread AABB::CreateNewThreadStorage(); - Vec3::CreateNewThreadStorage(); Compression::CreateNewThreadStorage(); OldChunkStorage::CreateNewThreadStorage(); Level::enableLightingCache(); @@ -1029,9 +1028,6 @@ int __cdecl main() { } // Fix for #7318 - Title crashes after short soak in the leaderboards - // menu A memory leak was caused because the icon renderer kept creating - // new Vec3's because the pool wasn't reset - Vec3::resetPool(); } // Free resources, unregister custom classes, and exit. diff --git a/Minecraft.Client/Rendering/GameRenderer.cpp b/Minecraft.Client/Rendering/GameRenderer.cpp index 30137286f..d31ede749 100644 --- a/Minecraft.Client/Rendering/GameRenderer.cpp +++ b/Minecraft.Client/Rendering/GameRenderer.cpp @@ -1115,7 +1115,6 @@ void GameRenderer::FinishedReassigning() { int GameRenderer::runUpdate(void* lpParam) { Minecraft* minecraft = Minecraft::GetInstance(); - Vec3::CreateNewThreadStorage(); AABB::CreateNewThreadStorage(); Tesselator::CreateNewThreadStorage(1024 * 1024); Compression::UseDefaultThreadStorage(); @@ -1196,7 +1195,6 @@ int GameRenderer::runUpdate(void* lpParam) { // PIXEndNamedEvent(); AABB::resetPool(); - Vec3::resetPool(); m_updateEvents->Set(eUpdateEventIsFinished); } @@ -1866,9 +1864,8 @@ void GameRenderer::setupClearColor(float a) { fb = (float)fogColor.z; if (mc->options->viewDistance < 2) { - Vec3 sunAngle = Mth::sin(level->getSunAngle(a)) > 0 - ? Vec3(-1, 0, 0) - : Vec3(1, 0, 0); + Vec3 sunAngle = Mth::sin(level->getSunAngle(a)) > 0 ? Vec3(-1, 0, 0) + : Vec3(1, 0, 0); float d = (float)player->getViewVector(a).dot(sunAngle); if (d < 0) d = 0; if (d > 0) { diff --git a/Minecraft.Client/Rendering/LevelRenderer.cpp b/Minecraft.Client/Rendering/LevelRenderer.cpp index 902cee656..c20356003 100644 --- a/Minecraft.Client/Rendering/LevelRenderer.cpp +++ b/Minecraft.Client/Rendering/LevelRenderer.cpp @@ -4039,7 +4039,6 @@ void LevelRenderer::staticCtor() { } int LevelRenderer::rebuildChunkThreadProc(void* lpParam) { - Vec3::CreateNewThreadStorage(); AABB::CreateNewThreadStorage(); Tesselator::CreateNewThreadStorage(1024 * 1024); RenderManager.InitialiseContext(); diff --git a/Minecraft.World/Util/Vec3.cpp b/Minecraft.World/Util/Vec3.cpp index 7017db739..4bedbf5a6 100644 --- a/Minecraft.World/Util/Vec3.cpp +++ b/Minecraft.World/Util/Vec3.cpp @@ -5,52 +5,6 @@ #include "AABB.h" -unsigned int Vec3::tlsIdx = 0; -Vec3::ThreadStorage* Vec3::tlsDefault = NULL; - -Vec3::ThreadStorage::ThreadStorage() { - pool = new Vec3[POOL_SIZE]; - poolPointer = 0; -} - -Vec3::ThreadStorage::~ThreadStorage() { delete[] pool; } - -void Vec3::CreateNewThreadStorage() { - ThreadStorage* tls = new ThreadStorage(); - if (tlsDefault == NULL) { - tlsIdx = TlsAlloc(); - tlsDefault = tls; - } - TlsSetValue(tlsIdx, tls); -} - -void Vec3::UseDefaultThreadStorage() { TlsSetValue(tlsIdx, tlsDefault); } - -void Vec3::ReleaseThreadStorage() { - ThreadStorage* tls = (ThreadStorage*)TlsGetValue(tlsIdx); - if (tls == tlsDefault) return; - - delete tls; -} - -Vec3* Vec3::newPermanent(double x, double y, double z) { - assert(0); - return new Vec3(x, y, z); -}; - -void Vec3::clearPool() {} - -void Vec3::resetPool() {} - -Vec3* Vec3::newTemp(double x, double y, double z) { - assert(0); - ThreadStorage* tls = (ThreadStorage*)TlsGetValue(tlsIdx); - Vec3* thisVec = &tls->pool[tls->poolPointer]; - thisVec->set(x, y, z); - tls->poolPointer = (tls->poolPointer + 1) % ThreadStorage::POOL_SIZE; - return thisVec; -} - Vec3::Vec3(double x, double y, double z) { if (x == -0.0) x = 0.0; if (y == -0.0) y = 0.0; @@ -60,13 +14,6 @@ Vec3::Vec3(double x, double y, double z) { this->z = z; } -Vec3* Vec3::set(double x, double y, double z) { - this->x = x; - this->y = y; - this->z = z; - return this; -} - Vec3 Vec3::vectorTo(const Vec3& p) const { return {p.x - x, p.y - y, p.z - z}; } Vec3 Vec3::normalize() const { diff --git a/Minecraft.World/Util/Vec3.h b/Minecraft.World/Util/Vec3.h index 92b3610a8..9d17f528a 100644 --- a/Minecraft.World/Util/Vec3.h +++ b/Minecraft.World/Util/Vec3.h @@ -6,39 +6,12 @@ class AABB; class Vec3 { - // 4J added so we can have separate pools for different threads - class ThreadStorage { - public: - static const int POOL_SIZE = 1024; - Vec3* pool; - unsigned int poolPointer; - ThreadStorage(); - ~ThreadStorage(); - }; - static unsigned int tlsIdx; - static ThreadStorage* tlsDefault; - public: - // Each new thread that needs to use Vec3 pools will need to call one of the - // following 2 functions, to either create its own local storage, or share - // the default storage already allocated by the main thread - static void CreateNewThreadStorage(); - static void UseDefaultThreadStorage(); - static void ReleaseThreadStorage(); - - static Vec3* newPermanent(double x, double y, double z); - static void clearPool(); - static void resetPool(); - static Vec3* newTemp(double x, double y, double z); double x, y, z; Vec3() {} Vec3(double x, double y, double z); -private: - Vec3* set(double x, double y, double z); - -public: Vec3 vectorTo(const Vec3& p) const; Vec3 normalize() const; double dot(const Vec3& p) const; From 87e8078a65a84be0739c395a2ee7033f81f24c00 Mon Sep 17 00:00:00 2001 From: orng Date: Thu, 26 Mar 2026 14:01:14 -0500 Subject: [PATCH 015/170] refactor: remove `new Vec3` --- .../ApplySchematicRuleDefinition.cpp | 39 +++++++++---------- .../GameRules/ApplySchematicRuleDefinition.h | 4 +- .../Common/GameRules/ConsoleSchematicFile.cpp | 13 +++---- .../Common/GameRules/ConsoleSchematicFile.h | 2 +- Minecraft.Client/Rendering/GameRenderer.cpp | 10 ++--- Minecraft.Client/Rendering/GameRenderer.h | 2 +- Minecraft.Client/Rendering/Polygon.cpp | 8 ++-- Minecraft.Client/Rendering/Vertex.cpp | 4 +- Minecraft.Client/Rendering/Vertex.h | 4 +- .../AI/Navigation/PathNavigation.cpp | 20 +++++----- .../AI/Navigation/PathNavigation.h | 2 +- Minecraft.World/AI/Navigation/RandomPos.cpp | 39 ++++++++++--------- Minecraft.World/AI/Navigation/RandomPos.h | 24 +++++++----- 13 files changed, 87 insertions(+), 84 deletions(-) diff --git a/Minecraft.Client/Platform/Common/GameRules/ApplySchematicRuleDefinition.cpp b/Minecraft.Client/Platform/Common/GameRules/ApplySchematicRuleDefinition.cpp index c7b2c0230..b2304fbdd 100644 --- a/Minecraft.Client/Platform/Common/GameRules/ApplySchematicRuleDefinition.cpp +++ b/Minecraft.Client/Platform/Common/GameRules/ApplySchematicRuleDefinition.cpp @@ -12,7 +12,7 @@ ApplySchematicRuleDefinition::ApplySchematicRuleDefinition( LevelGenerationOptions* levelGenOptions) { m_levelGenOptions = levelGenOptions; - m_location = new Vec3(0, 0, 0); + m_location = Vec3(0, 0, 0); m_locationBox = NULL; m_totalBlocksChanged = 0; m_totalBlocksChangedLighting = 0; @@ -26,7 +26,6 @@ ApplySchematicRuleDefinition::~ApplySchematicRuleDefinition() { app.DebugPrintf("Deleting ApplySchematicRuleDefinition.\n"); if (!m_completed) m_levelGenOptions->releaseSchematicFile(m_schematicName); m_schematic = NULL; - delete m_location; } void ApplySchematicRuleDefinition::writeAttributes(DataOutputStream* dos, @@ -36,11 +35,11 @@ void ApplySchematicRuleDefinition::writeAttributes(DataOutputStream* dos, ConsoleGameRules::write(dos, ConsoleGameRules::eGameRuleAttr_filename); dos->writeUTF(m_schematicName); ConsoleGameRules::write(dos, ConsoleGameRules::eGameRuleAttr_x); - dos->writeUTF(_toString(m_location->x)); + dos->writeUTF(_toString(m_location.x)); ConsoleGameRules::write(dos, ConsoleGameRules::eGameRuleAttr_y); - dos->writeUTF(_toString(m_location->y)); + dos->writeUTF(_toString(m_location.y)); ConsoleGameRules::write(dos, ConsoleGameRules::eGameRuleAttr_z); - dos->writeUTF(_toString(m_location->z)); + dos->writeUTF(_toString(m_location.z)); ConsoleGameRules::write(dos, ConsoleGameRules::eGameRuleAttr_rot); switch (m_rotation) { @@ -76,19 +75,19 @@ void ApplySchematicRuleDefinition::addAttribute( m_schematic = m_levelGenOptions->getSchematicFile(m_schematicName); } } else if (attributeName.compare(L"x") == 0) { - m_location->x = _fromString(attributeValue); - if (((int)abs(m_location->x)) % 2 != 0) m_location->x -= 1; + m_location.x = _fromString(attributeValue); + if (((int)abs(m_location.x)) % 2 != 0) m_location.x -= 1; // app.DebugPrintf("ApplySchematicRuleDefinition: Adding parameter // x=%f\n",m_location->x); } else if (attributeName.compare(L"y") == 0) { - m_location->y = _fromString(attributeValue); - if (((int)abs(m_location->y)) % 2 != 0) m_location->y -= 1; - if (m_location->y < 0) m_location->y = 0; + m_location.y = _fromString(attributeValue); + if (((int)abs(m_location.y)) % 2 != 0) m_location.y -= 1; + if (m_location.y < 0) m_location.y = 0; // app.DebugPrintf("ApplySchematicRuleDefinition: Adding parameter // y=%f\n",m_location->y); } else if (attributeName.compare(L"z") == 0) { - m_location->z = _fromString(attributeValue); - if (((int)abs(m_location->z)) % 2 != 0) m_location->z -= 1; + m_location.z = _fromString(attributeValue); + if (((int)abs(m_location.z)) % 2 != 0) m_location.z -= 1; // app.DebugPrintf("ApplySchematicRuleDefinition: Adding parameter // z=%f\n",m_location->z); } else if (attributeName.compare(L"rot") == 0) { @@ -133,23 +132,23 @@ void ApplySchematicRuleDefinition::updateLocationBox() { m_locationBox = AABB::newPermanent(0, 0, 0, 0, 0, 0); - m_locationBox->x0 = m_location->x; - m_locationBox->y0 = m_location->y; - m_locationBox->z0 = m_location->z; + m_locationBox->x0 = m_location.x; + m_locationBox->y0 = m_location.y; + m_locationBox->z0 = m_location.z; - m_locationBox->y1 = m_location->y + m_schematic->getYSize(); + m_locationBox->y1 = m_location.y + m_schematic->getYSize(); switch (m_rotation) { case ConsoleSchematicFile::eSchematicRot_90: case ConsoleSchematicFile::eSchematicRot_270: - m_locationBox->x1 = m_location->x + m_schematic->getZSize(); - m_locationBox->z1 = m_location->z + m_schematic->getXSize(); + m_locationBox->x1 = m_location.x + m_schematic->getZSize(); + m_locationBox->z1 = m_location.z + m_schematic->getXSize(); break; case ConsoleSchematicFile::eSchematicRot_0: case ConsoleSchematicFile::eSchematicRot_180: default: - m_locationBox->x1 = m_location->x + m_schematic->getXSize(); - m_locationBox->z1 = m_location->z + m_schematic->getZSize(); + m_locationBox->x1 = m_location.x + m_schematic->getXSize(); + m_locationBox->z1 = m_location.z + m_schematic->getZSize(); break; }; } diff --git a/Minecraft.Client/Platform/Common/GameRules/ApplySchematicRuleDefinition.h b/Minecraft.Client/Platform/Common/GameRules/ApplySchematicRuleDefinition.h index e3c5b425f..283c19586 100644 --- a/Minecraft.Client/Platform/Common/GameRules/ApplySchematicRuleDefinition.h +++ b/Minecraft.Client/Platform/Common/GameRules/ApplySchematicRuleDefinition.h @@ -13,7 +13,7 @@ private: LevelGenerationOptions* m_levelGenOptions; std::wstring m_schematicName; ConsoleSchematicFile* m_schematic; - Vec3* m_location; + Vec3 m_location; AABB* m_locationBox; ConsoleSchematicFile::ESchematicRotation m_rotation; int m_dimension; @@ -51,4 +51,4 @@ public: * Reset any state to how it should be before a new game. */ void reset(); -}; \ No newline at end of file +}; diff --git a/Minecraft.Client/Platform/Common/GameRules/ConsoleSchematicFile.cpp b/Minecraft.Client/Platform/Common/GameRules/ConsoleSchematicFile.cpp index b9fec3328..e48113989 100644 --- a/Minecraft.Client/Platform/Common/GameRules/ConsoleSchematicFile.cpp +++ b/Minecraft.Client/Platform/Common/GameRules/ConsoleSchematicFile.cpp @@ -155,8 +155,7 @@ void ConsoleSchematicFile::load(DataInputStream* dis) { // app.DebugPrintf(1,"Loaded entity type %d at // (%f,%f,%f)\n",(int)type,x,y,z); #endif - m_entities.push_back(std::pair( - new Vec3(x, y, z), (CompoundTag*)eTag->copy())); + m_entities.push_back(std::pair(Vec3(x, y, z), (CompoundTag*)eTag->copy())); } } delete tag; @@ -500,12 +499,12 @@ void ConsoleSchematicFile::applyTileEntities(LevelChunk* chunk, AABB* chunkBox, } } for (AUTO_VAR(it, m_entities.begin()); it != m_entities.end();) { - Vec3* source = it->first; + Vec3 source = it->first; - double targetX = source->x; - double targetY = source->y + destinationBox->y0; - double targetZ = source->z; - schematicCoordToChunkCoord(destinationBox, source->x, source->z, rot, + double targetX = source.x; + double targetY = source.y + destinationBox->y0; + double targetZ = source.z; + schematicCoordToChunkCoord(destinationBox, source.x, source.z, rot, targetX, targetZ); // Add 0.01 as the AABB::contains function returns false if a value is diff --git a/Minecraft.Client/Platform/Common/GameRules/ConsoleSchematicFile.h b/Minecraft.Client/Platform/Common/GameRules/ConsoleSchematicFile.h index 1990328a8..adf862a0b 100644 --- a/Minecraft.Client/Platform/Common/GameRules/ConsoleSchematicFile.h +++ b/Minecraft.Client/Platform/Common/GameRules/ConsoleSchematicFile.h @@ -54,7 +54,7 @@ public: private: int m_xSize, m_ySize, m_zSize; std::vector > m_tileEntities; - std::vector > m_entities; + std::vector > m_entities; public: byteArray m_data; diff --git a/Minecraft.Client/Rendering/GameRenderer.cpp b/Minecraft.Client/Rendering/GameRenderer.cpp index d31ede749..6364b2ba1 100644 --- a/Minecraft.Client/Rendering/GameRenderer.cpp +++ b/Minecraft.Client/Rendering/GameRenderer.cpp @@ -90,7 +90,7 @@ GameRenderer::GameRenderer(Minecraft* mc) { tickSmoothYO = 0; lastTickA = 0; - cameraPos = new Vec3(0.0f, 0.0f, 0.0f); + cameraPos = Vec3(0.0f, 0.0f, 0.0f); fovOffset = 0; fovOffsetO = 0; @@ -1370,10 +1370,10 @@ void GameRenderer::renderLevel(float a, int64_t until) { // Gameplay: Items and mobs not belonging to end world are // disappearing when Enderdragon is damaged. Vec3 cameraPosTemp = cameraEntity->getPos(a); - cameraPos->x = cameraPosTemp.x; - cameraPos->y = cameraPosTemp.y; - cameraPos->z = cameraPosTemp.z; - levelRenderer->renderEntities(cameraPos, frustum, a); + cameraPos.x = cameraPosTemp.x; + cameraPos.y = cameraPosTemp.y; + cameraPos.z = cameraPosTemp.z; + levelRenderer->renderEntities(&cameraPos, frustum, a); #ifdef __PSVITA__ // AP - make sure we're using the Alpha cut out effect for particles glEnable(GL_ALPHA_TEST); diff --git a/Minecraft.Client/Rendering/GameRenderer.h b/Minecraft.Client/Rendering/GameRenderer.h index e3b4c0ca7..c359e45e2 100644 --- a/Minecraft.Client/Rendering/GameRenderer.h +++ b/Minecraft.Client/Rendering/GameRenderer.h @@ -50,7 +50,7 @@ private: float thirdTiltO; float accumulatedSmoothXO, accumulatedSmoothYO; float tickSmoothXO, tickSmoothYO, lastTickA; - Vec3* cameraPos; // 4J added + Vec3 cameraPos; // 4J added // fov modification float fovOffset; diff --git a/Minecraft.Client/Rendering/Polygon.cpp b/Minecraft.Client/Rendering/Polygon.cpp index 6e5dd3d5f..44d65648b 100644 --- a/Minecraft.Client/Rendering/Polygon.cpp +++ b/Minecraft.Client/Rendering/Polygon.cpp @@ -45,8 +45,8 @@ void _Polygon::mirror() { } void _Polygon::render(Tesselator* t, float scale) { - Vec3 v0 = vertices[1]->pos->vectorTo(*vertices[0]->pos); - Vec3 v1 = vertices[1]->pos->vectorTo(*vertices[2]->pos); + Vec3 v0 = vertices[1]->pos.vectorTo(vertices[0]->pos); + Vec3 v1 = vertices[1]->pos.vectorTo(vertices[2]->pos); Vec3 n = v1.cross(v0).normalize(); t->begin(); @@ -58,8 +58,8 @@ void _Polygon::render(Tesselator* t, float scale) { for (int i = 0; i < 4; i++) { Vertex* v = vertices[i]; - t->vertexUV((float)(v->pos->x * scale), (float)(v->pos->y * scale), - (float)(v->pos->z * scale), (float)(v->u), (float)(v->v)); + t->vertexUV((float)(v->pos.x * scale), (float)(v->pos.y * scale), + (float)(v->pos.z * scale), (float)(v->u), (float)(v->v)); } t->end(); } diff --git a/Minecraft.Client/Rendering/Vertex.cpp b/Minecraft.Client/Rendering/Vertex.cpp index aaf37cc93..7222ed172 100644 --- a/Minecraft.Client/Rendering/Vertex.cpp +++ b/Minecraft.Client/Rendering/Vertex.cpp @@ -2,7 +2,7 @@ #include "Vertex.h" Vertex::Vertex(float x, float y, float z, float u, float v) { - this->pos = new Vec3(x, y, z); + this->pos = Vec3(x, y, z); this->u = u; this->v = v; } @@ -16,7 +16,7 @@ Vertex::Vertex(Vertex* vertex, float u, float v) { } Vertex::Vertex(Vec3* pos, float u, float v) { - this->pos = pos; + this->pos = *pos; this->u = u; this->v = v; } diff --git a/Minecraft.Client/Rendering/Vertex.h b/Minecraft.Client/Rendering/Vertex.h index 99166d1ee..7c4492a8d 100644 --- a/Minecraft.Client/Rendering/Vertex.h +++ b/Minecraft.Client/Rendering/Vertex.h @@ -3,7 +3,7 @@ class Vertex { public: - Vec3* pos; + Vec3 pos; float u, v; public: @@ -11,4 +11,4 @@ public: Vertex* remap(float u, float v); Vertex(Vertex* vertex, float u, float v); Vertex(Vec3* pos, float u, float v); -}; \ No newline at end of file +}; diff --git a/Minecraft.World/AI/Navigation/PathNavigation.cpp b/Minecraft.World/AI/Navigation/PathNavigation.cpp index 5b670ec7d..62547c4f0 100644 --- a/Minecraft.World/AI/Navigation/PathNavigation.cpp +++ b/Minecraft.World/AI/Navigation/PathNavigation.cpp @@ -20,7 +20,7 @@ PathNavigation::PathNavigation(Mob* mob, Level* level) { avoidSun = false; _tick = 0; lastStuckCheck = 0; - lastStuckCheckPos = new Vec3(0, 0, 0); + lastStuckCheckPos = Vec3(0, 0, 0); _canPassDoors = true; _canOpenDoors = false; avoidWater = false; @@ -29,7 +29,6 @@ PathNavigation::PathNavigation(Mob* mob, Level* level) { PathNavigation::~PathNavigation() { if (path != NULL) delete path; - delete lastStuckCheckPos; } void PathNavigation::setAvoidWater(bool avoidWater) { @@ -112,9 +111,9 @@ bool PathNavigation::moveTo(Path* newPath, double speedModifier) { this->speedModifier = speedModifier; Vec3 mobPos = getTempMobPos(); lastStuckCheck = _tick; - lastStuckCheckPos->x = mobPos.x; - lastStuckCheckPos->y = mobPos.y; - lastStuckCheckPos->z = mobPos.z; + lastStuckCheckPos.x = mobPos.x; + lastStuckCheckPos.y = mobPos.y; + lastStuckCheckPos.z = mobPos.z; return true; } @@ -161,8 +160,7 @@ void PathNavigation::updatePath() { int sz = sx; for (int i = firstElevation - 1; i >= path->getIndex(); --i) { Vec3 mob_pos = path->getPos(mob->shared_from_this(), i); - if (canMoveDirectly(&mobPos, &mob_pos, - sx, sy, sz)) { + if (canMoveDirectly(&mobPos, &mob_pos, sx, sy, sz)) { path->setIndex(i); break; } @@ -170,11 +168,11 @@ void PathNavigation::updatePath() { // stuck detection (probably pushed off path) if (_tick - lastStuckCheck > 100) { - if (mobPos.distanceToSqr(*lastStuckCheckPos) < 1.5 * 1.5) stop(); + if (mobPos.distanceToSqr(lastStuckCheckPos) < 1.5 * 1.5) stop(); lastStuckCheck = _tick; - lastStuckCheckPos->x = mobPos.x; - lastStuckCheckPos->y = mobPos.y; - lastStuckCheckPos->z = mobPos.z; + lastStuckCheckPos.x = mobPos.x; + lastStuckCheckPos.y = mobPos.y; + lastStuckCheckPos.z = mobPos.z; } } diff --git a/Minecraft.World/AI/Navigation/PathNavigation.h b/Minecraft.World/AI/Navigation/PathNavigation.h index 25130e1b0..0d5843281 100644 --- a/Minecraft.World/AI/Navigation/PathNavigation.h +++ b/Minecraft.World/AI/Navigation/PathNavigation.h @@ -14,7 +14,7 @@ private: bool avoidSun; int _tick; int lastStuckCheck; - Vec3* lastStuckCheckPos; + Vec3 lastStuckCheckPos; bool _canPassDoors; bool _canOpenDoors; diff --git a/Minecraft.World/AI/Navigation/RandomPos.cpp b/Minecraft.World/AI/Navigation/RandomPos.cpp index 1a804fbb9..4025cc9f3 100644 --- a/Minecraft.World/AI/Navigation/RandomPos.cpp +++ b/Minecraft.World/AI/Navigation/RandomPos.cpp @@ -4,33 +4,36 @@ #include "RandomPos.h" #include -Vec3* RandomPos::tempDir = new Vec3(0, 0, 0); +Vec3 RandomPos::tempDir = Vec3(0, 0, 0); -std::optional RandomPos::getPos(std::shared_ptr mob, int xzDist, - int yDist, int quadrant /*=-1*/) // 4J - added quadrant +std::optional RandomPos::getPos( + std::shared_ptr mob, int xzDist, int yDist, + int quadrant /*=-1*/) // 4J - added quadrant { return generateRandomPos(mob, xzDist, yDist, NULL, quadrant); } -std::optional RandomPos::getPosTowards(std::shared_ptr mob, int xzDist, - int yDist, Vec3* towardsPos) { - tempDir->x = towardsPos->x - mob->x; - tempDir->y = towardsPos->y - mob->y; - tempDir->z = towardsPos->z - mob->z; - return generateRandomPos(mob, xzDist, yDist, tempDir); +std::optional RandomPos::getPosTowards(std::shared_ptr mob, + int xzDist, int yDist, + Vec3* towardsPos) { + tempDir.x = towardsPos->x - mob->x; + tempDir.y = towardsPos->y - mob->y; + tempDir.z = towardsPos->z - mob->z; + return generateRandomPos(mob, xzDist, yDist, &tempDir); } -std::optional RandomPos::getPosAvoid(std::shared_ptr mob, int xzDist, - int yDist, Vec3* avoidPos) { - tempDir->x = mob->x - avoidPos->x; - tempDir->y = mob->y - avoidPos->y; - tempDir->z = mob->z - avoidPos->z; - return generateRandomPos(mob, xzDist, yDist, tempDir); +std::optional RandomPos::getPosAvoid(std::shared_ptr mob, + int xzDist, int yDist, + Vec3* avoidPos) { + tempDir.x = mob->x - avoidPos->x; + tempDir.y = mob->y - avoidPos->y; + tempDir.z = mob->z - avoidPos->z; + return generateRandomPos(mob, xzDist, yDist, &tempDir); } -std::optional RandomPos::generateRandomPos(std::shared_ptr mob, - int xzDist, int yDist, Vec3* dir, - int quadrant /*=-1*/) // 4J - added quadrant +std::optional RandomPos::generateRandomPos( + std::shared_ptr mob, int xzDist, int yDist, Vec3* dir, + int quadrant /*=-1*/) // 4J - added quadrant { Random* random = mob->getRandom(); bool hasBest = false; diff --git a/Minecraft.World/AI/Navigation/RandomPos.h b/Minecraft.World/AI/Navigation/RandomPos.h index 48e278ad0..b7bd8f394 100644 --- a/Minecraft.World/AI/Navigation/RandomPos.h +++ b/Minecraft.World/AI/Navigation/RandomPos.h @@ -5,17 +5,21 @@ class PathfinderMob; class RandomPos { private: - static Vec3* tempDir; + static Vec3 tempDir; public: - static std::optional getPos(std::shared_ptr mob, int xzDist, - int yDist, int quadrant = -1); // 4J added quadrant - static std::optional getPosTowards(std::shared_ptr mob, int xzDist, - int yDist, Vec3* towardsPos); - static std::optional getPosAvoid(std::shared_ptr mob, int xzDist, - int yDist, Vec3* avoidPos); + static std::optional getPos(std::shared_ptr mob, + int xzDist, int yDist, + int quadrant = -1); // 4J added quadrant + static std::optional getPosTowards(std::shared_ptr mob, + int xzDist, int yDist, + Vec3* towardsPos); + static std::optional getPosAvoid(std::shared_ptr mob, + int xzDist, int yDist, + Vec3* avoidPos); + private: - static std::optional generateRandomPos(std::shared_ptr mob, - int xzDist, int yDist, Vec3* dir, - int quadrant = -1); // 4J added quadrant + static std::optional generateRandomPos( + std::shared_ptr mob, int xzDist, int yDist, Vec3* dir, + int quadrant = -1); // 4J added quadrant }; From 20982f11c1e9145e2bfc9aa9e67d71690a729263 Mon Sep 17 00:00:00 2001 From: orng Date: Thu, 26 Mar 2026 14:13:45 -0500 Subject: [PATCH 016/170] chore: format files touched by refactor/remove-vec3-tls --- .../Common/GameRules/ConsoleSchematicFile.cpp | 3 ++- .../Platform/Common/Tutorial/AreaHint.cpp | 3 +-- .../Common/Tutorial/ChangeStateConstraint.cpp | 6 ++--- .../PS3/SPU_Tasks/ChunkUpdate/Tile_SPU.cpp | 27 ++++++++++--------- Minecraft.Client/Player/LocalPlayer.cpp | 6 ++--- Minecraft.Client/Rendering/Camera.h | 2 +- .../EntityRenderers/FishingHookRenderer.cpp | 8 +++--- Minecraft.World/Blocks/LiquidTile.cpp | 11 +++----- Minecraft.World/Entities/LivingEntity.cpp | 4 +-- Minecraft.World/Entities/Mobs/EnderDragon.cpp | 3 +-- Minecraft.World/Entities/Mobs/Minecart.cpp | 3 ++- Minecraft.World/Entities/Mobs/Minecart.h | 3 ++- Minecraft.World/Items/BoatItem.cpp | 5 ++-- Minecraft.World/Level/Explosion.cpp | 4 +-- Minecraft.World/Player/Player.cpp | 4 +-- .../WorldGen/Structures/Villages.h | 2 +- 16 files changed, 44 insertions(+), 50 deletions(-) diff --git a/Minecraft.Client/Platform/Common/GameRules/ConsoleSchematicFile.cpp b/Minecraft.Client/Platform/Common/GameRules/ConsoleSchematicFile.cpp index e48113989..217a7ffb8 100644 --- a/Minecraft.Client/Platform/Common/GameRules/ConsoleSchematicFile.cpp +++ b/Minecraft.Client/Platform/Common/GameRules/ConsoleSchematicFile.cpp @@ -155,7 +155,8 @@ void ConsoleSchematicFile::load(DataInputStream* dis) { // app.DebugPrintf(1,"Loaded entity type %d at // (%f,%f,%f)\n",(int)type,x,y,z); #endif - m_entities.push_back(std::pair(Vec3(x, y, z), (CompoundTag*)eTag->copy())); + m_entities.push_back(std::pair( + Vec3(x, y, z), (CompoundTag*)eTag->copy())); } } delete tag; diff --git a/Minecraft.Client/Platform/Common/Tutorial/AreaHint.cpp b/Minecraft.Client/Platform/Common/Tutorial/AreaHint.cpp index ced909db9..87dc976bf 100644 --- a/Minecraft.Client/Platform/Common/Tutorial/AreaHint.cpp +++ b/Minecraft.Client/Platform/Common/Tutorial/AreaHint.cpp @@ -28,8 +28,7 @@ int AreaHint::tick() { if ((m_displayState == e_Tutorial_State_Any || m_tutorial->getCurrentState() == m_displayState) && - m_hintNeeded && - area->contains(&player_pos) == contains) { + m_hintNeeded && area->contains(&player_pos) == contains) { if (m_completeState == e_Tutorial_State_None) { m_hintNeeded = false; } else if (m_tutorial->isStateCompleted(m_completeState)) { diff --git a/Minecraft.Client/Platform/Common/Tutorial/ChangeStateConstraint.cpp b/Minecraft.Client/Platform/Common/Tutorial/ChangeStateConstraint.cpp index 252d85f7d..e1f93eecb 100644 --- a/Minecraft.Client/Platform/Common/Tutorial/ChangeStateConstraint.cpp +++ b/Minecraft.Client/Platform/Common/Tutorial/ChangeStateConstraint.cpp @@ -87,8 +87,7 @@ void ChangeStateConstraint::tick(int iPad) { } Vec3 ipad_player = minecraft->localplayers[iPad]->getPos(1); if (!m_bHasChanged && inASourceState && - movementArea->contains(&ipad_player) == - contains) { + movementArea->contains(&ipad_player) == contains) { m_bHasChanged = true; m_changedFromState = m_tutorial->getCurrentState(); m_tutorial->changeTutorialState(m_targetState); @@ -126,8 +125,7 @@ void ChangeStateConstraint::tick(int iPad) { } } } else if (m_bHasChanged && - movementArea->contains( - &ipad_player) != contains) { + movementArea->contains(&ipad_player) != contains) { m_bHasChanged = false; m_tutorial->changeTutorialState(m_changedFromState); diff --git a/Minecraft.Client/Platform/PS3/SPU_Tasks/ChunkUpdate/Tile_SPU.cpp b/Minecraft.Client/Platform/PS3/SPU_Tasks/ChunkUpdate/Tile_SPU.cpp index 9da02ae9f..c12e1def6 100644 --- a/Minecraft.Client/Platform/PS3/SPU_Tasks/ChunkUpdate/Tile_SPU.cpp +++ b/Minecraft.Client/Platform/PS3/SPU_Tasks/ChunkUpdate/Tile_SPU.cpp @@ -316,8 +316,8 @@ bool Tile_SPU::isSolidRender(bool isServerLevel) { return true; } // double yo = level->random->nextFloat() * s + (1 - s) * 0.5; // double zo = level->random->nextFloat() * s + (1 - s) * 0.5; // std::shared_ptr item = std::shared_ptr( new -// ItemEntity(level, x + xo, y + yo, z + zo, itemInstance ) ); item->throwTime = -// 10; level->addEntity(item); +// ItemEntity(level, x + xo, y + yo, z + zo, itemInstance ) ); item->throwTime +// = 10; level->addEntity(item); // } // // // Brought forward for TU7 @@ -328,8 +328,8 @@ bool Tile_SPU::isSolidRender(bool isServerLevel) { return true; } // while (amount > 0) // { // int newCount = -// ExperienceOrb::getExperienceValue(amount); amount -= newCount; -// level->addEntity(std::shared_ptr( new +// ExperienceOrb::getExperienceValue(amount); amount -= +// newCount; level->addEntity(std::shared_ptr( new // ExperienceOrb(level, x + .5, y + .5, z + .5, newCount))); // } // } @@ -366,14 +366,14 @@ bool Tile_SPU::isSolidRender(bool isServerLevel) { return true; } // Vec3 *closest = NULL; // // if (containsX(xh0) && (closest == NULL || a->distanceTo(xh0) < -// a->distanceTo(closest))) closest = xh0; if (containsX(xh1) && (closest == -// NULL || a->distanceTo(xh1) < a->distanceTo(closest))) closest = xh1; if -// (containsY(yh0) && (closest == NULL || a->distanceTo(yh0) < -// a->distanceTo(closest))) closest = yh0; if (containsY(yh1) && (closest == -// NULL || a->distanceTo(yh1) < a->distanceTo(closest))) closest = yh1; if -// (containsZ(zh0) && (closest == NULL || a->distanceTo(zh0) < -// a->distanceTo(closest))) closest = zh0; if (containsZ(zh1) && (closest == -// NULL || a->distanceTo(zh1) < a->distanceTo(closest))) closest = zh1; +// a->distanceTo(closest))) closest = xh0; if (containsX(xh1) && (closest +// == NULL || a->distanceTo(xh1) < a->distanceTo(closest))) closest = xh1; +// if (containsY(yh0) && (closest == NULL || a->distanceTo(yh0) < +// a->distanceTo(closest))) closest = yh0; if (containsY(yh1) && (closest +// == NULL || a->distanceTo(yh1) < a->distanceTo(closest))) closest = yh1; +// if (containsZ(zh0) && (closest == NULL || a->distanceTo(zh0) < +// a->distanceTo(closest))) closest = zh0; if (containsZ(zh1) && (closest +// == NULL || a->distanceTo(zh1) < a->distanceTo(closest))) closest = zh1; // // LeaveCriticalSection(&m_csShape); // @@ -525,7 +525,8 @@ void Tile_SPU::updateDefaultShape() {} // player->awardStat(Stats::blocksMined[id], 1); // } // player->awardStat(Stats::totalBlocksMined, 1); // 4J : WESTY : Added -// for other award. player->causeFoodExhaustion(FoodConstants::EXHAUSTION_MINE); +// for other award. +// player->causeFoodExhaustion(FoodConstants::EXHAUSTION_MINE); // // if( id == Tile_SPU::treeTrunk_Id ) // player->awardStat(Achievements::mineWood); diff --git a/Minecraft.Client/Player/LocalPlayer.cpp b/Minecraft.Client/Player/LocalPlayer.cpp index 1f6e17a08..4a8e126e5 100644 --- a/Minecraft.Client/Player/LocalPlayer.cpp +++ b/Minecraft.Client/Player/LocalPlayer.cpp @@ -550,7 +550,8 @@ void LocalPlayer::closeContainer() { void LocalPlayer::openTextEdit(std::shared_ptr tileEntity) { #ifdef ENABLE_JAVA_GUIS if (tileEntity->GetType() == eTYPE_SIGNTILEENTITY) { - minecraft->setScreen(new TextEditScreen(std::dynamic_pointer_cast(tileEntity))); + minecraft->setScreen(new TextEditScreen( + std::dynamic_pointer_cast(tileEntity))); bool success = true; } #else @@ -782,8 +783,7 @@ void LocalPlayer::awardStat(Stat* stat, byteArray param) { // storage device, so needs a primary player, and the player may not // have been a primary player when they first 'got' the award so let the // award manager figure it out - if (!minecraft->stats[m_iPad]->hasTaken(ach)) - { + if (!minecraft->stats[m_iPad]->hasTaken(ach)) { // 4J-PB - Don't display the java popup #ifdef ENABLE_JAVA_GUIS minecraft->achievementPopup->popup(ach); diff --git a/Minecraft.Client/Rendering/Camera.h b/Minecraft.Client/Rendering/Camera.h index 4ce2d8419..894a01967 100644 --- a/Minecraft.Client/Rendering/Camera.h +++ b/Minecraft.Client/Rendering/Camera.h @@ -27,7 +27,7 @@ public: static TilePos* getCameraTilePos(std::shared_ptr player, double alpha); static Vec3 getCameraPos(std::shared_ptr player, - double alpha); + double alpha); static int getBlockAt(Level* level, std::shared_ptr player, float alpha); }; diff --git a/Minecraft.Client/Rendering/EntityRenderers/FishingHookRenderer.cpp b/Minecraft.Client/Rendering/EntityRenderers/FishingHookRenderer.cpp index b43acd1dd..1bd178e64 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/FishingHookRenderer.cpp +++ b/Minecraft.Client/Rendering/EntityRenderers/FishingHookRenderer.cpp @@ -60,11 +60,11 @@ void FishingHookRenderer::render(std::shared_ptr _hook, double x, Vec3 vv(-0.5, 0.03, 0.8); vv.xRot(-(hook->owner->xRotO + - (hook->owner->xRot - hook->owner->xRotO) * a) * - PI / 180); + (hook->owner->xRot - hook->owner->xRotO) * a) * + PI / 180); vv.yRot(-(hook->owner->yRotO + - (hook->owner->yRot - hook->owner->yRotO) * a) * - PI / 180); + (hook->owner->yRot - hook->owner->yRotO) * a) * + PI / 180); vv.yRot(swing2 * 0.5f); vv.xRot(-swing2 * 0.7f); diff --git a/Minecraft.World/Blocks/LiquidTile.cpp b/Minecraft.World/Blocks/LiquidTile.cpp index 2b3cda562..af1ee85b4 100644 --- a/Minecraft.World/Blocks/LiquidTile.cpp +++ b/Minecraft.World/Blocks/LiquidTile.cpp @@ -137,14 +137,13 @@ Vec3 LiquidTile::getFlow(LevelSource* level, int x, int y, int z) { if (t >= 0) { int dir = t - (mid - 8); flow = flow.add((xt - x) * dir, (yt - y) * dir, - (zt - z) * dir); + (zt - z) * dir); } } } else { if (t >= 0) { int dir = t - mid; - flow = - flow.add((xt - x) * dir, (yt - y) * dir, (zt - z) * dir); + flow = flow.add((xt - x) * dir, (yt - y) * dir, (zt - z) * dir); } } } @@ -308,10 +307,8 @@ void LiquidTile::animateTick(Level* level, int x, int y, int z, double LiquidTile::getSlopeAngle(LevelSource* level, int x, int y, int z, Material* m) { Vec3 flow; - if (m == Material::water) - flow = Tile::water->getFlow(level, x, y, z); - if (m == Material::lava) - flow = Tile::lava->getFlow(level, x, y, z); + if (m == Material::water) flow = Tile::water->getFlow(level, x, y, z); + if (m == Material::lava) flow = Tile::lava->getFlow(level, x, y, z); if (flow.x == 0 && flow.z == 0) return -1000; return atan2(flow.z, flow.x) - PI / 2; } diff --git a/Minecraft.World/Entities/LivingEntity.cpp b/Minecraft.World/Entities/LivingEntity.cpp index 00a5de704..b4b870baf 100644 --- a/Minecraft.World/Entities/LivingEntity.cpp +++ b/Minecraft.World/Entities/LivingEntity.cpp @@ -794,12 +794,12 @@ void LivingEntity::breakItem(std::shared_ptr itemInstance) { for (int i = 0; i < 5; i++) { Vec3 d = Vec3((random->nextFloat() - 0.5) * 0.1, - Math::random() * 0.1 + 0.1, 0); + Math::random() * 0.1 + 0.1, 0); d.xRot(-xRot * PI / 180); d.yRot(-yRot * PI / 180); Vec3 p = Vec3((random->nextFloat() - 0.5) * 0.3, - -random->nextFloat() * 0.6 - 0.3, 0.6); + -random->nextFloat() * 0.6 - 0.3, 0.6); p.xRot(-xRot * PI / 180); p.yRot(-yRot * PI / 180); p = p.add(x, y + getHeadHeight(), z); diff --git a/Minecraft.World/Entities/Mobs/EnderDragon.cpp b/Minecraft.World/Entities/Mobs/EnderDragon.cpp index 828eeb982..4625557e2 100644 --- a/Minecraft.World/Entities/Mobs/EnderDragon.cpp +++ b/Minecraft.World/Entities/Mobs/EnderDragon.cpp @@ -1024,8 +1024,7 @@ void EnderDragon::findNewTarget() { if (getSynchedAction() == e_EnderdragonAction_Takeoff) { Vec3 v = getHeadLookVector(1); - targetNodeIndex = - findClosestNode(-v.x * 40, 105.0, -v.z * 40); + targetNodeIndex = findClosestNode(-v.x * 40, 105.0, -v.z * 40); } else { if (random->nextInt(8) == 0) { m_holdingPatternClockwise = !m_holdingPatternClockwise; diff --git a/Minecraft.World/Entities/Mobs/Minecart.cpp b/Minecraft.World/Entities/Mobs/Minecart.cpp index 511764cb6..8f0350096 100644 --- a/Minecraft.World/Entities/Mobs/Minecart.cpp +++ b/Minecraft.World/Entities/Mobs/Minecart.cpp @@ -551,7 +551,8 @@ void Minecart::applyNaturalSlowdown() { } } -std::optional Minecart::getPosOffs(double x, double y, double z, double offs) { +std::optional Minecart::getPosOffs(double x, double y, double z, + double offs) { int xt = Mth::floor(x); int yt = Mth::floor(y); int zt = Mth::floor(z); diff --git a/Minecraft.World/Entities/Mobs/Minecart.h b/Minecraft.World/Entities/Mobs/Minecart.h index 3e96f1fc3..1fc6e2919 100644 --- a/Minecraft.World/Entities/Mobs/Minecart.h +++ b/Minecraft.World/Entities/Mobs/Minecart.h @@ -78,7 +78,8 @@ protected: virtual void moveAlongTrack(int xt, int yt, int zt, double maxSpeed, double slideSpeed, int tile, int data); virtual void applyNaturalSlowdown(); - virtual std::optional getPosOffs(double x, double y, double z, double offs); + virtual std::optional getPosOffs(double x, double y, double z, + double offs); virtual std::optional getPos(double x, double y, double z); protected: diff --git a/Minecraft.World/Items/BoatItem.cpp b/Minecraft.World/Items/BoatItem.cpp index 0d3b1749c..d84290919 100644 --- a/Minecraft.World/Items/BoatItem.cpp +++ b/Minecraft.World/Items/BoatItem.cpp @@ -84,9 +84,8 @@ std::shared_ptr BoatItem::use( bool hitEntity = false; float overlap = 1; std::vector >* objects = level->getEntities( - player, - player->bb->expand(b.x * (range), b.y * (range), b.z * (range)) - ->grow(overlap, overlap, overlap)); + player, player->bb->expand(b.x * (range), b.y * (range), b.z * (range)) + ->grow(overlap, overlap, overlap)); // for (int i = 0; i < objects.size(); i++) { for (AUTO_VAR(it, objects->begin()); it != objects->end(); ++it) { std::shared_ptr e = *it; // objects.get(i); diff --git a/Minecraft.World/Level/Explosion.cpp b/Minecraft.World/Level/Explosion.cpp index 752586bd6..a82786ebe 100644 --- a/Minecraft.World/Level/Explosion.cpp +++ b/Minecraft.World/Level/Explosion.cpp @@ -26,9 +26,7 @@ Explosion::Explosion(Level* level, std::shared_ptr source, double x, size = 16; } -Explosion::~Explosion() { - delete random; -} +Explosion::~Explosion() { delete random; } void Explosion::explode() { float oR = r; diff --git a/Minecraft.World/Player/Player.cpp b/Minecraft.World/Player/Player.cpp index 64e17333a..a345d2087 100644 --- a/Minecraft.World/Player/Player.cpp +++ b/Minecraft.World/Player/Player.cpp @@ -528,13 +528,13 @@ void Player::spawnEatParticles(std::shared_ptr useItem, if (useItem->getUseAnimation() == UseAnim_eat) { for (int i = 0; i < count; i++) { Vec3 d{(random->nextFloat() - 0.5) * 0.1, - Math::random() * 0.1 + 0.1, 0}; + Math::random() * 0.1 + 0.1, 0}; d.xRot(-xRot * PI / 180); d.yRot(-yRot * PI / 180); Vec3 p{(random->nextFloat() - 0.5) * 0.3, - -random->nextFloat() * 0.6 - 0.3, 0.6}; + -random->nextFloat() * 0.6 - 0.3, 0.6}; p.xRot(-xRot * PI / 180); p.yRot(-yRot * PI / 180); p = p.add(x, y + getHeadHeight(), z); diff --git a/Minecraft.World/WorldGen/Structures/Villages.h b/Minecraft.World/WorldGen/Structures/Villages.h index 9ab55837f..9c8cd5590 100644 --- a/Minecraft.World/WorldGen/Structures/Villages.h +++ b/Minecraft.World/WorldGen/Structures/Villages.h @@ -44,4 +44,4 @@ private: public: void load(CompoundTag* tag); void save(CompoundTag* tag); -}; \ No newline at end of file +}; From 99a7330e3150ed1de3d1c0db9525e2ee6014ebf8 Mon Sep 17 00:00:00 2001 From: orng Date: Thu, 26 Mar 2026 16:03:43 -0500 Subject: [PATCH 017/170] fit: missing const on `Vec3::distanceToSqr` --- Minecraft.World/Util/Vec3.cpp | 2 +- Minecraft.World/Util/Vec3.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Minecraft.World/Util/Vec3.cpp b/Minecraft.World/Util/Vec3.cpp index 4bedbf5a6..810456f27 100644 --- a/Minecraft.World/Util/Vec3.cpp +++ b/Minecraft.World/Util/Vec3.cpp @@ -40,7 +40,7 @@ double Vec3::distanceTo(const Vec3& p) const { return std::sqrt(xd * xd + yd * yd + zd * zd); } -double Vec3::distanceToSqr(const Vec3& p) { +double Vec3::distanceToSqr(const Vec3& p) const { double xd = p.x - x; double yd = p.y - y; double zd = p.z - z; diff --git a/Minecraft.World/Util/Vec3.h b/Minecraft.World/Util/Vec3.h index 9d17f528a..bd470f663 100644 --- a/Minecraft.World/Util/Vec3.h +++ b/Minecraft.World/Util/Vec3.h @@ -18,7 +18,7 @@ public: Vec3 cross(const Vec3& p) const; Vec3 add(double x, double y, double z) const; double distanceTo(const Vec3& p) const; - double distanceToSqr(const Vec3& p); + double distanceToSqr(const Vec3& p) const; double distanceToSqr(double x2, double y2, double z2) const; Vec3 scale(double l) const; double length() const; From 1e67adc1c2c82acea397439870706cab16b24acd Mon Sep 17 00:00:00 2001 From: orng Date: Fri, 27 Mar 2026 02:45:25 -0500 Subject: [PATCH 018/170] refactor: rewrite `flake.nix` --- flake.lock | 44 ++++++++++-- flake.nix | 202 +++++++++++++++++++++++++++++------------------------ 2 files changed, 151 insertions(+), 95 deletions(-) diff --git a/flake.lock b/flake.lock index 0f6e9ef3b..5a5335f73 100644 --- a/flake.lock +++ b/flake.lock @@ -17,6 +17,24 @@ "type": "github" } }, + "flake-utils": { + "inputs": { + "systems": "systems" + }, + "locked": { + "lastModified": 1731533236, + "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, "miniaudio": { "flake": false, "locked": { @@ -44,15 +62,15 @@ }, "nixpkgs": { "locked": { - "lastModified": 1774106199, - "narHash": "sha256-US5Tda2sKmjrg2lNHQL3jRQ6p96cgfWh3J1QBliQ8Ws=", - "owner": "nixos", + "lastModified": 1774386573, + "narHash": "sha256-4hAV26quOxdC6iyG7kYaZcM3VOskcPUrdCQd/nx8obc=", + "owner": "NixOS", "repo": "nixpkgs", - "rev": "6c9a78c09ff4d6c21d0319114873508a6ec01655", + "rev": "46db2e09e1d3f113a13c0d7b81e2f221c63b8ce9", "type": "github" }, "original": { - "owner": "nixos", + "owner": "NixOS", "ref": "nixos-unstable", "repo": "nixpkgs", "type": "github" @@ -61,6 +79,7 @@ "root": { "inputs": { "4jlibs": "4jlibs", + "flake-utils": "flake-utils", "miniaudio": "miniaudio", "miniaudio-patch": "miniaudio-patch", "nixpkgs": "nixpkgs", @@ -118,6 +137,21 @@ "repo": "stb", "type": "github" } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } } }, "root": "root", diff --git a/flake.nix b/flake.nix index 04fa60509..828529435 100644 --- a/flake.nix +++ b/flake.nix @@ -1,121 +1,143 @@ { - description = "4jcraft-nix package and dev shell"; + description = "4jcraft nix-package and dev-shell"; inputs = { - nixpkgs.url = "github:nixos/nixpkgs?ref=nixos-unstable"; + nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; + flake-utils.url = "github:numtide/flake-utils"; shiggy = { - url = "github:4jcraft/shiggy/main"; - flake = false; - }; - miniaudio = { - url = "https://github.com/mackron/miniaudio/archive/refs/tags/0.11.22.tar.gz"; - flake = false; - }; - miniaudio-patch = { - url = "https://wrapdb.mesonbuild.com/v2/miniaudio_0.11.22-2/get_patch"; + url = "github:4jcraft/shiggy/main"; flake = false; }; + "4jlibs" = { - url = "github:4jcraft/4jlibs/main"; + url = "github:4jcraft/4jlibs/main"; flake = false; }; + + miniaudio = { + url = "https://github.com/mackron/miniaudio/archive/refs/tags/0.11.22.tar.gz"; + flake = false; + }; + + miniaudio-patch = { + url = "https://wrapdb.mesonbuild.com/v2/miniaudio_0.11.22-2/get_patch"; + flake = false; + }; + stb = { - url = "github:nothings/stb/master"; + url = "github:nothings/stb/master"; flake = false; }; + simdutf = { - url = "github:simdutf/simdutf"; + url = "github:simdutf/simdutf"; flake = false; }; }; - outputs = { self, nixpkgs, ... } @ inputs: - let - allSystems = [ - "x86_64-linux" - "aarch64-linux" - "x86_64-darwin" - "aarch64-darwin" - ]; - forAllSystems = f: nixpkgs.lib.genAttrs allSystems (system: f { - pkgs = import nixpkgs { inherit system; }; - }); - in - { - packages = forAllSystems ({ pkgs }: { - default = pkgs.clangStdenv.mkDerivation { - pname = "4jcraft"; - version = "0.1.0"; - src = ./.; + outputs = + { + self, + nixpkgs, + flake-utils, + ... + }@inputs: + flake-utils.lib.eachDefaultSystem ( + system: + let + pkgs = import nixpkgs { inherit system; }; + in + { + packages.default = pkgs.clangStdenv.mkDerivation { + pname = "4jcraft"; + version = "0.1.0"; + src = ./.; - dontUseCmakeConfigure = true; + dontUseCmakeConfigure = true; - preConfigure = '' - # shiggy - cp -r ${inputs.shiggy} subprojects/shiggy + # 4jcraft - Meson expects this subprojects structure + postUnpack = '' + mkdir -p source/subprojects - # miniaudio - cp -r ${inputs.miniaudio} subprojects/miniaudio - chmod -R u+w subprojects/miniaudio - unzip ${inputs."miniaudio-patch"} -d /tmp/miniaudio-patch/ - cp -r /tmp/miniaudio-patch/*/. subprojects/miniaudio/ - cat > subprojects/miniaudio.wrap <<'EOF' - [wrap-file] - directory = miniaudio + cp -r ${inputs.shiggy} source/subprojects/shiggy + cp -r ${inputs."4jlibs"} source/subprojects/4jlibs + cp -r ${inputs.stb} source/subprojects/stb + cp -r ${inputs.simdutf} source/subprojects/simdutf + cp -r ${inputs.miniaudio} source/subprojects/miniaudio - [provide] - dependency_names = miniaudio - EOF + chmod -R u+w source/subprojects + ''; - # 4jlibs - cp -r ${inputs."4jlibs"} subprojects/4jlibs + # 4jcraft - `stb` and `simdutf` patches + postPatch = '' + cp subprojects/packhagefiles/stb/meson.build subprojects/stb/meson.build + cp subprojects/packagefiles/simdutf/meson.build subprojects/simdutf/meson.build + cp subprojects/packagefiles/simdutf/meson.options subprojects/simdutf/meson.options - # stb - cp -r ${inputs.stb} subprojects/stb - chmod -R u+w subprojects/ - cp subprojects/packagefiles/stb/meson.build subprojects/stb/meson.build + ${pkgs.unzip} ${inputs.miniaudio-patch} -d miniaudio-patch-tmp + cp -r miniaudio-patch-tmp/*/. subprojects/miniaudio/ - # simdutf - cp -r ${inputs.simdutf} subprojects/simdutf - chmod -R u+w subprojects/simdutf - cp subprojects/packagefiles/simdutf/meson.build subprojects/simdutf/meson.build - cp subprojects/packagefiles/simdutf/meson.options subprojects/simdutf/meson.options - ''; + cat > subprojects/miniaudio.wrap < Date: Fri, 27 Mar 2026 02:53:22 -0500 Subject: [PATCH 019/170] fix: spelling mistake --- flake.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flake.nix b/flake.nix index 828529435..24a17ed0b 100644 --- a/flake.nix +++ b/flake.nix @@ -71,7 +71,7 @@ # 4jcraft - `stb` and `simdutf` patches postPatch = '' - cp subprojects/packhagefiles/stb/meson.build subprojects/stb/meson.build + cp subprojects/packagefiles/stb/meson.build subprojects/stb/meson.build cp subprojects/packagefiles/simdutf/meson.build subprojects/simdutf/meson.build cp subprojects/packagefiles/simdutf/meson.options subprojects/simdutf/meson.options From 256a809750c5492e5d858c89cc6ea20ffa5e23f3 Mon Sep 17 00:00:00 2001 From: JuiceyDev Date: Fri, 27 Mar 2026 11:52:05 +0100 Subject: [PATCH 020/170] feat/bttr-cwd --- .../Platform/Common/Consoles_App.cpp | 30 +++++++++++++++++++ Minecraft.World/IO/Files/File.cpp | 23 ++++++++++++++ 2 files changed, 53 insertions(+) diff --git a/Minecraft.Client/Platform/Common/Consoles_App.cpp b/Minecraft.Client/Platform/Common/Consoles_App.cpp index f85d56632..5eb204c95 100644 --- a/Minecraft.Client/Platform/Common/Consoles_App.cpp +++ b/Minecraft.Client/Platform/Common/Consoles_App.cpp @@ -52,6 +52,10 @@ #include "../Minecraft.Client/Utils/ArchiveFile.h" #endif #include "../Minecraft.Client/Minecraft.h" +#if defined(__linux__) +#include +#include +#endif #ifdef _XBOX #include "../Minecraft.Client/Platform/Xbox/GameConfig/Minecraft.spa.h" #include "../Minecraft.Client/Platform/Xbox/Network/NetworkPlayerXbox.h" @@ -4600,7 +4604,33 @@ void CMinecraftApp::loadMediaArchive() { #endif if (!mediapath.empty()) { + // (check file.cpp) + // try to load the archive relative to the executable + // directory first. + // If that fails, fall back to the current working + // directory (original behavior) + // if everything fails, may god help you +#if defined(__linux__) + char exePathBuf[PATH_MAX]; + ssize_t exeLen = readlink("/proc/self/exe", exePathBuf, sizeof(exePathBuf) - 1); + if (exeLen != -1) { + exePathBuf[exeLen] = '\0'; + std::string exePathStr(exePathBuf); + size_t pos = exePathStr.find_last_of('/'); + std::string exeDir = (pos == std::string::npos) ? std::string(".") : exePathStr.substr(0, pos); + std::wstring exeDirW = convStringToWstring(exeDir.c_str()); + std::wstring candidate = exeDirW + File::pathSeparator + mediapath; + if (File(candidate).exists()) { + m_mediaArchive = new ArchiveFile(File(candidate)); + } else { + m_mediaArchive = new ArchiveFile(File(mediapath)); + } + } else { + m_mediaArchive = new ArchiveFile(File(mediapath)); + } +#else m_mediaArchive = new ArchiveFile(File(mediapath)); +#endif } #if 0 std::string path = "Common\\media.arc"; diff --git a/Minecraft.World/IO/Files/File.cpp b/Minecraft.World/IO/Files/File.cpp index fb09c1a4f..e5bff5c98 100644 --- a/Minecraft.World/IO/Files/File.cpp +++ b/Minecraft.World/IO/Files/File.cpp @@ -69,6 +69,29 @@ File::File(const std::wstring& pathname) //: parent( NULL ) else m_abstractPathName = pathname; +#if defined(__linux__) + // If this is a relative path and it doesn't exist in the CWD, try to + // resolve it relative to the executable directory + if (!m_abstractPathName.empty() && m_abstractPathName[0] != L'/') { + const char* native = wstringtofilename(m_abstractPathName); + if (access(native, F_OK) == -1) { + char exePathBuf[PATH_MAX]; + ssize_t exeLen = readlink("/proc/self/exe", exePathBuf, sizeof(exePathBuf) - 1); + if (exeLen != -1) { + exePathBuf[exeLen] = '\0'; + std::string exePathStr(exePathBuf); + size_t pos = exePathStr.find_last_of('/'); + std::string exeDir = (pos == std::string::npos) ? std::string(".") : exePathStr.substr(0, pos); + std::wstring exeDirW = convStringToWstring(exeDir); + std::wstring candidate = exeDirW + pathSeparator + m_abstractPathName; + const char* candNative = wstringtofilename(candidate); + if (access(candNative, F_OK) != -1) { + m_abstractPathName = candidate; + } + } + } + } +#endif #ifdef _WINDOWS64 std::string path = wstringtofilename(m_abstractPathName); std::string finalPath = StorageManager.GetMountedPath(path.c_str()); From 396e819b9b435c85c569adc2dd8cebd99fe07655 Mon Sep 17 00:00:00 2001 From: StevenSYS <139715581+StevenSYS@users.noreply.github.com> Date: Fri, 27 Mar 2026 01:19:33 +0000 Subject: [PATCH 021/170] Made the Java creative inventory more complete. --- .../Windows64Media/loc/en-EN/strings.lang | 3 + .../Windows64Media/loc/stringsGeneric.xml | 8 +- .../Common/UI/IUIScene_CreativeMenu.cpp | 16 +- .../Common/UI/IUIScene_CreativeMenu.h | 16 +- .../UI/Screens/AbstractContainerScreen.cpp | 9 +- .../UI/Screens/AbstractContainerScreen.h | 2 +- .../UI/Screens/CreativeInventoryScreen.cpp | 938 +++++++++--------- .../UI/Screens/CreativeInventoryScreen.h | 117 ++- 8 files changed, 585 insertions(+), 524 deletions(-) diff --git a/Minecraft.Assets/Windows64Media/loc/en-EN/strings.lang b/Minecraft.Assets/Windows64Media/loc/en-EN/strings.lang index 752552227..2a3a90f32 100644 --- a/Minecraft.Assets/Windows64Media/loc/en-EN/strings.lang +++ b/Minecraft.Assets/Windows64Media/loc/en-EN/strings.lang @@ -4760,6 +4760,9 @@ Would you like to unlock the full game? Food + + Search Items + Structures diff --git a/Minecraft.Assets/Windows64Media/loc/stringsGeneric.xml b/Minecraft.Assets/Windows64Media/loc/stringsGeneric.xml index 36b521dd0..ec3b88e28 100644 --- a/Minecraft.Assets/Windows64Media/loc/stringsGeneric.xml +++ b/Minecraft.Assets/Windows64Media/loc/stringsGeneric.xml @@ -1,4 +1,4 @@ - + New Downloadable Content is available! Access it from the Minecraft Store button on the Main Menu. @@ -6044,6 +6044,10 @@ Would you like to unlock the full game now? Food + + Search Items + + Structures @@ -8811,4 +8815,4 @@ All Ender Chests in a world are linked. Items placed into an Ender Chest are acc Cure - \ No newline at end of file + diff --git a/Minecraft.Client/Platform/Common/UI/IUIScene_CreativeMenu.cpp b/Minecraft.Client/Platform/Common/UI/IUIScene_CreativeMenu.cpp index 28a3773b4..2f609340b 100644 --- a/Minecraft.Client/Platform/Common/UI/IUIScene_CreativeMenu.cpp +++ b/Minecraft.Client/Platform/Common/UI/IUIScene_CreativeMenu.cpp @@ -469,6 +469,11 @@ void IUIScene_CreativeMenu::staticCtor() { ITEM(Item::carrotGolden_Id) ITEM(Item::pumpkinPie_Id) +// 4jcraft: Search +#ifdef ENABLE_JAVA_GUIS + DEF(eCreativeInventory_Search) +#endif + // Tools, Armour and Weapons (Complete) DEF(eCreativeInventory_ToolsArmourWeapons) ITEM(Item::compass_Id) @@ -856,6 +861,13 @@ void IUIScene_CreativeMenu::staticCtor() { specs[eCreativeInventoryTab_Food] = new TabSpec(L"Food", IDS_GROUPNAME_FOOD, 1, foodGroup); +// 4jcraft +#ifdef ENABLE_JAVA_GUIS + ECreative_Inventory_Groups searchGroup[] = {eCreativeInventory_Search}; + specs[eCreativeInventoryTab_Search] = + new TabSpec(L"Search Items", IDS_GROUPNAME_SEARCH, 1, searchGroup); +#endif + ECreative_Inventory_Groups toolsGroup[] = { eCreativeInventory_ToolsArmourWeapons}; specs[eCreativeInventoryTab_ToolsWeaponsArmor] = @@ -898,7 +910,7 @@ IUIScene_CreativeMenu::IUIScene_CreativeMenu() { m_bCarryingCreativeItem = false; m_creativeSlotX = m_creativeSlotY = m_inventorySlotX = m_inventorySlotY = 0; - // 4J JEV - Settup Tabs + // 4J JEV - Setup Tabs for (int i = 0; i < eCreativeInventoryTab_COUNT; i++) { m_tabDynamicPos[i] = 0; m_tabPage[i] = 0; @@ -1523,4 +1535,4 @@ void IUIScene_CreativeMenu::BuildFirework( } list->push_back(firework); -} +} \ No newline at end of file diff --git a/Minecraft.Client/Platform/Common/UI/IUIScene_CreativeMenu.h b/Minecraft.Client/Platform/Common/UI/IUIScene_CreativeMenu.h index 02967ac5a..fc2cb071e 100644 --- a/Minecraft.Client/Platform/Common/UI/IUIScene_CreativeMenu.h +++ b/Minecraft.Client/Platform/Common/UI/IUIScene_CreativeMenu.h @@ -7,20 +7,24 @@ class SimpleContainer; class IUIScene_CreativeMenu : public virtual IUIScene_AbstractContainerMenu { public: - // 4J Stu - These map directly to the tabs seenon the screen + // 4J Stu - These map directly to the tabs seen on the screen enum ECreativeInventoryTabs { eCreativeInventoryTab_BuildingBlocks = 0, eCreativeInventoryTab_Decorations, eCreativeInventoryTab_RedstoneAndTransport, eCreativeInventoryTab_Materials, eCreativeInventoryTab_Food, +// 4jcraft: java search tab +#ifdef ENABLE_JAVA_GUIS + eCreativeInventoryTab_Search, +#endif eCreativeInventoryTab_ToolsWeaponsArmor, eCreativeInventoryTab_Brewing, eCreativeInventoryTab_Misc, eCreativeInventoryTab_COUNT, }; - // 4J Stu - These are logical groupings of items, and be be combined for + // 4J Stu - These are logical groupings of items, and are combined for // tabs on-screen enum ECreative_Inventory_Groups { eCreativeInventory_BuildingBlocks, @@ -29,6 +33,10 @@ public: eCreativeInventory_Transport, eCreativeInventory_Materials, eCreativeInventory_Food, +// 4jcraft +#ifdef ENABLE_JAVA_GUIS + eCreativeInventory_Search, +#endif eCreativeInventory_ToolsArmourWeapons, eCreativeInventory_Brewing, eCreativeInventory_Potions_Basic, @@ -97,7 +105,7 @@ public: virtual void loopClick(int slotIndex, int buttonNum, bool quickKeyHeld, std::shared_ptr player) {} // do nothing }* itemPickerMenu; - + // 4jcraft: changed these two from public to protected for the java UI static std::vector > categoryGroups[eCreativeInventoryGroupsCount]; @@ -148,4 +156,4 @@ protected: static void BuildFirework(std::vector >* list, uint8_t type, int color, int sulphur, bool flicker, bool trail, int fadeColor = -1); -}; \ No newline at end of file +}; diff --git a/Minecraft.Client/UI/Screens/AbstractContainerScreen.cpp b/Minecraft.Client/UI/Screens/AbstractContainerScreen.cpp index a3b16edc5..bf608e7ee 100644 --- a/Minecraft.Client/UI/Screens/AbstractContainerScreen.cpp +++ b/Minecraft.Client/UI/Screens/AbstractContainerScreen.cpp @@ -306,9 +306,10 @@ void AbstractContainerScreen::mouseClicked(int x, int y, int buttonNum) { } if (slotId != -1) { - bool quickKey = slotId != AbstractContainerMenu::SLOT_CLICKED_OUTSIDE && - (Keyboard::isKeyDown(Keyboard::KEY_LSHIFT) || - Keyboard::isKeyDown(Keyboard::KEY_RSHIFT)); + bool quickKey = + slotId != AbstractContainerMenu::SLOT_CLICKED_OUTSIDE && + (Keyboard::isKeyDown(Keyboard::KEY_LSHIFT) || + Keyboard::isKeyDown(Keyboard::KEY_RSHIFT)); minecraft->gameMode->handleInventoryMouseClick( menu->containerId, slotId, buttonNum, quickKey, minecraft->player); @@ -341,4 +342,4 @@ void AbstractContainerScreen::tick() { Screen::tick(); if (!minecraft->player->isAlive() || minecraft->player->removed) minecraft->player->closeContainer(); -} \ No newline at end of file +} diff --git a/Minecraft.Client/UI/Screens/AbstractContainerScreen.h b/Minecraft.Client/UI/Screens/AbstractContainerScreen.h index da3d3e625..ace3ec4bf 100644 --- a/Minecraft.Client/UI/Screens/AbstractContainerScreen.h +++ b/Minecraft.Client/UI/Screens/AbstractContainerScreen.h @@ -42,4 +42,4 @@ public: virtual void slotsChanged(std::shared_ptr container); virtual bool isPauseScreen(); virtual void tick(); -}; \ No newline at end of file +}; diff --git a/Minecraft.Client/UI/Screens/CreativeInventoryScreen.cpp b/Minecraft.Client/UI/Screens/CreativeInventoryScreen.cpp index aea796309..98e2a3aec 100644 --- a/Minecraft.Client/UI/Screens/CreativeInventoryScreen.cpp +++ b/Minecraft.Client/UI/Screens/CreativeInventoryScreen.cpp @@ -15,513 +15,533 @@ #include // Static member initialization -int CreativeInventoryScreen::selectedTabIndex = IUIScene_CreativeMenu::eCreativeInventoryTab_BuildingBlocks; -std::shared_ptr CreativeInventoryScreen::basicInventory = std::make_shared(0, L"", false, ITEMS_PER_PAGE); +int CreativeInventoryScreen::selectedTabIndex = + IUIScene_CreativeMenu::eCreativeInventoryTab_BuildingBlocks; +int CreativeInventoryScreen::tabIconIds + [IUIScene_CreativeMenu::eCreativeInventoryTab_COUNT] = { + // Building Blocks + Tile::redBrick_Id, + + // Decorations + Tile::rose_Id, + + // Redstone & Transportation + Item::redStone_Id, + + // Materials + Item::stick_Id, + + // Food + Item::apple_Id, + +// Fix for it not compiling with shiggy +#ifdef ENABLE_JAVA_GUIS + // Search Items + Item::compass_Id, +#endif + + // Tools, Weapons & Armor + Item::hatchet_iron_Id, + + // Brewing + Item::potion_Id, + + // Materials + Item::bucket_lava_Id}; +std::shared_ptr CreativeInventoryScreen::basicInventory = + std::make_shared(0, L"", false, ITEMS_PER_PAGE); +ItemRenderer* CreativeInventoryScreen::itemRenderer = new ItemRenderer(); +std::shared_ptr CreativeInventoryScreen::tabIcons + [IUIScene_CreativeMenu::eCreativeInventoryTab_COUNT]; // ContainerCreative implementation -CreativeInventoryScreen::ContainerCreative::ContainerCreative(std::shared_ptr player) : AbstractContainerMenu() -{ - std::shared_ptr inventoryplayer = player->inventory; - - // Add creative inventory slots (5 rows x 9 columns = 45 slots) - for (int i = 0; i < ROWS; ++i) - { - for (int j = 0; j < COLUMNS; ++j) - { - addSlot(new Slot(basicInventory, i * COLUMNS + j, 9 + j * 18, 18 + i * 18)); - } - } - - // Add hotbar slots (9 slots at bottom) - for (int k = 0; k < 9; ++k) - { - addSlot(new Slot(inventoryplayer, k, 9 + k * 18, 112)); - } - - scrollTo(0.0f); +CreativeInventoryScreen::ContainerCreative::ContainerCreative( + std::shared_ptr player) + : AbstractContainerMenu() { + std::shared_ptr inventoryplayer = player->inventory; + + // Add creative inventory slots (5 rows x 9 columns = 45 slots) + for (int i = 0; i < ROWS; i++) { + for (int j = 0; j < COLUMNS; j++) { + addSlot(new Slot(basicInventory, i * COLUMNS + j, 9 + j * 18, + 18 + i * 18)); + } + } + + // Add hotbar slots (9 slots at bottom) + for (int k = 0; k < 9; k++) { + addSlot(new Slot(inventoryplayer, k, 9 + k * 18, 112)); + } + + scrollTo(0.0f); + + for (int i = 0; i < IUIScene_CreativeMenu::eCreativeInventoryTab_COUNT; + i++) { + tabIcons[i] = std::shared_ptr( + new ItemInstance(tabIconIds[i], 1, 0)); + } } -bool CreativeInventoryScreen::ContainerCreative::stillValid(std::shared_ptr player) -{ - return true; +bool CreativeInventoryScreen::ContainerCreative::stillValid( + std::shared_ptr player) { + return true; } -std::shared_ptr CreativeInventoryScreen::ContainerCreative::clicked(int slotIndex, int buttonNum, int clickType, std::shared_ptr player) -{ - std::shared_ptr inventory = player->inventory; - std::shared_ptr carried = inventory->getCarried(); - - // Handle clicks outside the GUI - if (slotIndex == SLOT_CLICKED_OUTSIDE) - { - // Drop the carried item - if (carried != NULL) - { - if (buttonNum == 0) - { - player->drop(carried, true); - inventory->setCarried(std::shared_ptr()); - } - else if (buttonNum == 1) - { - std::shared_ptr single = carried->copy(); - single->count = 1; - player->drop(single, true); - carried->count--; - if (carried->count <= 0) - { - inventory->setCarried(std::shared_ptr()); - } - } - } - return std::shared_ptr(); - } - - // Validate slot index - if (slotIndex < 0 || slotIndex >= (int)slots.size()) - { - return std::shared_ptr(); - } - - Slot* slot = slots.at(slotIndex); - - // Handle creative inventory slots (0-44) - if (slotIndex >= 0 && slotIndex < ITEMS_PER_PAGE) - { - std::shared_ptr slotItem = slot->getItem(); - - // Handle SWAP (number key) - copy item to hotbar - if (clickType == CLICK_SWAP) - { - if (slotItem != NULL && buttonNum >= 0 && buttonNum < 9) - { - std::shared_ptr copy = slotItem->copy(); - copy->count = copy->getMaxStackSize(); - inventory->setItem(buttonNum, copy); - } - return std::shared_ptr(); - } - - // Handle CLONE (middle click) - if (clickType == CLICK_CLONE) - { - if (slotItem != NULL) - { - std::shared_ptr copy = slotItem->copy(); - copy->count = copy->getMaxStackSize(); - inventory->setCarried(copy); - } - return std::shared_ptr(); - } - - // Handle normal clicks - if (slotItem != NULL) - { - if (buttonNum == 0) // Left click - { - std::shared_ptr copy = slotItem->copy(); - copy->count = copy->getMaxStackSize(); - inventory->setCarried(copy); - } - else if (buttonNum == 1) // Right click - { - std::shared_ptr copy = slotItem->copy(); - copy->count = 1; - inventory->setCarried(copy); - } - } - else if (carried != NULL) - { - // Clicking on empty creative slot with item - clear the carried item - inventory->setCarried(std::shared_ptr()); - } - - return std::shared_ptr(); - } - - // For hotbar slots (45-53), use normal container behavior - return AbstractContainerMenu::clicked(slotIndex, buttonNum, clickType, player); +std::shared_ptr +CreativeInventoryScreen::ContainerCreative::clicked( + int slotIndex, int buttonNum, int clickType, + std::shared_ptr player) { + std::shared_ptr inventory = player->inventory; + std::shared_ptr carried = inventory->getCarried(); + + // Handle clicks outside the GUI + if (slotIndex == SLOT_CLICKED_OUTSIDE) { + // Drop the carried item + if (carried != NULL) { + if (buttonNum == 0) { + player->drop(carried, true); + inventory->setCarried(std::shared_ptr()); + } else if (buttonNum == 1) { + std::shared_ptr single = carried->copy(); + single->count = 1; + player->drop(single, true); + carried->count--; + if (carried->count <= 0) { + inventory->setCarried(std::shared_ptr()); + } + } + } + return std::shared_ptr(); + } + + // Validate slot index + if (slotIndex < 0 || slotIndex >= (int)slots.size()) { + return std::shared_ptr(); + } + + Slot* slot = slots.at(slotIndex); + + // Handle creative inventory slots (0-44) + if (slotIndex >= 0 && slotIndex < ITEMS_PER_PAGE) { + std::shared_ptr slotItem = slot->getItem(); + + // Handle SWAP (number key) - copy item to hotbar + if (clickType == CLICK_SWAP) { + if (slotItem != NULL && buttonNum >= 0 && buttonNum < 9) { + std::shared_ptr copy = slotItem->copy(); + copy->count = copy->getMaxStackSize(); + inventory->setItem(buttonNum, copy); + } + return std::shared_ptr(); + } + + // Handle CLONE (middle click) + if (clickType == CLICK_CLONE) { + if (slotItem != NULL) { + std::shared_ptr copy = slotItem->copy(); + copy->count = copy->getMaxStackSize(); + inventory->setCarried(copy); + } + return std::shared_ptr(); + } + + // Handle normal clicks + if (slotItem != NULL) { + if (buttonNum == 0) // Left click + { + std::shared_ptr copy = slotItem->copy(); + copy->count = copy->getMaxStackSize(); + inventory->setCarried(copy); + } else if (buttonNum == 1) // Right click + { + std::shared_ptr copy = slotItem->copy(); + copy->count = 1; + inventory->setCarried(copy); + } + } else if (carried != NULL) { + // Clicking on empty creative slot with item - clear the carried + // item + inventory->setCarried(std::shared_ptr()); + } + + return std::shared_ptr(); + } + + // For hotbar slots (45-53), use normal container behavior + return AbstractContainerMenu::clicked(slotIndex, buttonNum, clickType, + player); } -void CreativeInventoryScreen::ContainerCreative::scrollTo(float pos) -{ - int i = (itemList.size() + COLUMNS - 1) / COLUMNS - ROWS; - int j = (int)((double)(pos * (float)i) + 0.5); - - if (j < 0) - { - j = 0; - } - - for (int k = 0; k < ROWS; ++k) - { - for (int l = 0; l < COLUMNS; ++l) - { - int i1 = l + (k + j) * COLUMNS; - - if (i1 >= 0 && i1 < (int)itemList.size()) - { - basicInventory->setItem(l + k * COLUMNS, itemList[i1]); - } - else - { - basicInventory->setItem(l + k * COLUMNS, std::shared_ptr()); - } - } - } +void CreativeInventoryScreen::ContainerCreative::scrollTo(float pos) { + int i = (itemList.size() + COLUMNS - 1) / COLUMNS - ROWS; + int j = (int)((double)(pos * (float)i) + 0.5); + + if (j < 0) { + j = 0; + } + + for (int k = 0; k < ROWS; k++) { + for (int l = 0; l < COLUMNS; l++) { + int i1 = l + (k + j) * COLUMNS; + + if (i1 >= 0 && i1 < (int)itemList.size()) { + basicInventory->setItem(l + k * COLUMNS, itemList[i1]); + } else { + basicInventory->setItem(l + k * COLUMNS, + std::shared_ptr()); + } + } + } } -bool CreativeInventoryScreen::ContainerCreative::canScroll() -{ - return itemList.size() > ITEMS_PER_PAGE; +bool CreativeInventoryScreen::ContainerCreative::canScroll() { + return itemList.size() > ITEMS_PER_PAGE; } -CreativeInventoryScreen::CreativeInventoryScreen(std::shared_ptr player) - : AbstractContainerScreen(new ContainerCreative(player)) -{ - this->player = player; - player->containerMenu = menu; - - currentScroll = 0.0f; - isScrolling = false; - wasClicking = false; - isLeftMouseDown = false; - - imageHeight = 136; - imageWidth = 195; +CreativeInventoryScreen::CreativeInventoryScreen(std::shared_ptr player) + : AbstractContainerScreen(new ContainerCreative(player)) { + this->player = player; + player->containerMenu = menu; + + currentScroll = 0.0f; + isScrolling = false; + wasClicking = false; + isLeftMouseDown = false; + + imageHeight = 136; + imageWidth = 195; } -void CreativeInventoryScreen::removed() -{ - AbstractContainerScreen::removed(); +void CreativeInventoryScreen::removed() { AbstractContainerScreen::removed(); } + +void CreativeInventoryScreen::init() { + buttons.clear(); + + int i = selectedTabIndex; + selectedTabIndex = -1; + setCurrentCreativeTab(i); } -void CreativeInventoryScreen::init() -{ - buttons.clear(); - - int i = selectedTabIndex; - selectedTabIndex = -1; - setCurrentCreativeTab(i); -} - -void CreativeInventoryScreen::updateEvents() -{ +void CreativeInventoryScreen::updateEvents() { #ifdef ENABLE_JAVA_GUIS - // Handle mouse wheel scrolling. - // We use ButtonDown with the scroll actions rather than GetScrollDelta() because - // both share s_scrollTicksForButtonPressed; whichever is called first in a tick - // zeroes it, so GetScrollDelta() would return 0 if hotbar scroll ran first. - // ButtonDown/ScrollSnap() snapshots once per tick so all callers see the same value. - if (needsScrollBars()) - { - ContainerCreative* container = (ContainerCreative*)menu; - int totalRows = ((int)container->itemList.size() + COLUMNS - 1) / COLUMNS; - int scrollableRows = totalRows - ROWS; - if (scrollableRows > 0) - { - float step = 1.0f / (float)scrollableRows; - if (InputManager.ButtonDown(0, MINECRAFT_ACTION_LEFT_SCROLL)) - { - currentScroll -= step; - currentScroll = std::max(0.0f, std::min(1.0f, currentScroll)); - container->scrollTo(currentScroll); - } - else if (InputManager.ButtonDown(0, MINECRAFT_ACTION_RIGHT_SCROLL)) - { - currentScroll += step; - currentScroll = std::max(0.0f, std::min(1.0f, currentScroll)); - container->scrollTo(currentScroll); - } - } - } + // Handle mouse wheel scrolling. + // We use ButtonDown with the scroll actions rather than GetScrollDelta() + // because both share s_scrollTicksForButtonPressed; whichever is called + // first in a tick zeroes it, so GetScrollDelta() would return 0 if hotbar + // scroll ran first. ButtonDown/ScrollSnap() snapshots once per tick so all + // callers see the same value. + if (needsScrollBars()) { + ContainerCreative* container = (ContainerCreative*)menu; + int totalRows = + ((int)container->itemList.size() + COLUMNS - 1) / COLUMNS; + int scrollableRows = totalRows - ROWS; + if (scrollableRows > 0) { + float step = 1.0f / (float)scrollableRows; + if (InputManager.ButtonDown(0, MINECRAFT_ACTION_LEFT_SCROLL)) { + currentScroll -= step; + currentScroll = std::max(0.0f, std::min(1.0f, currentScroll)); + container->scrollTo(currentScroll); + } else if (InputManager.ButtonDown(0, + MINECRAFT_ACTION_RIGHT_SCROLL)) { + currentScroll += step; + currentScroll = std::max(0.0f, std::min(1.0f, currentScroll)); + container->scrollTo(currentScroll); + } + } + } #endif - Screen::updateEvents(); + Screen::updateEvents(); } -void CreativeInventoryScreen::containerTick() -{ +void CreativeInventoryScreen::containerTick() {} + +void CreativeInventoryScreen::tick() { Screen::tick(); } + +void CreativeInventoryScreen::keyPressed(wchar_t eventCharacter, int eventKey) { + AbstractContainerScreen::keyPressed(eventCharacter, eventKey); } -void CreativeInventoryScreen::tick() -{ - Screen::tick(); +void CreativeInventoryScreen::mouseClicked(int x, int y, int buttonNum) { + if (buttonNum == 0) isLeftMouseDown = true; + + Screen::mouseClicked(x, y, buttonNum); + + if (buttonNum == 0 || buttonNum == 1) { + int mouseX = x - (width - imageWidth) / 2; + int mouseY = y - (height - imageHeight) / 2; + + // Check for tab clicks first; let mouseReleased handle the actual tab + // switch + for (int tab = 0; + tab < IUIScene_CreativeMenu::eCreativeInventoryTab_COUNT; tab++) { + if (isMouseOverTab(tab, mouseX, mouseY)) { + return; + } + } + + // Determine which slot (if any) was clicked + Slot* slot = findSlot(x, y); + + int xo = (width - imageWidth) / 2; + int yo = (height - imageHeight) / 2; + bool clickedOutside = + (x < xo || y < yo || x >= xo + imageWidth || y >= yo + imageHeight); + + int slotId = -1; + if (slot != NULL) slotId = slot->index; + if (clickedOutside) + slotId = AbstractContainerMenu::SLOT_CLICKED_OUTSIDE; + + if (slotId == -1) return; + + bool quickKey = slotId != AbstractContainerMenu::SLOT_CLICKED_OUTSIDE && + (Keyboard::isKeyDown(Keyboard::KEY_LSHIFT) || + Keyboard::isKeyDown(Keyboard::KEY_RSHIFT)); + int clickType = quickKey ? AbstractContainerMenu::CLICK_QUICK_MOVE + : AbstractContainerMenu::CLICK_PICKUP; + + // 4jcraft: bypass AbstractContainerScreen::mouseClicked / + // handleInventoryMouseClick here intentionally. The normal path sends a + // ContainerClickPacket to the server, where player->containerMenu is + // still the InventoryMenu (45 slots). Creative slot indices 0-44 are + // valid in ContainerCreative but not in InventoryMenu, and hotbar + // indices 45-53 exceed InventoryMenu's slot count entirely, causing an + // out-of-range crash in AbstractContainerMenu::clicked on the server + // side. Instead we apply the click locally and sync hotbar changes via + // SetCreativeModeSlotPacket. + menu->clicked(slotId, buttonNum, clickType, minecraft->player); + + // 4jcraft: sync hotbar slot changes to the server using + // SetCreativeModeSlotPacket. The packet handler + // (PlayerConnection::handleSetCreativeModeSlot) validates slots against + // InventoryMenu coordinates where the hotbar starts at + // USE_ROW_SLOT_START (36), so we must offset the local hotbar index + // (0-8) accordingly. + if (slotId >= ITEMS_PER_PAGE && slotId < ITEMS_PER_PAGE + 9) { + int hotbarSlot = slotId - ITEMS_PER_PAGE; + std::shared_ptr hotbarItem = + minecraft->player->inventory->getItem(hotbarSlot); + minecraft->gameMode->handleCreativeModeItemAdd( + hotbarItem, hotbarSlot + InventoryMenu::USE_ROW_SLOT_START); + } + } } -void CreativeInventoryScreen::keyPressed(wchar_t eventCharacter, int eventKey) -{ - AbstractContainerScreen::keyPressed(eventCharacter, eventKey); +void CreativeInventoryScreen::mouseReleased(int x, int y, int buttonNum) { + if (buttonNum == 0) isLeftMouseDown = false; + + if (buttonNum == 0) { + int mouseX = x - (width - imageWidth) / 2; + int mouseY = y - (height - imageHeight) / 2; + + // Check for tab clicks + for (int tab = 0; + tab < IUIScene_CreativeMenu::eCreativeInventoryTab_COUNT; tab++) { + if (isMouseOverTab(tab, mouseX, mouseY)) { + setCurrentCreativeTab(tab); + return; + } + } + } + + AbstractContainerScreen::mouseReleased(x, y, buttonNum); } -void CreativeInventoryScreen::mouseClicked(int x, int y, int buttonNum) -{ - if (buttonNum == 0) isLeftMouseDown = true; +void CreativeInventoryScreen::render(int xm, int ym, float a) { + // Java: drawDefaultBackground() + renderBackground(); - Screen::mouseClicked(x, y, buttonNum); + // Handle scrollbar dragging + bool mouseDown = isLeftMouseDown; + int left = (width - imageWidth) / 2; + int top = (height - imageHeight) / 2; + int x1 = left + 175; + int y1 = top + 18; + int x2 = x1 + 14; + int y2 = y1 + 112; - if (buttonNum == 0 || buttonNum == 1) - { - int i = x - (width - imageWidth) / 2; - int j = y - (height - imageHeight) / 2; + if (!wasClicking && mouseDown && xm >= x1 && ym >= y1 && xm < x2 && + ym < y2) { + isScrolling = needsScrollBars(); + } - // Check for tab clicks first; let mouseReleased handle the actual tab switch - for (int tab = 0; tab < IUIScene_CreativeMenu::eCreativeInventoryTab_COUNT; ++tab) - { - if (isMouseOverTab(tab, i, j)) - { - return; - } - } + if (!mouseDown) { + isScrolling = false; + } - // Determine which slot (if any) was clicked - Slot *slot = findSlot(x, y); + wasClicking = mouseDown; - int xo = (width - imageWidth) / 2; - int yo = (height - imageHeight) / 2; - bool clickedOutside = (x < xo || y < yo || x >= xo + imageWidth || y >= yo + imageHeight); + if (isScrolling) { + currentScroll = ((float)(ym - y1) - 7.5f) / ((float)(y2 - y1) - 15.0f); + currentScroll = std::max(0.0f, std::min(1.0f, currentScroll)); + ((ContainerCreative*)menu)->scrollTo(currentScroll); + } - int slotId = -1; - if (slot != NULL) slotId = slot->index; - if (clickedOutside) slotId = AbstractContainerMenu::SLOT_CLICKED_OUTSIDE; - - if (slotId == -1) return; - - bool quickKey = slotId != AbstractContainerMenu::SLOT_CLICKED_OUTSIDE && - (Keyboard::isKeyDown(Keyboard::KEY_LSHIFT) || Keyboard::isKeyDown(Keyboard::KEY_RSHIFT)); - int clickType = quickKey ? AbstractContainerMenu::CLICK_QUICK_MOVE : AbstractContainerMenu::CLICK_PICKUP; - - // 4jcraft: bypass AbstractContainerScreen::mouseClicked / handleInventoryMouseClick - // here intentionally. The normal path sends a ContainerClickPacket to the server, - // where player->containerMenu is still the InventoryMenu (45 slots). Creative slot - // indices 0-44 are valid in ContainerCreative but not in InventoryMenu, and hotbar - // indices 45-53 exceed InventoryMenu's slot count entirely, causing an out-of-range - // crash in AbstractContainerMenu::clicked on the server side. - // Instead we apply the click locally and sync hotbar changes via SetCreativeModeSlotPacket. - menu->clicked(slotId, buttonNum, clickType, minecraft->player); - - // 4jcraft: sync hotbar slot changes to the server using SetCreativeModeSlotPacket. - // The packet handler (PlayerConnection::handleSetCreativeModeSlot) validates slots - // against InventoryMenu coordinates where the hotbar starts at USE_ROW_SLOT_START (36), - // so we must offset the local hotbar index (0-8) accordingly. - if (slotId >= ITEMS_PER_PAGE && slotId < ITEMS_PER_PAGE + 9) - { - int hotbarSlot = slotId - ITEMS_PER_PAGE; - std::shared_ptr hotbarItem = minecraft->player->inventory->getItem(hotbarSlot); - minecraft->gameMode->handleCreativeModeItemAdd(hotbarItem, hotbarSlot + InventoryMenu::USE_ROW_SLOT_START); - } - } + AbstractContainerScreen::render(xm, ym, a); } -void CreativeInventoryScreen::mouseReleased(int x, int y, int buttonNum) -{ - if (buttonNum == 0) isLeftMouseDown = false; - - if (buttonNum == 0) - { - int i = x - (width - imageWidth) / 2; - int j = y - (height - imageHeight) / 2; - - // Check for tab clicks - for (int tab = 0; tab < IUIScene_CreativeMenu::eCreativeInventoryTab_COUNT; ++tab) - { - if (isMouseOverTab(tab, i, j)) - { - setCurrentCreativeTab(tab); - return; - } - } - } - - AbstractContainerScreen::mouseReleased(x, y, buttonNum); -} - -void CreativeInventoryScreen::render(int xm, int ym, float a) -{ - // Java: drawDefaultBackground() - renderBackground(); - - // Handle scrollbar dragging - bool mouseDown = isLeftMouseDown; - int i = (width - imageWidth) / 2; - int j = (height - imageHeight) / 2; - int k = i + 175; - int l = j + 18; - int i1 = k + 14; - int j1 = l + 112; - - if (!wasClicking && mouseDown && xm >= k && ym >= l && xm < i1 && ym < j1) - { - isScrolling = needsScrollBars(); - } - - if (!mouseDown) - { - isScrolling = false; - } - - wasClicking = mouseDown; - - if (isScrolling) - { - currentScroll = ((float)(ym - l) - 7.5f) / ((float)(j1 - l) - 15.0f); - currentScroll = std::max(0.0f, std::min(1.0f, currentScroll)); - ((ContainerCreative*)menu)->scrollTo(currentScroll); - } - - AbstractContainerScreen::render(xm, ym, a); -} - -void CreativeInventoryScreen::renderLabels() -{ +void CreativeInventoryScreen::renderLabels() { #ifdef ENABLE_JAVA_GUIS - if (IUIScene_CreativeMenu::specs && selectedTabIndex >= 0 && selectedTabIndex < IUIScene_CreativeMenu::eCreativeInventoryTab_COUNT) - { - IUIScene_CreativeMenu::TabSpec* spec = IUIScene_CreativeMenu::specs[selectedTabIndex]; - if (spec) - { - std::wstring tabName = app.GetString(spec->m_descriptionId); - font->draw(tabName, 8, 6, 0x404040); - } - } + if (IUIScene_CreativeMenu::specs && selectedTabIndex >= 0 && + selectedTabIndex < IUIScene_CreativeMenu::eCreativeInventoryTab_COUNT) { + IUIScene_CreativeMenu::TabSpec* spec = + IUIScene_CreativeMenu::specs[selectedTabIndex]; + if (spec) { + std::wstring tabName = app.GetString(spec->m_descriptionId); + font->draw(tabName, 8, 6, 0x404040); + } + } #endif } -void CreativeInventoryScreen::renderBg(float a) -{ - int x = (width - imageWidth) / 2; - int y = (height - imageHeight) / 2; +void CreativeInventoryScreen::renderBg(float a) { + int x = (width - imageWidth) / 2; + int y = (height - imageHeight) / 2; #ifdef ENABLE_JAVA_GUIS - // Render all non-selected tabs first - for (int tab = 0; tab < IUIScene_CreativeMenu::eCreativeInventoryTab_COUNT; ++tab) - { - if (tab != selectedTabIndex) - { - drawTab(tab); - } - } - - // Load and render main creative inventory background - int tex = minecraft->textures->loadTexture(TN_GUI_CREATIVE_TAB_ITEMS); - glColor4f(1, 1, 1, 1); - minecraft->textures->bind(tex); - blit(x, y, 0, 0, imageWidth, imageHeight); - - // Render scrollbar - tex = minecraft->textures->loadTexture(TN_GUI_CREATIVE_TABS); - minecraft->textures->bind(tex); - - int scrollX = x + 175; - int scrollY = y + 18; - int scrollHeight = 112; - - if (needsScrollBars()) - { - int scrollPos = (int)((float)(scrollHeight - 17) * currentScroll); - blit(scrollX, scrollY + scrollPos, 232, 0, 12, 15); - } - else - { - blit(scrollX, scrollY + (scrollHeight - 17) / 2, 244, 0, 12, 15); - } - - // Render selected tab last (on top) - drawTab(selectedTabIndex); + static int itemsTex = + minecraft->textures->loadTexture(TN_GUI_CREATIVE_TAB_ITEMS); + static int searchTex = + minecraft->textures->loadTexture(TN_GUI_CREATIVE_TAB_ITEM_SEARCH); + static int scrollTex = + minecraft->textures->loadTexture(TN_GUI_CREATIVE_TABS); + // Render all non-selected tabs first + for (int tab = 0; tab < IUIScene_CreativeMenu::eCreativeInventoryTab_COUNT; + tab++) { + if (tab != selectedTabIndex) { + drawTab(tab); + } + } + + // Load and render main creative inventory background + glColor4f(1, 1, 1, 1); + minecraft->textures->bind((selectedTabIndex == 5) ? searchTex : itemsTex); + blit(x, y, 0, 0, imageWidth, imageHeight); + + // Render scrollbar + minecraft->textures->bind(scrollTex); + + int scrollX = x + 175; + int scrollY = y + 18; + int scrollHeight = 112; + + if (needsScrollBars()) { + int scrollPos = (int)((float)(scrollHeight - 17) * currentScroll); + blit(scrollX, scrollY + scrollPos, 232, 0, 12, 15); + } else { + blit(scrollX, scrollY, 244, 0, 12, 15); + } + + // Render selected tab last (on top) + drawTab(selectedTabIndex); #endif } -void CreativeInventoryScreen::setCurrentCreativeTab(int tab) -{ - if (tab < 0 || tab >= IUIScene_CreativeMenu::eCreativeInventoryTab_COUNT) - return; - - int oldTab = selectedTabIndex; - selectedTabIndex = tab; - - ContainerCreative* container = (ContainerCreative*)menu; - container->itemList.clear(); - - // Populate itemList from the tab's category groups - if (IUIScene_CreativeMenu::specs && IUIScene_CreativeMenu::specs[tab]) - { - IUIScene_CreativeMenu::TabSpec* spec = IUIScene_CreativeMenu::specs[tab]; - - // Add items from static groups - for (int i = 0; i < spec->m_staticGroupsCount; ++i) - { - int groupIdx = spec->m_staticGroupsA[i]; - if (groupIdx >= 0 && groupIdx < IUIScene_CreativeMenu::eCreativeInventoryGroupsCount) - { - auto& group = IUIScene_CreativeMenu::categoryGroups[groupIdx]; - for (auto& item : group) - { - container->itemList.push_back(item); - } - } - } - } - - currentScroll = 0.0f; - container->scrollTo(0.0f); +void CreativeInventoryScreen::setCurrentCreativeTab(int tab) { + if (tab < 0 || tab >= IUIScene_CreativeMenu::eCreativeInventoryTab_COUNT) + return; + + int oldTab = selectedTabIndex; + selectedTabIndex = tab; + + ContainerCreative* container = (ContainerCreative*)menu; + container->itemList.clear(); + + // Populate itemList from the tab's category groups + if (IUIScene_CreativeMenu::specs && IUIScene_CreativeMenu::specs[tab]) { + IUIScene_CreativeMenu::TabSpec* spec = + IUIScene_CreativeMenu::specs[tab]; + + // Add items from static groups + for (int i = 0; i < spec->m_staticGroupsCount; i++) { + int groupIdx = spec->m_staticGroupsA[i]; + if (groupIdx >= 0 && + groupIdx < + IUIScene_CreativeMenu::eCreativeInventoryGroupsCount) { + auto& group = IUIScene_CreativeMenu::categoryGroups[groupIdx]; + for (auto& item : group) { + container->itemList.push_back(item); + } + } + } + } + + currentScroll = 0.0f; + container->scrollTo(0.0f); } -void CreativeInventoryScreen::selectTab(int tab) -{ - setCurrentCreativeTab(tab); +void CreativeInventoryScreen::selectTab(int tab) { setCurrentCreativeTab(tab); } + +bool CreativeInventoryScreen::needsScrollBars() { + return ((ContainerCreative*)menu)->canScroll(); } -bool CreativeInventoryScreen::needsScrollBars() -{ - return ((ContainerCreative*)menu)->canScroll(); +bool CreativeInventoryScreen::isMouseOverTab(int tab, int mouseX, int mouseY) { + int tabColumn = tab % 6; + int x = tabColumn * 28; + int y = 0; + + if (tabColumn == 5) { + x = imageWidth - 28 + 2; + } else if (tabColumn > 0) { + x += tabColumn; + } + + if (tab < 6) { + y -= 32; + } else { + y = imageHeight; + } + + return ((mouseX >= x && mouseX <= x + 28) && + (mouseY >= y && mouseY <= y + 32)); } -bool CreativeInventoryScreen::isMouseOverTab(int tab, int mouseX, int mouseY) -{ - int i = tab; - int j = 28 * i; - int k = 0; - - if (i > 0) - { - j += i; - } - - // Tabs are in the top row - k = k - 32; - - return mouseX >= j && mouseX <= j + 28 && mouseY >= k && mouseY <= k + 32; -} - -void CreativeInventoryScreen::drawTab(int tab) -{ +void CreativeInventoryScreen::drawTab(int tab) { #ifdef ENABLE_JAVA_GUIS - bool isSelected = (tab == selectedTabIndex); - int i = tab; - int j = i * 28; - int k = 0; - int l = (width - imageWidth) / 2 + 28 * i; - int i1 = (height - imageHeight) / 2; - int j1 = 32; - - if (isSelected) - { - k += 32; - } - - if (i > 0) - { - l += i; - } - - // Tabs are in the top row - i1 = i1 - 28; - - // Render tab background - int tex = minecraft->textures->loadTexture(TN_GUI_CREATIVE_TABS); - minecraft->textures->bind(tex); - glColor4f(1, 1, 1, 1); - blit(l, i1, j, k, 28, 32); - - // TODO: Render tab icon (would need item icons) + bool isSelected = (selectedTabIndex == tab); + bool tabFirstRow = (tab < 6); + int left = (width - imageWidth) / 2; + int top = (height - imageHeight) / 2; + int tabColumn = tab % 6; + int sy = 0; + int x = left + 28 * tabColumn; + int y = top; + static int tex = minecraft->textures->loadTexture(TN_GUI_CREATIVE_TABS); + + if (isSelected) { + sy += 32; + } + + if (tabColumn == 5) { + x = left + imageWidth - 28; + } else if (tabColumn > 0) { + x += tabColumn; + } + + // Tabs are in the top row + if (tabFirstRow) { + y -= 28; + } else { + sy += 64; + y += imageHeight - 4; + } + + // Render tab background + glDisable(GL_LIGHTING); + minecraft->textures->bind(tex); + glColor4f(1.0f, 1.0f, 1.0f, 1.0f); + blit(x, y, tabColumn * 28, sy, 28, 32); + + // Render tab icon + x += 6; + y += 8 + (tabFirstRow ? 1 : -1); + glEnable(GL_LIGHTING); + glEnable(GL_RESCALE_NORMAL); + Lighting::turnOnGui(); + itemRenderer->renderGuiItem(font, minecraft->textures, tabIcons[tab], x, y); + itemRenderer->renderGuiItemDecorations(font, minecraft->textures, + tabIcons[tab], x, y); + glDisable(GL_LIGHTING); #endif -} +} \ No newline at end of file diff --git a/Minecraft.Client/UI/Screens/CreativeInventoryScreen.h b/Minecraft.Client/UI/Screens/CreativeInventoryScreen.h index 4ce1659f4..987ec9a88 100644 --- a/Minecraft.Client/UI/Screens/CreativeInventoryScreen.h +++ b/Minecraft.Client/UI/Screens/CreativeInventoryScreen.h @@ -9,63 +9,76 @@ class SimpleContainer; class Inventory; class Slot; -class CreativeInventoryScreen : public AbstractContainerScreen -{ +class CreativeInventoryScreen : public AbstractContainerScreen { private: - static constexpr int ROWS = 5; - static constexpr int COLUMNS = 9; - static constexpr int ITEMS_PER_PAGE = ROWS * COLUMNS; // 45 items (9x5 grid) - - // Currently selected creative tab index - static int selectedTabIndex; - - // Temporary inventory for creative mode items - static std::shared_ptr basicInventory; - - // Amount scrolled in Creative mode inventory (0 = top, 1 = bottom) - float currentScroll; - - bool isScrolling; - - // True if the left mouse button is currently being held - bool isLeftMouseDown; + static constexpr int ROWS = 5; + static constexpr int COLUMNS = 9; + static constexpr int ITEMS_PER_PAGE = + ROWS * COLUMNS; // 45 items (9x5 grid) - // True if the left mouse button was held down last time render was called - bool wasClicking; + // Currently selected creative tab index + static int selectedTabIndex; + + // Array of item ids for the tab icons + static int tabIconIds[IUIScene_CreativeMenu::eCreativeInventoryTab_COUNT]; + + // Temporary inventory for creative mode items + static std::shared_ptr basicInventory; + + // Item renderer for the tab icons + static ItemRenderer* itemRenderer; + + // Array of tab icons + static std::shared_ptr + tabIcons[IUIScene_CreativeMenu::eCreativeInventoryTab_COUNT]; + + // Amount scrolled in Creative mode inventory (0 = top, 1 = bottom) + float currentScroll; + + bool isScrolling; + + // True if the left mouse button is currently being held + bool isLeftMouseDown; + + // True if the left mouse button was held down last time render was called + bool wasClicking; + + std::shared_ptr player; - std::shared_ptr player; - public: - class ContainerCreative : public AbstractContainerMenu - { - public: - std::vector> itemList; - - ContainerCreative(std::shared_ptr player); - virtual bool stillValid(std::shared_ptr player); - virtual std::shared_ptr clicked(int slotIndex, int buttonNum, int clickType, std::shared_ptr player); - void scrollTo(float pos); - bool canScroll(); - }; - + class ContainerCreative : public AbstractContainerMenu { + public: + std::vector> itemList; + + ContainerCreative(std::shared_ptr player); + virtual bool stillValid(std::shared_ptr player); + virtual std::shared_ptr clicked( + int slotIndex, int buttonNum, int clickType, + std::shared_ptr player); + void scrollTo(float pos); + bool canScroll(); + }; + public: - CreativeInventoryScreen(std::shared_ptr player); - virtual void removed(); - virtual void init(); - virtual void containerTick(); - virtual void tick(); - virtual void updateEvents(); - virtual void keyPressed(wchar_t eventCharacter, int eventKey); - virtual void mouseClicked(int x, int y, int buttonNum); - virtual void mouseReleased(int x, int y, int buttonNum); - virtual void render(int xm, int ym, float a); + CreativeInventoryScreen(std::shared_ptr player); + virtual void removed(); + virtual void init(); + virtual void containerTick(); + virtual void tick(); + virtual void updateEvents(); + virtual void keyPressed(wchar_t eventCharacter, int eventKey); + virtual void mouseClicked(int x, int y, int buttonNum); + virtual void mouseReleased(int x, int y, int buttonNum); + virtual void render(int xm, int ym, float a); + protected: - virtual void renderLabels(); - virtual void renderBg(float a); + virtual void renderLabels(); + virtual void renderBg(float a); + private: - void setCurrentCreativeTab(int tab); - void selectTab(int tab); - bool needsScrollBars(); - bool isMouseOverTab(int tab, int mouseX, int mouseY); - void drawTab(int tab); + void setCurrentCreativeTab(int tab); + void selectTab(int tab); + bool needsScrollBars(); + bool isMouseOverTab(int tab, int mouseX, int mouseY); + void drawTab(int tab); }; From ca84ac0512f4a9ddcac04bae12455f41171498fd Mon Sep 17 00:00:00 2001 From: JuiceyDev Date: Fri, 27 Mar 2026 18:07:38 +0100 Subject: [PATCH 022/170] okay managed to do it, anyways hacky code land :3 mainly rewrote a bit of the soundengine, made files now load without being mean and uh yeah it works --- .../Platform/Common/Audio/SoundEngine.cpp | 660 +++++++----------- Minecraft.Client/Textures/BufferedImage.cpp | 272 ++++---- Minecraft.World/IO/Files/File.cpp | 41 +- meson.build | 2 +- 4 files changed, 427 insertions(+), 548 deletions(-) diff --git a/Minecraft.Client/Platform/Common/Audio/SoundEngine.cpp b/Minecraft.Client/Platform/Common/Audio/SoundEngine.cpp index d9b52d283..fa53701b9 100644 --- a/Minecraft.Client/Platform/Common/Audio/SoundEngine.cpp +++ b/Minecraft.Client/Platform/Common/Audio/SoundEngine.cpp @@ -82,8 +82,8 @@ const char* SoundEngine::m_szStreamFileA[eStream_Max] = {"calm1", "ward", "where_are_we_now"}; #ifdef __linux__ -char SoundEngine::m_szSoundPath[] = {"Sound/"}; -char SoundEngine::m_szMusicPath[] = {"music/"}; +char SoundEngine::m_szSoundPath[] = {"Common/Sound/"}; +char SoundEngine::m_szMusicPath[] = {"Common/"}; char SoundEngine::m_szRedistName[] = {"redist64"}; #endif @@ -190,168 +190,144 @@ void SoundEngine::init(Options* pOptions) { void SoundEngine::destroy() { ma_engine_uninit(&m_engine); } void SoundEngine::play(int iSound, float x, float y, float z, float volume, float pitch) { - char szSoundName[256] = "Sound/Minecraft/"; + if (iSound == -1) return; - if (iSound == -1) { - app.DebugPrintf(6, "PlaySound with sound of -1 !!!!!!!!!!!!!!!\n"); - return; + char szIdentifier[256]; + wcstombs(szIdentifier, wchSoundNames[iSound], 255); + + // dot to folder structure (example step.grass -> step/grass) + for (int i = 0; szIdentifier[i]; i++) { + if (szIdentifier[i] == '.') szIdentifier[i] = '/'; } - wcstombs(szSoundName + 16, wchSoundNames[iSound], - sizeof(szSoundName) - 16 - 1); - szSoundName[sizeof(szSoundName) - 1] = '\0'; - - char finalPath[256]; + // YES I KNOW SOUNDNAMES.CPP EXISTS. const char* extensions[] = {".ogg", ".wav", ".mp3"}; - size_t extCount = sizeof(extensions) / sizeof(extensions[0]); + const char* roots[] = {"Sound/Minecraft/", + "build/Minecraft.Client/Sound/Minecraft/", + "Common/Sound/Minecraft/", + "Common/res/TitleUpdate/res/Sound/Minecraft/"}; + + char finalPath[512] = {0}; bool found = false; + // search for variants (grass1, grass2, etc.) + // this is hacky + for (const char* root : roots) { + for (const char* ext : extensions) { + int maxVariant = 0; + for (int i = 1; i <= 16; i++) { + char tryPath[512]; + snprintf(tryPath, sizeof(tryPath), "%s%s%d%s", root, + szIdentifier, i, ext); + if (access(tryPath, F_OK) != -1) + maxVariant = i; + else + break; + } - for (size_t extIdx = 0; extIdx < extCount; extIdx++) { - char basePlusExt[256]; - sprintf_s(basePlusExt, "%s%s", szSoundName, extensions[extIdx]); - - DWORD attr = GetFileAttributesA(basePlusExt); - if (attr != INVALID_FILE_ATTRIBUTES && - !(attr & FILE_ATTRIBUTE_DIRECTORY)) { - sprintf_s(finalPath, "%s", basePlusExt); - found = true; - break; - } - } - if (!found) { - int count = 0; - - for (size_t extIdx = 0; extIdx < extCount; extIdx++) { - for (size_t i = 1; i < 32; i++) { - char numberedPath[256]; - sprintf_s(numberedPath, "%s%d%s", szSoundName, i, - extensions[extIdx]); - - DWORD attr = GetFileAttributesA(numberedPath); - if (attr != INVALID_FILE_ATTRIBUTES && - !(attr & FILE_ATTRIBUTE_DIRECTORY)) { - count = i; - } + if (maxVariant > 0) { + int chosen = (rand() % maxVariant) + 1; + snprintf(finalPath, sizeof(finalPath), "%s%s%d%s", root, + szIdentifier, chosen, ext); + found = true; + break; } } - - if (count > 0) { - int chosen = (rand() % count) + 1; - for (size_t extIdx = 0; extIdx < extCount; extIdx++) { - char numberedPath[256]; - sprintf_s(numberedPath, "%s%d%s", szSoundName, chosen, - extensions[extIdx]); - - DWORD attr = GetFileAttributesA(numberedPath); - if (attr != INVALID_FILE_ATTRIBUTES && - !(attr & FILE_ATTRIBUTE_DIRECTORY)) { - sprintf_s(finalPath, "%s", numberedPath); + if (found) break; + } + if (!found) { + for (const char* root : roots) { + for (const char* ext : extensions) { + char tryPath[512]; + snprintf(tryPath, sizeof(tryPath), "%s%s%s", root, szIdentifier, + ext); + if (access(tryPath, F_OK) != -1) { + strncpy(finalPath, tryPath, 511); found = true; break; } } - if (!found) { - sprintf_s(finalPath, "%s%d.ogg", szSoundName, chosen); - } + if (found) break; } } + if (!found) return; + MiniAudioSound* s = new MiniAudioSound(); memset(&s->info, 0, sizeof(AUDIO_INFO)); - s->info.x = x; s->info.y = y; s->info.z = z; - s->info.volume = volume; s->info.pitch = pitch; s->info.bIs3D = true; - s->info.bUseSoundsPitchVal = false; - s->info.iSound = iSound + eSFX_MAX; if (ma_sound_init_from_file(&m_engine, finalPath, MA_SOUND_FLAG_ASYNC, - nullptr, nullptr, &s->sound) != MA_SUCCESS) { - app.DebugPrintf("Failed to load sound ID : %i from %S\n", iSound, - wchSoundNames[iSound]); + nullptr, nullptr, &s->sound) == MA_SUCCESS) { + ma_sound_set_spatialization_enabled(&s->sound, MA_TRUE); + ma_sound_set_min_distance(&s->sound, 2.0f); + ma_sound_set_max_distance(&s->sound, 48.0f); + ma_sound_set_volume(&s->sound, volume * m_MasterEffectsVolume); + ma_sound_set_pitch(&s->sound, pitch); + ma_sound_set_position(&s->sound, x, y, z); + ma_sound_start(&s->sound); + m_activeSounds.push_back(s); + } else { delete s; - return; } - - ma_sound_set_spatialization_enabled(&s->sound, MA_TRUE); - ma_sound_set_min_distance(&s->sound, SFX_3D_MIN_DISTANCE); - ma_sound_set_max_distance(&s->sound, SFX_3D_MAX_DISTANCE); - ma_sound_set_rolloff(&s->sound, SFX_3D_ROLLOFF); - - float finalVolume = volume * m_MasterEffectsVolume * SFX_VOLUME_MULTIPLIER; - if (finalVolume > SFX_MAX_GAIN) finalVolume = SFX_MAX_GAIN; - - ma_sound_set_volume(&s->sound, finalVolume); - ma_sound_set_pitch(&s->sound, pitch); - ma_sound_set_position(&s->sound, x, y, z); - - ma_sound_start(&s->sound); - - m_activeSounds.push_back(s); } void SoundEngine::playUI(int iSound, float volume, float pitch) { - char szSoundName[256]; - wstring name; - + char szIdentifier[256]; if (iSound >= eSFX_MAX) { - strcpy(szSoundName, "Sound/Minecraft/"); - name = wchSoundNames[iSound]; + wcstombs(szIdentifier, wchSoundNames[iSound], 255); } else { - strcpy(szSoundName, "Sound/Minecraft/UI/"); - name = wchUISoundNames[iSound]; + wcstombs(szIdentifier, wchUISoundNames[iSound], 255); } - wcstombs(szSoundName + strlen(szSoundName), name.c_str(), - sizeof(szSoundName) - strlen(szSoundName) - 1); - char finalPath[256]; + + for (int i = 0; szIdentifier[i]; i++) { + if (szIdentifier[i] == '.') szIdentifier[i] = '/'; + } + // ui sfx also WHO WHO THAT EWWW const char* extensions[] = {".ogg", ".wav", ".mp3"}; - size_t extCount = sizeof(extensions) / sizeof(extensions[0]); + const char* roots[] = {"Sound/Minecraft/UI/", "Sound/Minecraft/", + "build/Minecraft.Client/Sound/Minecraft/UI/", + "build/Minecraft.Client/Sound/Minecraft/", + "Common/Sound/Minecraft/UI/"}; + + char finalPath[512] = {0}; bool found = false; - for (size_t extIdx = 0; extIdx < extCount; extIdx++) { - char basePlusExt[256]; - sprintf_s(basePlusExt, "%s%s", szSoundName, extensions[extIdx]); - - DWORD attr = GetFileAttributesA(basePlusExt); - if (attr != INVALID_FILE_ATTRIBUTES && - !(attr & FILE_ATTRIBUTE_DIRECTORY)) { - sprintf_s(finalPath, "%s", basePlusExt); - found = true; - break; + for (const char* root : roots) { + for (const char* ext : extensions) { + char tryPath[512]; + snprintf(tryPath, sizeof(tryPath), "%s%s%s", root, szIdentifier, + ext); + if (access(tryPath, F_OK) != -1) { + strncpy(finalPath, tryPath, 511); + found = true; + break; + } } + if (found) break; } + if (!found) return; + MiniAudioSound* s = new MiniAudioSound(); memset(&s->info, 0, sizeof(AUDIO_INFO)); - s->info.volume = volume; s->info.pitch = pitch; s->info.bIs3D = false; - s->info.bUseSoundsPitchVal = true; if (ma_sound_init_from_file(&m_engine, finalPath, MA_SOUND_FLAG_ASYNC, - nullptr, nullptr, &s->sound) != MA_SUCCESS) { + nullptr, nullptr, &s->sound) == MA_SUCCESS) { + ma_sound_set_spatialization_enabled(&s->sound, MA_FALSE); + ma_sound_set_volume(&s->sound, volume * m_MasterEffectsVolume); + ma_sound_set_pitch(&s->sound, pitch); + ma_sound_start(&s->sound); + m_activeSounds.push_back(s); + } else { delete s; - app.DebugPrintf("ma_sound_init_from_file failed: %s\n", finalPath); - return; } - - ma_sound_set_spatialization_enabled(&s->sound, MA_FALSE); - - float finalVolume = volume * m_MasterEffectsVolume; - if (finalVolume > 1.0f) finalVolume = 1.0f; - printf("UI Sound volume set to %f\nEffects volume: %f\n", finalVolume, - m_MasterEffectsVolume); - - ma_sound_set_volume(&s->sound, finalVolume); - ma_sound_set_pitch(&s->sound, pitch); - - ma_sound_start(&s->sound); - - m_activeSounds.push_back(s); } int SoundEngine::getMusicID(int iDomain) { @@ -507,142 +483,102 @@ void SoundEngine::playMusicTick() { switch (m_StreamState) { case eMusicStreamState_Idle: - - // start a stream playing if (m_iMusicDelay > 0) { m_iMusicDelay--; return; } if (m_musicStreamActive) { - app.DebugPrintf( - "WARNING: m_musicStreamActive already true in Idle state, " - "resetting to Playing\n"); m_StreamState = eMusicStreamState_Playing; return; } if (m_musicID != -1) { - // start playing it + bool isCD = (m_musicID >= m_iStream_CD_1); + const char* folder = isCD ? "cds/" : "music/"; + const char* trackName = m_szStreamFileA[m_musicID]; + const char* extensions[] = {".ogg", ".mp3", ".wav"}; - strcpy((char*)m_szStreamName, m_szMusicPath); - // are we using a mash-up pack? - // if(pMinecraft && !pMinecraft->skins->isUsingDefaultSkin() && - // pMinecraft->skins->getSelected()->hasAudio()) + bool found = false; + m_szStreamName[0] = '\0'; + + // DLC Mashup pack check if (Minecraft::GetInstance() ->skins->getSelected() ->hasAudio()) { - // It's a mash-up - need to use the DLC path for the music TexturePack* pTexPack = Minecraft::GetInstance()->skins->getSelected(); - DLCTexturePack* pDLCTexPack = (DLCTexturePack*)pTexPack; - DLCPack* pack = pDLCTexPack->getDLCInfoParentPack(); + DLCPack* pack = + ((DLCTexturePack*)pTexPack)->getDLCInfoParentPack(); DLCAudioFile* dlcAudioFile = (DLCAudioFile*)pack->getFile( DLCManager::e_DLCType_Audio, 0); - app.DebugPrintf("Mashup pack \n"); - - // build the name - - // if the music ID is beyond the end of the texture pack - // music files, then it's a CD - if (m_musicID < m_iStream_CD_1) { - SetIsPlayingStreamingGameMusic(true); - SetIsPlayingStreamingCDMusic(false); + if (!isCD) { m_MusicType = eMusicType_Game; m_StreamingAudioInfo.bIs3D = false; wstring& wstrSoundName = dlcAudioFile->GetSoundName(m_musicID); - char szName[255]; wcstombs(szName, wstrSoundName.c_str(), 255); - string strFile = + std::string strFile = "TPACK:\\Data\\" + string(szName) + ".wav"; - std::string mountedPath = StorageManager.GetMountedPath(strFile); strcpy(m_szStreamName, mountedPath.c_str()); - } else { - SetIsPlayingStreamingGameMusic(false); - SetIsPlayingStreamingCDMusic(true); - m_MusicType = eMusicType_CD; - m_StreamingAudioInfo.bIs3D = true; - // Need to adjust to index into the cds in the game's - // m_szStreamFileA - strcat((char*)m_szStreamName, "cds/"); - strcat((char*)m_szStreamName, - m_szStreamFileA[m_musicID - m_iStream_CD_1 + - eStream_CD_1]); - strcat((char*)m_szStreamName, ".wav"); + if (access(m_szStreamName, F_OK) != -1) found = true; } - } else { - if (m_musicID < m_iStream_CD_1) { - SetIsPlayingStreamingGameMusic(true); - SetIsPlayingStreamingCDMusic(false); - m_MusicType = eMusicType_Game; - m_StreamingAudioInfo.bIs3D = false; - // build the name - strcat((char*)m_szStreamName, "music/"); - } else { - SetIsPlayingStreamingGameMusic(false); - SetIsPlayingStreamingCDMusic(true); - m_MusicType = eMusicType_CD; - m_StreamingAudioInfo.bIs3D = true; - // build the name - strcat((char*)m_szStreamName, "cds/"); - } - strcat((char*)m_szStreamName, m_szStreamFileA[m_musicID]); - strcat((char*)m_szStreamName, ".wav"); } - FILE* pFile = nullptr; - pFile = fopen(reinterpret_cast(m_szStreamName), "rb"); - if (pFile) { - fclose(pFile); - } else { - const char* extensions[] = {".ogg", ".mp3", ".wav"}; - size_t extCount = - sizeof(extensions) / sizeof(extensions[0]); - bool found = false; + // we're doing this again, daring aren't we + if (!found) { + const char* roots[] = { + "build/Minecraft.Client/Common/music/", + "build/Minecraft.Client/music/", "Common/music/", + "music/", "./"}; - char* dotPos = - strrchr(reinterpret_cast(m_szStreamName), '.'); - if (dotPos != nullptr && - (dotPos - reinterpret_cast(m_szStreamName)) < - 250) { - for (size_t i = 0; i < extCount; i++) { - strncpy(dotPos, extensions[i], 5); - app.DebugPrintf("Checking %s\n", m_szStreamName); - pFile = fopen( - reinterpret_cast(m_szStreamName), "rb"); - if (pFile) { - fclose(pFile); + for (const char* root : roots) { + for (const char* ext : extensions) { + char cand[512]; + + // if only i wrote a function that does EXACTLY + // that., nope ctrl c ctrl v it is + snprintf(cand, sizeof(cand), "%s%s%s%s", root, + folder, trackName, ext); + if (access(cand, F_OK) != -1) { + strncpy(m_szStreamName, cand, 511); + found = true; + break; + } + + snprintf(cand, sizeof(cand), "%s%s%s", root, + trackName, ext); + if (access(cand, F_OK) != -1) { + strncpy(m_szStreamName, cand, 511); found = true; break; } } - } - - if (!found) { - if (dotPos != nullptr) { - strncpy(dotPos, ".wav", 5); - } - app.DebugPrintf( - "WARNING: No audio file found for music ID %d " - "(tried .ogg, .mp3, .wav)\n", - m_musicID); - return; + if (found) break; } } - app.DebugPrintf("Starting streaming - %s\n", m_szStreamName); - m_openStreamThread = new C4JThread(OpenStreamThreadProc, this, - "OpenStreamThreadProc"); - m_openStreamThread->Run(); - m_StreamState = eMusicStreamState_Opening; + if (found) { + m_MusicType = isCD ? eMusicType_CD : eMusicType_Game; + m_StreamingAudioInfo.bIs3D = isCD; + SetIsPlayingStreamingGameMusic(!isCD); + SetIsPlayingStreamingCDMusic(isCD); + + m_openStreamThread = new C4JThread( + OpenStreamThreadProc, this, "OpenStreamThreadProc"); + m_openStreamThread->Run(); + m_StreamState = eMusicStreamState_Opening; + } else { + // Retry later if missing + m_iMusicDelay = 20 * 60; + } } break; @@ -651,64 +587,30 @@ void SoundEngine::playMusicTick() { delete m_openStreamThread; m_openStreamThread = nullptr; - app.DebugPrintf( - "OpenStreamThreadProc finished. m_musicStreamActive=%d\n", - m_musicStreamActive); - if (!m_musicStreamActive) { - const char* currentExt = - strrchr(reinterpret_cast(m_szStreamName), '.'); - if (currentExt && _stricmp(currentExt, ".wav") == 0) { - const bool isCD = (m_musicID >= m_iStream_CD_1); - const char* folder = isCD ? "cds/" : "music/"; - - int n = - sprintf_s(reinterpret_cast(m_szStreamName), - 512, "%s%s%s.wav", m_szMusicPath, folder, - m_szStreamFileA[m_musicID]); - - if (n > 0) { - FILE* pFile = fopen( - reinterpret_cast(m_szStreamName), "rb"); - if (pFile) { - fclose(pFile); - - m_openStreamThread = - new C4JThread(OpenStreamThreadProc, this, - "OpenStreamThreadProc"); - m_openStreamThread->Run(); - break; - } - } - } - m_StreamState = eMusicStreamState_Idle; break; } + ma_sound_set_spatialization_enabled( + &m_musicStream, + m_StreamingAudioInfo.bIs3D ? MA_TRUE : MA_FALSE); if (m_StreamingAudioInfo.bIs3D) { - ma_sound_set_spatialization_enabled(&m_musicStream, - MA_TRUE); ma_sound_set_position( &m_musicStream, m_StreamingAudioInfo.x, m_StreamingAudioInfo.y, m_StreamingAudioInfo.z); - } else { - ma_sound_set_spatialization_enabled(&m_musicStream, - MA_FALSE); } ma_sound_set_pitch(&m_musicStream, m_StreamingAudioInfo.pitch); - - float finalVolume = - m_StreamingAudioInfo.volume * getMasterMusicVolume(); - - ma_sound_set_volume(&m_musicStream, finalVolume); - ma_result startResult = ma_sound_start(&m_musicStream); - app.DebugPrintf("ma_sound_start result: %d\n", startResult); + ma_sound_set_volume( + &m_musicStream, + m_StreamingAudioInfo.volume * getMasterMusicVolume()); + ma_sound_start(&m_musicStream); m_StreamState = eMusicStreamState_Playing; } break; + case eMusicStreamState_OpeningCancel: if (!m_openStreamThread->isRunning()) { delete m_openStreamThread; @@ -716,200 +618,130 @@ void SoundEngine::playMusicTick() { m_StreamState = eMusicStreamState_Stop; } break; + case eMusicStreamState_Stop: if (m_musicStreamActive) { ma_sound_stop(&m_musicStream); ma_sound_uninit(&m_musicStream); m_musicStreamActive = false; } - SetIsPlayingStreamingCDMusic(false); SetIsPlayingStreamingGameMusic(false); - m_StreamState = eMusicStreamState_Idle; break; - case eMusicStreamState_Stopping: - break; - case eMusicStreamState_Play: - break; - case eMusicStreamState_Playing: { - static int frameCount = 0; - if (frameCount++ % 60 == 0) { - if (m_musicStreamActive) { - bool isPlaying = ma_sound_is_playing(&m_musicStream); - float vol = ma_sound_get_volume(&m_musicStream); - bool isAtEnd = ma_sound_at_end(&m_musicStream); - } - } - } + + case eMusicStreamState_Playing: if (GetIsPlayingStreamingGameMusic()) { - { - bool playerInEnd = false; - bool playerInNether = false; - Minecraft* pMinecraft = Minecraft::GetInstance(); - for (unsigned int i = 0; i < MAX_LOCAL_PLAYERS; ++i) { - if (pMinecraft->localplayers[i] != nullptr) { - if (pMinecraft->localplayers[i]->dimension == - LevelData::DIMENSION_END) { - playerInEnd = true; - } else if (pMinecraft->localplayers[i]->dimension == - LevelData::DIMENSION_NETHER) { - playerInNether = true; - } - } - } + bool playerInEnd = false, playerInNether = false; + Minecraft* pMinecraft = Minecraft::GetInstance(); - if (playerInEnd && !GetIsPlayingEndMusic()) { - m_StreamState = eMusicStreamState_Stop; - - // Set the end track - m_musicID = getMusicID(LevelData::DIMENSION_END); - SetIsPlayingEndMusic(true); - SetIsPlayingNetherMusic(false); - } else if (!playerInEnd && GetIsPlayingEndMusic()) { - if (playerInNether) { - m_StreamState = eMusicStreamState_Stop; - - // Set the end track - m_musicID = getMusicID(LevelData::DIMENSION_NETHER); - SetIsPlayingEndMusic(false); - SetIsPlayingNetherMusic(true); - } else { - m_StreamState = eMusicStreamState_Stop; - - // Set the end track - m_musicID = - getMusicID(LevelData::DIMENSION_OVERWORLD); - SetIsPlayingEndMusic(false); - SetIsPlayingNetherMusic(false); - } - } else if (playerInNether && !GetIsPlayingNetherMusic()) { - m_StreamState = eMusicStreamState_Stop; - // set the Nether track - m_musicID = getMusicID(LevelData::DIMENSION_NETHER); - SetIsPlayingNetherMusic(true); - SetIsPlayingEndMusic(false); - } else if (!playerInNether && GetIsPlayingNetherMusic()) { - if (playerInEnd) { - m_StreamState = eMusicStreamState_Stop; - // set the Nether track - m_musicID = getMusicID(LevelData::DIMENSION_END); - SetIsPlayingNetherMusic(false); - SetIsPlayingEndMusic(true); - } else { - m_StreamState = eMusicStreamState_Stop; - // set the Nether track - m_musicID = - getMusicID(LevelData::DIMENSION_OVERWORLD); - SetIsPlayingNetherMusic(false); - SetIsPlayingEndMusic(false); - } - } - - // volume change required? - if (m_musicStreamActive) { - float finalVolume = - m_StreamingAudioInfo.volume * fMusicVol; - - ma_sound_set_volume(&m_musicStream, finalVolume); + for (unsigned int i = 0; i < MAX_LOCAL_PLAYERS; ++i) { + if (pMinecraft->localplayers[i]) { + if (pMinecraft->localplayers[i]->dimension == + LevelData::DIMENSION_END) + playerInEnd = true; + else if (pMinecraft->localplayers[i]->dimension == + LevelData::DIMENSION_NETHER) + playerInNether = true; } } - } else { - // Music disc playing - if it's a 3D stream, then set the - // position - we don't have any streaming audio in the world - // that moves, so this isn't required unless we have more than - // one listener, and are setting the listening position to the - // origin and setting a fake position for the sound down the z - // axis - if (m_StreamingAudioInfo.bIs3D && m_validListenerCount > 1) { - int iClosestListener = 0; - float fClosestDist = 1e6f; - for (size_t i = 0; i < MAX_LOCAL_PLAYERS; i++) { - if (m_ListenerA[i].bValid) { - float dx = m_StreamingAudioInfo.x - - m_ListenerA[i].vPosition.x; - float dy = m_StreamingAudioInfo.y - - m_ListenerA[i].vPosition.y; - float dz = m_StreamingAudioInfo.z - - m_ListenerA[i].vPosition.z; - float dist = sqrtf(dx * dx + dy * dy + dz * dz); + // Handle Dimension Switching + bool needsStop = false; + if (playerInEnd && !GetIsPlayingEndMusic()) { + m_musicID = getMusicID(LevelData::DIMENSION_END); + SetIsPlayingEndMusic(true); + SetIsPlayingNetherMusic(false); + needsStop = true; + } else if (!playerInEnd && GetIsPlayingEndMusic()) { + m_musicID = + playerInNether + ? getMusicID(LevelData::DIMENSION_NETHER) + : getMusicID(LevelData::DIMENSION_OVERWORLD); + SetIsPlayingEndMusic(false); + SetIsPlayingNetherMusic(playerInNether); + needsStop = true; + } else if (playerInNether && !GetIsPlayingNetherMusic()) { + m_musicID = getMusicID(LevelData::DIMENSION_NETHER); + SetIsPlayingNetherMusic(true); + SetIsPlayingEndMusic(false); + needsStop = true; + } else if (!playerInNether && GetIsPlayingNetherMusic()) { + m_musicID = + playerInEnd + ? getMusicID(LevelData::DIMENSION_END) + : getMusicID(LevelData::DIMENSION_OVERWORLD); + SetIsPlayingNetherMusic(false); + SetIsPlayingEndMusic(playerInEnd); + needsStop = true; + } - if (dist < fClosestDist) { - fClosestDist = dist; - iClosestListener = i; - } + if (needsStop) m_StreamState = eMusicStreamState_Stop; + + // volume change required? + if (m_musicStreamActive) + ma_sound_set_volume( + &m_musicStream, + m_StreamingAudioInfo.volume * fMusicVol); + + } else if (m_StreamingAudioInfo.bIs3D && m_validListenerCount > 1 && + m_musicStreamActive) { + // incase we're splitscreen + float fClosestDist = 1e6f; + int iClosest = 0; + for (size_t i = 0; i < MAX_LOCAL_PLAYERS; i++) { + if (m_ListenerA[i].bValid) { + float dist = sqrtf(powf(m_StreamingAudioInfo.x - + m_ListenerA[i].vPosition.x, + 2) + + powf(m_StreamingAudioInfo.y - + m_ListenerA[i].vPosition.y, + 2) + + powf(m_StreamingAudioInfo.z - + m_ListenerA[i].vPosition.z, + 2)); + if (dist < fClosestDist) { + fClosestDist = dist; + iClosest = i; } } - - float relX = m_StreamingAudioInfo.x - - m_ListenerA[iClosestListener].vPosition.x; - float relY = m_StreamingAudioInfo.y - - m_ListenerA[iClosestListener].vPosition.y; - float relZ = m_StreamingAudioInfo.z - - m_ListenerA[iClosestListener].vPosition.z; - - if (m_musicStreamActive) { - ma_sound_set_position(&m_musicStream, relX, relY, relZ); - } } + ma_sound_set_position( + &m_musicStream, + m_StreamingAudioInfo.x - m_ListenerA[iClosest].vPosition.x, + m_StreamingAudioInfo.y - m_ListenerA[iClosest].vPosition.y, + m_StreamingAudioInfo.z - m_ListenerA[iClosest].vPosition.z); } - break; - case eMusicStreamState_Completed: { - // random delay of up to 3 minutes for music - m_iMusicDelay = random->nextInt( - 20 * 60 * 3); // random->nextInt(20 * 60 * 10) + 20 * 60 * 10; - // Check if we have a local player in The Nether or in The End, and - // play that music if they are - Minecraft* pMinecraft = Minecraft::GetInstance(); - bool playerInEnd = false; - bool playerInNether = false; + case eMusicStreamState_Completed: + m_iMusicDelay = random->nextInt(20 * 60 * 3); - for (unsigned int i = 0; i < MAX_LOCAL_PLAYERS; i++) { - if (pMinecraft->localplayers[i] != nullptr) { - if (pMinecraft->localplayers[i]->dimension == - LevelData::DIMENSION_END) { - playerInEnd = true; - } else if (pMinecraft->localplayers[i]->dimension == - LevelData::DIMENSION_NETHER) { - playerInNether = true; - } + int dim = LevelData::DIMENSION_OVERWORLD; + Minecraft* pMc = Minecraft::GetInstance(); + for (int i = 0; i < MAX_LOCAL_PLAYERS; i++) { + if (pMc->localplayers[i]) { + dim = pMc->localplayers[i]->dimension; + break; } } - if (playerInEnd) { - m_musicID = getMusicID(LevelData::DIMENSION_END); - SetIsPlayingEndMusic(true); - SetIsPlayingNetherMusic(false); - } else if (playerInNether) { - m_musicID = getMusicID(LevelData::DIMENSION_NETHER); - SetIsPlayingNetherMusic(true); - SetIsPlayingEndMusic(false); - } else { - m_musicID = getMusicID(LevelData::DIMENSION_OVERWORLD); - SetIsPlayingNetherMusic(false); - SetIsPlayingEndMusic(false); - } - + m_musicID = getMusicID(dim); + SetIsPlayingEndMusic(dim == LevelData::DIMENSION_END); + SetIsPlayingNetherMusic(dim == LevelData::DIMENSION_NETHER); m_StreamState = eMusicStreamState_Idle; - } break; + break; } // check the status of the stream - this is for when a track completes // rather than is stopped by the user action - if (m_musicStreamActive) { - if (!ma_sound_is_playing(&m_musicStream) && - ma_sound_at_end(&m_musicStream)) { - ma_sound_uninit(&m_musicStream); - m_musicStreamActive = false; - - SetIsPlayingStreamingCDMusic(false); - SetIsPlayingStreamingGameMusic(false); - - m_StreamState = eMusicStreamState_Completed; - } + if (m_musicStreamActive && !ma_sound_is_playing(&m_musicStream) && + ma_sound_at_end(&m_musicStream)) { + ma_sound_uninit(&m_musicStream); + m_musicStreamActive = false; + SetIsPlayingStreamingCDMusic(false); + SetIsPlayingStreamingGameMusic(false); + m_StreamState = eMusicStreamState_Completed; } } diff --git a/Minecraft.Client/Textures/BufferedImage.cpp b/Minecraft.Client/Textures/BufferedImage.cpp index 5509ea360..236690d5f 100644 --- a/Minecraft.Client/Textures/BufferedImage.cpp +++ b/Minecraft.Client/Textures/BufferedImage.cpp @@ -4,6 +4,12 @@ #include "../../Minecraft.World/Util/ArrayWithLength.h" #include "BufferedImage.h" +#if defined(__linux__) +#include +#endif +#include +#include + #ifdef _XBOX typedef struct { unsigned int filesz; @@ -28,7 +34,7 @@ BufferedImage::BufferedImage(int width, int height, int type) { data[0] = new int[width * height]; for (int i = 1; i < 10; i++) { - data[i] = NULL; + data[i] = nullptr; } this->width = width; this->height = height; @@ -43,136 +49,125 @@ void BufferedImage::ByteFlip4(unsigned int& data) { // the compression method. Compression method 3 is a 32-bit image with only // 24-bits used (ie no alpha channel) whereas method 0 is a full 32-bit image // with a valid alpha channel. + +// 4jcraft: mostly rewrote this function BufferedImage::BufferedImage(const std::wstring& File, - bool filenameHasExtension /*=false*/, - bool bTitleUpdateTexture /*=false*/, - const std::wstring& drive /*=L""*/) { - HRESULT hr; - std::wstring wDrive; - std::wstring filePath; - filePath = File; + bool filenameHasExtension, + bool bTitleUpdateTexture, + const std::wstring& drive) { + HRESULT hr = -1; + std::wstring filePath = File; - wDrive = drive; - if (wDrive.empty()) { -#ifdef _XBOX - if (bTitleUpdateTexture) { - // Make the content package point to to the UPDATE: drive is needed -#ifdef _TU_BUILD - wDrive = L"UPDATE:\\"; -#else + // turn that \ upside down! (grace ref) + for (size_t i = 0; i < filePath.length(); ++i) { + if (filePath[i] == L'\\') filePath[i] = L'/'; + } + for (int l = 0; l < 10; l++) data[l] = nullptr; - wDrive = L"GAME:\\res\\TitleUpdate\\"; -#endif - } else { - wDrive = L"GAME:\\"; + // clean the filename + std::wstring baseName = filePath; + if (!filenameHasExtension) { + if (baseName.size() > 4 && + baseName.substr(baseName.size() - 4) == L".png") { + baseName = baseName.substr(0, baseName.size() - 4); } -#else - -#ifdef __PS3__ - - char* pchUsrDir; - if (app.GetBootedFromDiscPatch()) { - const char* pchTextureName = wstringtofilename(File); - pchUsrDir = app.GetBDUsrDirPath(pchTextureName); - } else { - pchUsrDir = getUsrDirPath(); - } - - std::wstring wstr(pchUsrDir, pchUsrDir + strlen(pchUsrDir)); - - if (bTitleUpdateTexture) { - // Make the content package point to to the UPDATE: drive is needed - wDrive = wstr + L"\\Common\\res\\TitleUpdate\\"; - } else { - wDrive = wstr + L"/Common/"; - } -#elif __PSVITA__ - - /*char *pchUsrDir=getUsrDirPath(); - - wstring wstr (pchUsrDir, pchUsrDir+strlen(pchUsrDir)); - - if(bTitleUpdateTexture) - { - // Make the content package point to to the UPDATE: drive is - needed wDrive= wstr + L"\\Common\\res\\TitleUpdate\\"; - } - else - { - wDrive= wstr + L"/Common/"; - }*/ - - if (bTitleUpdateTexture) { - // Make the content package point to to the UPDATE: drive is needed - wDrive = L"Common\\res\\TitleUpdate\\"; - } else { - wDrive = L"Common/"; - } -#else - if (bTitleUpdateTexture) { - // Make the content package point to to the UPDATE: drive is needed - wDrive = L"Common\\res\\TitleUpdate\\"; - } else { - wDrive = L"Common/"; - } -#endif - -#endif } - for (int l = 0; l < 10; l++) { - data[l] = NULL; - } + // avoid // mess + while (!baseName.empty() && baseName[0] == L'/') + baseName = baseName.substr(1); + if (baseName.find(L"res/") == 0) baseName = baseName.substr(4); + // bad code alert + // loops through stuff on the drives because i don't fucking know what 4j + // did with the paths and i don't to break it.. for (int l = 0; l < 10; l++) { - std::wstring name; - std::wstring mipMapPath = L""; - if (l != 0) { - mipMapPath = L"MipMapLevel" + _toString(l + 1); - } - if (filenameHasExtension) { - name = wDrive + L"res" + filePath.substr(0, filePath.length()); - } else { - name = wDrive + L"res" + filePath.substr(0, filePath.length() - 4) + - mipMapPath + L".png"; + std::wstring mipSuffix = + (l != 0) ? L"MipMapLevel" + _toString(l + 1) : L""; + std::wstring fileName = baseName + mipSuffix + L".png"; + + bool foundOnDisk = false; + std::wstring finalPath; + + // i tried everything i can think of. + std::vector searchPaths = { + L"build/Minecraft.Client/Common/res/TitleUpdate/res/" + fileName, + L"build/Minecraft.Client/Common/res/" + fileName, + L"build/Minecraft.Client/Common/Media/" + fileName, + L"Common/res/TitleUpdate/res/" + fileName, + L"Common/res/" + fileName, + L"Minecraft.Assets/Common/res/TitleUpdate/res/" + fileName}; + + if (!drive.empty()) { + std::wstring drivePath = drive; + if (drivePath.back() != L'/') drivePath += L'/'; + searchPaths.push_back(drivePath + fileName); + searchPaths.push_back(drivePath + L"res/" + fileName); } - const char* pchTextureName = wstringtofilename(name); + for (auto& attempt : searchPaths) { + size_t p; + while ((p = attempt.find(L"//")) != std::wstring::npos) + attempt.replace(p, 2, L"/"); -#ifndef _CONTENT_PACKAGE - app.DebugPrintf("\n--- Loading TEXTURE - %s\n\n", pchTextureName); +#if defined(__linux__) + if (access(wstringtofilename(attempt), F_OK) != -1) { + finalPath = attempt; + foundOnDisk = true; + break; + } #endif + } D3DXIMAGE_INFO ImageInfo; ZeroMemory(&ImageInfo, sizeof(D3DXIMAGE_INFO)); - hr = - RenderManager.LoadTextureData(pchTextureName, &ImageInfo, &data[l]); - if (hr != ERROR_SUCCESS) { - // 4J - If we haven't loaded the non-mipmap version then exit the - // game - if (l == 0) { - app.FatalLoadError(); + if (foundOnDisk) { + hr = RenderManager.LoadTextureData(wstringtofilename(finalPath), + &ImageInfo, &data[l]); + } else { + // if everything fails just try the archive maybe theres something + // in it + std::wstring archiveKey = L"res/" + fileName; + if (app.hasArchiveFile(archiveKey)) { + byteArray ba = app.getArchiveFile(archiveKey); + hr = RenderManager.LoadTextureData(ba.data, ba.length, + &ImageInfo, &data[l]); } - return; } - if (l == 0) { - width = ImageInfo.Width; - height = ImageInfo.Height; + if (hr == ERROR_SUCCESS) { + if (l == 0) { + width = ImageInfo.Width; + height = ImageInfo.Height; + } + } else { + if (l == 0) { + app.DebugPrintf("[Texture Warning] Missing asset: %S\n", + fileName.c_str()); + // We MUST initialize width/height to avoid the program being a + // crybaby and crash + width = 1; + height = 1; + // Create a tiny missingno buffer so the rest of the game loads + // without crashing up + data[0] = new int[1]; + data[0][0] = 0xFFFF00FF; + } + break; } } } BufferedImage::BufferedImage(DLCPack* dlcPack, const std::wstring& File, - bool filenameHasExtension /*= false*/) { + bool filenameHasExtension) { HRESULT hr; std::wstring filePath = File; - std::uint8_t* pbData = NULL; + std::uint8_t* pbData = nullptr; std::uint32_t dataBytes = 0; for (int l = 0; l < 10; l++) { - data[l] = NULL; + data[l] = nullptr; } for (int l = 0; l < 10; l++) { @@ -199,12 +194,8 @@ BufferedImage::BufferedImage(DLCPack* dlcPack, const std::wstring& File, DLCFile* dlcFile = dlcPack->getFile(DLCManager::e_DLCType_All, name); pbData = dlcFile->getData(dataBytes); - if (pbData == NULL || dataBytes == 0) { - // 4J - If we haven't loaded the non-mipmap version then exit the - // game - if (l == 0) { - app.FatalLoadError(); - } + if (pbData == nullptr || dataBytes == 0) { + if (l == 0) app.FatalLoadError(); return; } @@ -214,10 +205,54 @@ BufferedImage::BufferedImage(DLCPack* dlcPack, const std::wstring& File, &data[l]); if (hr != ERROR_SUCCESS) { - // 4J - If we haven't loaded the non-mipmap version then exit the - // game if (l == 0) { - app.FatalLoadError(); + std::wstring wname = L"res" + + filePath.substr(0, filePath.length() - 4) + + L".png"; + std::vector candidates; + candidates.push_back(wname); + if (wname.rfind(L"Common/res/", 0) == 0) { + candidates.push_back( + wname.substr(std::wstring(L"Common/res/").length())); + } + candidates.push_back(filePath); + if (!filePath.empty() && filePath[0] == L'/') + candidates.push_back(filePath.substr(1)); + + std::wstring baseName2; + size_t posSlash2 = filePath.find_last_of(L"/\\"); + if (posSlash2 == std::wstring::npos) + baseName2 = filePath; + else + baseName2 = filePath.substr(posSlash2 + 1); + // same thing but for the fonts.. i found a way to make this + // less horrible but im lazy sorry :/ + if (!baseName2.empty()) { + candidates.insert(candidates.begin(), + L"Common/Res/Font/" + baseName2); + candidates.push_back(L"font/" + baseName2); + candidates.push_back(L"font\\" + baseName2); + candidates.push_back(L"res/font/" + baseName2); + candidates.push_back(L"Common/res/font/" + baseName2); + candidates.push_back(L"Common/Res/Font/" + baseName2); + } + + bool loaded = false; + for (auto& key : candidates) { + if (key.empty()) continue; + if (app.hasArchiveFile(key)) { + byteArray ba = app.getArchiveFile(key); + if (ba.data != nullptr && ba.length > 0) { + hr = RenderManager.LoadTextureData( + ba.data, ba.length, &ImageInfo, &data[l]); + if (hr == ERROR_SUCCESS) { + loaded = true; + break; + } + } + } + } + if (!loaded) app.FatalLoadError(); } return; } @@ -230,9 +265,8 @@ BufferedImage::BufferedImage(DLCPack* dlcPack, const std::wstring& File, } BufferedImage::BufferedImage(std::uint8_t* pbData, std::uint32_t dataBytes) { - int iCurrentByte = 0; for (int l = 0; l < 10; l++) { - data[l] = NULL; + data[l] = nullptr; } D3DXIMAGE_INFO ImageInfo; @@ -273,7 +307,7 @@ int* BufferedImage::getData() { return data[0]; } int* BufferedImage::getData(int level) { return data[level]; } -Graphics* BufferedImage::getGraphics() { return NULL; } +Graphics* BufferedImage::getGraphics() { return nullptr; } // Returns the transparency. Returns either OPAQUE, BITMASK, or TRANSLUCENT. // Specified by: @@ -299,14 +333,15 @@ BufferedImage* BufferedImage::getSubimage(int x, int y, int w, int h) { this->getRGB(x, y, w, h, arrayWrapper, 0, w); int level = 1; - while (getData(level) != NULL) { + // prevent overflow + while (level < 10 && getData(level) != nullptr) { int ww = w >> level; int hh = h >> level; int xx = x >> level; int yy = y >> level; img->data[level] = new int[ww * hh]; - intArray arrayWrapper(img->data[level], ww * hh); - this->getRGB(xx, yy, ww, hh, arrayWrapper, 0, ww, level); + intArray levelWrapper(img->data[level], ww * hh); + this->getRGB(xx, yy, ww, hh, levelWrapper, 0, ww, level); ++level; } @@ -324,7 +359,8 @@ void BufferedImage::preMultiplyAlpha() { int b = 0; int total = width * height; - for (unsigned int i = 0; i < total; ++i) { + // why was it unsigned?? + for (int i = 0; i < total; ++i) { cur = curData[i]; alpha = (cur >> 24) & 0xff; r = ((cur >> 16) & 0xff) * (float)alpha / 255; diff --git a/Minecraft.World/IO/Files/File.cpp b/Minecraft.World/IO/Files/File.cpp index e5bff5c98..7567d80d1 100644 --- a/Minecraft.World/IO/Files/File.cpp +++ b/Minecraft.World/IO/Files/File.cpp @@ -57,33 +57,44 @@ File::File(const File& parent, const std::wstring& child) { // Creates a new File instance by converting the given pathname string into an // abstract pathname. -File::File(const std::wstring& pathname) //: parent( NULL ) -{ - // #ifndef _CONTENT_PACKAGE - // char buf[256]; - // wcstombs(buf, pathname.c_str(), 256); - // printf("File::File - %s\n",buf); - // #endif - if (pathname.empty()) - m_abstractPathName = std::wstring(L""); - else - m_abstractPathName = pathname; +File::File(const std::wstring& pathname) { + if (pathname.empty()) { + m_abstractPathName = L""; + return; + } + // same thing as in bufferedoverflow + std::wstring fixedPath = pathname; + + for (size_t i = 0; i < fixedPath.length(); ++i) { + if (fixedPath[i] == L'\\') fixedPath[i] = L'/'; + } + + size_t dpos; + while ((dpos = fixedPath.find(L"//")) != std::wstring::npos) + fixedPath.erase(dpos, 1); + if (fixedPath.find(L"GAME:/") == 0) fixedPath = fixedPath.substr(6); + + m_abstractPathName = fixedPath; #if defined(__linux__) // If this is a relative path and it doesn't exist in the CWD, try to - // resolve it relative to the executable directory + // resolve it relative to the executable directory if (!m_abstractPathName.empty() && m_abstractPathName[0] != L'/') { const char* native = wstringtofilename(m_abstractPathName); if (access(native, F_OK) == -1) { char exePathBuf[PATH_MAX]; - ssize_t exeLen = readlink("/proc/self/exe", exePathBuf, sizeof(exePathBuf) - 1); + ssize_t exeLen = + readlink("/proc/self/exe", exePathBuf, sizeof(exePathBuf) - 1); if (exeLen != -1) { exePathBuf[exeLen] = '\0'; std::string exePathStr(exePathBuf); size_t pos = exePathStr.find_last_of('/'); - std::string exeDir = (pos == std::string::npos) ? std::string(".") : exePathStr.substr(0, pos); + std::string exeDir = (pos == std::string::npos) + ? std::string(".") + : exePathStr.substr(0, pos); std::wstring exeDirW = convStringToWstring(exeDir); - std::wstring candidate = exeDirW + pathSeparator + m_abstractPathName; + std::wstring candidate = + exeDirW + pathSeparator + m_abstractPathName; const char* candNative = wstringtofilename(candidate); if (access(candNative, F_OK) != -1) { m_abstractPathName = candidate; diff --git a/meson.build b/meson.build index cd2b7daa8..767f1a4f5 100644 --- a/meson.build +++ b/meson.build @@ -1,4 +1,4 @@ -project('4jcraft-chucklegrounds', ['cpp', 'c'], +project('4jcraft', ['cpp', 'c'], version : '0.1.0', meson_version: '>= 1.7', default_options : [ From 21fc2166ffe0cc3fd5a5579a748d2d88f154a33a Mon Sep 17 00:00:00 2001 From: JuiceyDev Date: Fri, 27 Mar 2026 20:54:21 +0100 Subject: [PATCH 023/170] cleaned up, less hacky, more silly --- .../Platform/Common/Audio/SoundEngine.cpp | 244 +++++++----------- .../Platform/Common/Consoles_App.cpp | 12 +- Minecraft.Client/Textures/BufferedImage.cpp | 132 ++-------- Minecraft.Client/meson.build | 2 +- Minecraft.World/IO/Files/File.cpp | 59 +++-- Minecraft.World/Platform/PathHelper.h | 37 +++ 6 files changed, 186 insertions(+), 300 deletions(-) create mode 100644 Minecraft.World/Platform/PathHelper.h diff --git a/Minecraft.Client/Platform/Common/Audio/SoundEngine.cpp b/Minecraft.Client/Platform/Common/Audio/SoundEngine.cpp index fa53701b9..557bd4478 100644 --- a/Minecraft.Client/Platform/Common/Audio/SoundEngine.cpp +++ b/Minecraft.Client/Platform/Common/Audio/SoundEngine.cpp @@ -1,6 +1,6 @@ #include "../../Minecraft.World/Platform/stdafx.h" - #include "SoundEngine.h" +#include "PathHelper.h" #include "../Consoles_App.h" #include "../../Minecraft.Client/Player/MultiPlayerLocalPlayer.h" #include "../../Minecraft.World/Headers/net.minecraft.world.level.h" @@ -188,69 +188,51 @@ void SoundEngine::init(Options* pOptions) { m_bSystemMusicPlaying = false; } void SoundEngine::destroy() { ma_engine_uninit(&m_engine); } + void SoundEngine::play(int iSound, float x, float y, float z, float volume, float pitch) { if (iSound == -1) return; + char szId[256]; + wcstombs(szId, wchSoundNames[iSound], 255); + for (int i = 0; szId[i]; i++) + if (szId[i] == '.') szId[i] = '/'; - char szIdentifier[256]; - wcstombs(szIdentifier, wchSoundNames[iSound], 255); - - // dot to folder structure (example step.grass -> step/grass) - for (int i = 0; szIdentifier[i]; i++) { - if (szIdentifier[i] == '.') szIdentifier[i] = '/'; - } - // YES I KNOW SOUNDNAMES.CPP EXISTS. - const char* extensions[] = {".ogg", ".wav", ".mp3"}; - const char* roots[] = {"Sound/Minecraft/", - "build/Minecraft.Client/Sound/Minecraft/", - "Common/Sound/Minecraft/", + std::string base = PathHelper::GetExecutableDirA() + "/"; + const char* roots[] = {"Sound/Minecraft/", "Common/Sound/Minecraft/", "Common/res/TitleUpdate/res/Sound/Minecraft/"}; - char finalPath[512] = {0}; bool found = false; - // search for variants (grass1, grass2, etc.) - // this is hacky + for (const char* root : roots) { - for (const char* ext : extensions) { - int maxVariant = 0; + std::string fullRoot = base + root; + for (const char* ext : {".ogg", ".wav"}) { + int count = 0; for (int i = 1; i <= 16; i++) { - char tryPath[512]; - snprintf(tryPath, sizeof(tryPath), "%s%s%d%s", root, - szIdentifier, i, ext); - if (access(tryPath, F_OK) != -1) - maxVariant = i; + char tryP[512]; + snprintf(tryP, 512, "%s%s%d%s", fullRoot.c_str(), szId, i, ext); + if (access(tryP, F_OK) != -1) + count = i; else break; } - - if (maxVariant > 0) { - int chosen = (rand() % maxVariant) + 1; - snprintf(finalPath, sizeof(finalPath), "%s%s%d%s", root, - szIdentifier, chosen, ext); + if (count > 0) { + snprintf(finalPath, 512, "%s%s%d%s", fullRoot.c_str(), szId, + (rand() % count) + 1, ext); + found = true; + break; + } + char tryP[512]; + snprintf(tryP, 512, "%s%s%s", fullRoot.c_str(), szId, ext); + if (access(tryP, F_OK) != -1) { + strncpy(finalPath, tryP, 511); found = true; break; } } if (found) break; } - if (!found) { - for (const char* root : roots) { - for (const char* ext : extensions) { - char tryPath[512]; - snprintf(tryPath, sizeof(tryPath), "%s%s%s", root, szIdentifier, - ext); - if (access(tryPath, F_OK) != -1) { - strncpy(finalPath, tryPath, 511); - found = true; - break; - } - } - if (found) break; - } - } if (!found) return; - MiniAudioSound* s = new MiniAudioSound(); memset(&s->info, 0, sizeof(AUDIO_INFO)); s->info.x = x; @@ -266,43 +248,38 @@ void SoundEngine::play(int iSound, float x, float y, float z, float volume, ma_sound_set_min_distance(&s->sound, 2.0f); ma_sound_set_max_distance(&s->sound, 48.0f); ma_sound_set_volume(&s->sound, volume * m_MasterEffectsVolume); - ma_sound_set_pitch(&s->sound, pitch); ma_sound_set_position(&s->sound, x, y, z); ma_sound_start(&s->sound); m_activeSounds.push_back(s); - } else { + } else delete s; - } } void SoundEngine::playUI(int iSound, float volume, float pitch) { char szIdentifier[256]; - if (iSound >= eSFX_MAX) { + if (iSound >= eSFX_MAX) wcstombs(szIdentifier, wchSoundNames[iSound], 255); - } else { + else wcstombs(szIdentifier, wchUISoundNames[iSound], 255); - } - - for (int i = 0; szIdentifier[i]; i++) { + for (int i = 0; szIdentifier[i]; i++) if (szIdentifier[i] == '.') szIdentifier[i] = '/'; - } - // ui sfx also WHO WHO THAT EWWW - const char* extensions[] = {".ogg", ".wav", ".mp3"}; - const char* roots[] = {"Sound/Minecraft/UI/", "Sound/Minecraft/", - "build/Minecraft.Client/Sound/Minecraft/UI/", - "build/Minecraft.Client/Sound/Minecraft/", - "Common/Sound/Minecraft/UI/"}; - + std::string base = PathHelper::GetExecutableDirA() + "/"; + const char* roots[] = { + "Sound/Minecraft/UI/", + "Sound/Minecraft/", + "Common/Sound/Minecraft/UI/", + "Common/Sound/Minecraft/", + }; char finalPath[512] = {0}; bool found = false; for (const char* root : roots) { - for (const char* ext : extensions) { - char tryPath[512]; - snprintf(tryPath, sizeof(tryPath), "%s%s%s", root, szIdentifier, + for (const char* ext : {".ogg", ".wav", ".mp3"}) { + char tryP[512]; + snprintf(tryP, 512, "%s%s%s%s", base.c_str(), root, szIdentifier, ext); - if (access(tryPath, F_OK) != -1) { - strncpy(finalPath, tryPath, 511); + if (access(tryP, F_OK) != -1) { + strncpy(finalPath, tryP, 511); found = true; break; } @@ -311,7 +288,6 @@ void SoundEngine::playUI(int iSound, float volume, float pitch) { } if (!found) return; - MiniAudioSound* s = new MiniAudioSound(); memset(&s->info, 0, sizeof(AUDIO_INFO)); s->info.volume = volume; @@ -325,9 +301,8 @@ void SoundEngine::playUI(int iSound, float volume, float pitch) { ma_sound_set_pitch(&s->sound, pitch); ma_sound_start(&s->sound); m_activeSounds.push_back(s); - } else { + } else delete s; - } } int SoundEngine::getMusicID(int iDomain) { @@ -344,9 +319,10 @@ int SoundEngine::getMusicID(int iDomain) { if (pMinecraft->skins->isUsingDefaultSkin()) { switch (iDomain) { case LevelData::DIMENSION_END: - // the end isn't random - it has different music depending on - // whether the dragon is alive or not, but we've not added the - // dead dragon music yet + // the end isn't random - it has different music depending + // whether the dragon is alive or not, but we've not + // added the dead dragon music yet + // haha they said wheter return m_iStream_End_Min; case LevelData::DIMENSION_NETHER: return GetRandomishTrack(m_iStream_Nether_Min, @@ -464,7 +440,8 @@ int SoundEngine::OpenStreamThreadProc(void* lpParameter) { if (result != MA_SUCCESS) { app.DebugPrintf( - "SoundEngine::OpenStreamThreadProc - Failed to open stream: %s\n", + "SoundEngine::OpenStreamThreadProc - Failed to open stream: " + "%s\n", soundEngine->m_szStreamName); return 0; } @@ -476,7 +453,6 @@ int SoundEngine::OpenStreamThreadProc(void* lpParameter) { return 0; } - void SoundEngine::playMusicTick() { static float fMusicVol = 0.0f; fMusicVol = getMasterMusicVolume(); @@ -487,96 +463,51 @@ void SoundEngine::playMusicTick() { m_iMusicDelay--; return; } - - if (m_musicStreamActive) { - m_StreamState = eMusicStreamState_Playing; - return; - } - if (m_musicID != -1) { + std::string base = PathHelper::GetExecutableDirA() + "/"; bool isCD = (m_musicID >= m_iStream_CD_1); const char* folder = isCD ? "cds/" : "music/"; - const char* trackName = m_szStreamFileA[m_musicID]; - const char* extensions[] = {".ogg", ".mp3", ".wav"}; - + const char* track = m_szStreamFileA[m_musicID]; bool found = false; m_szStreamName[0] = '\0'; - // DLC Mashup pack check - if (Minecraft::GetInstance() - ->skins->getSelected() - ->hasAudio()) { - TexturePack* pTexPack = - Minecraft::GetInstance()->skins->getSelected(); - DLCPack* pack = - ((DLCTexturePack*)pTexPack)->getDLCInfoParentPack(); - DLCAudioFile* dlcAudioFile = (DLCAudioFile*)pack->getFile( - DLCManager::e_DLCType_Audio, 0); + const char* roots[] = {"Common/music/", "music/", "./"}; - if (!isCD) { - m_MusicType = eMusicType_Game; - m_StreamingAudioInfo.bIs3D = false; - - wstring& wstrSoundName = - dlcAudioFile->GetSoundName(m_musicID); - char szName[255]; - wcstombs(szName, wstrSoundName.c_str(), 255); - - std::string strFile = - "TPACK:\\Data\\" + string(szName) + ".wav"; - std::string mountedPath = - StorageManager.GetMountedPath(strFile); - strcpy(m_szStreamName, mountedPath.c_str()); - - if (access(m_szStreamName, F_OK) != -1) found = true; - } - } - - // we're doing this again, daring aren't we - if (!found) { - const char* roots[] = { - "build/Minecraft.Client/Common/music/", - "build/Minecraft.Client/music/", "Common/music/", - "music/", "./"}; - - for (const char* root : roots) { - for (const char* ext : extensions) { - char cand[512]; - - // if only i wrote a function that does EXACTLY - // that., nope ctrl c ctrl v it is - snprintf(cand, sizeof(cand), "%s%s%s%s", root, - folder, trackName, ext); - if (access(cand, F_OK) != -1) { - strncpy(m_szStreamName, cand, 511); - found = true; - break; - } - - snprintf(cand, sizeof(cand), "%s%s%s", root, - trackName, ext); - if (access(cand, F_OK) != -1) { - strncpy(m_szStreamName, cand, 511); - found = true; - break; - } + for (const char* r : roots) { + for (const char* e : {".ogg", ".mp3", ".wav"}) { + char c[512]; + // try with folder prefix (music/ or cds/) + snprintf(c, 512, "%s%s%s%s%s", base.c_str(), r, folder, + track, e); + if (access(c, F_OK) != -1) { + strncpy(m_szStreamName, c, 511); + found = true; + break; + } + // try without folder prefix + snprintf(c, 512, "%s%s%s%s", base.c_str(), r, track, e); + if (access(c, F_OK) != -1) { + strncpy(m_szStreamName, c, 511); + found = true; + break; } - if (found) break; } + if (found) break; } if (found) { - m_MusicType = isCD ? eMusicType_CD : eMusicType_Game; - m_StreamingAudioInfo.bIs3D = isCD; SetIsPlayingStreamingGameMusic(!isCD); SetIsPlayingStreamingCDMusic(isCD); - m_openStreamThread = new C4JThread( OpenStreamThreadProc, this, "OpenStreamThreadProc"); m_openStreamThread->Run(); m_StreamState = eMusicStreamState_Opening; } else { - // Retry later if missing + app.DebugPrintf( + "[SoundEngine] oh noes couldn't find music track '%s', " + "retrying " + "in 1min\n", + track); m_iMusicDelay = 20 * 60; } } @@ -686,7 +617,6 @@ void SoundEngine::playMusicTick() { } else if (m_StreamingAudioInfo.bIs3D && m_validListenerCount > 1 && m_musicStreamActive) { - // incase we're splitscreen float fClosestDist = 1e6f; int iClosest = 0; for (size_t i = 0; i < MAX_LOCAL_PLAYERS; i++) { @@ -716,18 +646,19 @@ void SoundEngine::playMusicTick() { case eMusicStreamState_Completed: m_iMusicDelay = random->nextInt(20 * 60 * 3); - - int dim = LevelData::DIMENSION_OVERWORLD; - Minecraft* pMc = Minecraft::GetInstance(); - for (int i = 0; i < MAX_LOCAL_PLAYERS; i++) { - if (pMc->localplayers[i]) { - dim = pMc->localplayers[i]->dimension; - break; + { + int dim = LevelData::DIMENSION_OVERWORLD; + Minecraft* pMc = Minecraft::GetInstance(); + for (int i = 0; i < MAX_LOCAL_PLAYERS; i++) { + if (pMc->localplayers[i]) { + dim = pMc->localplayers[i]->dimension; + break; + } } + m_musicID = getMusicID(dim); + SetIsPlayingEndMusic(dim == LevelData::DIMENSION_END); + SetIsPlayingNetherMusic(dim == LevelData::DIMENSION_NETHER); } - m_musicID = getMusicID(dim); - SetIsPlayingEndMusic(dim == LevelData::DIMENSION_END); - SetIsPlayingNetherMusic(dim == LevelData::DIMENSION_NETHER); m_StreamState = eMusicStreamState_Idle; break; } @@ -2134,7 +2065,8 @@ F32 AILCALLBACK custom_falloff_function(HSAMPLE S, F32 distance, } #endif -// Universal, these functions shouldn't need platform specific implementations +// Universal, these functions shouldn't need platform specific +// implementations void SoundEngine::updateMusicVolume(float fVal) { m_MasterMusicVolume = fVal; } void SoundEngine::updateSystemMusicPlaying(bool isPlaying) { m_bSystemMusicPlaying = isPlaying; diff --git a/Minecraft.Client/Platform/Common/Consoles_App.cpp b/Minecraft.Client/Platform/Common/Consoles_App.cpp index 5eb204c95..afe871205 100644 --- a/Minecraft.Client/Platform/Common/Consoles_App.cpp +++ b/Minecraft.Client/Platform/Common/Consoles_App.cpp @@ -54,7 +54,7 @@ #include "../Minecraft.Client/Minecraft.h" #if defined(__linux__) #include -#include +#include #endif #ifdef _XBOX #include "../Minecraft.Client/Platform/Xbox/GameConfig/Minecraft.spa.h" @@ -4606,18 +4606,22 @@ void CMinecraftApp::loadMediaArchive() { if (!mediapath.empty()) { // (check file.cpp) // try to load the archive relative to the executable - // directory first. + // directory first. // If that fails, fall back to the current working // directory (original behavior) // if everything fails, may god help you #if defined(__linux__) + // THIS CAN USE PATHHELPER.h char exePathBuf[PATH_MAX]; - ssize_t exeLen = readlink("/proc/self/exe", exePathBuf, sizeof(exePathBuf) - 1); + ssize_t exeLen = + readlink("/proc/self/exe", exePathBuf, sizeof(exePathBuf) - 1); if (exeLen != -1) { exePathBuf[exeLen] = '\0'; std::string exePathStr(exePathBuf); size_t pos = exePathStr.find_last_of('/'); - std::string exeDir = (pos == std::string::npos) ? std::string(".") : exePathStr.substr(0, pos); + std::string exeDir = (pos == std::string::npos) + ? std::string(".") + : exePathStr.substr(0, pos); std::wstring exeDirW = convStringToWstring(exeDir.c_str()); std::wstring candidate = exeDirW + File::pathSeparator + mediapath; if (File(candidate).exists()) { diff --git a/Minecraft.Client/Textures/BufferedImage.cpp b/Minecraft.Client/Textures/BufferedImage.cpp index 236690d5f..7981e60d7 100644 --- a/Minecraft.Client/Textures/BufferedImage.cpp +++ b/Minecraft.Client/Textures/BufferedImage.cpp @@ -1,9 +1,9 @@ #include "../Platform/stdafx.h" #include "../../Minecraft.World/Util/StringHelpers.h" #include "Textures.h" +#include "PathHelper.h" #include "../../Minecraft.World/Util/ArrayWithLength.h" #include "BufferedImage.h" - #if defined(__linux__) #include #endif @@ -58,13 +58,11 @@ BufferedImage::BufferedImage(const std::wstring& File, HRESULT hr = -1; std::wstring filePath = File; - // turn that \ upside down! (grace ref) for (size_t i = 0; i < filePath.length(); ++i) { if (filePath[i] == L'\\') filePath[i] = L'/'; } for (int l = 0; l < 10; l++) data[l] = nullptr; - // clean the filename std::wstring baseName = filePath; if (!filenameHasExtension) { if (baseName.size() > 4 && @@ -73,50 +71,36 @@ BufferedImage::BufferedImage(const std::wstring& File, } } - // avoid // mess - while (!baseName.empty() && baseName[0] == L'/') + while (!baseName.empty() && (baseName[0] == L'/' || baseName[0] == L'\\')) baseName = baseName.substr(1); if (baseName.find(L"res/") == 0) baseName = baseName.substr(4); - // bad code alert - // loops through stuff on the drives because i don't fucking know what 4j - // did with the paths and i don't to break it.. + std::wstring exeDir = PathHelper::GetExecutableDirW(); + for (int l = 0; l < 10; l++) { std::wstring mipSuffix = (l != 0) ? L"MipMapLevel" + _toString(l + 1) : L""; std::wstring fileName = baseName + mipSuffix + L".png"; - - bool foundOnDisk = false; std::wstring finalPath; + bool foundOnDisk = false; - // i tried everything i can think of. std::vector searchPaths = { - L"build/Minecraft.Client/Common/res/TitleUpdate/res/" + fileName, - L"build/Minecraft.Client/Common/res/" + fileName, - L"build/Minecraft.Client/Common/Media/" + fileName, - L"Common/res/TitleUpdate/res/" + fileName, - L"Common/res/" + fileName, - L"Minecraft.Assets/Common/res/TitleUpdate/res/" + fileName}; - - if (!drive.empty()) { - std::wstring drivePath = drive; - if (drivePath.back() != L'/') drivePath += L'/'; - searchPaths.push_back(drivePath + fileName); - searchPaths.push_back(drivePath + L"res/" + fileName); - } + exeDir + L"/Common/res/TitleUpdate/res/" + fileName, + exeDir + L"/Common/res/" + fileName, + exeDir + L"/Common/Media/Graphics/" + fileName, + exeDir + L"/Common/Media/font/" + fileName, + exeDir + L"/Common/res/font/" + fileName, + exeDir + L"/Common/Media/" + fileName}; for (auto& attempt : searchPaths) { size_t p; while ((p = attempt.find(L"//")) != std::wstring::npos) attempt.replace(p, 2, L"/"); - -#if defined(__linux__) if (access(wstringtofilename(attempt), F_OK) != -1) { finalPath = attempt; foundOnDisk = true; break; } -#endif } D3DXIMAGE_INFO ImageInfo; @@ -126,8 +110,6 @@ BufferedImage::BufferedImage(const std::wstring& File, hr = RenderManager.LoadTextureData(wstringtofilename(finalPath), &ImageInfo, &data[l]); } else { - // if everything fails just try the archive maybe theres something - // in it std::wstring archiveKey = L"res/" + fileName; if (app.hasArchiveFile(archiveKey)) { byteArray ba = app.getArchiveFile(archiveKey); @@ -143,14 +125,9 @@ BufferedImage::BufferedImage(const std::wstring& File, } } else { if (l == 0) { - app.DebugPrintf("[Texture Warning] Missing asset: %S\n", - fileName.c_str()); - // We MUST initialize width/height to avoid the program being a - // crybaby and crash + // safety dummy to prevent crash width = 1; height = 1; - // Create a tiny missingno buffer so the rest of the game loads - // without crashing up data[0] = new int[1]; data[0][0] = 0xFFFF00FF; } @@ -158,37 +135,25 @@ BufferedImage::BufferedImage(const std::wstring& File, } } } - BufferedImage::BufferedImage(DLCPack* dlcPack, const std::wstring& File, bool filenameHasExtension) { HRESULT hr; std::wstring filePath = File; std::uint8_t* pbData = nullptr; std::uint32_t dataBytes = 0; - - for (int l = 0; l < 10; l++) { - data[l] = nullptr; - } + for (int l = 0; l < 10; l++) data[l] = nullptr; for (int l = 0; l < 10; l++) { std::wstring name; - std::wstring mipMapPath = L""; - if (l != 0) { - mipMapPath = L"MipMapLevel" + _toString(l + 1); - } - if (filenameHasExtension) { - name = L"res" + filePath.substr(0, filePath.length()); - } else { - name = L"res" + filePath.substr(0, filePath.length() - 4) + - mipMapPath + L".png"; - } + std::wstring mipMapPath = + (l != 0) ? L"MipMapLevel" + _toString(l + 1) : L""; + name = L"res" + (filenameHasExtension + ? filePath + : filePath.substr(0, filePath.length() - 4) + + mipMapPath + L".png"); if (!dlcPack->doesPackContainFile(DLCManager::e_DLCType_All, name)) { - // 4J - If we haven't loaded the non-mipmap version then exit the - // game - if (l == 0) { - app.FatalLoadError(); - } + if (l == 0) app.FatalLoadError(); return; } @@ -200,64 +165,9 @@ BufferedImage::BufferedImage(DLCPack* dlcPack, const std::wstring& File, } D3DXIMAGE_INFO ImageInfo; - ZeroMemory(&ImageInfo, sizeof(D3DXIMAGE_INFO)); hr = RenderManager.LoadTextureData(pbData, dataBytes, &ImageInfo, &data[l]); - - if (hr != ERROR_SUCCESS) { - if (l == 0) { - std::wstring wname = L"res" + - filePath.substr(0, filePath.length() - 4) + - L".png"; - std::vector candidates; - candidates.push_back(wname); - if (wname.rfind(L"Common/res/", 0) == 0) { - candidates.push_back( - wname.substr(std::wstring(L"Common/res/").length())); - } - candidates.push_back(filePath); - if (!filePath.empty() && filePath[0] == L'/') - candidates.push_back(filePath.substr(1)); - - std::wstring baseName2; - size_t posSlash2 = filePath.find_last_of(L"/\\"); - if (posSlash2 == std::wstring::npos) - baseName2 = filePath; - else - baseName2 = filePath.substr(posSlash2 + 1); - // same thing but for the fonts.. i found a way to make this - // less horrible but im lazy sorry :/ - if (!baseName2.empty()) { - candidates.insert(candidates.begin(), - L"Common/Res/Font/" + baseName2); - candidates.push_back(L"font/" + baseName2); - candidates.push_back(L"font\\" + baseName2); - candidates.push_back(L"res/font/" + baseName2); - candidates.push_back(L"Common/res/font/" + baseName2); - candidates.push_back(L"Common/Res/Font/" + baseName2); - } - - bool loaded = false; - for (auto& key : candidates) { - if (key.empty()) continue; - if (app.hasArchiveFile(key)) { - byteArray ba = app.getArchiveFile(key); - if (ba.data != nullptr && ba.length > 0) { - hr = RenderManager.LoadTextureData( - ba.data, ba.length, &ImageInfo, &data[l]); - if (hr == ERROR_SUCCESS) { - loaded = true; - break; - } - } - } - } - if (!loaded) app.FatalLoadError(); - } - return; - } - - if (l == 0) { + if (hr == ERROR_SUCCESS && l == 0) { width = ImageInfo.Width; height = ImageInfo.Height; } diff --git a/Minecraft.Client/meson.build b/Minecraft.Client/meson.build index f81dddddd..6b43ab90c 100644 --- a/Minecraft.Client/meson.build +++ b/Minecraft.Client/meson.build @@ -95,7 +95,7 @@ endif client = executable('Minecraft.Client', client_sources + platform_sources + localisation[1], - include_directories : [include_directories('Platform', 'Platform/Linux/Iggy/include'),stb], + include_directories : [include_directories('Platform', 'Platform/Linux/Iggy/include', '../Minecraft.World/Platform'),stb], dependencies : client_dependencies, cpp_args : global_cpp_args + global_cpp_defs + [ '-DUNICODE', '-D_UNICODE', diff --git a/Minecraft.World/IO/Files/File.cpp b/Minecraft.World/IO/Files/File.cpp index 7567d80d1..b67d8db33 100644 --- a/Minecraft.World/IO/Files/File.cpp +++ b/Minecraft.World/IO/Files/File.cpp @@ -2,7 +2,7 @@ #include "FileFilter.h" #include "../../Level/Storage/McRegionLevelStorageSource.h" #include "File.h" - +#include "PathHelper.h" #if !defined(__PS3__) && !defined(__ORBIS__) && !defined(__PSVITA__) #include #include @@ -57,52 +57,55 @@ File::File(const File& parent, const std::wstring& child) { // Creates a new File instance by converting the given pathname string into an // abstract pathname. + File::File(const std::wstring& pathname) { if (pathname.empty()) { m_abstractPathName = L""; return; } - // same thing as in bufferedoverflow - std::wstring fixedPath = pathname; + std::wstring fixedPath = pathname; for (size_t i = 0; i < fixedPath.length(); ++i) { if (fixedPath[i] == L'\\') fixedPath[i] = L'/'; } - size_t dpos; while ((dpos = fixedPath.find(L"//")) != std::wstring::npos) fixedPath.erase(dpos, 1); if (fixedPath.find(L"GAME:/") == 0) fixedPath = fixedPath.substr(6); - m_abstractPathName = fixedPath; #if defined(__linux__) - // If this is a relative path and it doesn't exist in the CWD, try to - // resolve it relative to the executable directory - if (!m_abstractPathName.empty() && m_abstractPathName[0] != L'/') { - const char* native = wstringtofilename(m_abstractPathName); - if (access(native, F_OK) == -1) { - char exePathBuf[PATH_MAX]; - ssize_t exeLen = - readlink("/proc/self/exe", exePathBuf, sizeof(exePathBuf) - 1); - if (exeLen != -1) { - exePathBuf[exeLen] = '\0'; - std::string exePathStr(exePathBuf); - size_t pos = exePathStr.find_last_of('/'); - std::string exeDir = (pos == std::string::npos) - ? std::string(".") - : exePathStr.substr(0, pos); - std::wstring exeDirW = convStringToWstring(exeDir); - std::wstring candidate = - exeDirW + pathSeparator + m_abstractPathName; - const char* candNative = wstringtofilename(candidate); - if (access(candNative, F_OK) != -1) { - m_abstractPathName = candidate; - } - } + std::string request = wstringtofilename(m_abstractPathName); + while (!request.empty() && request[0] == '/') request.erase(0, 1); + if (request.find("res/") == 0) request.erase(0, 4); + + std::string exeDir = PathHelper::GetExecutableDirA(); + std::string fileName = request; + size_t lastSlash = fileName.find_last_of('/'); + if (lastSlash != std::string::npos) + fileName = fileName.substr(lastSlash + 1); + + const char* bases[] = {"/", + "/Common/res/TitleUpdate/res/", + "/Common/Media/", + "/Common/res/", + "/Common/", + "/Minecraft.Assets/"}; + + for (const char* base : bases) { + std::string tryFull = exeDir + base + request; + std::string tryFile = exeDir + base + fileName; + if (access(tryFull.c_str(), F_OK) != -1) { + m_abstractPathName = convStringToWstring(tryFull); + return; + } + if (access(tryFile.c_str(), F_OK) != -1) { + m_abstractPathName = convStringToWstring(tryFile); + return; } } #endif + #ifdef _WINDOWS64 std::string path = wstringtofilename(m_abstractPathName); std::string finalPath = StorageManager.GetMountedPath(path.c_str()); diff --git a/Minecraft.World/Platform/PathHelper.h b/Minecraft.World/Platform/PathHelper.h new file mode 100644 index 000000000..e02b755cd --- /dev/null +++ b/Minecraft.World/Platform/PathHelper.h @@ -0,0 +1,37 @@ +#pragma once +#include +#if defined(__linux__) +#include +#include +#endif + +namespace PathHelper { +inline std::wstring GetExecutableDirW() { +#if defined(__linux__) + char buffer[4096]; + ssize_t len = readlink("/proc/self/exe", buffer, sizeof(buffer) - 1); + if (len != -1) { + buffer[len] = '\0'; + std::string path(buffer); + size_t lastSlash = path.find_last_of('/'); + if (lastSlash != std::string::npos) + return std::wstring(path.begin(), path.begin() + lastSlash); + } +#endif + return L"."; +} + +inline std::string GetExecutableDirA() { +#if defined(__linux__) + char buffer[4096]; + ssize_t len = readlink("/proc/self/exe", buffer, sizeof(buffer) - 1); + if (len != -1) { + buffer[len] = '\0'; + std::string path(buffer); + size_t lastSlash = path.find_last_of('/'); + if (lastSlash != std::string::npos) return path.substr(0, lastSlash); + } +#endif + return "."; +} +} // namespace PathHelper \ No newline at end of file From 6be5f627efa4cd03746fd78d353952a06746e12c Mon Sep 17 00:00:00 2001 From: JuiceyDev Date: Fri, 27 Mar 2026 20:57:46 +0100 Subject: [PATCH 024/170] make consoles_app use pathhelper :) --- .../Platform/Common/Consoles_App.cpp | 31 ++++--------------- 1 file changed, 6 insertions(+), 25 deletions(-) diff --git a/Minecraft.Client/Platform/Common/Consoles_App.cpp b/Minecraft.Client/Platform/Common/Consoles_App.cpp index afe871205..95053b713 100644 --- a/Minecraft.Client/Platform/Common/Consoles_App.cpp +++ b/Minecraft.Client/Platform/Common/Consoles_App.cpp @@ -4585,7 +4585,6 @@ int CMinecraftApp::BannedLevelDialogReturned( return 0; } - void CMinecraftApp::loadMediaArchive() { std::wstring mediapath = L""; @@ -4604,31 +4603,12 @@ void CMinecraftApp::loadMediaArchive() { #endif if (!mediapath.empty()) { - // (check file.cpp) - // try to load the archive relative to the executable - // directory first. - // If that fails, fall back to the current working - // directory (original behavior) - // if everything fails, may god help you + // boom headshot #if defined(__linux__) - // THIS CAN USE PATHHELPER.h - char exePathBuf[PATH_MAX]; - ssize_t exeLen = - readlink("/proc/self/exe", exePathBuf, sizeof(exePathBuf) - 1); - if (exeLen != -1) { - exePathBuf[exeLen] = '\0'; - std::string exePathStr(exePathBuf); - size_t pos = exePathStr.find_last_of('/'); - std::string exeDir = (pos == std::string::npos) - ? std::string(".") - : exePathStr.substr(0, pos); - std::wstring exeDirW = convStringToWstring(exeDir.c_str()); - std::wstring candidate = exeDirW + File::pathSeparator + mediapath; - if (File(candidate).exists()) { - m_mediaArchive = new ArchiveFile(File(candidate)); - } else { - m_mediaArchive = new ArchiveFile(File(mediapath)); - } + std::wstring exeDirW = PathHelper::GetExecutableDirW(); + std::wstring candidate = exeDirW + File::pathSeparator + mediapath; + if (File(candidate).exists()) { + m_mediaArchive = new ArchiveFile(File(candidate)); } else { m_mediaArchive = new ArchiveFile(File(mediapath)); } @@ -4636,6 +4616,7 @@ void CMinecraftApp::loadMediaArchive() { m_mediaArchive = new ArchiveFile(File(mediapath)); #endif } +} #if 0 std::string path = "Common\\media.arc"; HANDLE hFile = CreateFile( path.c_str(), From 23ab4de9acba2cf124bc17653d311c1da4d36333 Mon Sep 17 00:00:00 2001 From: Sally Knight Date: Sat, 28 Mar 2026 02:18:23 +0300 Subject: [PATCH 025/170] fix(goal): add a duration to panics --- Minecraft.World/AI/Goals/PanicGoal.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Minecraft.World/AI/Goals/PanicGoal.cpp b/Minecraft.World/AI/Goals/PanicGoal.cpp index 9c32c1c6e..48febd49e 100644 --- a/Minecraft.World/AI/Goals/PanicGoal.cpp +++ b/Minecraft.World/AI/Goals/PanicGoal.cpp @@ -14,6 +14,14 @@ PanicGoal::PanicGoal(PathfinderMob* mob, double speedModifier) { bool PanicGoal::canUse() { if (mob->getLastHurtByMob() == NULL && !mob->isOnFire()) return false; + + // 4jcraft: stop entities from being eternally scared (referenced from + // smartcmd/MinecraftConsoles #519) + const int hurtTimeout = mob->getLastHurtByMobTimestamp(); + static thread_local Random random; + const int panicDuration = random.nextInt(41) + 60; + if (mob->tickCount - hurtTimeout > panicDuration) return false; + Vec3* pos = RandomPos::getPos( std::dynamic_pointer_cast(mob->shared_from_this()), 5, 4); From 40a3f90d894644256bdd715f4e371a2280f502c8 Mon Sep 17 00:00:00 2001 From: Sally Knight Date: Sat, 28 Mar 2026 03:47:49 +0300 Subject: [PATCH 026/170] fix: add null check to renderItemInHand --- Minecraft.Client/Rendering/GameRenderer.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Minecraft.Client/Rendering/GameRenderer.cpp b/Minecraft.Client/Rendering/GameRenderer.cpp index 6364b2ba1..d228b1030 100644 --- a/Minecraft.Client/Rendering/GameRenderer.cpp +++ b/Minecraft.Client/Rendering/GameRenderer.cpp @@ -671,6 +671,11 @@ void GameRenderer::setupCamera(float a, int eye) { void GameRenderer::renderItemInHand(float a, int eye) { if (cameraFlip > 0) return; + // 4jcraft: this function sometimes causes a segfault (was hell to catch + // this in gdb) because of itemInHandRenderer not being initialized so let's + // add a nullcheck + if (itemInHandRenderer == nullptr) return; + // 4J-JEV: I'm fairly confident this method would crash if the cameratarget // isnt a local player anyway, but oh well. std::shared_ptr localplayer = From 79217ca8e380a931f352b03242b5d68f97d3ddbf Mon Sep 17 00:00:00 2001 From: orng Date: Fri, 27 Mar 2026 21:11:11 -0500 Subject: [PATCH 027/170] refactor: modernize `AABB` class --- Minecraft.Client/Network/PlayerConnection.cpp | 11 +- .../ApplySchematicRuleDefinition.cpp | 4 +- .../Common/GameRules/ConsoleSchematicFile.cpp | 4 +- .../Common/Tutorial/AreaConstraint.cpp | 6 +- .../Platform/Common/Tutorial/AreaHint.cpp | 2 +- .../Common/Tutorial/ChangeStateConstraint.cpp | 6 +- Minecraft.Client/Rendering/Chunk.cpp | 4 +- Minecraft.Client/Rendering/GameRenderer.cpp | 17 +- Minecraft.Client/Rendering/LevelRenderer.cpp | 9 +- Minecraft.World/AI/Goals/AvoidPlayerGoal.cpp | 3 +- Minecraft.World/AI/Goals/BreedGoal.cpp | 3 +- Minecraft.World/AI/Goals/FollowParentGoal.cpp | 4 +- Minecraft.World/AI/Goals/HurtByTargetGoal.cpp | 7 +- Minecraft.World/AI/Goals/LookAtPlayerGoal.cpp | 3 +- Minecraft.World/AI/Goals/MakeLoveGoal.cpp | 3 +- .../AI/Goals/NearestAttackableTargetGoal.cpp | 3 +- Minecraft.World/AI/Goals/OfferFlowerGoal.cpp | 5 +- Minecraft.World/AI/Goals/PlayGoal.cpp | 3 +- Minecraft.World/AI/Goals/TakeFlowerGoal.cpp | 3 +- Minecraft.World/Blocks/Tile.cpp | 2 +- .../Blocks/TileEntities/BeaconTileEntity.cpp | 9 +- Minecraft.World/Entities/Entity.cpp | 96 +++---- Minecraft.World/Entities/HangingEntity.cpp | 6 +- Minecraft.World/Entities/ItemEntity.cpp | 3 +- Minecraft.World/Entities/LargeFireball.cpp | 2 +- Minecraft.World/Entities/LivingEntity.cpp | 15 +- Minecraft.World/Entities/MinecartHopper.cpp | 5 +- Minecraft.World/Entities/Mob.cpp | 6 +- Minecraft.World/Entities/Mobs/Animal.cpp | 31 ++- Minecraft.World/Entities/Mobs/Arrow.cpp | 11 +- Minecraft.World/Entities/Mobs/Boat.cpp | 3 +- .../Entities/Mobs/DragonFireball.cpp | 4 +- Minecraft.World/Entities/Mobs/EnderDragon.cpp | 24 +- Minecraft.World/Entities/Mobs/EntityHorse.cpp | 6 +- Minecraft.World/Entities/Mobs/Fireball.cpp | 9 +- Minecraft.World/Entities/Mobs/FishingHook.cpp | 9 +- Minecraft.World/Entities/Mobs/Ghast.cpp | 6 +- Minecraft.World/Entities/Mobs/Minecart.cpp | 3 +- Minecraft.World/Entities/Mobs/PigZombie.cpp | 5 +- Minecraft.World/Entities/Mobs/Squid.cpp | 3 +- .../Entities/Mobs/ThrownPotion.cpp | 4 +- Minecraft.World/Entities/Mobs/WitherBoss.cpp | 4 +- Minecraft.World/Entities/Throwable.cpp | 9 +- Minecraft.World/Entities/WitherSkull.cpp | 2 +- Minecraft.World/Items/BoatItem.cpp | 15 +- Minecraft.World/Level/BaseMobSpawner.cpp | 17 +- Minecraft.World/Level/Level.cpp | 7 +- Minecraft.World/Level/LevelChunk.cpp | 6 +- Minecraft.World/Player/Player.cpp | 6 +- Minecraft.World/Util/AABB.cpp | 242 ++++++++---------- Minecraft.World/Util/AABB.h | 44 ++-- Minecraft.World/Util/Vec3.cpp | 3 +- .../WorldGen/Structures/StructureStart.cpp | 2 +- 53 files changed, 362 insertions(+), 357 deletions(-) diff --git a/Minecraft.Client/Network/PlayerConnection.cpp b/Minecraft.Client/Network/PlayerConnection.cpp index 9f5e861e8..5a4d5d3d7 100644 --- a/Minecraft.Client/Network/PlayerConnection.cpp +++ b/Minecraft.Client/Network/PlayerConnection.cpp @@ -272,8 +272,9 @@ void PlayerConnection::handleMovePlayer( */ float r = 1 / 16.0f; + AABB shrunk = player->bb->shrink(r, r, r); bool oldOk = - level->getCubes(player, player->bb->copy()->shrink(r, r, r)) + level->getCubes(player, &shrunk) ->empty(); if (player->onGround && !packet->onGround && yDist > 0) { @@ -324,17 +325,19 @@ void PlayerConnection::handleMovePlayer( } player->absMoveTo(xt, yt, zt, yRotT, xRotT); + // TODO: check if this can be elided + shrunk = player->bb->shrink(r, r, r); bool newOk = - level->getCubes(player, player->bb->copy()->shrink(r, r, r)) + level->getCubes(player, &shrunk) ->empty(); if (oldOk && (fail || !newOk) && !player->isSleeping()) { teleport(xLastOk, yLastOk, zLastOk, yRotT, xRotT); return; } - AABB* testBox = player->bb->copy()->grow(r, r, r)->expand(0, -0.55, 0); + AABB testBox = (*player->bb).grow(r, r, r).expand(0, -0.55, 0); // && server.level.getCubes(player, testBox).size() == 0 if (!server->isFlightAllowed() && !player->gameMode->isCreative() && - !level->containsAnyBlocks(testBox) && !player->isAllowedToFly()) { + !level->containsAnyBlocks(&testBox) && !player->isAllowedToFly()) { if (oyDist >= (-0.5f / 16.0f)) { aboveGroundTickCount++; if (aboveGroundTickCount > 80) { diff --git a/Minecraft.Client/Platform/Common/GameRules/ApplySchematicRuleDefinition.cpp b/Minecraft.Client/Platform/Common/GameRules/ApplySchematicRuleDefinition.cpp index b2304fbdd..dd91c027c 100644 --- a/Minecraft.Client/Platform/Common/GameRules/ApplySchematicRuleDefinition.cpp +++ b/Minecraft.Client/Platform/Common/GameRules/ApplySchematicRuleDefinition.cpp @@ -163,7 +163,7 @@ void ApplySchematicRuleDefinition::processSchematic(AABB* chunkBox, m_schematic = m_levelGenOptions->getSchematicFile(m_schematicName); if (m_locationBox == NULL) updateLocationBox(); - if (chunkBox->intersects(m_locationBox)) { + if (chunkBox->intersects(*m_locationBox)) { m_locationBox->y1 = std::min((double)Level::maxBuildHeight, m_locationBox->y1); @@ -207,7 +207,7 @@ void ApplySchematicRuleDefinition::processSchematicLighting(AABB* chunkBox, m_schematic = m_levelGenOptions->getSchematicFile(m_schematicName); if (m_locationBox == NULL) updateLocationBox(); - if (chunkBox->intersects(m_locationBox)) { + if (chunkBox->intersects(*m_locationBox)) { m_locationBox->y1 = std::min((double)Level::maxBuildHeight, m_locationBox->y1); diff --git a/Minecraft.Client/Platform/Common/GameRules/ConsoleSchematicFile.cpp b/Minecraft.Client/Platform/Common/GameRules/ConsoleSchematicFile.cpp index 217a7ffb8..2409b12c9 100644 --- a/Minecraft.Client/Platform/Common/GameRules/ConsoleSchematicFile.cpp +++ b/Minecraft.Client/Platform/Common/GameRules/ConsoleSchematicFile.cpp @@ -464,7 +464,7 @@ void ConsoleSchematicFile::applyTileEntities(LevelChunk* chunk, AABB* chunkBox, targetZ); Vec3 pos(targetX, targetY, targetZ); - if (chunkBox->containsIncludingLowerBound(&pos)) { + if (chunkBox->containsIncludingLowerBound(pos)) { std::shared_ptr teCopy = chunk->getTileEntity( (int)targetX & 15, (int)targetY & 15, (int)targetZ & 15); @@ -511,7 +511,7 @@ void ConsoleSchematicFile::applyTileEntities(LevelChunk* chunk, AABB* chunkBox, // Add 0.01 as the AABB::contains function returns false if a value is // <= the lower bound Vec3 pos(targetX + 0.01, targetY + 0.01, targetZ + 0.01); - if (!chunkBox->containsIncludingLowerBound(&pos)) { + if (!chunkBox->containsIncludingLowerBound(pos)) { ++it; continue; } diff --git a/Minecraft.Client/Platform/Common/Tutorial/AreaConstraint.cpp b/Minecraft.Client/Platform/Common/Tutorial/AreaConstraint.cpp index 016cc71ff..271275948 100644 --- a/Minecraft.Client/Platform/Common/Tutorial/AreaConstraint.cpp +++ b/Minecraft.Client/Platform/Common/Tutorial/AreaConstraint.cpp @@ -25,8 +25,10 @@ AreaConstraint::~AreaConstraint() { bool AreaConstraint::isConstraintSatisfied(int iPad) { Minecraft* minecraft = Minecraft::GetInstance(); + + // TODO: check if this can be elided Vec3 ipad_player = minecraft->localplayers[iPad]->getPos(1); - return messageArea->contains(&ipad_player) == contains; + return messageArea->contains(ipad_player) == contains; } bool AreaConstraint::isConstraintRestrictive(int iPad) { @@ -40,7 +42,7 @@ bool AreaConstraint::canMoveToPosition(double xo, double yo, double zo, Vec3 targetPos(xt, yt, zt); Minecraft* minecraft = Minecraft::GetInstance(); - if (movementArea->contains(&targetPos) == contains) { + if (movementArea->contains(targetPos) == contains) { return true; } Vec3 origPos(xo, yo, zo); diff --git a/Minecraft.Client/Platform/Common/Tutorial/AreaHint.cpp b/Minecraft.Client/Platform/Common/Tutorial/AreaHint.cpp index 87dc976bf..1eb6c1017 100644 --- a/Minecraft.Client/Platform/Common/Tutorial/AreaHint.cpp +++ b/Minecraft.Client/Platform/Common/Tutorial/AreaHint.cpp @@ -28,7 +28,7 @@ int AreaHint::tick() { if ((m_displayState == e_Tutorial_State_Any || m_tutorial->getCurrentState() == m_displayState) && - m_hintNeeded && area->contains(&player_pos) == contains) { + m_hintNeeded && area->contains(player_pos) == contains) { if (m_completeState == e_Tutorial_State_None) { m_hintNeeded = false; } else if (m_tutorial->isStateCompleted(m_completeState)) { diff --git a/Minecraft.Client/Platform/Common/Tutorial/ChangeStateConstraint.cpp b/Minecraft.Client/Platform/Common/Tutorial/ChangeStateConstraint.cpp index e1f93eecb..9efbd42c9 100644 --- a/Minecraft.Client/Platform/Common/Tutorial/ChangeStateConstraint.cpp +++ b/Minecraft.Client/Platform/Common/Tutorial/ChangeStateConstraint.cpp @@ -85,9 +85,11 @@ void ChangeStateConstraint::tick(int iPad) { break; } } + + // TODO: check if this can be elided Vec3 ipad_player = minecraft->localplayers[iPad]->getPos(1); if (!m_bHasChanged && inASourceState && - movementArea->contains(&ipad_player) == contains) { + movementArea->contains(ipad_player) == contains) { m_bHasChanged = true; m_changedFromState = m_tutorial->getCurrentState(); m_tutorial->changeTutorialState(m_targetState); @@ -125,7 +127,7 @@ void ChangeStateConstraint::tick(int iPad) { } } } else if (m_bHasChanged && - movementArea->contains(&ipad_player) != contains) { + movementArea->contains(ipad_player) != contains) { m_bHasChanged = false; m_tutorial->changeTutorialState(m_changedFromState); diff --git a/Minecraft.Client/Rendering/Chunk.cpp b/Minecraft.Client/Rendering/Chunk.cpp index fa311aed4..03dc40b8f 100644 --- a/Minecraft.Client/Rendering/Chunk.cpp +++ b/Minecraft.Client/Rendering/Chunk.cpp @@ -509,9 +509,9 @@ void Chunk::rebuild() { // 4J MGH - added this to take the bound from the value calc'd in the // tesselator if (bb) { - bb->set(bounds.boundingBox[0], bounds.boundingBox[1], + *bb = {bounds.boundingBox[0], bounds.boundingBox[1], bounds.boundingBox[2], bounds.boundingBox[3], - bounds.boundingBox[4], bounds.boundingBox[5]); + bounds.boundingBox[4], bounds.boundingBox[5]}; } delete tileRenderer; diff --git a/Minecraft.Client/Rendering/GameRenderer.cpp b/Minecraft.Client/Rendering/GameRenderer.cpp index d228b1030..b2f589b88 100644 --- a/Minecraft.Client/Rendering/GameRenderer.cpp +++ b/Minecraft.Client/Rendering/GameRenderer.cpp @@ -309,11 +309,12 @@ void GameRenderer::pick(float a) { to = to.add(from.x, from.y, from.z); hovered = nullptr; float overlap = 1; - std::vector >* objects = mc->level->getEntities( - mc->cameraTargetPlayer, - mc->cameraTargetPlayer->bb - ->expand(b.x * (range), b.y * (range), b.z * (range)) - ->grow(overlap, overlap, overlap)); + AABB grown = mc->cameraTargetPlayer->bb + ->expand(b.x * (range), b.y * (range), b.z * (range)) + .grow(overlap, overlap, overlap); + + std::vector >* objects = + mc->level->getEntities(mc->cameraTargetPlayer, &grown); double nearest = dist; AUTO_VAR(itEnd, objects->end()); @@ -322,9 +323,9 @@ void GameRenderer::pick(float a) { if (!e->isPickable()) continue; float rr = e->getPickRadius(); - AABB* bb = e->bb->grow(rr, rr, rr); - HitResult* p = bb->clip(&from, &to); - if (bb->contains(&from)) { + AABB bb = e->bb->grow(rr, rr, rr); + HitResult* p = bb.clip(from, to); + if (bb.contains(from)) { if (0 < nearest || nearest == 0) { hovered = e; nearest = 0; diff --git a/Minecraft.Client/Rendering/LevelRenderer.cpp b/Minecraft.Client/Rendering/LevelRenderer.cpp index 722fcfbef..d412a7ede 100644 --- a/Minecraft.Client/Rendering/LevelRenderer.cpp +++ b/Minecraft.Client/Rendering/LevelRenderer.cpp @@ -2479,10 +2479,13 @@ void LevelRenderer::renderHitOutline(std::shared_ptr player, double xo = player->xOld + (player->x - player->xOld) * a; double yo = player->yOld + (player->y - player->yOld) * a; double zo = player->zOld + (player->z - player->zOld) * a; - render(Tile::tiles[tileId] + + AABB bb = Tile::tiles[tileId] ->getTileAABB(level[iPad], h->x, h->y, h->z) ->grow(ss, ss, ss) - ->cloneMove(-xo, -yo, -zo)); + .move(-xo, -yo, -zo); + + render(&bb); } glDepthMask(true); glEnable(GL_TEXTURE_2D); @@ -3974,7 +3977,7 @@ void LevelRenderer::DestroyedTileManager::addAABBs(Level* level, AABB* box, // interested in, add them to the output list, making a temp // AABB copy so that we can destroy our own copy without // worrying about the lifespan of the copy we've passed out - if (m_destroyedTiles[i]->boxes[j]->intersects(box)) { + if (m_destroyedTiles[i]->boxes[j]->intersects(*box)) { boxes->push_back( AABB::newTemp(m_destroyedTiles[i]->boxes[j]->x0, m_destroyedTiles[i]->boxes[j]->y0, diff --git a/Minecraft.World/AI/Goals/AvoidPlayerGoal.cpp b/Minecraft.World/AI/Goals/AvoidPlayerGoal.cpp index 59045d029..cf595ea05 100644 --- a/Minecraft.World/AI/Goals/AvoidPlayerGoal.cpp +++ b/Minecraft.World/AI/Goals/AvoidPlayerGoal.cpp @@ -53,9 +53,10 @@ bool AvoidPlayerGoal::canUse() { mob->level->getNearestPlayer(mob->shared_from_this(), maxDist)); if (toAvoid.lock() == NULL) return false; } else { + AABB grown_bb = mob->bb->grow(maxDist, 3, maxDist); std::vector >* entities = mob->level->getEntitiesOfClass( - avoidType, mob->bb->grow(maxDist, 3, maxDist), entitySelector); + avoidType, &grown_bb, entitySelector); if (entities->empty()) { delete entities; return false; diff --git a/Minecraft.World/AI/Goals/BreedGoal.cpp b/Minecraft.World/AI/Goals/BreedGoal.cpp index 25281c61d..1ec4f59fc 100644 --- a/Minecraft.World/AI/Goals/BreedGoal.cpp +++ b/Minecraft.World/AI/Goals/BreedGoal.cpp @@ -48,8 +48,9 @@ void BreedGoal::tick() { std::shared_ptr BreedGoal::getFreePartner() { float r = 8; + AABB grown_bb = animal->bb->grow(r, r, r); std::vector >* others = - level->getEntitiesOfClass(typeid(*animal), animal->bb->grow(r, r, r)); + level->getEntitiesOfClass(typeid(*animal), &grown_bb); double dist = std::numeric_limits::max(); std::shared_ptr partner = nullptr; for (AUTO_VAR(it, others->begin()); it != others->end(); ++it) { diff --git a/Minecraft.World/AI/Goals/FollowParentGoal.cpp b/Minecraft.World/AI/Goals/FollowParentGoal.cpp index d60dd34a9..0a740a35c 100644 --- a/Minecraft.World/AI/Goals/FollowParentGoal.cpp +++ b/Minecraft.World/AI/Goals/FollowParentGoal.cpp @@ -16,9 +16,9 @@ FollowParentGoal::FollowParentGoal(Animal* animal, double speedModifier) { bool FollowParentGoal::canUse() { if (animal->getAge() >= 0) return false; + AABB grown_bb = animal->bb->grow(8, 4, 8); std::vector >* parents = - animal->level->getEntitiesOfClass(typeid(*animal), - animal->bb->grow(8, 4, 8)); + animal->level->getEntitiesOfClass(typeid(*animal), &grown_bb); std::shared_ptr closest = nullptr; double closestDistSqr = std::numeric_limits::max(); diff --git a/Minecraft.World/AI/Goals/HurtByTargetGoal.cpp b/Minecraft.World/AI/Goals/HurtByTargetGoal.cpp index 7bee32298..00a3e838d 100644 --- a/Minecraft.World/AI/Goals/HurtByTargetGoal.cpp +++ b/Minecraft.World/AI/Goals/HurtByTargetGoal.cpp @@ -22,11 +22,10 @@ void HurtByTargetGoal::start() { if (alertSameType) { double within = getFollowDistance(); + AABB mob_bb = AABB(mob->x, mob->y, mob->z, mob->x + 1, mob->y + 1, mob->z + 1).grow(within, 4, within); std::vector >* nearby = mob->level->getEntitiesOfClass( - typeid(*mob), AABB::newTemp(mob->x, mob->y, mob->z, mob->x + 1, - mob->y + 1, mob->z + 1) - ->grow(within, 4, within)); + typeid(*mob), &mob_bb); for (AUTO_VAR(it, nearby->begin()); it != nearby->end(); ++it) { std::shared_ptr other = std::dynamic_pointer_cast(*it); @@ -40,4 +39,4 @@ void HurtByTargetGoal::start() { } TargetGoal::start(); -} \ No newline at end of file +} diff --git a/Minecraft.World/AI/Goals/LookAtPlayerGoal.cpp b/Minecraft.World/AI/Goals/LookAtPlayerGoal.cpp index 32cd4d1d6..b073212c2 100644 --- a/Minecraft.World/AI/Goals/LookAtPlayerGoal.cpp +++ b/Minecraft.World/AI/Goals/LookAtPlayerGoal.cpp @@ -37,8 +37,9 @@ bool LookAtPlayerGoal::canUse() { lookAt = mob->level->getNearestPlayer(mob->shared_from_this(), lookDistance); } else { + AABB mob_bb = mob->bb->grow(lookDistance, 3, lookDistance); lookAt = std::weak_ptr(mob->level->getClosestEntityOfClass( - lookAtType, mob->bb->grow(lookDistance, 3, lookDistance), + lookAtType, &mob_bb, mob->shared_from_this())); } return lookAt.lock() != NULL; diff --git a/Minecraft.World/AI/Goals/MakeLoveGoal.cpp b/Minecraft.World/AI/Goals/MakeLoveGoal.cpp index 733036801..0357f7113 100644 --- a/Minecraft.World/AI/Goals/MakeLoveGoal.cpp +++ b/Minecraft.World/AI/Goals/MakeLoveGoal.cpp @@ -29,8 +29,9 @@ bool MakeLoveGoal::canUse() { if (village.lock() == NULL) return false; if (!villageNeedsMoreVillagers()) return false; + AABB villager_bb = villager->bb->grow(8, 3, 8); std::shared_ptr mate = level->getClosestEntityOfClass( - typeid(Villager), villager->bb->grow(8, 3, 8), + typeid(Villager), &villager_bb, villager->shared_from_this()); if (mate == NULL) return false; diff --git a/Minecraft.World/AI/Goals/NearestAttackableTargetGoal.cpp b/Minecraft.World/AI/Goals/NearestAttackableTargetGoal.cpp index a67f91cf9..938102d3e 100644 --- a/Minecraft.World/AI/Goals/NearestAttackableTargetGoal.cpp +++ b/Minecraft.World/AI/Goals/NearestAttackableTargetGoal.cpp @@ -55,9 +55,10 @@ bool NearestAttackableTargetGoal::canUse() { return false; double within = getFollowDistance(); + AABB mob_bb = mob->bb->grow(within, 4, within); std::vector >* entities = mob->level->getEntitiesOfClass( - targetType, mob->bb->grow(within, 4, within), selector); + targetType, &mob_bb, selector); bool result = false; if (entities != NULL && !entities->empty()) { diff --git a/Minecraft.World/AI/Goals/OfferFlowerGoal.cpp b/Minecraft.World/AI/Goals/OfferFlowerGoal.cpp index 01c1b3dbf..902b221ee 100644 --- a/Minecraft.World/AI/Goals/OfferFlowerGoal.cpp +++ b/Minecraft.World/AI/Goals/OfferFlowerGoal.cpp @@ -15,9 +15,10 @@ OfferFlowerGoal::OfferFlowerGoal(VillagerGolem* golem) { bool OfferFlowerGoal::canUse() { if (!golem->level->isDay()) return false; if (golem->getRandom()->nextInt(8000) != 0) return false; + AABB golem_bb = golem->bb->grow(6, 2, 6); villager = std::weak_ptr(std::dynamic_pointer_cast( golem->level->getClosestEntityOfClass(typeid(Villager), - golem->bb->grow(6, 2, 6), + &golem_bb, golem->shared_from_this()))); return villager.lock() != NULL; } @@ -39,4 +40,4 @@ void OfferFlowerGoal::stop() { void OfferFlowerGoal::tick() { golem->getLookControl()->setLookAt(villager.lock(), 30, 30); --_tick; -} \ No newline at end of file +} diff --git a/Minecraft.World/AI/Goals/PlayGoal.cpp b/Minecraft.World/AI/Goals/PlayGoal.cpp index 0259d5c93..550f3bb6e 100644 --- a/Minecraft.World/AI/Goals/PlayGoal.cpp +++ b/Minecraft.World/AI/Goals/PlayGoal.cpp @@ -23,9 +23,10 @@ bool PlayGoal::canUse() { if (mob->getAge() >= 0) return false; if (mob->getRandom()->nextInt(400) != 0) return false; + AABB mob_bb = mob->bb->grow(6, 3, 6); std::vector >* children = mob->level->getEntitiesOfClass(typeid(Villager), - mob->bb->grow(6, 3, 6)); + &mob_bb); double closestDistSqr = std::numeric_limits::max(); // for (Entity c : children) for (AUTO_VAR(it, children->begin()); it != children->end(); ++it) { diff --git a/Minecraft.World/AI/Goals/TakeFlowerGoal.cpp b/Minecraft.World/AI/Goals/TakeFlowerGoal.cpp index e7c5410c4..e4e9ed042 100644 --- a/Minecraft.World/AI/Goals/TakeFlowerGoal.cpp +++ b/Minecraft.World/AI/Goals/TakeFlowerGoal.cpp @@ -22,9 +22,10 @@ bool TakeFlowerGoal::canUse() { if (villager->getAge() >= 0) return false; if (!villager->level->isDay()) return false; + AABB villager_bb = villager->bb->grow(6, 2, 6); std::vector >* golems = villager->level->getEntitiesOfClass(typeid(VillagerGolem), - villager->bb->grow(6, 2, 6)); + &villager_bb); if (golems->size() == 0) { delete golems; return false; diff --git a/Minecraft.World/Blocks/Tile.cpp b/Minecraft.World/Blocks/Tile.cpp index d110d7e8a..a895238ef 100644 --- a/Minecraft.World/Blocks/Tile.cpp +++ b/Minecraft.World/Blocks/Tile.cpp @@ -2016,7 +2016,7 @@ AABB* Tile::getTileAABB(Level* level, int x, int y, int z) { void Tile::addAABBs(Level* level, int x, int y, int z, AABB* box, AABBList* boxes, std::shared_ptr source) { AABB* aabb = getAABB(level, x, y, z); - if (aabb != NULL && box->intersects(aabb)) boxes->push_back(aabb); + if (aabb != NULL && box->intersects(*aabb)) boxes->push_back(aabb); } AABB* Tile::getAABB(Level* level, int x, int y, int z) { diff --git a/Minecraft.World/Blocks/TileEntities/BeaconTileEntity.cpp b/Minecraft.World/Blocks/TileEntities/BeaconTileEntity.cpp index 5b160f153..738303f3c 100644 --- a/Minecraft.World/Blocks/TileEntities/BeaconTileEntity.cpp +++ b/Minecraft.World/Blocks/TileEntities/BeaconTileEntity.cpp @@ -70,11 +70,10 @@ void BeaconTileEntity::applyEffects() { baseAmp = 1; } - AABB* bb = AABB::newTemp(x, y, z, x + 1, y + 1, z + 1) - ->grow(range, range, range); - bb->y1 = level->getMaxBuildHeight(); + AABB bb = AABB(x, y, z, x + 1, y + 1, z + 1).grow(range, range, range); + bb.y1 = level->getMaxBuildHeight(); std::vector >* players = - level->getEntitiesOfClass(typeid(Player), bb); + level->getEntitiesOfClass(typeid(Player), &bb); for (AUTO_VAR(it, players->begin()); it != players->end(); ++it) { std::shared_ptr player = std::dynamic_pointer_cast(*it); @@ -299,4 +298,4 @@ bool BeaconTileEntity::canPlaceItem(int slot, std::shared_ptr item) { return (item->id == Item::emerald_Id || item->id == Item::diamond_Id || item->id == Item::goldIngot_Id || item->id == Item::ironIngot_Id); -} \ No newline at end of file +} diff --git a/Minecraft.World/Entities/Entity.cpp b/Minecraft.World/Entities/Entity.cpp index 51ed60e8f..191789eb8 100644 --- a/Minecraft.World/Entities/Entity.cpp +++ b/Minecraft.World/Entities/Entity.cpp @@ -463,8 +463,8 @@ void Entity::setPos(double x, double y, double z) { this->z = z; float w = bbWidth / 2; float h = bbHeight; - bb->set(x - w, y - heightOffset + ySlideOffset, z - w, x + w, - y - heightOffset + ySlideOffset + h, z + w); + *bb = {x - w, y - heightOffset + ySlideOffset, z - w, x + w, + y - heightOffset + ySlideOffset + h, z + w}; } void Entity::turn(float xo, float yo) { @@ -618,18 +618,18 @@ void Entity::clearFire() { onFire = 0; } void Entity::outOfWorld() { remove(); } bool Entity::isFree(float xa, float ya, float za, float grow) { - AABB* box = bb->grow(grow, grow, grow)->cloneMove(xa, ya, za); - AABBList* aABBs = level->getCubes(shared_from_this(), box); + AABB box = bb->grow(grow, grow, grow).move(xa, ya, za); + AABBList* aABBs = level->getCubes(shared_from_this(), &box); if (!aABBs->empty()) return false; - if (level->containsAnyLiquid(box)) return false; + if (level->containsAnyLiquid(&box)) return false; return true; } bool Entity::isFree(double xa, double ya, double za) { - AABB* box = bb->cloneMove(xa, ya, za); - AABBList* aABBs = level->getCubes(shared_from_this(), box); + AABB box = bb->move(xa, ya, za); + AABBList* aABBs = level->getCubes(shared_from_this(), &box); if (!aABBs->empty()) return false; - if (level->containsAnyLiquid(box)) return false; + if (level->containsAnyLiquid(&box)) return false; return true; } @@ -637,7 +637,7 @@ void Entity::move(double xa, double ya, double za, bool noEntityCubes) // 4J - added noEntityCubes parameter { if (noPhysics) { - bb->move(xa, ya, za); + *bb = bb->move(xa, ya, za); x = (bb->x0 + bb->x1) / 2.0f; y = bb->y0 + heightOffset - ySlideOffset; z = (bb->z0 + bb->z1) / 2.0f; @@ -665,16 +665,17 @@ void Entity::move(double xa, double ya, double za, double yaOrg = ya; double zaOrg = za; - AABB* bbOrg = bb->copy(); + AABB bbOrg = *bb; bool isPlayerSneaking = onGround && isSneaking() && instanceof(eTYPE_PLAYER); if (isPlayerSneaking) { double d = 0.05; + + AABB translated_bb = bb->move(xa, -1.0, 0.0); while (xa != 0 && - level->getCubes(shared_from_this(), bb->cloneMove(xa, -1.0, 0)) - ->empty()) { + level->getCubes(shared_from_this(), &translated_bb)->empty()) { if (xa < d && xa >= -d) xa = 0; else if (xa > 0) @@ -683,9 +684,10 @@ void Entity::move(double xa, double ya, double za, xa += d; xaOrg = xa; } + + translated_bb = bb->move(0, -1.0, za); while (za != 0 && - level->getCubes(shared_from_this(), bb->cloneMove(0, -1.0, za)) - ->empty()) { + level->getCubes(shared_from_this(), &translated_bb)->empty()) { if (za < d && za >= -d) za = 0; else if (za > 0) @@ -694,9 +696,10 @@ void Entity::move(double xa, double ya, double za, za += d; zaOrg = za; } + + translated_bb = bb->move(xa, -1.0, za); while (xa != 0 && za != 0 && - level->getCubes(shared_from_this(), bb->cloneMove(xa, -1.0, za)) - ->empty()) { + level->getCubes(shared_from_this(), &translated_bb)->empty()) { if (xa < d && xa >= -d) xa = 0; else if (xa > 0) @@ -714,8 +717,9 @@ void Entity::move(double xa, double ya, double za, } } - AABBList* aABBs = level->getCubes( - shared_from_this(), bb->expand(xa, ya, za), noEntityCubes, true); + AABB expanded = bb->expand(xa, ya, za); + AABBList* aABBs = + level->getCubes(shared_from_this(), &expanded, noEntityCubes, true); // LAND FIRST, then x and z AUTO_VAR(itEndAABB, aABBs->end()); @@ -729,8 +733,8 @@ void Entity::move(double xa, double ya, double za, // But if we don't have the chunk data then all the collision info will // be incorrect as well for (AUTO_VAR(it, aABBs->begin()); it != itEndAABB; it++) - ya = (*it)->clipYCollide(bb, ya); - bb->move(0, ya, 0); + ya = (*it)->clipYCollide(*bb, ya); + *bb = bb->move(0, ya, 0); } if (!slide && yaOrg != ya) { @@ -741,9 +745,9 @@ void Entity::move(double xa, double ya, double za, itEndAABB = aABBs->end(); for (AUTO_VAR(it, aABBs->begin()); it != itEndAABB; it++) - xa = (*it)->clipXCollide(bb, xa); + xa = (*it)->clipXCollide(*bb, xa); - bb->move(xa, 0, 0); + *bb = bb->move(xa, 0, 0); if (!slide && xaOrg != xa) { xa = ya = za = 0; @@ -751,8 +755,8 @@ void Entity::move(double xa, double ya, double za, itEndAABB = aABBs->end(); for (AUTO_VAR(it, aABBs->begin()); it != itEndAABB; it++) - za = (*it)->clipZCollide(bb, za); - bb->move(0, 0, za); + za = (*it)->clipZCollide(*bb, za); + *bb = bb->move(0, 0, za); if (!slide && zaOrg != za) { xa = ya = za = 0; @@ -768,15 +772,14 @@ void Entity::move(double xa, double ya, double za, ya = footSize; za = zaOrg; - AABB* normal = bb->copy(); - bb->set(bbOrg); + AABB normal = *bb; + *bb = bbOrg; // 4J - added extra expand, as if we don't move up by footSize by // hitting a block above us, then overall we could be trying to move as // much as footSize downwards, so we'd better include cubes under our // feet in this list of things we might possibly collide with - aABBs = level->getCubes(shared_from_this(), - bb->expand(xa, ya, za)->expand(0, -ya, 0), - false, true); + AABB expanded = bb->expand(xa, ya, za).expand(0, -ya, 0); + aABBs = level->getCubes(shared_from_this(), &expanded, false, true); // LAND FIRST, then x and z itEndAABB = aABBs->end(); @@ -786,8 +789,8 @@ void Entity::move(double xa, double ya, double za, // all! But if we don't have the chunk data then all the collision // info will be incorrect as well for (AUTO_VAR(it, aABBs->begin()); it != itEndAABB; it++) - ya = (*it)->clipYCollide(bb, ya); - bb->move(0, ya, 0); + ya = (*it)->clipYCollide(*bb, ya); + *bb = bb->move(0, ya, 0); } if (!slide && yaOrg != ya) { @@ -796,8 +799,8 @@ void Entity::move(double xa, double ya, double za, itEndAABB = aABBs->end(); for (AUTO_VAR(it, aABBs->begin()); it != itEndAABB; it++) - xa = (*it)->clipXCollide(bb, xa); - bb->move(xa, 0, 0); + xa = (*it)->clipXCollide(*bb, xa); + *bb = bb->move(xa, 0, 0); if (!slide && xaOrg != xa) { xa = ya = za = 0; @@ -805,8 +808,8 @@ void Entity::move(double xa, double ya, double za, itEndAABB = aABBs->end(); for (AUTO_VAR(it, aABBs->begin()); it != itEndAABB; it++) - za = (*it)->clipZCollide(bb, za); - bb->move(0, 0, za); + za = (*it)->clipZCollide(*bb, za); + *bb = bb->move(0, 0, za); if (!slide && zaOrg != za) { xa = ya = za = 0; @@ -819,15 +822,15 @@ void Entity::move(double xa, double ya, double za, // LAND FIRST, then x and z itEndAABB = aABBs->end(); for (AUTO_VAR(it, aABBs->begin()); it != itEndAABB; it++) - ya = (*it)->clipYCollide(bb, ya); - bb->move(0, ya, 0); + ya = (*it)->clipYCollide(*bb, ya); + *bb = bb->move(0, ya, 0); } if (xaN * xaN + zaN * zaN >= xa * xa + za * za) { xa = xaN; ya = yaN; za = zaN; - bb->set(normal); + *bb = normal; } } @@ -888,7 +891,8 @@ void Entity::move(double xa, double ya, double za, checkInsideTiles(); bool water = isInWaterOrRain(); - if (level->containsFireTile(bb->shrink(0.001, 0.001, 0.001))) { + const AABB& shrunk = bb->shrink(0.001, 0.001, 0.001); + if (level->containsFireTile(bb)) { burn(1); if (!water) { onFire++; @@ -996,9 +1000,9 @@ bool Entity::isInWaterOrRain() { bool Entity::isInWater() { return wasInWater; } bool Entity::updateInWaterState() { - if (level->checkAndHandleWater( - bb->grow(0, -0.4f, 0)->shrink(0.001, 0.001, 0.001), Material::water, - shared_from_this())) { + AABB shrunk = bb->grow(0, -0.4, 0).shrink(0.001, 0.001, 0.001); + if (level->checkAndHandleWater(&shrunk, Material::water, + shared_from_this())) { if (!wasInWater && !firstTick && canCreateParticles()) { float speed = Mth::sqrt(xd * xd * 0.2f + yd * yd + zd * zd * 0.2f) * 0.2f; @@ -1048,8 +1052,8 @@ bool Entity::isUnderLiquid(Material* material) { float Entity::getHeadHeight() { return 0; } bool Entity::isInLava() { - return level->containsMaterial(bb->grow(-0.1f, -0.4f, -0.1f), - Material::lava); + AABB mat_bounds = bb->grow(-0.1, -0.4, -0.1); + return level->containsMaterial(&mat_bounds, Material::lava); } void Entity::moveRelative(float xa, float za, float speed) { @@ -1516,8 +1520,8 @@ void Entity::lerpTo(double x, double y, double z, float yRot, float xRot, // its definitely bad news for arrows as they are actually Meant to // intersect the geometry they land in slightly. if (GetType() != eTYPE_ARROW) { - AABBList* collisions = level->getCubes( - shared_from_this(), bb->shrink(1 / 32.0, 0, 1 / 32.0)); + AABB shrunk = bb->shrink(1 / 32.0, 0.0, 1 / 32.0); + AABBList* collisions = level->getCubes(shared_from_this(), &shrunk); if (!collisions->empty()) { double yTop = 0; AUTO_VAR(itEnd, collisions->end()); diff --git a/Minecraft.World/Entities/HangingEntity.cpp b/Minecraft.World/Entities/HangingEntity.cpp index d67329209..b94d8fdf1 100644 --- a/Minecraft.World/Entities/HangingEntity.cpp +++ b/Minecraft.World/Entities/HangingEntity.cpp @@ -74,8 +74,8 @@ void HangingEntity::setDir(int dir) { float y1 = y + h + ss; float z0 = z - d - ss; float z1 = z + d + ss; - bb->set(std::min(x0, x1), std::min(y0, y1), std::min(z0, z1), - std::max(x0, x1), std::max(y0, y1), std::max(z0, z1)); + *bb = {std::min(x0, x1), std::min(y0, y1), std::min(z0, z1), + std::max(x0, x1), std::max(y0, y1), std::max(z0, z1)}; } float HangingEntity::offs(int w) { @@ -253,4 +253,4 @@ void HangingEntity::readAdditionalSaveData(CompoundTag* tag) { setDir(dir); } -bool HangingEntity::repositionEntityAfterLoad() { return false; } \ No newline at end of file +bool HangingEntity::repositionEntityAfterLoad() { return false; } diff --git a/Minecraft.World/Entities/ItemEntity.cpp b/Minecraft.World/Entities/ItemEntity.cpp index 8725cbe5f..880971f67 100644 --- a/Minecraft.World/Entities/ItemEntity.cpp +++ b/Minecraft.World/Entities/ItemEntity.cpp @@ -119,8 +119,9 @@ void ItemEntity::tick() { } void ItemEntity::mergeWithNeighbours() { + AABB grown = bb->grow(0.5, 0, 0.5); std::vector >* neighbours = - level->getEntitiesOfClass(typeid(*this), bb->grow(0.5, 0, 0.5)); + level->getEntitiesOfClass(typeid(*this), &grown); for (AUTO_VAR(it, neighbours->begin()); it != neighbours->end(); ++it) { std::shared_ptr entity = std::dynamic_pointer_cast(*it); diff --git a/Minecraft.World/Entities/LargeFireball.cpp b/Minecraft.World/Entities/LargeFireball.cpp index 81677498d..5c2eb50a6 100644 --- a/Minecraft.World/Entities/LargeFireball.cpp +++ b/Minecraft.World/Entities/LargeFireball.cpp @@ -44,4 +44,4 @@ void LargeFireball::readAdditionalSaveData(CompoundTag* tag) { Fireball::readAdditionalSaveData(tag); if (tag->contains(L"ExplosionPower")) explosionPower = tag->getInt(L"ExplosionPower"); -} \ No newline at end of file +} diff --git a/Minecraft.World/Entities/LivingEntity.cpp b/Minecraft.World/Entities/LivingEntity.cpp index b4b870baf..8725643cf 100644 --- a/Minecraft.World/Entities/LivingEntity.cpp +++ b/Minecraft.World/Entities/LivingEntity.cpp @@ -1164,7 +1164,7 @@ void LivingEntity::teleportTo(double x, double y, double z) { } void LivingEntity::findStandUpPosition(std::shared_ptr vehicle) { - AABB* boundingBox; + AABB boundingBox; double fallbackX = vehicle->x; double fallbackY = vehicle->bb->y0 + vehicle->bbHeight; double fallbackZ = vehicle->z; @@ -1177,9 +1177,9 @@ void LivingEntity::findStandUpPosition(std::shared_ptr vehicle) { int xToInt = (int)(x + xDiff); int zToInt = (int)(z + zDiff); - boundingBox = bb->cloneMove(xDiff, 1, zDiff); + boundingBox = bb->move(xDiff, 1, zDiff); - if (level->getTileCubes(boundingBox, true)->empty()) { + if (level->getTileCubes(&boundingBox, true)->empty()) { if (level->isTopSolidBlocking(xToInt, (int)y, zToInt)) { teleportTo(x + xDiff, y + 1, z + zDiff); return; @@ -1511,9 +1511,9 @@ void LivingEntity::aiStep() { // collision used to be calculated as: bb->shrink(1 / 32.0, 0, 1 / 32.0) // now using a reduced BB to try and get rid of some issues where mobs // pop up the sides of walls, undersides of trees etc. - AABB* shrinkbb = bb->shrink(0.1, 0, 0.1); - shrinkbb->y1 = shrinkbb->y0 + 0.1; - AABBList* collisions = level->getCubes(shared_from_this(), shrinkbb); + AABB shrinkbb = bb->shrink(0.1, 0, 0.1); + shrinkbb.y1 = shrinkbb.y0 + 0.1; + AABBList* collisions = level->getCubes(shared_from_this(), &shrinkbb); if (collisions->size() > 0) { double yTop = 0; AUTO_VAR(itEnd, collisions->end()); @@ -1582,8 +1582,9 @@ void LivingEntity::aiStep() { void LivingEntity::newServerAiStep() {} void LivingEntity::pushEntities() { + AABB grown = bb->grow(0.2, 0, 0.2); std::vector >* entities = - level->getEntities(shared_from_this(), this->bb->grow(0.2f, 0, 0.2f)); + level->getEntities(shared_from_this(), &grown); if (entities != NULL && !entities->empty()) { AUTO_VAR(itEnd, entities->end()); for (AUTO_VAR(it, entities->begin()); it != itEnd; it++) { diff --git a/Minecraft.World/Entities/MinecartHopper.cpp b/Minecraft.World/Entities/MinecartHopper.cpp index 55b7ed3aa..43707b810 100644 --- a/Minecraft.World/Entities/MinecartHopper.cpp +++ b/Minecraft.World/Entities/MinecartHopper.cpp @@ -85,8 +85,9 @@ void MinecartHopper::tick() { bool MinecartHopper::suckInItems() { if (HopperTileEntity::suckInItems(this)) return true; + AABB grown = bb->grow(0.25, 0, 0.25); std::vector >* items = - level->getEntitiesOfClass(typeid(ItemEntity), bb->grow(0.25f, 0, 0.25f), + level->getEntitiesOfClass(typeid(ItemEntity), &grown, EntitySelector::ENTITY_STILL_ALIVE); if (items->size() > 0) { @@ -116,4 +117,4 @@ void MinecartHopper::readAdditionalSaveData(CompoundTag* base) { void MinecartHopper::setCooldown(int time) { cooldownTime = time; } -bool MinecartHopper::isOnCooldown() { return cooldownTime > 0; } \ No newline at end of file +bool MinecartHopper::isOnCooldown() { return cooldownTime > 0; } diff --git a/Minecraft.World/Entities/Mob.cpp b/Minecraft.World/Entities/Mob.cpp index 6b744faf8..b7fe61e1a 100644 --- a/Minecraft.World/Entities/Mob.cpp +++ b/Minecraft.World/Entities/Mob.cpp @@ -301,8 +301,9 @@ void Mob::aiStep() { if (!level->isClientSide && canPickUpLoot() && !dead && level->getGameRules()->getBoolean(GameRules::RULE_MOBGRIEFING)) { + AABB grown = bb->grow(1, 0, 1); std::vector >* entities = - level->getEntitiesOfClass(typeid(ItemEntity), bb->grow(1, 0, 1)); + level->getEntitiesOfClass(typeid(ItemEntity), &grown); for (AUTO_VAR(it, entities->begin()); it != entities->end(); ++it) { std::shared_ptr entity = std::dynamic_pointer_cast(*it); @@ -847,9 +848,10 @@ void Mob::restoreLeashFromSave() { if (_isLeashed && leashInfoTag != NULL) { if (leashInfoTag->contains(L"UUID")) { std::wstring leashUuid = leashInfoTag->getString(L"UUID"); + AABB grown = bb->grow(10, 10, 10); std::vector >* livingEnts = level->getEntitiesOfClass(typeid(LivingEntity), - bb->grow(10, 10, 10)); + &grown); for (AUTO_VAR(it, livingEnts->begin()); it != livingEnts->end(); ++it) { std::shared_ptr le = diff --git a/Minecraft.World/Entities/Mobs/Animal.cpp b/Minecraft.World/Entities/Mobs/Animal.cpp index b404a0102..8df5245d2 100644 --- a/Minecraft.World/Entities/Mobs/Animal.cpp +++ b/Minecraft.World/Entities/Mobs/Animal.cpp @@ -61,7 +61,7 @@ void Animal::aiStep() { void Animal::checkHurtTarget(std::shared_ptr target, float d) { // 4J-JEV: Changed from dynamic cast to use eINSTANCEOF - if (target->instanceof (eTYPE_PLAYER)) { + if (target->instanceof(eTYPE_PLAYER)) { if (d < 3) { double xd = target->x - x; double zd = target->z - z; @@ -77,7 +77,7 @@ void Animal::checkHurtTarget(std::shared_ptr target, float d) { } // 4J-JEV: Changed from dynamic cast to use eINSTANCEOF - else if (target->instanceof (eTYPE_ANIMAL)) { + else if (target->instanceof(eTYPE_ANIMAL)) { std::shared_ptr a = std::dynamic_pointer_cast(target); if (getAge() > 0 && a->getAge() < 0) { if (d < 2.5) { @@ -162,22 +162,22 @@ bool Animal::hurt(DamageSource* dmgSource, float dmg) { std::shared_ptr source = dmgSource->getDirectEntity(); // 4J-JEV: Changed from dynamic cast to use eINSTANCEOF - if (source->instanceof - (eTYPE_PLAYER) && !std::dynamic_pointer_cast(source) - ->isAllowedToAttackAnimals()) { + if (source->instanceof(eTYPE_PLAYER) && + !std::dynamic_pointer_cast(source) + ->isAllowedToAttackAnimals()) { return false; } - if ((source != NULL) && source->instanceof (eTYPE_ARROW)) { + if ((source != NULL) && source->instanceof(eTYPE_ARROW)) { std::shared_ptr arrow = std::dynamic_pointer_cast(source); // 4J: Check that the arrow's owner can attack animals (dispenser // arrows are not owned) - if (arrow->owner != NULL && arrow->owner->instanceof - (eTYPE_PLAYER) && - !std::dynamic_pointer_cast(arrow->owner) - ->isAllowedToAttackAnimals()) { + if (arrow->owner != NULL && + arrow->owner->instanceof(eTYPE_PLAYER) && + !std::dynamic_pointer_cast(arrow->owner) + ->isAllowedToAttackAnimals()) { return false; } } @@ -216,8 +216,9 @@ std::shared_ptr Animal::findAttackTarget() { float r = 8; if (getInLoveValue() > 0) { + AABB grown = bb->grow(r, r, r); std::vector >* others = - level->getEntitiesOfClass(typeid(*this), bb->grow(r, r, r)); + level->getEntitiesOfClass(typeid(*this), &grown); // for (int i = 0; i < others->size(); i++) for (AUTO_VAR(it, others->begin()); it != others->end(); ++it) { std::shared_ptr p = std::dynamic_pointer_cast(*it); @@ -229,8 +230,9 @@ std::shared_ptr Animal::findAttackTarget() { delete others; } else { if (getAge() == 0) { + AABB grown = bb->grow(r, r, r); std::vector >* players = - level->getEntitiesOfClass(typeid(Player), bb->grow(r, r, r)); + level->getEntitiesOfClass(typeid(Player), &grown); // for (int i = 0; i < players.size(); i++) for (AUTO_VAR(it, players->begin()); it != players->end(); ++it) { setDespawnProtected(); @@ -245,8 +247,9 @@ std::shared_ptr Animal::findAttackTarget() { } delete players; } else if (getAge() > 0) { + AABB grown = bb->grow(r, r, r); std::vector >* others = - level->getEntitiesOfClass(typeid(*this), bb->grow(r, r, r)); + level->getEntitiesOfClass(typeid(*this), &grown); // for (int i = 0; i < others.size(); i++) for (AUTO_VAR(it, others->begin()); it != others->end(); ++it) { std::shared_ptr p = @@ -332,7 +335,7 @@ bool Animal::mobInteract(std::shared_ptr player) { return false; } - } else if (instanceof (eTYPE_MONSTER)) { + } else if (instanceof(eTYPE_MONSTER)) { } break; } diff --git a/Minecraft.World/Entities/Mobs/Arrow.cpp b/Minecraft.World/Entities/Mobs/Arrow.cpp index 5de30c9a4..6c02a0eea 100644 --- a/Minecraft.World/Entities/Mobs/Arrow.cpp +++ b/Minecraft.World/Entities/Mobs/Arrow.cpp @@ -185,7 +185,7 @@ void Arrow::tick() { Tile::tiles[t]->updateShape(level, xTile, yTile, zTile); AABB* aabb = Tile::tiles[t]->getAABB(level, xTile, yTile, zTile); Vec3 pos{x, y, z}; - if (aabb != NULL && aabb->contains(&pos)) { + if (aabb != NULL && aabb->contains(pos)) { inGround = true; } } @@ -230,8 +230,9 @@ void Arrow::tick() { } std::shared_ptr hitEntity = nullptr; - std::vector >* objects = level->getEntities( - shared_from_this(), this->bb->expand(xd, yd, zd)->grow(1, 1, 1)); + AABB grown = bb->expand(xd, yd, zd).grow(1, 1, 1); + std::vector >* objects = + level->getEntities(shared_from_this(), &grown); double nearest = 0; AUTO_VAR(itEnd, objects->end()); for (AUTO_VAR(it, objects->begin()); it != itEnd; it++) { @@ -239,8 +240,8 @@ void Arrow::tick() { if (!e->isPickable() || (e == owner && flightTime < 5)) continue; float rr = 0.3f; - AABB* bb = e->bb->grow(rr, rr, rr); - HitResult* p = bb->clip(&from, &to); + AABB bb = e->bb->grow(rr, rr, rr); + HitResult* p = bb.clip(from, to); if (p != NULL) { double dd = from.distanceTo(p->pos); if (dd < nearest || nearest == 0) { diff --git a/Minecraft.World/Entities/Mobs/Boat.cpp b/Minecraft.World/Entities/Mobs/Boat.cpp index 356dacf57..f379b068e 100644 --- a/Minecraft.World/Entities/Mobs/Boat.cpp +++ b/Minecraft.World/Entities/Mobs/Boat.cpp @@ -345,8 +345,9 @@ void Boat::tick() { if (level->isClientSide) return; + AABB grown = bb->grow(0.2, 0, 0.2); std::vector >* entities = - level->getEntities(shared_from_this(), bb->grow(0.2f, 0, 0.2f)); + level->getEntities(shared_from_this(), &grown); if (entities != NULL && !entities->empty()) { AUTO_VAR(itEnd, entities->end()); for (AUTO_VAR(it, entities->begin()); it != itEnd; it++) { diff --git a/Minecraft.World/Entities/Mobs/DragonFireball.cpp b/Minecraft.World/Entities/Mobs/DragonFireball.cpp index 62f4a067c..11607882a 100644 --- a/Minecraft.World/Entities/Mobs/DragonFireball.cpp +++ b/Minecraft.World/Entities/Mobs/DragonFireball.cpp @@ -29,9 +29,9 @@ DragonFireball::DragonFireball(Level* level, double x, double y, double z, void DragonFireball::onHit(HitResult* res) { if (!level->isClientSide) { - AABB* aoe = bb->grow(SPLASH_RANGE, SPLASH_RANGE / 2, SPLASH_RANGE); + AABB aoe = bb->grow(SPLASH_RANGE, SPLASH_RANGE / 2, SPLASH_RANGE); std::vector >* entitiesOfClass = - level->getEntitiesOfClass(typeid(LivingEntity), aoe); + level->getEntitiesOfClass(typeid(LivingEntity), &aoe); if (entitiesOfClass != NULL && !entitiesOfClass->empty()) { // for (Entity e : entitiesOfClass) diff --git a/Minecraft.World/Entities/Mobs/EnderDragon.cpp b/Minecraft.World/Entities/Mobs/EnderDragon.cpp index 4625557e2..7f9697bc3 100644 --- a/Minecraft.World/Entities/Mobs/EnderDragon.cpp +++ b/Minecraft.World/Entities/Mobs/EnderDragon.cpp @@ -646,12 +646,17 @@ void EnderDragon::aiStep() { if (!level->isClientSide) checkAttack(); if (!level->isClientSide && hurtDuration == 0) { + AABB wing_mov = wing1->bb->grow(4, 2, 4).move(0, -2, 0); knockBack(level->getEntities(shared_from_this(), - wing1->bb->grow(4, 2, 4)->move(0, -2, 0))); + &wing_mov)); + wing_mov = wing2->bb->grow(4, 2, 4).move(0, -2, 0); knockBack(level->getEntities(shared_from_this(), - wing2->bb->grow(4, 2, 4)->move(0, -2, 0))); - hurt(level->getEntities(shared_from_this(), neck->bb->grow(1, 1, 1))); - hurt(level->getEntities(shared_from_this(), head->bb->grow(1, 1, 1))); + &wing_mov)); + + AABB neck_bb = neck->bb->grow(1, 1, 1); + AABB head_bb = head->bb->grow(1, 1, 1); + hurt(level->getEntities(shared_from_this(), &neck_bb)); + hurt(level->getEntities(shared_from_this(), &head_bb)); } double p1components[3]; @@ -684,8 +689,8 @@ void EnderDragon::aiStep() { double acidX = x + ss * 9.5f * ccTilt; double acidY = y + yOffset + ssTilt * 10.5f; double acidZ = z - cc * 9.5f * ccTilt; - m_acidArea->set(acidX - 5, acidY - 17, acidZ - 5, acidX + 5, acidY + 4, - acidZ + 5); + *m_acidArea = {acidX - 5, acidY - 17, acidZ - 5, acidX + 5, acidY + 4, + acidZ + 5}; // app.DebugPrintf("\nDragon is %s, yRot = %f, yRotA = %f, ss = %f, cc = // %f, ccTilt = %f\n",level->isClientSide?"client":"server", yRot, @@ -811,9 +816,11 @@ void EnderDragon::checkCrystals() { if (random->nextInt(10) == 0) { float maxDist = 32; + AABB grown = +bb->grow(maxDist, maxDist, maxDist); std::vector >* crystals = level->getEntitiesOfClass(typeid(EnderCrystal), - bb->grow(maxDist, maxDist, maxDist)); + &grown); std::shared_ptr crystal = nullptr; double nearest = std::numeric_limits::max(); @@ -1422,8 +1429,9 @@ EnderDragon::EEnderdragonAction EnderDragon::getSynchedAction() { void EnderDragon::handleCrystalDestroyed(DamageSource* source) { AABB* tempBB = AABB::newTemp(PODIUM_X_POS, 84.0, PODIUM_Z_POS, PODIUM_X_POS + 1.0, 85.0, PODIUM_Z_POS + 1.0); + AABB grown = tempBB->grow(48, 40, 48); std::vector >* crystals = level->getEntitiesOfClass( - typeid(EnderCrystal), tempBB->grow(48, 40, 48)); + typeid(EnderCrystal), &grown); m_remainingCrystalsCount = (int)crystals->size() - 1; if (m_remainingCrystalsCount < 0) m_remainingCrystalsCount = 0; delete crystals; diff --git a/Minecraft.World/Entities/Mobs/EntityHorse.cpp b/Minecraft.World/Entities/Mobs/EntityHorse.cpp index 65502c329..cd2563466 100644 --- a/Minecraft.World/Entities/Mobs/EntityHorse.cpp +++ b/Minecraft.World/Entities/Mobs/EntityHorse.cpp @@ -420,9 +420,9 @@ std::shared_ptr EntityHorse::getClosestMommy( double closestDistance = std::numeric_limits::max(); std::shared_ptr mommy = nullptr; - std::vector >* list = level->getEntities( - baby, baby->bb->expand(searchRadius, searchRadius, searchRadius), - PARENT_HORSE_SELECTOR); + AABB expanded = baby->bb->expand(searchRadius, searchRadius, searchRadius); + std::vector >* list = + level->getEntities(baby, &expanded, PARENT_HORSE_SELECTOR); for (AUTO_VAR(it, list->begin()); it != list->end(); ++it) { std::shared_ptr horse = *it; diff --git a/Minecraft.World/Entities/Mobs/Fireball.cpp b/Minecraft.World/Entities/Mobs/Fireball.cpp index 91bfe34f7..b6613549c 100644 --- a/Minecraft.World/Entities/Mobs/Fireball.cpp +++ b/Minecraft.World/Entities/Mobs/Fireball.cpp @@ -176,8 +176,9 @@ void Fireball::tick() { to = Vec3{res->pos.x, res->pos.y, res->pos.z}; } std::shared_ptr hitEntity = nullptr; - std::vector >* objects = level->getEntities( - shared_from_this(), bb->expand(xd, yd, zd)->grow(1, 1, 1)); + AABB grown = bb->expand(xd, yd, zd).grow(1, 1, 1); + std::vector >* objects = + level->getEntities(shared_from_this(), &grown); double nearest = 0; AUTO_VAR(itEnd, objects->end()); for (AUTO_VAR(it, objects->begin()); it != itEnd; it++) { @@ -187,8 +188,8 @@ void Fireball::tick() { // && flightTime < 25)) continue; float rr = 0.3f; - AABB* bb = e->bb->grow(rr, rr, rr); - HitResult* p = bb->clip(&from, &to); + AABB bb = e->bb->grow(rr, rr, rr); + HitResult* p = bb.clip(from, to); if (p != NULL) { double dd = from.distanceTo(p->pos); if (dd < nearest || nearest == 0) { diff --git a/Minecraft.World/Entities/Mobs/FishingHook.cpp b/Minecraft.World/Entities/Mobs/FishingHook.cpp index b8cc293bf..76a4d5b07 100644 --- a/Minecraft.World/Entities/Mobs/FishingHook.cpp +++ b/Minecraft.World/Entities/Mobs/FishingHook.cpp @@ -213,8 +213,9 @@ void FishingHook::tick() { to = Vec3(res->pos.x, res->pos.y, res->pos.z); } std::shared_ptr hitEntity = nullptr; - std::vector >* objects = level->getEntities( - shared_from_this(), bb->expand(xd, yd, zd)->grow(1, 1, 1)); + AABB grown = bb->expand(xd, yd, zd).grow(1, 1, 1); + std::vector >* objects = + level->getEntities(shared_from_this(), &grown); double nearest = 0; AUTO_VAR(itEnd, objects->end()); for (AUTO_VAR(it, objects->begin()); it != itEnd; it++) { @@ -222,8 +223,8 @@ void FishingHook::tick() { if (!e->isPickable() || (e == owner && flightTime < 5)) continue; float rr = 0.3f; - AABB* bb = e->bb->grow(rr, rr, rr); - HitResult* p = bb->clip(&from, &to); + AABB bb = e->bb->grow(rr, rr, rr); + HitResult* p = bb.clip(from, to); if (p != NULL) { double dd = from.distanceTo(p->pos); if (dd < nearest || nearest == 0) { diff --git a/Minecraft.World/Entities/Mobs/Ghast.cpp b/Minecraft.World/Entities/Mobs/Ghast.cpp index 6dedd39ef..40c65a43c 100644 --- a/Minecraft.World/Entities/Mobs/Ghast.cpp +++ b/Minecraft.World/Entities/Mobs/Ghast.cpp @@ -170,10 +170,10 @@ bool Ghast::canReach(double xt, double yt, double zt, double dist) { double yd = (yTarget - y) / dist; double zd = (zTarget - z) / dist; - AABB* bb = this->bb->copy(); + AABB bb = *this->bb; for (int d = 1; d < dist; d++) { - bb->move(xd, yd, zd); - if (!level->getCubes(shared_from_this(), bb)->empty()) return false; + bb.move(xd, yd, zd); + if (!level->getCubes(shared_from_this(), &bb)->empty()) return false; } return true; diff --git a/Minecraft.World/Entities/Mobs/Minecart.cpp b/Minecraft.World/Entities/Mobs/Minecart.cpp index 8f0350096..16dcbb183 100644 --- a/Minecraft.World/Entities/Mobs/Minecart.cpp +++ b/Minecraft.World/Entities/Mobs/Minecart.cpp @@ -305,8 +305,9 @@ void Minecart::tick() { } setRot(yRot, xRot); + AABB grown = bb->grow(0.2, 0, 0.2); std::vector >* entities = - level->getEntities(shared_from_this(), bb->grow(0.2f, 0, 0.2f)); + level->getEntities(shared_from_this(), &grown); if (entities != NULL && !entities->empty()) { AUTO_VAR(itEnd, entities->end()); for (AUTO_VAR(it, entities->begin()); it != itEnd; it++) { diff --git a/Minecraft.World/Entities/Mobs/PigZombie.cpp b/Minecraft.World/Entities/Mobs/PigZombie.cpp index e619286cb..0c016c83f 100644 --- a/Minecraft.World/Entities/Mobs/PigZombie.cpp +++ b/Minecraft.World/Entities/Mobs/PigZombie.cpp @@ -100,8 +100,9 @@ std::shared_ptr PigZombie::findAttackTarget() { bool PigZombie::hurt(DamageSource* source, float dmg) { std::shared_ptr sourceEntity = source->getEntity(); if (sourceEntity != NULL && sourceEntity->instanceof(eTYPE_PLAYER)) { + AABB grown = bb->grow(32, 32, 32); std::vector >* nearby = - level->getEntities(shared_from_this(), bb->grow(32, 32, 32)); + level->getEntities(shared_from_this(), &grown); AUTO_VAR(itEnd, nearby->end()); for (AUTO_VAR(it, nearby->begin()); it != itEnd; it++) { std::shared_ptr e = *it; // nearby->at(i); @@ -158,4 +159,4 @@ MobGroupData* PigZombie::finalizeMobSpawn( Zombie::finalizeMobSpawn(groupData); setVillager(false); return groupData; -} \ No newline at end of file +} diff --git a/Minecraft.World/Entities/Mobs/Squid.cpp b/Minecraft.World/Entities/Mobs/Squid.cpp index 951d7b511..7cb96c08d 100644 --- a/Minecraft.World/Entities/Mobs/Squid.cpp +++ b/Minecraft.World/Entities/Mobs/Squid.cpp @@ -65,7 +65,8 @@ void Squid::dropDeathLoot(bool wasKilledByPlayer, int playerBonusLevel) { } bool Squid::isInWater() { - return level->checkAndHandleWater(bb->grow(0, -0.6f, 0), Material::water, + AABB grown = bb->grow(0, -0.6, 0); + return level->checkAndHandleWater(&grown, Material::water, shared_from_this()); } diff --git a/Minecraft.World/Entities/Mobs/ThrownPotion.cpp b/Minecraft.World/Entities/Mobs/ThrownPotion.cpp index 7bfc9cf6a..da329189c 100644 --- a/Minecraft.World/Entities/Mobs/ThrownPotion.cpp +++ b/Minecraft.World/Entities/Mobs/ThrownPotion.cpp @@ -82,9 +82,9 @@ void ThrownPotion::onHit(HitResult* res) { Item::potion->getMobEffects(potionItem); if (mobEffects != NULL && !mobEffects->empty()) { - AABB* aoe = bb->grow(SPLASH_RANGE, SPLASH_RANGE / 2, SPLASH_RANGE); + AABB aoe = bb->grow(SPLASH_RANGE, SPLASH_RANGE / 2, SPLASH_RANGE); std::vector >* entitiesOfClass = - level->getEntitiesOfClass(typeid(LivingEntity), aoe); + level->getEntitiesOfClass(typeid(LivingEntity), &aoe); if (entitiesOfClass != NULL && !entitiesOfClass->empty()) { // for (Entity e : entitiesOfClass) diff --git a/Minecraft.World/Entities/Mobs/WitherBoss.cpp b/Minecraft.World/Entities/Mobs/WitherBoss.cpp index 092e810ea..80316042e 100644 --- a/Minecraft.World/Entities/Mobs/WitherBoss.cpp +++ b/Minecraft.World/Entities/Mobs/WitherBoss.cpp @@ -252,9 +252,9 @@ void WitherBoss::newServerAiStep() { idleHeadUpdates[i - 1] = 0; } } else { + AABB grown = bb->grow(20, 8, 20); std::vector >* entities = - level->getEntitiesOfClass(typeid(LivingEntity), - bb->grow(20, 8, 20), + level->getEntitiesOfClass(typeid(LivingEntity), &grown, livingEntitySelector); // randomly try to find a target 10 times for (int attempt = 0; attempt < 10 && !entities->empty(); diff --git a/Minecraft.World/Entities/Throwable.cpp b/Minecraft.World/Entities/Throwable.cpp index 93e9a9701..056129287 100644 --- a/Minecraft.World/Entities/Throwable.cpp +++ b/Minecraft.World/Entities/Throwable.cpp @@ -147,8 +147,9 @@ void Throwable::tick() { if (!level->isClientSide) { std::shared_ptr hitEntity = nullptr; - std::vector >* objects = level->getEntities( - shared_from_this(), bb->expand(xd, yd, zd)->grow(1, 1, 1)); + AABB grown = bb->expand(xd, yd, zd).grow(1, 1, 1); + std::vector >* objects = + level->getEntities(shared_from_this(), &grown); double nearest = 0; std::shared_ptr owner = getOwner(); for (int i = 0; i < objects->size(); i++) { @@ -156,8 +157,8 @@ void Throwable::tick() { if (!e->isPickable() || (e == owner && flightTime < 5)) continue; float rr = 0.3f; - AABB* bb = e->bb->grow(rr, rr, rr); - HitResult* p = bb->clip(&from, &to); + AABB bb = e->bb->grow(rr, rr, rr); + HitResult* p = bb.clip(from, to); if (p != NULL) { double dd = from.distanceTo(p->pos); delete p; diff --git a/Minecraft.World/Entities/WitherSkull.cpp b/Minecraft.World/Entities/WitherSkull.cpp index 81a6a4cca..049309c04 100644 --- a/Minecraft.World/Entities/WitherSkull.cpp +++ b/Minecraft.World/Entities/WitherSkull.cpp @@ -105,4 +105,4 @@ void WitherSkull::setDangerous(bool value) { entityData->set(DATA_DANGEROUS, value ? (uint8_t)1 : (uint8_t)0); } -bool WitherSkull::shouldBurn() { return false; } \ No newline at end of file +bool WitherSkull::shouldBurn() { return false; } diff --git a/Minecraft.World/Items/BoatItem.cpp b/Minecraft.World/Items/BoatItem.cpp index d84290919..0c4d6a1b9 100644 --- a/Minecraft.World/Items/BoatItem.cpp +++ b/Minecraft.World/Items/BoatItem.cpp @@ -83,17 +83,18 @@ std::shared_ptr BoatItem::use( Vec3 b = player->getViewVector(a); bool hitEntity = false; float overlap = 1; - std::vector >* objects = level->getEntities( - player, player->bb->expand(b.x * (range), b.y * (range), b.z * (range)) - ->grow(overlap, overlap, overlap)); + AABB grown = player->bb->expand(b.x * (range), b.y * (range), b.z * (range)) + .grow(overlap, overlap, overlap); + std::vector >* objects = + level->getEntities(player, &grown); // for (int i = 0; i < objects.size(); i++) { for (AUTO_VAR(it, objects->begin()); it != objects->end(); ++it) { std::shared_ptr e = *it; // objects.get(i); if (!e->isPickable()) continue; float rr = e->getPickRadius(); - AABB* bb = e->bb->grow(rr, rr, rr); - if (bb->contains(&from)) { + AABB bb = e->bb->grow(rr, rr, rr); + if (bb.contains(from)) { hitEntity = true; } } @@ -115,8 +116,8 @@ std::shared_ptr BoatItem::use( boat->yRot = ((Mth::floor(player->yRot * 4.0F / 360.0F + 0.5) & 0x3) - 1) * 90; - if (!level->getCubes(boat, boat->bb->grow(-.1, -.1, -.1)) - ->empty()) { + AABB grown = boat->bb->grow(-0.1, -0.1, -0.1); + if (!level->getCubes(boat, &grown)->empty()) { return itemInstance; } if (!level->isClientSide) { diff --git a/Minecraft.World/Level/BaseMobSpawner.cpp b/Minecraft.World/Level/BaseMobSpawner.cpp index 522290eec..bf6fcb51c 100644 --- a/Minecraft.World/Level/BaseMobSpawner.cpp +++ b/Minecraft.World/Level/BaseMobSpawner.cpp @@ -83,14 +83,13 @@ void BaseMobSpawner::tick() { EntityIO::newEntity(getEntityId(), getLevel()); if (entity == NULL) return; - int nearBy = - getLevel() - ->getEntitiesOfClass( - typeid(entity.get()), - AABB::newTemp(getX(), getY(), getZ(), getX() + 1, - getY() + 1, getZ() + 1) - ->grow(spawnRange * 2, 4, spawnRange * 2)) - ->size(); + AABB grown = + AABB(getX(), getY(), getZ(), getX() + 1, getY() + 1, getZ() + 1) + .grow(spawnRange * 2, 4, spawnRange * 2); + + int nearBy = getLevel() + ->getEntitiesOfClass(typeid(entity.get()), &grown) + ->size(); if (nearBy >= maxNearbyEntities) { delay(); return; @@ -359,4 +358,4 @@ CompoundTag* BaseMobSpawner::SpawnData::save() { result->putInt(L"Weight", randomWeight); return result; -} \ No newline at end of file +} diff --git a/Minecraft.World/Level/Level.cpp b/Minecraft.World/Level/Level.cpp index f61f88c8b..cd572cbf7 100644 --- a/Minecraft.World/Level/Level.cpp +++ b/Minecraft.World/Level/Level.cpp @@ -1798,17 +1798,18 @@ AABBList* Level::getCubes(std::shared_ptr source, AABB* box, if (noEntities) return &boxes; double r = 0.25; + AABB grown = box->grow(r, r, r); std::vector >* ee = - getEntities(source, box->grow(r, r, r)); + getEntities(source, &grown); std::vector >::iterator itEnd = ee->end(); for (AUTO_VAR(it, ee->begin()); it != itEnd; it++) { AABB* collideBox = (*it)->getCollideBox(); - if (collideBox != NULL && collideBox->intersects(box)) { + if (collideBox != NULL && collideBox->intersects(*box)) { boxes.push_back(collideBox); } collideBox = source->getCollideAgainstBox(*it); - if (collideBox != NULL && collideBox->intersects(box)) { + if (collideBox != NULL && collideBox->intersects(*box)) { boxes.push_back(collideBox); } } diff --git a/Minecraft.World/Level/LevelChunk.cpp b/Minecraft.World/Level/LevelChunk.cpp index 71c285e5c..c5c0632ef 100644 --- a/Minecraft.World/Level/LevelChunk.cpp +++ b/Minecraft.World/Level/LevelChunk.cpp @@ -1691,7 +1691,7 @@ void LevelChunk::getEntities(std::shared_ptr except, AABB* bb, AUTO_VAR(itEnd, entities->end()); for (AUTO_VAR(it, entities->begin()); it != itEnd; it++) { std::shared_ptr e = *it; // entities->at(i); - if (e != except && e->bb->intersects(bb) && + if (e != except && e->bb->intersects(*bb) && (selector == NULL || selector->matches(e))) { es.push_back(e); std::vector >* subs = @@ -1699,7 +1699,7 @@ void LevelChunk::getEntities(std::shared_ptr except, AABB* bb, if (subs != NULL) { for (int j = 0; j < subs->size(); j++) { e = subs->at(j); - if (e != except && e->bb->intersects(bb) && + if (e != except && e->bb->intersects(*bb) && (selector == NULL || selector->matches(e))) { es.push_back(e); } @@ -1765,7 +1765,7 @@ void LevelChunk::getEntitiesOfClass(const std::type_info& ec, AABB* bb, else if (Entity* entity = e.get(); entity != NULL && ec == typeid(*entity)) isAssignableFrom = true; - if (isAssignableFrom && e->bb->intersects(bb)) { + if (isAssignableFrom && e->bb->intersects(*bb)) { if (selector == NULL || selector->matches(e)) { es.push_back(e); } diff --git a/Minecraft.World/Player/Player.cpp b/Minecraft.World/Player/Player.cpp index a345d2087..fff23c15e 100644 --- a/Minecraft.World/Player/Player.cpp +++ b/Minecraft.World/Player/Player.cpp @@ -961,17 +961,17 @@ void Player::aiStep() { tilt += (tTilt - tilt) * 0.8f; if (getHealth() > 0) { - AABB* pickupArea = NULL; + AABB pickupArea; if (riding != NULL && !riding->removed) { // if the player is riding, also touch entities under the // pig/horse - pickupArea = bb->minmax(riding->bb)->grow(1, 0, 1); + pickupArea = bb->minmax(*riding->bb).grow(1, 0, 1); } else { pickupArea = bb->grow(1, .5, 1); } std::vector >* entities = - level->getEntities(shared_from_this(), pickupArea); + level->getEntities(shared_from_this(), &pickupArea); if (entities != NULL) { AUTO_VAR(itEnd, entities->end()); for (AUTO_VAR(it, entities->begin()); it != itEnd; it++) { diff --git a/Minecraft.World/Util/AABB.cpp b/Minecraft.World/Util/AABB.cpp index 2cb797e38..53b4412f3 100644 --- a/Minecraft.World/Util/AABB.cpp +++ b/Minecraft.World/Util/AABB.cpp @@ -3,8 +3,11 @@ // import java->util.ArrayList; // import java->util.List; +// TODO: use brace initialization everywhere + #include "../Platform/stdafx.h" #include "AABB.h" +#include #include #include "HitResult.h" #include "Util/Vec3.h" @@ -50,7 +53,7 @@ AABB* AABB::newTemp(double x0, double y0, double z0, double x1, double y1, double z1) { ThreadStorage* tls = m_tlsPool; AABB* thisAABB = &tls->pool[tls->poolPointer]; - thisAABB->set(x0, y0, z0, x1, y1, z1); + *thisAABB = {x0, y0, z0, x1, y1, z1}; tls->poolPointer = (tls->poolPointer + 1) % ThreadStorage::POOL_SIZE; return thisAABB; } @@ -64,18 +67,7 @@ AABB::AABB(double x0, double y0, double z0, double x1, double y1, double z1) { this->z1 = z1; } -AABB* AABB::set(double x0, double y0, double z0, double x1, double y1, - double z1) { - this->x0 = x0; - this->y0 = y0; - this->z0 = z0; - this->x1 = x1; - this->y1 = y1; - this->z1 = z1; - return this; -} - -AABB* AABB::expand(double xa, double ya, double za) { +AABB AABB::expand(double xa, double ya, double za) const { double _x0 = x0; double _y0 = y0; double _z0 = z0; @@ -92,10 +84,10 @@ AABB* AABB::expand(double xa, double ya, double za) { if (za < 0) _z0 += za; if (za > 0) _z1 += za; - return AABB::newTemp(_x0, _y0, _z0, _x1, _y1, _z1); + return {_x0, _y0, _z0, _x1, _y1, _z1}; } -AABB* AABB::grow(double xa, double ya, double za) { +AABB AABB::grow(const double xa, const double ya, const double za) const { double _x0 = x0 - xa; double _y0 = y0 - ya; double _z0 = z0 - za; @@ -103,127 +95,121 @@ AABB* AABB::grow(double xa, double ya, double za) { double _y1 = y1 + ya; double _z1 = z1 + za; - return AABB::newTemp(_x0, _y0, _z0, _x1, _y1, _z1); + return {_x0, _y0, _z0, _x1, _y1, _z1}; } -AABB* AABB::minmax(AABB* other) { - double _x0 = std::min(x0, other->x0); - double _y0 = std::min(y0, other->y0); - double _z0 = std::min(z0, other->z0); - double _x1 = std::max(x1, other->x1); - double _y1 = std::max(y1, other->y1); - double _z1 = std::max(z1, other->z1); +AABB AABB::minmax(const AABB& other) const { + double _x0 = std::min(x0, other.x0); + double _y0 = std::min(y0, other.y0); + double _z0 = std::min(z0, other.z0); + double _x1 = std::max(x1, other.x1); + double _y1 = std::max(y1, other.y1); + double _z1 = std::max(z1, other.z1); - return newTemp(_x0, _y0, _z0, _x1, _y1, _z1); + return {_x0, _y0, _z0, _x1, _y1, _z1}; } -AABB* AABB::cloneMove(double xa, double ya, double za) { - return AABB::newTemp(x0 + xa, y0 + ya, z0 + za, x1 + xa, y1 + ya, z1 + za); -} +double AABB::clipXCollide(const AABB& c, double xa) const { + if (c.y1 <= y0 || c.y0 >= y1) return xa; + if (c.z1 <= z0 || c.z0 >= z1) return xa; -double AABB::clipXCollide(AABB* c, double xa) { - if (c->y1 <= y0 || c->y0 >= y1) return xa; - if (c->z1 <= z0 || c->z0 >= z1) return xa; - - if (xa > 0 && c->x1 <= x0) { - double max = x0 - c->x1; + if (xa > 0 && c.x1 <= x0) { + double max = x0 - c.x1; if (max < xa) xa = max; } - if (xa < 0 && c->x0 >= x1) { - double max = x1 - c->x0; + + if (xa < 0 && c.x0 >= x1) { + double max = x1 - c.x0; if (max > xa) xa = max; } return xa; } -double AABB::clipYCollide(AABB* c, double ya) { - if (c->x1 <= x0 || c->x0 >= x1) return ya; - if (c->z1 <= z0 || c->z0 >= z1) return ya; +double AABB::clipYCollide(const AABB& c, double ya) const { + if (c.x1 <= x0 || c.x0 >= x1) return ya; + if (c.z1 <= z0 || c.z0 >= z1) return ya; - if (ya > 0 && c->y1 <= y0) { - double max = y0 - c->y1; + if (ya > 0 && c.y1 <= y0) { + double max = y0 - c.y1; if (max < ya) ya = max; } - if (ya < 0 && c->y0 >= y1) { - double max = y1 - c->y0; + + if (ya < 0 && c.y0 >= y1) { + double max = y1 - c.y0; if (max > ya) ya = max; } return ya; } -double AABB::clipZCollide(AABB* c, double za) { - if (c->x1 <= x0 || c->x0 >= x1) return za; - if (c->y1 <= y0 || c->y0 >= y1) return za; +double AABB::clipZCollide(const AABB& c, double za) const { + if (c.x1 <= x0 || c.x0 >= x1) return za; + if (c.y1 <= y0 || c.y0 >= y1) return za; - if (za > 0 && c->z1 <= z0) { - double max = z0 - c->z1; + if (za > 0 && c.z1 <= z0) { + double max = z0 - c.z1; if (max < za) za = max; } - if (za < 0 && c->z0 >= z1) { - double max = z1 - c->z0; + + if (za < 0 && c.z0 >= z1) { + double max = z1 - c.z0; if (max > za) za = max; } return za; } -bool AABB::intersects(AABB* c) { - if (c->x1 <= x0 || c->x0 >= x1) return false; - if (c->y1 <= y0 || c->y0 >= y1) return false; - if (c->z1 <= z0 || c->z0 >= z1) return false; +bool AABB::intersects(const AABB& c) const { + if (c.x1 <= x0 || c.x0 >= x1) return false; + if (c.y1 <= y0 || c.y0 >= y1) return false; + if (c.z1 <= z0 || c.z0 >= z1) return false; return true; } -bool AABB::intersectsInner(AABB* c) { - if (c->x1 < x0 || c->x0 > x1) return false; - if (c->y1 < y0 || c->y0 > y1) return false; - if (c->z1 < z0 || c->z0 > z1) return false; - return true; +AABB AABB::move(const double xa, const double ya, const double za) const { + return { + x0 + xa, y0 + ya, z0 + za, + + x1 + xa, y1 + ya, z1 + za, + }; } -AABB* AABB::move(double xa, double ya, double za) { - x0 += xa; - y0 += ya; - z0 += za; - x1 += xa; - y1 += ya; - z1 += za; - return this; -} - -bool AABB::intersects(double x02, double y02, double z02, double x12, - double y12, double z12) { +bool AABB::intersects(const double x02, const double y02, const double z02, + const double x12, const double y12, + const double z12) const { if (x12 <= x0 || x02 >= x1) return false; if (y12 <= y0 || y02 >= y1) return false; if (z12 <= z0 || z02 >= z1) return false; + return true; } -bool AABB::contains(Vec3* p) { - if (p->x <= x0 || p->x >= x1) return false; - if (p->y <= y0 || p->y >= y1) return false; - if (p->z <= z0 || p->z >= z1) return false; +bool AABB::contains(const Vec3& p) const { + if (p.x <= x0 || p.x >= x1) return false; + if (p.y <= y0 || p.y >= y1) return false; + if (p.z <= z0 || p.z >= z1) return false; + return true; } // 4J Added -bool AABB::containsIncludingLowerBound(Vec3* p) { - if (p->x < x0 || p->x >= x1) return false; - if (p->y < y0 || p->y >= y1) return false; - if (p->z < z0 || p->z >= z1) return false; +bool AABB::containsIncludingLowerBound(const Vec3& p) const { + if (p.x < x0 || p.x >= x1) return false; + if (p.y < y0 || p.y >= y1) return false; + if (p.z < z0 || p.z >= z1) return false; return true; } -double AABB::getSize() { - double xs = x1 - x0; - double ys = y1 - y0; - double zs = z1 - z0; +double AABB::getSize() const { + const double xs = x1 - x0; + const double ys = y1 - y0; + const double zs = z1 - z0; + return (xs + ys + zs) / 3.0f; } -AABB* AABB::shrink(double xa, double ya, double za) { +AABB AABB::shrink(const double xa, const double ya, const double za) const { double _x0 = x0 + xa; double _y0 = y0 + ya; double _z0 = z0 + za; @@ -231,58 +217,50 @@ AABB* AABB::shrink(double xa, double ya, double za) { double _y1 = y1 - ya; double _z1 = z1 - za; - return AABB::newTemp(_x0, _y0, _z0, _x1, _y1, _z1); + return {_x0, _y0, _z0, _x1, _y1, _z1}; } -AABB* AABB::copy() { return AABB::newTemp(x0, y0, z0, x1, y1, z1); } +HitResult* AABB::clip(const Vec3& a, const Vec3& b) const { + auto xh0 = a.clipX(b, x0); + auto xh1 = a.clipX(b, x1); -HitResult* AABB::clip(Vec3* a, Vec3* b) { - auto xh0 = a->clipX(*b, x0); - auto xh1 = a->clipX(*b, x1); + auto yh0 = a.clipY(b, y0); + auto yh1 = a.clipY(b, y1); - auto yh0 = a->clipY(*b, y0); - auto yh1 = a->clipY(*b, y1); + auto zh0 = a.clipZ(b, z0); + auto zh1 = a.clipZ(b, z1); - auto zh0 = a->clipZ(*b, z0); - auto zh1 = a->clipZ(*b, z1); - - if (!(xh0.has_value() and containsX(&*xh0))) xh0 = std::nullopt; - if (!(xh1.has_value() and containsX(&*xh1))) xh1 = std::nullopt; - if (!(yh0.has_value() and containsY(&*yh0))) yh0 = std::nullopt; - if (!(yh1.has_value() and containsY(&*yh1))) yh1 = std::nullopt; - if (!(zh0.has_value() and containsZ(&*zh0))) zh0 = std::nullopt; - if (!(zh1.has_value() and containsZ(&*zh1))) zh1 = std::nullopt; + if (!(xh0.has_value() and containsX(*xh0))) xh0 = std::nullopt; + if (!(xh1.has_value() and containsX(*xh1))) xh1 = std::nullopt; + if (!(yh0.has_value() and containsY(*yh0))) yh0 = std::nullopt; + if (!(yh1.has_value() and containsY(*yh1))) yh1 = std::nullopt; + if (!(zh0.has_value() and containsZ(*zh0))) zh0 = std::nullopt; + if (!(zh1.has_value() and containsZ(*zh1))) zh1 = std::nullopt; std::optional closest = std::nullopt; - if (xh0.has_value() and - (!closest.has_value() or - a->distanceToSqr(*xh0) < a->distanceToSqr(*closest))) + if (xh0.has_value() and (!closest.has_value() or + a.distanceToSqr(*xh0) < a.distanceToSqr(*closest))) closest = xh0; - if (xh1.has_value() and - (!closest.has_value() or - a->distanceToSqr(*xh1) < a->distanceToSqr(*closest))) + if (xh1.has_value() and (!closest.has_value() or + a.distanceToSqr(*xh1) < a.distanceToSqr(*closest))) closest = xh1; - if (yh0.has_value() and - (!closest.has_value() or - a->distanceToSqr(*yh0) < a->distanceToSqr(*closest))) + if (yh0.has_value() and (!closest.has_value() or + a.distanceToSqr(*yh0) < a.distanceToSqr(*closest))) closest = yh0; - if (yh1.has_value() and - (!closest.has_value() or - a->distanceToSqr(*yh1) < a->distanceToSqr(*closest))) + if (yh1.has_value() and (!closest.has_value() or + a.distanceToSqr(*yh1) < a.distanceToSqr(*closest))) closest = yh1; - if (zh0.has_value() and - (!closest.has_value() or - a->distanceToSqr(*zh0) < a->distanceToSqr(*closest))) + if (zh0.has_value() and (!closest.has_value() or + a.distanceToSqr(*zh0) < a.distanceToSqr(*closest))) closest = zh0; - if (zh1.has_value() and - (!closest.has_value() or - a->distanceToSqr(*zh1) < a->distanceToSqr(*closest))) + if (zh1.has_value() and (!closest.has_value() or + a.distanceToSqr(*zh1) < a.distanceToSqr(*closest))) closest = zh1; if (!closest.has_value()) return nullptr; @@ -299,32 +277,18 @@ HitResult* AABB::clip(Vec3* a, Vec3* b) { return new HitResult(0, 0, 0, face, *closest); } -bool AABB::containsX(Vec3* v) { - if (v == NULL) return false; - return v->y >= y0 && v->y <= y1 && v->z >= z0 && v->z <= z1; +bool AABB::containsX(const Vec3& v) const { + return v.y >= y0 && v.y <= y1 && v.z >= z0 && v.z <= z1; } -bool AABB::containsY(Vec3* v) { - if (v == NULL) return false; - return v->x >= x0 && v->x <= x1 && v->z >= z0 && v->z <= z1; +bool AABB::containsY(const Vec3& v) const { + return v.x >= x0 && v.x <= x1 && v.z >= z0 && v.z <= z1; } -bool AABB::containsZ(Vec3* v) { - if (v == NULL) return false; - return v->x >= x0 && v->x <= x1 && v->y >= y0 && v->y <= y1; +bool AABB::containsZ(const Vec3& v) const { + return v.x >= x0 && v.x <= x1 && v.y >= y0 && v.y <= y1; } -void AABB::set(AABB* b) { - x0 = b->x0; - y0 = b->y0; - z0 = b->z0; - x1 = b->x1; - y1 = b->y1; - z1 = b->z1; -} - -std::wstring AABB::toString() { - return L"box[" + _toString(x0) + L", " + _toString(y0) + - L", " + _toString(z0) + L" -> " + _toString(x1) + - L", " + _toString(y1) + L", " + _toString(z1) + L"]"; +std::wstring AABB::toString() const { + return std::format(L"box[{}, {}, {}, {}, {}, {}]", x0, y0, z0, x1, y1, z1); } diff --git a/Minecraft.World/Util/AABB.h b/Minecraft.World/Util/AABB.h index 205d5ac98..975f6ebcd 100644 --- a/Minecraft.World/Util/AABB.h +++ b/Minecraft.World/Util/AABB.h @@ -36,33 +36,27 @@ public: double x0, y0, z0; double x1, y1, z1; -private: - AABB(double x0, double y0, double z0, double x1, double y1, double z1); AABB() {} + AABB(double x0, double y0, double z0, double x1, double y1, double z1); public: - AABB* set(double x0, double y0, double z0, double x1, double y1, double z1); - AABB* expand(double xa, double ya, double za); - AABB* grow(double xa, double ya, double za); - AABB* minmax(AABB* other); - AABB* cloneMove(double xa, double ya, double za); - double clipXCollide(AABB* c, double xa); - double clipYCollide(AABB* c, double ya); - double clipZCollide(AABB* c, double za); - bool intersects(AABB* c); - bool intersectsInner(AABB* c); - AABB* move(double xa, double ya, double za); + AABB expand(double xa, double ya, double za) const; + AABB grow(double xa, double ya, double za) const; + AABB minmax(const AABB& other) const; + double clipXCollide(const AABB& c, double xa) const; + double clipYCollide(const AABB& c, double ya) const; + double clipZCollide(const AABB& c, double za) const; + bool intersects(const AABB& c) const; + AABB move(double xa, double ya, double za) const; bool intersects(double x02, double y02, double z02, double x12, double y12, - double z12); - bool contains(Vec3* p); - bool containsIncludingLowerBound(Vec3* p); // 4J Added - double getSize(); - AABB* shrink(double xa, double ya, double za); - AABB* copy(); - HitResult* clip(Vec3* a, Vec3* b); - bool containsX(Vec3* v); - bool containsY(Vec3* v); - bool containsZ(Vec3* v); - void set(AABB* b); - std::wstring toString(); + double z12) const; + bool contains(const Vec3& p) const; + bool containsIncludingLowerBound(const Vec3& p) const; // 4J Added + double getSize() const; + AABB shrink(double xa, double ya, double za) const; + HitResult* clip(const Vec3& a, const Vec3& b) const; + bool containsX(const Vec3& v) const; + bool containsY(const Vec3& v) const; + bool containsZ(const Vec3& v) const; + std::wstring toString() const; }; diff --git a/Minecraft.World/Util/Vec3.cpp b/Minecraft.World/Util/Vec3.cpp index 810456f27..00718fabe 100644 --- a/Minecraft.World/Util/Vec3.cpp +++ b/Minecraft.World/Util/Vec3.cpp @@ -150,8 +150,9 @@ void Vec3::zRot(const float degs) { // Returns 0 if this point is within the box // Otherwise returns the distance to the box +// TODO: rewrite this function double Vec3::distanceTo(AABB* box) { - if (box->contains(this)) return 0; + if (box->contains(*this)) return 0; double xd = 0, yd = 0, zd = 0; diff --git a/Minecraft.World/WorldGen/Structures/StructureStart.cpp b/Minecraft.World/WorldGen/Structures/StructureStart.cpp index 9bcb12777..d378e9c33 100644 --- a/Minecraft.World/WorldGen/Structures/StructureStart.cpp +++ b/Minecraft.World/WorldGen/Structures/StructureStart.cpp @@ -138,4 +138,4 @@ bool StructureStart::isValid() { return true; } int StructureStart::getChunkX() { return chunkX; } -int StructureStart::getChunkZ() { return chunkZ; } \ No newline at end of file +int StructureStart::getChunkZ() { return chunkZ; } From 534879e2e74af790907190b0b05717bcb16c5111 Mon Sep 17 00:00:00 2001 From: orng Date: Fri, 27 Mar 2026 21:17:55 -0500 Subject: [PATCH 028/170] refactor: replace `AABB::newPermanent` with `new AABB` --- .../Common/GameRules/ApplySchematicRuleDefinition.cpp | 2 +- .../Platform/Common/GameRules/NamedAreaRuleDefinition.cpp | 2 +- Minecraft.Client/Platform/Common/Tutorial/AreaConstraint.cpp | 4 ++-- Minecraft.Client/Platform/Common/Tutorial/AreaHint.cpp | 2 +- .../Platform/Common/Tutorial/ChangeStateConstraint.cpp | 2 +- Minecraft.Client/Rendering/Chunk.cpp | 2 +- Minecraft.Client/Rendering/LevelRenderer.cpp | 2 +- Minecraft.World/Entities/Entity.cpp | 2 +- Minecraft.World/Entities/Mobs/EnderDragon.cpp | 2 +- Minecraft.World/Util/AABB.cpp | 5 ----- Minecraft.World/Util/AABB.h | 2 -- 11 files changed, 10 insertions(+), 17 deletions(-) diff --git a/Minecraft.Client/Platform/Common/GameRules/ApplySchematicRuleDefinition.cpp b/Minecraft.Client/Platform/Common/GameRules/ApplySchematicRuleDefinition.cpp index dd91c027c..f2c5b4360 100644 --- a/Minecraft.Client/Platform/Common/GameRules/ApplySchematicRuleDefinition.cpp +++ b/Minecraft.Client/Platform/Common/GameRules/ApplySchematicRuleDefinition.cpp @@ -130,7 +130,7 @@ void ApplySchematicRuleDefinition::updateLocationBox() { if (m_schematic == NULL) m_schematic = m_levelGenOptions->getSchematicFile(m_schematicName); - m_locationBox = AABB::newPermanent(0, 0, 0, 0, 0, 0); + m_locationBox = new AABB(0, 0, 0, 0, 0, 0); m_locationBox->x0 = m_location.x; m_locationBox->y0 = m_location.y; diff --git a/Minecraft.Client/Platform/Common/GameRules/NamedAreaRuleDefinition.cpp b/Minecraft.Client/Platform/Common/GameRules/NamedAreaRuleDefinition.cpp index b09982ae9..aefc12453 100644 --- a/Minecraft.Client/Platform/Common/GameRules/NamedAreaRuleDefinition.cpp +++ b/Minecraft.Client/Platform/Common/GameRules/NamedAreaRuleDefinition.cpp @@ -5,7 +5,7 @@ NamedAreaRuleDefinition::NamedAreaRuleDefinition() { m_name = L""; - m_area = AABB::newPermanent(0, 0, 0, 0, 0, 0); + m_area = new AABB(0, 0, 0, 0, 0, 0); } NamedAreaRuleDefinition::~NamedAreaRuleDefinition() { delete m_area; } diff --git a/Minecraft.Client/Platform/Common/Tutorial/AreaConstraint.cpp b/Minecraft.Client/Platform/Common/Tutorial/AreaConstraint.cpp index 271275948..36c53aa47 100644 --- a/Minecraft.Client/Platform/Common/Tutorial/AreaConstraint.cpp +++ b/Minecraft.Client/Platform/Common/Tutorial/AreaConstraint.cpp @@ -11,8 +11,8 @@ AreaConstraint::AreaConstraint(int descriptionId, double x0, double y0, bool restrictsMovement /*=true*/) : TutorialConstraint(descriptionId) { messageArea = - AABB::newPermanent(x0 + 2, y0 + 2, z0 + 2, x1 - 2, y1 - 2, z1 - 2); - movementArea = AABB::newPermanent(x0, y0, z0, x1, y1, z1); + new AABB(x0 + 2, y0 + 2, z0 + 2, x1 - 2, y1 - 2, z1 - 2); + movementArea = new AABB(x0, y0, z0, x1, y1, z1); this->contains = contains; m_restrictsMovement = restrictsMovement; diff --git a/Minecraft.Client/Platform/Common/Tutorial/AreaHint.cpp b/Minecraft.Client/Platform/Common/Tutorial/AreaHint.cpp index 1eb6c1017..b6bae48d3 100644 --- a/Minecraft.Client/Platform/Common/Tutorial/AreaHint.cpp +++ b/Minecraft.Client/Platform/Common/Tutorial/AreaHint.cpp @@ -12,7 +12,7 @@ AreaHint::AreaHint(eTutorial_Hint id, Tutorial* tutorial, double x1, double y1, double z1, bool allowFade /*= false*/, bool contains /*= true*/) : TutorialHint(id, tutorial, descriptionId, e_Hint_Area, allowFade) { - area = AABB::newPermanent(x0, y0, z0, x1, y1, z1); + area = new AABB(x0, y0, z0, x1, y1, z1); this->contains = contains; diff --git a/Minecraft.Client/Platform/Common/Tutorial/ChangeStateConstraint.cpp b/Minecraft.Client/Platform/Common/Tutorial/ChangeStateConstraint.cpp index 9efbd42c9..5934505e8 100644 --- a/Minecraft.Client/Platform/Common/Tutorial/ChangeStateConstraint.cpp +++ b/Minecraft.Client/Platform/Common/Tutorial/ChangeStateConstraint.cpp @@ -16,7 +16,7 @@ ChangeStateConstraint::ChangeStateConstraint( bool contains /*= true*/, bool changeGameMode /*= false*/, GameType* targetGameMode /*= 0*/) : TutorialConstraint(-1) { - movementArea = AABB::newPermanent(x0, y0, z0, x1, y1, z1); + movementArea = new AABB(x0, y0, z0, x1, y1, z1); this->contains = contains; diff --git a/Minecraft.Client/Rendering/Chunk.cpp b/Minecraft.Client/Rendering/Chunk.cpp index 03dc40b8f..95e060ed9 100644 --- a/Minecraft.Client/Rendering/Chunk.cpp +++ b/Minecraft.Client/Rendering/Chunk.cpp @@ -95,7 +95,7 @@ void Chunk::setPos(int x, int y, int z) { // 4J - changed to just set the value rather than make a new one, if we've // already created storage if (bb == NULL) { - bb = AABB::newPermanent(-g, -g, -g, XZSIZE + g, SIZE + g, XZSIZE + g); + bb = new AABB(-g, -g, -g, XZSIZE + g, SIZE + g, XZSIZE + g); } else { // 4J MGH - bounds are relative to the position now, so the AABB will be // setup already, either above, or from the tesselator bounds. diff --git a/Minecraft.Client/Rendering/LevelRenderer.cpp b/Minecraft.Client/Rendering/LevelRenderer.cpp index d412a7ede..84f11665f 100644 --- a/Minecraft.Client/Rendering/LevelRenderer.cpp +++ b/Minecraft.Client/Rendering/LevelRenderer.cpp @@ -3901,7 +3901,7 @@ void LevelRenderer::DestroyedTileManager::destroyingTileAt(Level* level, int x, // Make these temporary AABBs into permanently allocated AABBs for (unsigned int i = 0; i < recentTile->boxes.size(); i++) { - recentTile->boxes[i] = AABB::newPermanent( + recentTile->boxes[i] = new AABB( recentTile->boxes[i]->x0, recentTile->boxes[i]->y0, recentTile->boxes[i]->z0, recentTile->boxes[i]->x1, recentTile->boxes[i]->y1, recentTile->boxes[i]->z1); diff --git a/Minecraft.World/Entities/Entity.cpp b/Minecraft.World/Entities/Entity.cpp index 191789eb8..80a56fd74 100644 --- a/Minecraft.World/Entities/Entity.cpp +++ b/Minecraft.World/Entities/Entity.cpp @@ -268,7 +268,7 @@ void Entity::_init(bool useSmallId, Level* level) { xd = yd = zd = 0.0; yRot = xRot = 0.0f; yRotO = xRotO = 0.0f; - bb = AABB::newPermanent(0, 0, 0, 0, 0, 0); // 4J Was final + bb = new AABB(0, 0, 0, 0, 0, 0); // 4J Was final onGround = false; horizontalCollision = verticalCollision = false; collision = false; diff --git a/Minecraft.World/Entities/Mobs/EnderDragon.cpp b/Minecraft.World/Entities/Mobs/EnderDragon.cpp index 7f9697bc3..2cb92716b 100644 --- a/Minecraft.World/Entities/Mobs/EnderDragon.cpp +++ b/Minecraft.World/Entities/Mobs/EnderDragon.cpp @@ -73,7 +73,7 @@ void EnderDragon::_init() { m_actionTicks = 0; m_sittingDamageReceived = 0; m_headYRot = 0.0; - m_acidArea = AABB::newPermanent(-4, -10, -3, 6, 3, 3); + m_acidArea = new AABB(-4, -10, -3, 6, 3, 3); m_flameAttacks = 0; for (int i = 0; i < positionsLength; i++) { diff --git a/Minecraft.World/Util/AABB.cpp b/Minecraft.World/Util/AABB.cpp index 53b4412f3..2cf5236e5 100644 --- a/Minecraft.World/Util/AABB.cpp +++ b/Minecraft.World/Util/AABB.cpp @@ -40,11 +40,6 @@ void AABB::ReleaseThreadStorage() { } } -AABB* AABB::newPermanent(double x0, double y0, double z0, double x1, double y1, - double z1) { - return new AABB(x0, y0, z0, x1, y1, z1); -} - void AABB::clearPool() {} void AABB::resetPool() {} diff --git a/Minecraft.World/Util/AABB.h b/Minecraft.World/Util/AABB.h index 975f6ebcd..61d8446cd 100644 --- a/Minecraft.World/Util/AABB.h +++ b/Minecraft.World/Util/AABB.h @@ -26,8 +26,6 @@ public: static void UseDefaultThreadStorage(); static void ReleaseThreadStorage(); - static AABB* newPermanent(double x0, double y0, double z0, double x1, - double y1, double z1); static void clearPool(); static void resetPool(); static AABB* newTemp(double x0, double y0, double z0, double x1, double y1, From d7d99db4c5cf518fc46701faf95ec161e64b156d Mon Sep 17 00:00:00 2001 From: orng Date: Fri, 27 Mar 2026 21:56:57 -0500 Subject: [PATCH 029/170] refactor: remove `AABB::newTemp` when not returned --- .../Common/GameRules/ConsoleSchematicFile.cpp | 4 +-- .../GameRules/LevelGenerationOptions.cpp | 14 ++++---- .../PS3/SPU_Tasks/ChunkUpdate/Tile_SPU.cpp | 4 +-- Minecraft.Client/Rendering/LevelRenderer.cpp | 34 +++++++++---------- .../Blocks/BasePressurePlateTile.cpp | 2 +- Minecraft.World/Blocks/ButtonTile.cpp | 9 +++-- Minecraft.World/Blocks/CakeTile.cpp | 2 +- Minecraft.World/Blocks/ChestTile.cpp | 5 +-- Minecraft.World/Blocks/DetectorRailTile.cpp | 12 +++---- Minecraft.World/Blocks/FenceGateTile.cpp | 2 +- Minecraft.World/Blocks/SoulSandTile.cpp | 2 +- .../Blocks/TileEntities/ChestTileEntity.cpp | 9 +++-- .../Blocks/TileEntities/HopperTileEntity.cpp | 13 +++---- Minecraft.World/Blocks/TripWireTile.cpp | 7 ++-- .../Entities/LeashFenceKnotEntity.cpp | 21 ++++++------ Minecraft.World/Entities/Mobs/Boat.cpp | 4 +-- Minecraft.World/Entities/Mobs/EnderDragon.cpp | 26 ++++++-------- Minecraft.World/Entities/Mobs/FishingHook.cpp | 4 +-- .../Entities/Mobs/LightningBolt.cpp | 5 ++- Minecraft.World/Items/ArmorItem.cpp | 6 ++-- Minecraft.World/Items/LeashItem.cpp | 15 ++++---- Minecraft.World/Level/Explosion.cpp | 5 ++- Minecraft.World/Player/Player.cpp | 7 ++-- .../WorldGen/Structures/Village.cpp | 11 +++--- 24 files changed, 112 insertions(+), 111 deletions(-) diff --git a/Minecraft.Client/Platform/Common/GameRules/ConsoleSchematicFile.cpp b/Minecraft.Client/Platform/Common/GameRules/ConsoleSchematicFile.cpp index 2409b12c9..3ba460f65 100644 --- a/Minecraft.Client/Platform/Common/GameRules/ConsoleSchematicFile.cpp +++ b/Minecraft.Client/Platform/Common/GameRules/ConsoleSchematicFile.cpp @@ -733,9 +733,9 @@ void ConsoleSchematicFile::generateSchematicFile( } tag.put(L"TileEntities", tileEntitiesTag); - AABB* bb = AABB::newTemp(xStart, yStart, zStart, xEnd, yEnd, zEnd); + AABB bb(xStart, yStart, zStart, xEnd, yEnd, zEnd); std::vector >* entities = - level->getEntities(nullptr, bb); + level->getEntities(nullptr, &bb); ListTag* entitiesTag = new ListTag(L"entities"); for (AUTO_VAR(it, entities->begin()); it != entities->end(); ++it) { diff --git a/Minecraft.Client/Platform/Common/GameRules/LevelGenerationOptions.cpp b/Minecraft.Client/Platform/Common/GameRules/LevelGenerationOptions.cpp index 8e2260a11..5e65c983f 100644 --- a/Minecraft.Client/Platform/Common/GameRules/LevelGenerationOptions.cpp +++ b/Minecraft.Client/Platform/Common/GameRules/LevelGenerationOptions.cpp @@ -253,13 +253,12 @@ void LevelGenerationOptions::addAttribute(const std::wstring& attributeName, void LevelGenerationOptions::processSchematics(LevelChunk* chunk) { PIXBeginNamedEvent(0, "Processing schematics for chunk (%d,%d)", chunk->x, chunk->z); - AABB* chunkBox = - AABB::newTemp(chunk->x * 16, 0, chunk->z * 16, chunk->x * 16 + 16, - Level::maxBuildHeight, chunk->z * 16 + 16); + AABB chunkBox(chunk->x * 16, 0, chunk->z * 16, chunk->x * 16 + 16, + Level::maxBuildHeight, chunk->z * 16 + 16); for (AUTO_VAR(it, m_schematicRules.begin()); it != m_schematicRules.end(); ++it) { ApplySchematicRuleDefinition* rule = *it; - rule->processSchematic(chunkBox, chunk); + rule->processSchematic(&chunkBox, chunk); } int cx = (chunk->x << 4); @@ -282,13 +281,12 @@ void LevelGenerationOptions::processSchematics(LevelChunk* chunk) { void LevelGenerationOptions::processSchematicsLighting(LevelChunk* chunk) { PIXBeginNamedEvent(0, "Processing schematics (lighting) for chunk (%d,%d)", chunk->x, chunk->z); - AABB* chunkBox = - AABB::newTemp(chunk->x * 16, 0, chunk->z * 16, chunk->x * 16 + 16, - Level::maxBuildHeight, chunk->z * 16 + 16); + AABB chunkBox(chunk->x * 16, 0, chunk->z * 16, chunk->x * 16 + 16, + Level::maxBuildHeight, chunk->z * 16 + 16); for (AUTO_VAR(it, m_schematicRules.begin()); it != m_schematicRules.end(); ++it) { ApplySchematicRuleDefinition* rule = *it; - rule->processSchematicLighting(chunkBox, chunk); + rule->processSchematicLighting(&chunkBox, chunk); } PIXEndNamedEvent(); } diff --git a/Minecraft.Client/Platform/PS3/SPU_Tasks/ChunkUpdate/Tile_SPU.cpp b/Minecraft.Client/Platform/PS3/SPU_Tasks/ChunkUpdate/Tile_SPU.cpp index c12e1def6..8e7a0af90 100644 --- a/Minecraft.Client/Platform/PS3/SPU_Tasks/ChunkUpdate/Tile_SPU.cpp +++ b/Minecraft.Client/Platform/PS3/SPU_Tasks/ChunkUpdate/Tile_SPU.cpp @@ -329,8 +329,8 @@ bool Tile_SPU::isSolidRender(bool isServerLevel) { return true; } // { // int newCount = // ExperienceOrb::getExperienceValue(amount); amount -= -// newCount; level->addEntity(std::shared_ptr( new -// ExperienceOrb(level, x + .5, y + .5, z + .5, newCount))); +// newCount; level->addEntity(std::shared_ptr( +// new ExperienceOrb(level, x + .5, y + .5, z + .5, newCount))); // } // } // } diff --git a/Minecraft.Client/Rendering/LevelRenderer.cpp b/Minecraft.Client/Rendering/LevelRenderer.cpp index 84f11665f..76138cf23 100644 --- a/Minecraft.Client/Rendering/LevelRenderer.cpp +++ b/Minecraft.Client/Rendering/LevelRenderer.cpp @@ -2481,9 +2481,9 @@ void LevelRenderer::renderHitOutline(std::shared_ptr player, double zo = player->zOld + (player->z - player->zOld) * a; AABB bb = Tile::tiles[tileId] - ->getTileAABB(level[iPad], h->x, h->y, h->z) - ->grow(ss, ss, ss) - .move(-xo, -yo, -zo); + ->getTileAABB(level[iPad], h->x, h->y, h->z) + ->grow(ss, ss, ss) + .move(-xo, -yo, -zo); render(&bb); } @@ -3891,20 +3891,20 @@ void LevelRenderer::DestroyedTileManager::destroyingTileAt(Level* level, int x, // ones, so make a temporary list and then copy over RecentTile* recentTile = new RecentTile(x, y, z, level); - AABB* box = AABB::newTemp((float)x, (float)y, (float)z, (float)(x + 1), - (float)(y + 1), (float)(z + 1)); + AABB box((float)x, (float)y, (float)z, (float)(x + 1), (float)(y + 1), + (float)(z + 1)); Tile* tile = Tile::tiles[level->getTile(x, y, z)]; if (tile != NULL) { - tile->addAABBs(level, x, y, z, box, &recentTile->boxes, nullptr); + tile->addAABBs(level, x, y, z, &box, &recentTile->boxes, nullptr); } // Make these temporary AABBs into permanently allocated AABBs for (unsigned int i = 0; i < recentTile->boxes.size(); i++) { - recentTile->boxes[i] = new AABB( - recentTile->boxes[i]->x0, recentTile->boxes[i]->y0, - recentTile->boxes[i]->z0, recentTile->boxes[i]->x1, - recentTile->boxes[i]->y1, recentTile->boxes[i]->z1); + recentTile->boxes[i] = + new AABB(recentTile->boxes[i]->x0, recentTile->boxes[i]->y0, + recentTile->boxes[i]->z0, recentTile->boxes[i]->x1, + recentTile->boxes[i]->y1, recentTile->boxes[i]->z1); } m_destroyedTiles.push_back(recentTile); @@ -3978,13 +3978,13 @@ void LevelRenderer::DestroyedTileManager::addAABBs(Level* level, AABB* box, // AABB copy so that we can destroy our own copy without // worrying about the lifespan of the copy we've passed out if (m_destroyedTiles[i]->boxes[j]->intersects(*box)) { - boxes->push_back( - AABB::newTemp(m_destroyedTiles[i]->boxes[j]->x0, - m_destroyedTiles[i]->boxes[j]->y0, - m_destroyedTiles[i]->boxes[j]->z0, - m_destroyedTiles[i]->boxes[j]->x1, - m_destroyedTiles[i]->boxes[j]->y1, - m_destroyedTiles[i]->boxes[j]->z1)); + AABB bb(m_destroyedTiles[i]->boxes[j]->x0, + m_destroyedTiles[i]->boxes[j]->y0, + m_destroyedTiles[i]->boxes[j]->z0, + m_destroyedTiles[i]->boxes[j]->x1, + m_destroyedTiles[i]->boxes[j]->y1, + m_destroyedTiles[i]->boxes[j]->z1); + boxes->push_back(&bb); } } } diff --git a/Minecraft.World/Blocks/BasePressurePlateTile.cpp b/Minecraft.World/Blocks/BasePressurePlateTile.cpp index 740e0a871..d6fb7e697 100644 --- a/Minecraft.World/Blocks/BasePressurePlateTile.cpp +++ b/Minecraft.World/Blocks/BasePressurePlateTile.cpp @@ -160,4 +160,4 @@ int BasePressurePlateTile::getPistonPushReaction() { void BasePressurePlateTile::registerIcons(IconRegister* iconRegister) { icon = iconRegister->registerIcon(texture); -} \ No newline at end of file +} diff --git a/Minecraft.World/Blocks/ButtonTile.cpp b/Minecraft.World/Blocks/ButtonTile.cpp index 73ac3122a..550805d9d 100644 --- a/Minecraft.World/Blocks/ButtonTile.cpp +++ b/Minecraft.World/Blocks/ButtonTile.cpp @@ -261,9 +261,12 @@ void ButtonTile::checkPressed(Level* level, int x, int y, int z) { updateShape(data); Tile::ThreadStorage* tls = m_tlsShape; - std::vector >* entities = level->getEntitiesOfClass( - typeid(Arrow), AABB::newTemp(x + tls->xx0, y + tls->yy0, z + tls->zz0, - x + tls->xx1, y + tls->yy1, z + tls->zz1)); + AABB arrow_aabb{ + x + tls->xx0, y + tls->yy0, z + tls->zz0, + x + tls->xx1, y + tls->yy1, z + tls->zz1, + }; + std::vector >* entities = + level->getEntitiesOfClass(typeid(Arrow), &arrow_aabb); shouldBePressed = !entities->empty(); delete entities; diff --git a/Minecraft.World/Blocks/CakeTile.cpp b/Minecraft.World/Blocks/CakeTile.cpp index b0d8d8ee9..437438c48 100644 --- a/Minecraft.World/Blocks/CakeTile.cpp +++ b/Minecraft.World/Blocks/CakeTile.cpp @@ -124,4 +124,4 @@ int CakeTile::getResource(int data, Random* random, int playerBonusLevel) { int CakeTile::cloneTileId(Level* level, int x, int y, int z) { return Item::cake_Id; -} \ No newline at end of file +} diff --git a/Minecraft.World/Blocks/ChestTile.cpp b/Minecraft.World/Blocks/ChestTile.cpp index 9ac3c5364..4a866151c 100644 --- a/Minecraft.World/Blocks/ChestTile.cpp +++ b/Minecraft.World/Blocks/ChestTile.cpp @@ -345,8 +345,9 @@ int ChestTile::getDirectSignal(LevelSource* level, int x, int y, int z, } bool ChestTile::isCatSittingOnChest(Level* level, int x, int y, int z) { - std::vector >* entities = level->getEntitiesOfClass( - typeid(Ocelot), AABB::newTemp(x, y + 1, z, x + 1, y + 2, z + 1)); + AABB ocelot_aabb(x, y + 1, z, x + 1, y + 2, z + 1); + std::vector >* entities = + level->getEntitiesOfClass(typeid(Ocelot), &ocelot_aabb); for (AUTO_VAR(it, entities->begin()); it != entities->end(); ++it) { std::shared_ptr ocelot = std::dynamic_pointer_cast(*it); if (ocelot->isSitting()) { diff --git a/Minecraft.World/Blocks/DetectorRailTile.cpp b/Minecraft.World/Blocks/DetectorRailTile.cpp index dacc5f51b..b7bd2d4e5 100644 --- a/Minecraft.World/Blocks/DetectorRailTile.cpp +++ b/Minecraft.World/Blocks/DetectorRailTile.cpp @@ -64,9 +64,9 @@ void DetectorRailTile::checkPressed(Level* level, int x, int y, int z, bool shouldBePressed = false; float b = 2 / 16.0f; - std::vector >* entities = level->getEntitiesOfClass( - typeid(Minecart), - AABB::newTemp(x + b, y, z + b, x + 1 - b, y + 1 - b, z + 1 - b)); + AABB minecart_aabb(x + b, y, z + b, x + b - b, y + b - b, z + 1 - b); + std::vector >* entities = + level->getEntitiesOfClass(typeid(Minecart), &minecart_aabb); if (!entities->empty()) { shouldBePressed = true; } @@ -105,10 +105,10 @@ int DetectorRailTile::getAnalogOutputSignal(Level* level, int x, int y, int z, int dir) { if ((level->getData(x, y, z) & RAIL_DATA_BIT) > 0) { float b = 2 / 16.0f; + AABB minecart_bb(x + b, y, z + b, x + 1 - b, y + 1 - b, z + 1 - b); std::vector >* entities = level->getEntitiesOfClass( - typeid(Minecart), - AABB::newTemp(x + b, y, z + b, x + 1 - b, y + 1 - b, z + 1 - b), + typeid(Minecart), &minecart_bb, EntitySelector::CONTAINER_ENTITY_SELECTOR); if (entities->size() > 0) { @@ -133,4 +133,4 @@ Icon* DetectorRailTile::getTexture(int face, int data) { return icons[1]; } return icons[0]; -} \ No newline at end of file +} diff --git a/Minecraft.World/Blocks/FenceGateTile.cpp b/Minecraft.World/Blocks/FenceGateTile.cpp index 4a9a11268..44ee44135 100644 --- a/Minecraft.World/Blocks/FenceGateTile.cpp +++ b/Minecraft.World/Blocks/FenceGateTile.cpp @@ -123,4 +123,4 @@ void FenceGateTile::registerIcons(IconRegister* iconRegister) { bool FenceGateTile::shouldRenderFace(LevelSource* level, int x, int y, int z, int face) { return true; -} \ No newline at end of file +} diff --git a/Minecraft.World/Blocks/SoulSandTile.cpp b/Minecraft.World/Blocks/SoulSandTile.cpp index fe240022f..22b4f8509 100644 --- a/Minecraft.World/Blocks/SoulSandTile.cpp +++ b/Minecraft.World/Blocks/SoulSandTile.cpp @@ -14,4 +14,4 @@ void SoulSandTile::entityInside(Level* level, int x, int y, int z, std::shared_ptr entity) { entity->xd *= 0.4; entity->zd *= 0.4; -} \ No newline at end of file +} diff --git a/Minecraft.World/Blocks/TileEntities/ChestTileEntity.cpp b/Minecraft.World/Blocks/TileEntities/ChestTileEntity.cpp index d1cbd500b..d66c15c24 100644 --- a/Minecraft.World/Blocks/TileEntities/ChestTileEntity.cpp +++ b/Minecraft.World/Blocks/TileEntities/ChestTileEntity.cpp @@ -242,11 +242,10 @@ void ChestTileEntity::tick() { openCount = 0; float range = 5; + AABB player_aabb(x - range, y - range, z - range, x + 1 + range, + y + 1 + range, z + 1 + range); std::vector >* players = - level->getEntitiesOfClass( - typeid(Player), - AABB::newTemp(x - range, y - range, z - range, x + 1 + range, - y + 1 + range, z + 1 + range)); + level->getEntitiesOfClass(typeid(Player), &player_aabb); for (AUTO_VAR(it, players->begin()); it != players->end(); ++it) { std::shared_ptr player = std::dynamic_pointer_cast(*it); @@ -383,4 +382,4 @@ std::shared_ptr ChestTileEntity::clone() { } } return result; -} \ No newline at end of file +} diff --git a/Minecraft.World/Blocks/TileEntities/HopperTileEntity.cpp b/Minecraft.World/Blocks/TileEntities/HopperTileEntity.cpp index 36da69010..26ed8f516 100644 --- a/Minecraft.World/Blocks/TileEntities/HopperTileEntity.cpp +++ b/Minecraft.World/Blocks/TileEntities/HopperTileEntity.cpp @@ -345,9 +345,10 @@ std::shared_ptr HopperTileEntity::getSourceContainer( std::shared_ptr HopperTileEntity::getItemAt(Level* level, double xt, double yt, double zt) { - std::vector >* entities = level->getEntitiesOfClass( - typeid(ItemEntity), AABB::newTemp(xt, yt, zt, xt + 1, yt + 1, zt + 1), - EntitySelector::ENTITY_STILL_ALIVE); + AABB item_entity_aabb{xt, yt, zt, xt + 1, yt + 1, zt + 1}; + std::vector >* entities = + level->getEntitiesOfClass(typeid(ItemEntity), &item_entity_aabb, + EntitySelector::ENTITY_STILL_ALIVE); if (entities->size() > 0) { std::shared_ptr out = @@ -384,9 +385,9 @@ std::shared_ptr HopperTileEntity::getContainerAt(Level* level, } if (result == NULL) { + AABB block_above{x, y, z, x + 1, y + 1, z + 1}; std::vector >* entities = level->getEntities( - nullptr, AABB::newTemp(x, y, z, x + 1, y + 1, z + 1), - EntitySelector::CONTAINER_ENTITY_SELECTOR); + nullptr, &block_above, EntitySelector::CONTAINER_ENTITY_SELECTOR); if ((entities != NULL) && (entities->size() > 0)) { result = std::dynamic_pointer_cast( @@ -432,4 +433,4 @@ std::shared_ptr HopperTileEntity::clone() { } } return result; -} \ No newline at end of file +} diff --git a/Minecraft.World/Blocks/TripWireTile.cpp b/Minecraft.World/Blocks/TripWireTile.cpp index 0118aa0a1..0e5755e47 100644 --- a/Minecraft.World/Blocks/TripWireTile.cpp +++ b/Minecraft.World/Blocks/TripWireTile.cpp @@ -132,9 +132,10 @@ void TripWireTile::checkPressed(Level* level, int x, int y, int z) { bool shouldBePressed = false; ThreadStorage* tls = m_tlsShape; - std::vector >* entities = level->getEntities( - nullptr, AABB::newTemp(x + tls->xx0, y + tls->yy0, z + tls->zz0, - x + tls->xx1, y + tls->yy1, z + tls->zz1)); + AABB offs_aabb(x + tls->xx0, y + tls->yy0, z + tls->zz0, x + tls->xx1, + y + tls->yy1, z + tls->zz1); + std::vector >* entities = + level->getEntities(nullptr, &offs_aabb); if (!entities->empty()) { for (AUTO_VAR(it, entities->begin()); it != entities->end(); ++it) { std::shared_ptr e = *it; diff --git a/Minecraft.World/Entities/LeashFenceKnotEntity.cpp b/Minecraft.World/Entities/LeashFenceKnotEntity.cpp index 5a4ccd45f..d86972cad 100644 --- a/Minecraft.World/Entities/LeashFenceKnotEntity.cpp +++ b/Minecraft.World/Entities/LeashFenceKnotEntity.cpp @@ -54,11 +54,10 @@ bool LeashFenceKnotEntity::interact(std::shared_ptr player) { if (!level->isClientSide) { // look for entities that can be attached to the fence double range = 7; + AABB mob_aabb{x - range, y - range, z - range, + x + range, y + range, z + range}; std::vector >* mobs = - level->getEntitiesOfClass( - typeid(Mob), - AABB::newTemp(x - range, y - range, z - range, x + range, - y + range, z + range)); + level->getEntitiesOfClass(typeid(Mob), &mob_aabb); if (mobs != NULL) { for (AUTO_VAR(it, mobs->begin()); it != mobs->end(); ++it) { std::shared_ptr mob = @@ -79,11 +78,10 @@ bool LeashFenceKnotEntity::interact(std::shared_ptr player) { // if the player is in creative mode, attempt to remove all leashed // mobs without dropping additional items double range = 7; + AABB mob_aabb{x - range, y - range, z - range, + x + range, y + range, z + range}; std::vector >* mobs = - level->getEntitiesOfClass( - typeid(Mob), - AABB::newTemp(x - range, y - range, z - range, x + range, - y + range, z + range)); + level->getEntitiesOfClass(typeid(Mob), &mob_aabb); if (mobs != NULL) { for (AUTO_VAR(it, mobs->begin()); it != mobs->end(); ++it) { std::shared_ptr mob = @@ -122,9 +120,10 @@ std::shared_ptr LeashFenceKnotEntity::createAndAddKnot( std::shared_ptr LeashFenceKnotEntity::findKnotAt( Level* level, int x, int y, int z) { + AABB leash_fence_knot_entity_aabb{x - 1.0, y - 1.0, z - 1.0, + x + 1.0, y + 1.0, z + 1.0}; std::vector >* knots = level->getEntitiesOfClass( - typeid(LeashFenceKnotEntity), - AABB::newTemp(x - 1.0, y - 1.0, z - 1.0, x + 1.0, y + 1.0, z + 1.0)); + typeid(LeashFenceKnotEntity), &leash_fence_knot_entity_aabb); if (knots != NULL) { for (AUTO_VAR(it, knots->begin()); it != knots->end(); ++it) { std::shared_ptr knot = @@ -137,4 +136,4 @@ std::shared_ptr LeashFenceKnotEntity::findKnotAt( delete knots; } return nullptr; -} \ No newline at end of file +} diff --git a/Minecraft.World/Entities/Mobs/Boat.cpp b/Minecraft.World/Entities/Mobs/Boat.cpp index f379b068e..d04c7f33e 100644 --- a/Minecraft.World/Entities/Mobs/Boat.cpp +++ b/Minecraft.World/Entities/Mobs/Boat.cpp @@ -167,8 +167,8 @@ void Boat::tick() { for (int i = 0; i < steps; i++) { double y0 = bb->y0 + (bb->y1 - bb->y0) * (i + 0) / steps - 2 / 16.0f; double y1 = bb->y0 + (bb->y1 - bb->y0) * (i + 1) / steps - 2 / 16.0f; - AABB* bb2 = AABB::newTemp(bb->x0, y0, bb->z0, bb->x1, y1, bb->z1); - if (level->containsLiquid(bb2, Material::water)) { + AABB bb2(bb->x0, y0, bb->z0, bb->x1, y1, bb->z1); + if (level->containsLiquid(&bb2, Material::water)) { waterPercentage += 1.0 / steps; } } diff --git a/Minecraft.World/Entities/Mobs/EnderDragon.cpp b/Minecraft.World/Entities/Mobs/EnderDragon.cpp index 2cb92716b..abcab5c46 100644 --- a/Minecraft.World/Entities/Mobs/EnderDragon.cpp +++ b/Minecraft.World/Entities/Mobs/EnderDragon.cpp @@ -647,11 +647,9 @@ void EnderDragon::aiStep() { if (!level->isClientSide) checkAttack(); if (!level->isClientSide && hurtDuration == 0) { AABB wing_mov = wing1->bb->grow(4, 2, 4).move(0, -2, 0); - knockBack(level->getEntities(shared_from_this(), - &wing_mov)); + knockBack(level->getEntities(shared_from_this(), &wing_mov)); wing_mov = wing2->bb->grow(4, 2, 4).move(0, -2, 0); - knockBack(level->getEntities(shared_from_this(), - &wing_mov)); + knockBack(level->getEntities(shared_from_this(), &wing_mov)); AABB neck_bb = neck->bb->grow(1, 1, 1); AABB head_bb = head->bb->grow(1, 1, 1); @@ -689,8 +687,8 @@ void EnderDragon::aiStep() { double acidX = x + ss * 9.5f * ccTilt; double acidY = y + yOffset + ssTilt * 10.5f; double acidZ = z - cc * 9.5f * ccTilt; - *m_acidArea = {acidX - 5, acidY - 17, acidZ - 5, acidX + 5, acidY + 4, - acidZ + 5}; + *m_acidArea = {acidX - 5, acidY - 17, acidZ - 5, + acidX + 5, acidY + 4, acidZ + 5}; // app.DebugPrintf("\nDragon is %s, yRot = %f, yRotA = %f, ss = %f, cc = // %f, ccTilt = %f\n",level->isClientSide?"client":"server", yRot, @@ -816,11 +814,9 @@ void EnderDragon::checkCrystals() { if (random->nextInt(10) == 0) { float maxDist = 32; - AABB grown = -bb->grow(maxDist, maxDist, maxDist); + AABB grown = bb->grow(maxDist, maxDist, maxDist); std::vector >* crystals = - level->getEntitiesOfClass(typeid(EnderCrystal), - &grown); + level->getEntitiesOfClass(typeid(EnderCrystal), &grown); std::shared_ptr crystal = nullptr; double nearest = std::numeric_limits::max(); @@ -1427,11 +1423,11 @@ EnderDragon::EEnderdragonAction EnderDragon::getSynchedAction() { } void EnderDragon::handleCrystalDestroyed(DamageSource* source) { - AABB* tempBB = AABB::newTemp(PODIUM_X_POS, 84.0, PODIUM_Z_POS, - PODIUM_X_POS + 1.0, 85.0, PODIUM_Z_POS + 1.0); - AABB grown = tempBB->grow(48, 40, 48); - std::vector >* crystals = level->getEntitiesOfClass( - typeid(EnderCrystal), &grown); + AABB tempBB(PODIUM_X_POS, 84.0, PODIUM_Z_POS, PODIUM_X_POS + 1.0, 85.0, + PODIUM_Z_POS + 1.0); + AABB grown = tempBB.grow(48, 40, 48); + std::vector >* crystals = + level->getEntitiesOfClass(typeid(EnderCrystal), &grown); m_remainingCrystalsCount = (int)crystals->size() - 1; if (m_remainingCrystalsCount < 0) m_remainingCrystalsCount = 0; delete crystals; diff --git a/Minecraft.World/Entities/Mobs/FishingHook.cpp b/Minecraft.World/Entities/Mobs/FishingHook.cpp index 76a4d5b07..fe8ff9b8b 100644 --- a/Minecraft.World/Entities/Mobs/FishingHook.cpp +++ b/Minecraft.World/Entities/Mobs/FishingHook.cpp @@ -288,8 +288,8 @@ void FishingHook::tick() { 2 / 16.0f; double y1 = bb->y0 + (bb->y1 - bb->y0) * (i + 1) / steps - 2 / 16.0f + 2 / 16.0f; - AABB* bb2 = AABB::newTemp(bb->x0, y0, bb->z0, bb->x1, y1, bb->z1); - if (level->containsLiquid(bb2, Material::water)) { + AABB bb2(bb->x0, y0, bb->z0, bb->x1, y1, bb->z1); + if (level->containsLiquid(&bb2, Material::water)) { waterPercentage += 1.0 / steps; } } diff --git a/Minecraft.World/Entities/Mobs/LightningBolt.cpp b/Minecraft.World/Entities/Mobs/LightningBolt.cpp index fe864cb07..24bd495dd 100644 --- a/Minecraft.World/Entities/Mobs/LightningBolt.cpp +++ b/Minecraft.World/Entities/Mobs/LightningBolt.cpp @@ -105,10 +105,9 @@ void LightningBolt::tick() { level->skyFlashTime = 2; } else { double r = 3; + AABB aoe_bb = AABB(x, y, z, x, y + 6, z).grow(r, r, r); std::vector >* entities = - level->getEntities(shared_from_this(), - AABB::newTemp(x - r, y - r, z - r, x + r, - y + 6 + r, z + r)); + level->getEntities(shared_from_this(), &aoe_bb); AUTO_VAR(itEnd, entities->end()); for (AUTO_VAR(it, entities->begin()); it != itEnd; it++) { std::shared_ptr e = (*it); // entities->at(i); diff --git a/Minecraft.World/Items/ArmorItem.cpp b/Minecraft.World/Items/ArmorItem.cpp index 3feb87e07..2f4173530 100644 --- a/Minecraft.World/Items/ArmorItem.cpp +++ b/Minecraft.World/Items/ArmorItem.cpp @@ -26,10 +26,10 @@ std::shared_ptr ArmorItem::ArmorDispenseItemBehavior::execute( int x = source->getBlockX() + facing->getStepX(); int y = source->getBlockY() + facing->getStepY(); int z = source->getBlockZ() + facing->getStepZ(); - AABB* bb = AABB::newTemp(x, y, z, x + 1, y + 1, z + 1); + AABB bb = AABB(x, y, z, x + 1, y + 1, z + 1); EntitySelector* selector = new MobCanWearArmourEntitySelector(dispensed); std::vector >* entities = - source->getWorld()->getEntitiesOfClass(typeid(LivingEntity), bb, + source->getWorld()->getEntitiesOfClass(typeid(LivingEntity), &bb, selector); delete selector; @@ -237,4 +237,4 @@ Icon* ArmorItem::getEmptyIcon(int slot) { } return NULL; -} \ No newline at end of file +} diff --git a/Minecraft.World/Items/LeashItem.cpp b/Minecraft.World/Items/LeashItem.cpp index a00d296a1..1139a5d86 100644 --- a/Minecraft.World/Items/LeashItem.cpp +++ b/Minecraft.World/Items/LeashItem.cpp @@ -3,6 +3,7 @@ #include "../Headers/net.minecraft.world.level.h" #include "../Headers/net.minecraft.world.entity.h" #include "../Headers/net.minecraft.world.phys.h" +#include "Util/AABB.h" #include "LeashItem.h" LeashItem::LeashItem(int id) : Item(id) {} @@ -35,9 +36,9 @@ bool LeashItem::bindPlayerMobs(std::shared_ptr player, Level* level, // look for entities that can be attached to the fence bool foundMobs = false; double range = 7; - std::vector >* mobs = level->getEntitiesOfClass( - typeid(Mob), AABB::newTemp(x - range, y - range, z - range, x + range, - y + range, z + range)); + AABB mob_bb = AABB(x, y, z, x, y, z).grow(range, range, range); + std::vector >* mobs = + level->getEntitiesOfClass(typeid(Mob), &mob_bb); if (mobs != NULL) { for (AUTO_VAR(it, mobs->begin()); it != mobs->end(); ++it) { std::shared_ptr mob = std::dynamic_pointer_cast(*it); @@ -59,9 +60,9 @@ bool LeashItem::bindPlayerMobsTest(std::shared_ptr player, Level* level, int x, int y, int z) { // look for entities that can be attached to the fence double range = 7; - std::vector >* mobs = level->getEntitiesOfClass( - typeid(Mob), AABB::newTemp(x - range, y - range, z - range, x + range, - y + range, z + range)); + AABB mob_bb = AABB(x, y, z, x, y, z).grow(range, range, range); + std::vector >* mobs = + level->getEntitiesOfClass(typeid(Mob), &mob_bb); if (mobs != NULL) { for (AUTO_VAR(it, mobs->begin()); it != mobs->end(); ++it) { @@ -71,4 +72,4 @@ bool LeashItem::bindPlayerMobsTest(std::shared_ptr player, Level* level, } } return false; -} \ No newline at end of file +} diff --git a/Minecraft.World/Level/Explosion.cpp b/Minecraft.World/Level/Explosion.cpp index a82786ebe..bdc17689d 100644 --- a/Minecraft.World/Level/Explosion.cpp +++ b/Minecraft.World/Level/Explosion.cpp @@ -9,6 +9,7 @@ #include "TilePos.h" #include "Explosion.h" #include "../Util/SoundTypes.h" +#include "Util/AABB.h" Explosion::Explosion(Level* level, std::shared_ptr source, double x, double y, double z, float r) { @@ -99,8 +100,10 @@ void Explosion::explode() { // time. If we explode something next to an EnderCrystal then it creates a // new explosion that overwrites the shared vector in the level So copy it // here instead of directly using the shared one + + AABB source_bb(x0, y0, z0, x1, y1, z1); std::vector >* levelEntities = - level->getEntities(source, AABB::newTemp(x0, y0, z0, x1, y1, z1)); + level->getEntities(source, &source_bb); std::vector > entities(levelEntities->begin(), levelEntities->end()); Vec3 center(x, y, z); diff --git a/Minecraft.World/Player/Player.cpp b/Minecraft.World/Player/Player.cpp index fff23c15e..f36caeefa 100644 --- a/Minecraft.World/Player/Player.cpp +++ b/Minecraft.World/Player/Player.cpp @@ -1596,11 +1596,10 @@ Player::BedSleepingResult Player::startSleepInBed(int x, int y, int z, double hRange = 8; double vRange = 5; + AABB monster_bb = + AABB(x, y, z, x, y, z).grow(hRange, vRange, hRange); std::vector >* monsters = - level->getEntitiesOfClass( - typeid(Monster), - AABB::newTemp(x - hRange, y - vRange, z - hRange, - x + hRange, y + vRange, z + hRange)); + level->getEntitiesOfClass(typeid(Monster), &monster_bb); if (!monsters->empty()) { delete monsters; return NOT_SAFE; diff --git a/Minecraft.World/WorldGen/Structures/Village.cpp b/Minecraft.World/WorldGen/Structures/Village.cpp index 16a6a2283..03a079387 100644 --- a/Minecraft.World/WorldGen/Structures/Village.cpp +++ b/Minecraft.World/WorldGen/Structures/Village.cpp @@ -117,21 +117,22 @@ bool Village::canSpawnAt(int x, int y, int z, int sx, int sy, int sz) { void Village::countGolem() { // Fix - let bots report themselves? + AABB village_golem_bb = + AABB(center->x, center->y, center->z, center->x, center->y, center->z) + .grow(radius, 4, radius); std::vector >* golems = level->getEntitiesOfClass( typeid(VillagerGolem), - AABB::newTemp(center->x - radius, center->y - 4, center->z - radius, - center->x + radius, center->y + 4, center->z + radius)); + &village_golem_bb); golemCount = golems->size(); delete golems; } void Village::countPopulation() { + AABB villager_bb = AABB(center->x, center->y, center->z, center->x, center->y, center->z).grow(radius, 4, radius); std::vector >* villagers = level->getEntitiesOfClass( typeid(Villager), - AABB::newTemp(center->x - radius, center->y - 4, center->z - radius, - center->x + radius, center->y + 4, - center->z + radius)); + &villager_bb); populationSize = villagers->size(); delete villagers; From 78b5255224afe66b567426e24067749c720d4fd6 Mon Sep 17 00:00:00 2001 From: orng Date: Fri, 27 Mar 2026 22:37:22 -0500 Subject: [PATCH 030/170] refactor: make `AABBList` own its values --- Minecraft.Client/Rendering/LevelRenderer.cpp | 29 +++++--------------- Minecraft.Client/Rendering/LevelRenderer.h | 2 +- Minecraft.World/Blocks/Tile.cpp | 2 +- Minecraft.World/Entities/Entity.cpp | 19 ++++++------- Minecraft.World/Entities/LivingEntity.cpp | 3 +- Minecraft.World/Level/Level.cpp | 4 +-- Minecraft.World/Util/Definitions.h | 4 +-- 7 files changed, 23 insertions(+), 40 deletions(-) diff --git a/Minecraft.Client/Rendering/LevelRenderer.cpp b/Minecraft.Client/Rendering/LevelRenderer.cpp index 76138cf23..927a8b71f 100644 --- a/Minecraft.Client/Rendering/LevelRenderer.cpp +++ b/Minecraft.Client/Rendering/LevelRenderer.cpp @@ -3862,12 +3862,6 @@ LevelRenderer::DestroyedTileManager::RecentTile::RecentTile(int x, int y, int z, rebuilt = false; } -LevelRenderer::DestroyedTileManager::RecentTile::~RecentTile() { - for (AUTO_VAR(it, boxes.begin()); it != boxes.end(); it++) { - delete *it; - } -} - LevelRenderer::DestroyedTileManager::DestroyedTileManager() { InitializeCriticalSection(&m_csDestroyedTiles); } @@ -3899,14 +3893,6 @@ void LevelRenderer::DestroyedTileManager::destroyingTileAt(Level* level, int x, tile->addAABBs(level, x, y, z, &box, &recentTile->boxes, nullptr); } - // Make these temporary AABBs into permanently allocated AABBs - for (unsigned int i = 0; i < recentTile->boxes.size(); i++) { - recentTile->boxes[i] = - new AABB(recentTile->boxes[i]->x0, recentTile->boxes[i]->y0, - recentTile->boxes[i]->z0, recentTile->boxes[i]->x1, - recentTile->boxes[i]->y1, recentTile->boxes[i]->z1); - } - m_destroyedTiles.push_back(recentTile); LeaveCriticalSection(&m_csDestroyedTiles); @@ -3977,14 +3963,13 @@ void LevelRenderer::DestroyedTileManager::addAABBs(Level* level, AABB* box, // interested in, add them to the output list, making a temp // AABB copy so that we can destroy our own copy without // worrying about the lifespan of the copy we've passed out - if (m_destroyedTiles[i]->boxes[j]->intersects(*box)) { - AABB bb(m_destroyedTiles[i]->boxes[j]->x0, - m_destroyedTiles[i]->boxes[j]->y0, - m_destroyedTiles[i]->boxes[j]->z0, - m_destroyedTiles[i]->boxes[j]->x1, - m_destroyedTiles[i]->boxes[j]->y1, - m_destroyedTiles[i]->boxes[j]->z1); - boxes->push_back(&bb); + if (m_destroyedTiles[i]->boxes[j].intersects(*box)) { + boxes->push_back({m_destroyedTiles[i]->boxes[j].x0, + m_destroyedTiles[i]->boxes[j].y0, + m_destroyedTiles[i]->boxes[j].z0, + m_destroyedTiles[i]->boxes[j].x1, + m_destroyedTiles[i]->boxes[j].y1, + m_destroyedTiles[i]->boxes[j].z1}); } } } diff --git a/Minecraft.Client/Rendering/LevelRenderer.h b/Minecraft.Client/Rendering/LevelRenderer.h index 1275ee4e8..58f194a3b 100644 --- a/Minecraft.Client/Rendering/LevelRenderer.h +++ b/Minecraft.Client/Rendering/LevelRenderer.h @@ -234,7 +234,7 @@ public: int timeout_ticks; bool rebuilt; RecentTile(int x, int y, int z, Level* level); - ~RecentTile(); + ~RecentTile() = default; }; CRITICAL_SECTION m_csDestroyedTiles; std::vector m_destroyedTiles; diff --git a/Minecraft.World/Blocks/Tile.cpp b/Minecraft.World/Blocks/Tile.cpp index a895238ef..a2033379b 100644 --- a/Minecraft.World/Blocks/Tile.cpp +++ b/Minecraft.World/Blocks/Tile.cpp @@ -2016,7 +2016,7 @@ AABB* Tile::getTileAABB(Level* level, int x, int y, int z) { void Tile::addAABBs(Level* level, int x, int y, int z, AABB* box, AABBList* boxes, std::shared_ptr source) { AABB* aabb = getAABB(level, x, y, z); - if (aabb != NULL && box->intersects(*aabb)) boxes->push_back(aabb); + if (aabb != NULL && box->intersects(*aabb)) boxes->push_back(*aabb); } AABB* Tile::getAABB(Level* level, int x, int y, int z) { diff --git a/Minecraft.World/Entities/Entity.cpp b/Minecraft.World/Entities/Entity.cpp index 80a56fd74..d07f16799 100644 --- a/Minecraft.World/Entities/Entity.cpp +++ b/Minecraft.World/Entities/Entity.cpp @@ -733,7 +733,7 @@ void Entity::move(double xa, double ya, double za, // But if we don't have the chunk data then all the collision info will // be incorrect as well for (AUTO_VAR(it, aABBs->begin()); it != itEndAABB; it++) - ya = (*it)->clipYCollide(*bb, ya); + ya = it->clipYCollide(*bb, ya); *bb = bb->move(0, ya, 0); } @@ -745,7 +745,7 @@ void Entity::move(double xa, double ya, double za, itEndAABB = aABBs->end(); for (AUTO_VAR(it, aABBs->begin()); it != itEndAABB; it++) - xa = (*it)->clipXCollide(*bb, xa); + xa = it->clipXCollide(*bb, xa); *bb = bb->move(xa, 0, 0); @@ -755,7 +755,7 @@ void Entity::move(double xa, double ya, double za, itEndAABB = aABBs->end(); for (AUTO_VAR(it, aABBs->begin()); it != itEndAABB; it++) - za = (*it)->clipZCollide(*bb, za); + za = it->clipZCollide(*bb, za); *bb = bb->move(0, 0, za); if (!slide && zaOrg != za) { @@ -789,7 +789,7 @@ void Entity::move(double xa, double ya, double za, // all! But if we don't have the chunk data then all the collision // info will be incorrect as well for (AUTO_VAR(it, aABBs->begin()); it != itEndAABB; it++) - ya = (*it)->clipYCollide(*bb, ya); + ya = it->clipYCollide(*bb, ya); *bb = bb->move(0, ya, 0); } @@ -799,7 +799,7 @@ void Entity::move(double xa, double ya, double za, itEndAABB = aABBs->end(); for (AUTO_VAR(it, aABBs->begin()); it != itEndAABB; it++) - xa = (*it)->clipXCollide(*bb, xa); + xa = it->clipXCollide(*bb, xa); *bb = bb->move(xa, 0, 0); if (!slide && xaOrg != xa) { @@ -808,7 +808,7 @@ void Entity::move(double xa, double ya, double za, itEndAABB = aABBs->end(); for (AUTO_VAR(it, aABBs->begin()); it != itEndAABB; it++) - za = (*it)->clipZCollide(*bb, za); + za = it->clipZCollide(*bb, za); *bb = bb->move(0, 0, za); if (!slide && zaOrg != za) { @@ -822,7 +822,7 @@ void Entity::move(double xa, double ya, double za, // LAND FIRST, then x and z itEndAABB = aABBs->end(); for (AUTO_VAR(it, aABBs->begin()); it != itEndAABB; it++) - ya = (*it)->clipYCollide(*bb, ya); + ya = it->clipYCollide(*bb, ya); *bb = bb->move(0, ya, 0); } @@ -1526,8 +1526,7 @@ void Entity::lerpTo(double x, double y, double z, float yRot, float xRot, double yTop = 0; AUTO_VAR(itEnd, collisions->end()); for (AUTO_VAR(it, collisions->begin()); it != itEnd; it++) { - AABB* ab = *it; // collisions->at(i); - if (ab->y1 > yTop) yTop = ab->y1; + if (it->y1 > yTop) yTop = it->y1; } y += yTop - bb->y0; @@ -1668,7 +1667,7 @@ bool Entity::checkInTile(double x, double y, double z) { double yd = y - (yTile); double zd = z - (zTile); - std::vector* cubes = level->getTileCubes(bb); + auto* cubes = level->getTileCubes(bb); if ((cubes && !cubes->empty()) || level->isFullAABBTile(xTile, yTile, zTile)) { bool west = !level->isFullAABBTile(xTile - 1, yTile, zTile); diff --git a/Minecraft.World/Entities/LivingEntity.cpp b/Minecraft.World/Entities/LivingEntity.cpp index 8725643cf..c30033456 100644 --- a/Minecraft.World/Entities/LivingEntity.cpp +++ b/Minecraft.World/Entities/LivingEntity.cpp @@ -1518,8 +1518,7 @@ void LivingEntity::aiStep() { double yTop = 0; AUTO_VAR(itEnd, collisions->end()); for (AUTO_VAR(it, collisions->begin()); it != itEnd; it++) { - AABB* ab = *it; // collisions->at(i); - if (ab->y1 > yTop) yTop = ab->y1; + if (it->y1 > yTop) yTop = it->y1; } yt += yTop - bb->y0; diff --git a/Minecraft.World/Level/Level.cpp b/Minecraft.World/Level/Level.cpp index cd572cbf7..bfaab0c3d 100644 --- a/Minecraft.World/Level/Level.cpp +++ b/Minecraft.World/Level/Level.cpp @@ -1805,12 +1805,12 @@ AABBList* Level::getCubes(std::shared_ptr source, AABB* box, for (AUTO_VAR(it, ee->begin()); it != itEnd; it++) { AABB* collideBox = (*it)->getCollideBox(); if (collideBox != NULL && collideBox->intersects(*box)) { - boxes.push_back(collideBox); + boxes.push_back(*collideBox); } collideBox = source->getCollideAgainstBox(*it); if (collideBox != NULL && collideBox->intersects(*box)) { - boxes.push_back(collideBox); + boxes.push_back(*collideBox); } } diff --git a/Minecraft.World/Util/Definitions.h b/Minecraft.World/Util/Definitions.h index b0dec3cfe..3ad0caa91 100644 --- a/Minecraft.World/Util/Definitions.h +++ b/Minecraft.World/Util/Definitions.h @@ -4,7 +4,7 @@ class AABB; class Recipy; class Object; -typedef std::vector AABBList; +typedef std::vector AABBList; typedef std::vector RecipyList; typedef std::vector ObjectList; @@ -34,4 +34,4 @@ enum EDefaultSkins { eDefaultSkins_Skin7, eDefaultSkins_Count, -}; \ No newline at end of file +}; From 7158fd398fff993b89ae593a49136ae4ee776876 Mon Sep 17 00:00:00 2001 From: orng Date: Sat, 28 Mar 2026 00:11:19 -0500 Subject: [PATCH 031/170] refactor: make `Tile::getAABB` return `optional` --- .../Blocks/BasePressurePlateTile.cpp | 6 ++-- .../Blocks/BasePressurePlateTile.h | 4 +-- Minecraft.World/Blocks/BaseRailTile.cpp | 5 ++-- Minecraft.World/Blocks/BaseRailTile.h | 2 +- Minecraft.World/Blocks/ButtonTile.cpp | 3 +- Minecraft.World/Blocks/ButtonTile.h | 4 +-- Minecraft.World/Blocks/CactusTile.cpp | 4 +-- Minecraft.World/Blocks/CactusTile.h | 4 +-- Minecraft.World/Blocks/CakeTile.cpp | 4 +-- Minecraft.World/Blocks/CakeTile.h | 4 +-- Minecraft.World/Blocks/CocoaTile.cpp | 5 ++-- Minecraft.World/Blocks/CocoaTile.h | 2 +- Minecraft.World/Blocks/DoorTile.cpp | 7 ++--- Minecraft.World/Blocks/DoorTile.h | 2 +- Minecraft.World/Blocks/FarmTile.cpp | 4 +-- Minecraft.World/Blocks/FarmTile.h | 2 +- Minecraft.World/Blocks/FenceGateTile.cpp | 29 +++++++++++++------ Minecraft.World/Blocks/FenceGateTile.h | 2 +- Minecraft.World/Blocks/FireTile.cpp | 3 +- Minecraft.World/Blocks/FireTile.h | 4 +-- Minecraft.World/Blocks/LadderTile.cpp | 5 ++-- Minecraft.World/Blocks/LadderTile.h | 4 +-- Minecraft.World/Blocks/LeverTile.cpp | 3 +- Minecraft.World/Blocks/LeverTile.h | 2 +- Minecraft.World/Blocks/LiquidTile.cpp | 6 +++- Minecraft.World/Blocks/LiquidTile.h | 3 +- Minecraft.World/Blocks/PistonBaseTile.cpp | 5 +++- Minecraft.World/Blocks/PistonBaseTile.h | 5 ++-- .../Blocks/PistonMovingTileEntity.cpp | 22 +++++++++----- .../Blocks/PistonMovingTileEntity.h | 6 ++-- Minecraft.World/Blocks/PlantTile.cpp | 3 +- Minecraft.World/Blocks/PlantTile.h | 2 +- Minecraft.World/Blocks/PortalTile.cpp | 5 +++- Minecraft.World/Blocks/PortalTile.h | 3 +- Minecraft.World/Blocks/RedStoneDustTile.cpp | 8 +++-- Minecraft.World/Blocks/RedStoneDustTile.h | 3 +- Minecraft.World/Blocks/ReedTile.cpp | 3 +- Minecraft.World/Blocks/ReedTile.h | 3 +- Minecraft.World/Blocks/SignTile.cpp | 7 +++-- Minecraft.World/Blocks/SignTile.h | 5 ++-- Minecraft.World/Blocks/SkullTile.cpp | 4 +-- Minecraft.World/Blocks/SkullTile.h | 2 +- Minecraft.World/Blocks/SoulSandTile.cpp | 4 +-- Minecraft.World/Blocks/SoulSandTile.h | 4 +-- Minecraft.World/Blocks/Tile.cpp | 10 +++---- Minecraft.World/Blocks/Tile.h | 3 +- .../TileEntities/PistonPieceTileEntity.cpp | 7 +++-- Minecraft.World/Blocks/TopSnowTile.cpp | 4 +-- Minecraft.World/Blocks/TopSnowTile.h | 2 +- Minecraft.World/Blocks/TorchTile.cpp | 4 ++- Minecraft.World/Blocks/TorchTile.h | 2 +- Minecraft.World/Blocks/TrapDoorTile.cpp | 5 ++-- Minecraft.World/Blocks/TrapDoorTile.h | 4 +-- Minecraft.World/Blocks/TripWireSourceTile.cpp | 6 ++-- Minecraft.World/Blocks/TripWireSourceTile.h | 2 +- Minecraft.World/Blocks/TripWireTile.cpp | 3 +- Minecraft.World/Blocks/TripWireTile.h | 2 +- Minecraft.World/Blocks/VineTile.cpp | 3 +- Minecraft.World/Blocks/VineTile.h | 4 +-- Minecraft.World/Blocks/WallTile.cpp | 4 +-- Minecraft.World/Blocks/WallTile.h | 4 +-- Minecraft.World/Blocks/WaterLilyTile.cpp | 4 +-- Minecraft.World/Blocks/WaterLilyTile.h | 2 +- Minecraft.World/Blocks/WebTile.cpp | 5 ++-- Minecraft.World/Blocks/WebTile.h | 4 +-- Minecraft.World/Blocks/WoolCarpetTile.cpp | 4 +-- Minecraft.World/Blocks/WoolCarpetTile.h | 5 ++-- Minecraft.World/Entities/Mobs/Arrow.cpp | 4 +-- Minecraft.World/Items/SnowItem.cpp | 6 ++-- .../Items/TileItems/StoneSlabTileItem.cpp | 9 ++++-- Minecraft.World/Level/Level.cpp | 15 +++++----- 71 files changed, 205 insertions(+), 139 deletions(-) diff --git a/Minecraft.World/Blocks/BasePressurePlateTile.cpp b/Minecraft.World/Blocks/BasePressurePlateTile.cpp index d6fb7e697..434ce8e56 100644 --- a/Minecraft.World/Blocks/BasePressurePlateTile.cpp +++ b/Minecraft.World/Blocks/BasePressurePlateTile.cpp @@ -6,6 +6,8 @@ #include "../Headers/net.minecraft.h" #include "../Headers/net.minecraft.world.h" #include "BasePressurePlateTile.h" +#include +#include "Util/AABB.h" BasePressurePlateTile::BasePressurePlateTile(int id, const std::wstring& tex, Material* material) @@ -38,8 +40,8 @@ int BasePressurePlateTile::getTickDelay(Level* level) { return SharedConstants::TICKS_PER_SECOND; } -AABB* BasePressurePlateTile::getAABB(Level* level, int x, int y, int z) { - return NULL; +std::optional BasePressurePlateTile::getAABB(Level* level, int x, int y, int z) { + return std::nullopt; } bool BasePressurePlateTile::isSolidRender(bool isServerLevel) { return false; } diff --git a/Minecraft.World/Blocks/BasePressurePlateTile.h b/Minecraft.World/Blocks/BasePressurePlateTile.h index 62d8de583..e42ff69eb 100644 --- a/Minecraft.World/Blocks/BasePressurePlateTile.h +++ b/Minecraft.World/Blocks/BasePressurePlateTile.h @@ -20,7 +20,7 @@ protected: public: virtual int getTickDelay(Level* level); - virtual AABB* getAABB(Level* level, int x, int y, int z); + virtual std::optional getAABB(Level* level, int x, int y, int z); virtual bool isSolidRender(bool isServerLevel = false); virtual bool blocksLight(); virtual bool isCubeShaped(); @@ -56,4 +56,4 @@ protected: public: virtual void registerIcons(IconRegister* iconRegister); -}; \ No newline at end of file +}; diff --git a/Minecraft.World/Blocks/BaseRailTile.cpp b/Minecraft.World/Blocks/BaseRailTile.cpp index 6478c61bb..31332510e 100644 --- a/Minecraft.World/Blocks/BaseRailTile.cpp +++ b/Minecraft.World/Blocks/BaseRailTile.cpp @@ -3,6 +3,7 @@ #include "../Headers/net.minecraft.world.level.h" #include "../Headers/net.minecraft.world.h" #include "BaseRailTile.h" +#include BaseRailTile::Rail::Rail(Level* level, int x, int y, int z) { this->level = level; @@ -311,7 +312,7 @@ BaseRailTile::BaseRailTile(int id, bool usesDataBit) bool BaseRailTile::isUsesDataBit() { return usesDataBit; } -AABB* BaseRailTile::getAABB(Level* level, int x, int y, int z) { return NULL; } +std::optional BaseRailTile::getAABB(Level* level, int x, int y, int z) { return std::nullopt; } bool BaseRailTile::blocksLight() { return false; } @@ -415,4 +416,4 @@ void BaseRailTile::onRemove(Level* level, int x, int y, int z, int id, level->updateNeighborsAt(x, y, z, id); level->updateNeighborsAt(x, y - 1, z, id); } -} \ No newline at end of file +} diff --git a/Minecraft.World/Blocks/BaseRailTile.h b/Minecraft.World/Blocks/BaseRailTile.h index e352bd3ca..23a7b45af 100644 --- a/Minecraft.World/Blocks/BaseRailTile.h +++ b/Minecraft.World/Blocks/BaseRailTile.h @@ -70,7 +70,7 @@ public: using Tile::getResourceCount; bool isUsesDataBit(); - virtual AABB* getAABB(Level* level, int x, int y, int z); + virtual std::optional getAABB(Level* level, int x, int y, int z); virtual bool blocksLight(); virtual bool isSolidRender(bool isServerLevel = false); virtual HitResult* clip(Level* level, int xt, int yt, int zt, Vec3* a, diff --git a/Minecraft.World/Blocks/ButtonTile.cpp b/Minecraft.World/Blocks/ButtonTile.cpp index 550805d9d..bf0cb742e 100644 --- a/Minecraft.World/Blocks/ButtonTile.cpp +++ b/Minecraft.World/Blocks/ButtonTile.cpp @@ -5,6 +5,7 @@ #include "../Headers/net.minecraft.world.phys.h" #include "../Headers/net.minecraft.h" #include "ButtonTile.h" +#include #include "../Util/SoundTypes.h" ButtonTile::ButtonTile(int id, bool sensitive) @@ -20,7 +21,7 @@ Icon* ButtonTile::getTexture(int face, int data) { return Tile::stone->getTexture(Facing::UP); } -AABB* ButtonTile::getAABB(Level* level, int x, int y, int z) { return NULL; } +std::optional ButtonTile::getAABB(Level* level, int x, int y, int z) { return std::nullopt; } int ButtonTile::getTickDelay(Level* level) { return sensitive ? 30 : 20; } diff --git a/Minecraft.World/Blocks/ButtonTile.h b/Minecraft.World/Blocks/ButtonTile.h index da0f6f757..570dc1be0 100644 --- a/Minecraft.World/Blocks/ButtonTile.h +++ b/Minecraft.World/Blocks/ButtonTile.h @@ -17,7 +17,7 @@ protected: public: Icon* getTexture(int face, int data); - virtual AABB* getAABB(Level* level, int x, int y, int z); + virtual std::optional getAABB(Level* level, int x, int y, int z); virtual int getTickDelay(Level* level); virtual bool blocksLight(); virtual bool isSolidRender(bool isServerLevel = false); @@ -74,4 +74,4 @@ public: // 4J Added so we can check before we try to add a tile to the tick list if // it's actually going to do seomthing virtual bool shouldTileTick(Level* level, int x, int y, int z); -}; \ No newline at end of file +}; diff --git a/Minecraft.World/Blocks/CactusTile.cpp b/Minecraft.World/Blocks/CactusTile.cpp index 34469f773..43aaa0062 100644 --- a/Minecraft.World/Blocks/CactusTile.cpp +++ b/Minecraft.World/Blocks/CactusTile.cpp @@ -33,9 +33,9 @@ void CactusTile::tick(Level* level, int x, int y, int z, Random* random) { } } -AABB* CactusTile::getAABB(Level* level, int x, int y, int z) { +std::optional CactusTile::getAABB(Level* level, int x, int y, int z) { float r = 1 / 16.0f; - return AABB::newTemp(x + r, y, z + r, x + 1 - r, y + 1 - r, z + 1 - r); + return AABB{x + r, static_cast(y), z + r, x + 1 - r, y + 1 - r, z + 1 - r}; } AABB* CactusTile::getTileAABB(Level* level, int x, int y, int z) { diff --git a/Minecraft.World/Blocks/CactusTile.h b/Minecraft.World/Blocks/CactusTile.h index a34b596d0..ef0cf69f9 100644 --- a/Minecraft.World/Blocks/CactusTile.h +++ b/Minecraft.World/Blocks/CactusTile.h @@ -20,7 +20,7 @@ protected: public: virtual void tick(Level* level, int x, int y, int z, Random* random); - virtual AABB* getAABB(Level* level, int x, int y, int z); + virtual std::optional getAABB(Level* level, int x, int y, int z); virtual AABB* getTileAABB(Level* level, int x, int y, int z); virtual Icon* getTexture(int face, int data); virtual bool isCubeShaped(); @@ -37,4 +37,4 @@ public: // 4J Added so we can check before we try to add a tile to the tick list if // it's actually going to do seomthing virtual bool shouldTileTick(Level* level, int x, int y, int z); -}; \ No newline at end of file +}; diff --git a/Minecraft.World/Blocks/CakeTile.cpp b/Minecraft.World/Blocks/CakeTile.cpp index 437438c48..f35919594 100644 --- a/Minecraft.World/Blocks/CakeTile.cpp +++ b/Minecraft.World/Blocks/CakeTile.cpp @@ -34,12 +34,12 @@ void CakeTile::updateDefaultShape() { this->setShape(r, 0, r, 1 - r, h, 1 - r); } -AABB* CakeTile::getAABB(Level* level, int x, int y, int z) { +std::optional CakeTile::getAABB(Level* level, int x, int y, int z) { int d = level->getData(x, y, z); float r = 1 / 16.0f; float r2 = (1 + d * 2) / 16.0f; float h = 8 / 16.0f; - return AABB::newTemp(x + r2, y, z + r, x + 1 - r, y + h - r, z + 1 - r); + return AABB{x + r2, static_cast(y), z + r, x + 1 - r, y + h - r, z + 1 - r}; } AABB* CakeTile::getTileAABB(Level* level, int x, int y, int z) { diff --git a/Minecraft.World/Blocks/CakeTile.h b/Minecraft.World/Blocks/CakeTile.h index 4f201e0a0..ebd33baf2 100644 --- a/Minecraft.World/Blocks/CakeTile.h +++ b/Minecraft.World/Blocks/CakeTile.h @@ -24,7 +24,7 @@ protected: std::shared_ptr forceEntity = std::shared_ptr< TileEntity>()); // 4J added forceData, forceEntity param virtual void updateDefaultShape(); - virtual AABB* getAABB(Level* level, int x, int y, int z); + virtual std::optional getAABB(Level* level, int x, int y, int z); virtual AABB* getTileAABB(Level* level, int x, int y, int z); virtual Icon* getTexture(int face, int data); //@Override @@ -49,4 +49,4 @@ public: virtual int getResourceCount(Random* random); virtual int getResource(int data, Random* random, int playerBonusLevel); int cloneTileId(Level* level, int x, int y, int z); -}; \ No newline at end of file +}; diff --git a/Minecraft.World/Blocks/CocoaTile.cpp b/Minecraft.World/Blocks/CocoaTile.cpp index c0a066699..6250508a8 100644 --- a/Minecraft.World/Blocks/CocoaTile.cpp +++ b/Minecraft.World/Blocks/CocoaTile.cpp @@ -5,6 +5,7 @@ #include "../Headers/net.minecraft.world.h" #include "../Headers/net.minecraft.h" #include "CocoaTile.h" +#include "Util/AABB.h" const std::wstring CocoaTile::TEXTURE_AGES[] = {L"cocoa_0", L"cocoa_1", L"cocoa_2"}; @@ -56,7 +57,7 @@ bool CocoaTile::isCubeShaped() { return false; } bool CocoaTile::isSolidRender(bool isServerLevel) { return false; } -AABB* CocoaTile::getAABB(Level* level, int x, int y, int z) { +std::optional CocoaTile::getAABB(Level* level, int x, int y, int z) { updateShape(level, x, y, z); return DirectionalTile::getAABB(level, x, y, z); } @@ -157,4 +158,4 @@ void CocoaTile::registerIcons(IconRegister* iconRegister) { for (int i = 0; i < COCOA_TEXTURES_LENGTH; i++) { icons[i] = iconRegister->registerIcon(TEXTURE_AGES[i]); } -} \ No newline at end of file +} diff --git a/Minecraft.World/Blocks/CocoaTile.h b/Minecraft.World/Blocks/CocoaTile.h index 9726e232b..7ff5c81ee 100644 --- a/Minecraft.World/Blocks/CocoaTile.h +++ b/Minecraft.World/Blocks/CocoaTile.h @@ -22,7 +22,7 @@ public: virtual int getRenderShape(); virtual bool isCubeShaped(); virtual bool isSolidRender(bool isServerLevel = false); - virtual AABB* getAABB(Level* level, int x, int y, int z); + virtual std::optional getAABB(Level* level, int x, int y, int z); virtual AABB* getTileAABB(Level* level, int x, int y, int z); virtual void updateShape(LevelSource* level, int x, int y, int z, int forceData = -1, diff --git a/Minecraft.World/Blocks/DoorTile.cpp b/Minecraft.World/Blocks/DoorTile.cpp index 11378ce8a..df461bb6b 100644 --- a/Minecraft.World/Blocks/DoorTile.cpp +++ b/Minecraft.World/Blocks/DoorTile.cpp @@ -91,10 +91,9 @@ AABB* DoorTile::getTileAABB(Level* level, int x, int y, int z) { return retval; } -AABB* DoorTile::getAABB(Level* level, int x, int y, int z) { +std::optional DoorTile::getAABB(Level* level, int x, int y, int z) { updateShape(level, x, y, z); - AABB* retval = Tile::getAABB(level, x, y, z); - return retval; + return Tile::getAABB(level, x, y, z); } void DoorTile::updateShape( @@ -307,4 +306,4 @@ void DoorTile::playerWillDestroy(Level* level, int x, int y, int z, int data, } } } -} \ No newline at end of file +} diff --git a/Minecraft.World/Blocks/DoorTile.h b/Minecraft.World/Blocks/DoorTile.h index 1c9abde7b..339775515 100644 --- a/Minecraft.World/Blocks/DoorTile.h +++ b/Minecraft.World/Blocks/DoorTile.h @@ -41,7 +41,7 @@ public: virtual bool isCubeShaped(); virtual int getRenderShape(); virtual AABB* getTileAABB(Level* level, int x, int y, int z); - virtual AABB* getAABB(Level* level, int x, int y, int z); + virtual std::optional getAABB(Level* level, int x, int y, int z); virtual void updateShape( LevelSource* level, int x, int y, int z, int forceData = -1, std::shared_ptr forceEntity = std::shared_ptr< diff --git a/Minecraft.World/Blocks/FarmTile.cpp b/Minecraft.World/Blocks/FarmTile.cpp index dce769962..191f0963c 100644 --- a/Minecraft.World/Blocks/FarmTile.cpp +++ b/Minecraft.World/Blocks/FarmTile.cpp @@ -17,8 +17,8 @@ FarmTile::FarmTile(int id) : Tile(id, Material::dirt, false) { // 4J Added override void FarmTile::updateDefaultShape() { setShape(0, 0, 0, 1, 15 / 16.0f, 1); } -AABB* FarmTile::getAABB(Level* level, int x, int y, int z) { - return AABB::newTemp(x + 0, y + 0, z + 0, x + 1, y + 1, z + 1); +std::optional FarmTile::getAABB(Level* level, int x, int y, int z) { + return AABB(x + 0, y + 0, z + 0, x + 1, y + 1, z + 1); } bool FarmTile::isSolidRender(bool isServerLevel) { return false; } diff --git a/Minecraft.World/Blocks/FarmTile.h b/Minecraft.World/Blocks/FarmTile.h index 15be34ebd..ee7a7e3df 100644 --- a/Minecraft.World/Blocks/FarmTile.h +++ b/Minecraft.World/Blocks/FarmTile.h @@ -18,7 +18,7 @@ protected: public: virtual void updateDefaultShape(); // 4J Added override - virtual AABB* getAABB(Level* level, int x, int y, int z); + virtual std::optional getAABB(Level* level, int x, int y, int z); virtual bool isSolidRender(bool isServerLevel = false); virtual bool isCubeShaped(); virtual Icon* getTexture(int face, int data); diff --git a/Minecraft.World/Blocks/FenceGateTile.cpp b/Minecraft.World/Blocks/FenceGateTile.cpp index 44ee44135..2b947b0e8 100644 --- a/Minecraft.World/Blocks/FenceGateTile.cpp +++ b/Minecraft.World/Blocks/FenceGateTile.cpp @@ -4,6 +4,7 @@ #include "../Headers/net.minecraft.world.level.h" #include "../Headers/net.minecraft.h" #include "../Level/Events/LevelEvent.h" +#include "Util/Direction.h" FenceGateTile::FenceGateTile(int id) : DirectionalTile(id, Material::wood, false) {} @@ -17,19 +18,29 @@ bool FenceGateTile::mayPlace(Level* level, int x, int y, int z) { return Tile::mayPlace(level, x, y, z); } -AABB* FenceGateTile::getAABB(Level* level, int x, int y, int z) { +std::optional FenceGateTile::getAABB(Level* level, int x, int y, int z) { int data = level->getData(x, y, z); if (isOpen(data)) { - return NULL; + return std::nullopt; } - // 4J Brought forward change from 1.2.3 to fix hit box rotation - if (data == Direction::NORTH || data == Direction::SOUTH) { - return AABB::newTemp(x, y, z + 6.0f / 16.0f, x + 1, y + 1.5f, - z + 10.0f / 16.0f); + + switch (data) { + case Direction::NORTH: + case Direction::SOUTH: + return AABB{static_cast(x), + static_cast(y), + z + 6.0 / 16.0, + x + 1.0, + y + 1.5, + z + 10.0 / 16.0}; + default: + return AABB{x + 6.0 / 16.0, + static_cast(y), + static_cast(z), + x + 10.0 / 16.0, + y + 1.5, + z + 1.0}; } - return AABB::newTemp(x + 6.0f / 16.0f, y, z, x + 10.0f / 16.0f, y + 1.5f, - z + 1); - // return AABB::newTemp(x, y, z, x + 1, y + 1.5f, z + 1); } // 4J - Brought forward from 1.2.3 to fix hit box rotation diff --git a/Minecraft.World/Blocks/FenceGateTile.h b/Minecraft.World/Blocks/FenceGateTile.h index 85767bf37..c43b41416 100644 --- a/Minecraft.World/Blocks/FenceGateTile.h +++ b/Minecraft.World/Blocks/FenceGateTile.h @@ -9,7 +9,7 @@ public: FenceGateTile(int id); Icon* getTexture(int face, int data); virtual bool mayPlace(Level* level, int x, int y, int z); - virtual AABB* getAABB(Level* level, int x, int y, int z); + virtual std::optional getAABB(Level* level, int x, int y, int z); virtual void updateShape( LevelSource* level, int x, int y, int z, int forceData = -1, std::shared_ptr forceEntity = std::shared_ptr< diff --git a/Minecraft.World/Blocks/FireTile.cpp b/Minecraft.World/Blocks/FireTile.cpp index 8b5d45b51..e70202920 100644 --- a/Minecraft.World/Blocks/FireTile.cpp +++ b/Minecraft.World/Blocks/FireTile.cpp @@ -7,6 +7,7 @@ #include "../Util/SoundTypes.h" #include "../../Minecraft.Client/MinecraftServer.h" #include "../../Minecraft.Client/Network/PlayerList.h" +#include "Util/AABB.h" // AP - added for Vita to set Alpha Cut out #include "../IO/Streams/IntBuffer.h" @@ -57,7 +58,7 @@ void FireTile::setFlammable(int id, int flame, int burn) { burnOdds[id] = burn; } -AABB* FireTile::getAABB(Level* level, int x, int y, int z) { return NULL; } +std::optional FireTile::getAABB(Level* level, int x, int y, int z) { return std::nullopt; } bool FireTile::blocksLight() { return false; } diff --git a/Minecraft.World/Blocks/FireTile.h b/Minecraft.World/Blocks/FireTile.h index 260e98d97..c93e7e94f 100644 --- a/Minecraft.World/Blocks/FireTile.h +++ b/Minecraft.World/Blocks/FireTile.h @@ -39,7 +39,7 @@ private: void setFlammable(int id, int flame, int burn); public: - virtual AABB* getAABB(Level* level, int x, int y, int z); + virtual std::optional getAABB(Level* level, int x, int y, int z); virtual bool blocksLight(); virtual bool isSolidRender(bool isServerLevel = false); virtual bool isCubeShaped(); @@ -69,4 +69,4 @@ public: void registerIcons(IconRegister* iconRegister); Icon* getTextureLayer(int layer); Icon* getTexture(int face, int data); -}; \ No newline at end of file +}; diff --git a/Minecraft.World/Blocks/LadderTile.cpp b/Minecraft.World/Blocks/LadderTile.cpp index ac0595ea5..f95650843 100644 --- a/Minecraft.World/Blocks/LadderTile.cpp +++ b/Minecraft.World/Blocks/LadderTile.cpp @@ -1,11 +1,12 @@ #include "../Platform/stdafx.h" #include "../Headers/net.minecraft.world.level.h" #include "LadderTile.h" +#include "Util/AABB.h" LadderTile::LadderTile(int id) : Tile(id, Material::decoration, false) {} -AABB* LadderTile::getAABB(Level* level, int x, int y, int z) { +std::optional LadderTile::getAABB(Level* level, int x, int y, int z) { updateShape(level, x, y, z); return Tile::getAABB(level, x, y, z); } @@ -87,4 +88,4 @@ void LadderTile::neighborChanged(Level* level, int x, int y, int z, int type) { Tile::neighborChanged(level, x, y, z, type); } -int LadderTile::getResourceCount(Random* random) { return 1; } \ No newline at end of file +int LadderTile::getResourceCount(Random* random) { return 1; } diff --git a/Minecraft.World/Blocks/LadderTile.h b/Minecraft.World/Blocks/LadderTile.h index d91eeda1f..133c01230 100644 --- a/Minecraft.World/Blocks/LadderTile.h +++ b/Minecraft.World/Blocks/LadderTile.h @@ -11,7 +11,7 @@ protected: LadderTile(int id); public: - virtual AABB* getAABB(Level* level, int x, int y, int z); + virtual std::optional getAABB(Level* level, int x, int y, int z); virtual AABB* getTileAABB(Level* level, int x, int y, int z); virtual void updateShape( LevelSource* level, int x, int y, int z, int forceData = -1, @@ -29,4 +29,4 @@ public: float clickZ, int itemValue); virtual void neighborChanged(Level* level, int x, int y, int z, int type); virtual int getResourceCount(Random* random); -}; \ No newline at end of file +}; diff --git a/Minecraft.World/Blocks/LeverTile.cpp b/Minecraft.World/Blocks/LeverTile.cpp index e44a69ac3..ffb8deead 100644 --- a/Minecraft.World/Blocks/LeverTile.cpp +++ b/Minecraft.World/Blocks/LeverTile.cpp @@ -3,11 +3,12 @@ #include "../Headers/net.minecraft.world.level.redstone.h" #include "../Headers/net.minecraft.h" #include "LeverTile.h" +#include "Util/AABB.h" LeverTile::LeverTile(int id) : Tile(id, Material::decoration, false) {} -AABB* LeverTile::getAABB(Level* level, int x, int y, int z) { return NULL; } +std::optional LeverTile::getAABB(Level* level, int x, int y, int z) { return std::nullopt; } bool LeverTile::blocksLight() { return false; } diff --git a/Minecraft.World/Blocks/LeverTile.h b/Minecraft.World/Blocks/LeverTile.h index 47a6b21cf..7f27ba4a4 100644 --- a/Minecraft.World/Blocks/LeverTile.h +++ b/Minecraft.World/Blocks/LeverTile.h @@ -8,7 +8,7 @@ protected: LeverTile(int id); public: - virtual AABB* getAABB(Level* level, int x, int y, int z); + virtual std::optional getAABB(Level* level, int x, int y, int z); virtual bool blocksLight(); virtual bool isSolidRender(bool isServerLevel = false); virtual bool isCubeShaped(); diff --git a/Minecraft.World/Blocks/LiquidTile.cpp b/Minecraft.World/Blocks/LiquidTile.cpp index af1ee85b4..1c94595f9 100644 --- a/Minecraft.World/Blocks/LiquidTile.cpp +++ b/Minecraft.World/Blocks/LiquidTile.cpp @@ -5,9 +5,11 @@ #include "../Headers/net.minecraft.world.level.biome.h" #include "../Headers/net.minecraft.world.h" #include "LiquidTile.h" +#include #include "../Util/Facing.h" #include "../Util/SoundTypes.h" #include "Blocks/Material.h" +#include "Util/AABB.h" const std::wstring LiquidTile::TEXTURE_LAVA_STILL = L"lava"; const std::wstring LiquidTile::TEXTURE_WATER_STILL = L"water"; @@ -107,7 +109,9 @@ bool LiquidTile::shouldRenderFace(LevelSource* level, int x, int y, int z, return Tile::shouldRenderFace(level, x, y, z, face); } -AABB* LiquidTile::getAABB(Level* level, int x, int y, int z) { return NULL; } +std::optional LiquidTile::getAABB(Level* level, int x, int y, int z) { + return std::nullopt; +} int LiquidTile::getRenderShape() { return Tile::SHAPE_WATER; } diff --git a/Minecraft.World/Blocks/LiquidTile.h b/Minecraft.World/Blocks/LiquidTile.h index 1d59d274a..7ffed063a 100644 --- a/Minecraft.World/Blocks/LiquidTile.h +++ b/Minecraft.World/Blocks/LiquidTile.h @@ -1,4 +1,5 @@ #pragma once +#include #include "Tile.h" #include "../Util/Definitions.h" @@ -40,7 +41,7 @@ public: virtual bool isSolidFace(LevelSource* level, int x, int y, int z, int face); virtual bool shouldRenderFace(LevelSource* level, int x, int y, int z, int face); - virtual AABB* getAABB(Level* level, int x, int y, int z); + virtual std::optional getAABB(Level* level, int x, int y, int z); virtual int getRenderShape(); virtual int getResource(int data, Random* random, int playerBonusLevel); virtual int getResourceCount(Random* random); diff --git a/Minecraft.World/Blocks/PistonBaseTile.cpp b/Minecraft.World/Blocks/PistonBaseTile.cpp index de8c30b23..8a85152cc 100644 --- a/Minecraft.World/Blocks/PistonBaseTile.cpp +++ b/Minecraft.World/Blocks/PistonBaseTile.cpp @@ -1,5 +1,6 @@ #include "../Platform/stdafx.h" #include +#include #include "PistonBaseTile.h" #include "PistonMovingTileEntity.h" #include "TileEntities/PistonPieceTileEntity.h" @@ -12,6 +13,8 @@ #include "../Level/LevelChunk.h" #include "../Level/Dimensions/Dimension.h" +#include "Util/AABB.h" + const std::wstring PistonBaseTile::EDGE_TEX = L"piston_side"; const std::wstring PistonBaseTile::PLATFORM_TEX = L"piston_top"; const std::wstring PistonBaseTile::PLATFORM_STICKY_TEX = L"piston_top_sticky"; @@ -398,7 +401,7 @@ void PistonBaseTile::addAABBs(Level* level, int x, int y, int z, AABB* box, Tile::addAABBs(level, x, y, z, box, boxes, source); } -AABB* PistonBaseTile::getAABB(Level* level, int x, int y, int z) { +std::optional PistonBaseTile::getAABB(Level* level, int x, int y, int z) { updateShape(level, x, y, z); return Tile::getAABB(level, x, y, z); } diff --git a/Minecraft.World/Blocks/PistonBaseTile.h b/Minecraft.World/Blocks/PistonBaseTile.h index 272b44e81..36097aacf 100644 --- a/Minecraft.World/Blocks/PistonBaseTile.h +++ b/Minecraft.World/Blocks/PistonBaseTile.h @@ -1,6 +1,7 @@ #pragma once #include "Tile.h" #include +#include class PistonBaseTile : public Tile { public: @@ -68,7 +69,7 @@ public: virtual void updateDefaultShape(); virtual void addAABBs(Level* level, int x, int y, int z, AABB* box, AABBList* boxes, std::shared_ptr source); - virtual AABB* getAABB(Level* level, int x, int y, int z); + virtual std::optional getAABB(Level* level, int x, int y, int z); virtual bool isCubeShaped(); static int getFacing(int data); @@ -84,4 +85,4 @@ private: int z); // 4J added bool createPush(Level* level, int sx, int sy, int sz, int facing); -}; \ No newline at end of file +}; diff --git a/Minecraft.World/Blocks/PistonMovingTileEntity.cpp b/Minecraft.World/Blocks/PistonMovingTileEntity.cpp index b12d0dd7d..f4109695d 100644 --- a/Minecraft.World/Blocks/PistonMovingTileEntity.cpp +++ b/Minecraft.World/Blocks/PistonMovingTileEntity.cpp @@ -1,5 +1,6 @@ #include "../Platform/stdafx.h" #include "PistonMovingTileEntity.h" +#include #include "TileEntities/PistonPieceTileEntity.h" #include "../Headers/net.minecraft.world.level.h" #include "../Headers/net.minecraft.world.h" @@ -91,10 +92,11 @@ std::shared_ptr PistonMovingPiece::newMovingPieceEntity( new PistonPieceEntity(block, data, facing, extending, isSourcePiston)); } -AABB* PistonMovingPiece::getAABB(Level* level, int x, int y, int z) { +std::optional PistonMovingPiece::getAABB(Level* level, int x, int y, + int z) { std::shared_ptr entity = getEntity(level, x, y, z); if (entity == NULL) { - return NULL; + return std::nullopt; } // move the aabb depending on the animation @@ -136,15 +138,16 @@ void PistonMovingPiece::updateShape( } } -AABB* PistonMovingPiece::getAABB(Level* level, int x, int y, int z, int tile, - float progress, int facing) { +std::optional PistonMovingPiece::getAABB(Level* level, int x, int y, + int z, int tile, float progress, + int facing) { if (tile == 0 || tile == id) { - return NULL; + return std::nullopt; } - AABB* aabb = Tile::tiles[tile]->getAABB(level, x, y, z); + auto aabb = Tile::tiles[tile]->getAABB(level, x, y, z); - if (aabb == NULL) { - return NULL; + if (!aabb.has_value()) { + return std::nullopt; } // move the aabb depending on the animation @@ -153,16 +156,19 @@ AABB* PistonMovingPiece::getAABB(Level* level, int x, int y, int z, int tile, } else { aabb->x1 -= Facing::STEP_X[facing] * progress; } + if (Facing::STEP_Y[facing] < 0) { aabb->y0 -= Facing::STEP_Y[facing] * progress; } else { aabb->y1 -= Facing::STEP_Y[facing] * progress; } + if (Facing::STEP_Z[facing] < 0) { aabb->z0 -= Facing::STEP_Z[facing] * progress; } else { aabb->z1 -= Facing::STEP_Z[facing] * progress; } + return aabb; } diff --git a/Minecraft.World/Blocks/PistonMovingTileEntity.h b/Minecraft.World/Blocks/PistonMovingTileEntity.h index 530c6e87d..ec3a5aa7f 100644 --- a/Minecraft.World/Blocks/PistonMovingTileEntity.h +++ b/Minecraft.World/Blocks/PistonMovingTileEntity.h @@ -28,13 +28,13 @@ public: virtual void neighborChanged(Level* level, int x, int y, int z, int type); static std::shared_ptr newMovingPieceEntity( int block, int data, int facing, bool extending, bool isSourcePiston); - virtual AABB* getAABB(Level* level, int x, int y, int z); + virtual std::optional getAABB(Level* level, int x, int y, int z); virtual void updateShape( LevelSource* level, int x, int y, int z, int forceData = -1, std::shared_ptr forceEntity = std::shared_ptr< TileEntity>()); // 4J added forceData, forceEntity param - AABB* getAABB(Level* level, int x, int y, int z, int tile, float progress, + std::optional getAABB(Level* level, int x, int y, int z, int tile, float progress, int facing); private: @@ -44,4 +44,4 @@ private: public: virtual int cloneTileId(Level* level, int x, int y, int z); void registerIcons(IconRegister* iconRegister); -}; \ No newline at end of file +}; diff --git a/Minecraft.World/Blocks/PlantTile.cpp b/Minecraft.World/Blocks/PlantTile.cpp index ee3f09669..543008466 100644 --- a/Minecraft.World/Blocks/PlantTile.cpp +++ b/Minecraft.World/Blocks/PlantTile.cpp @@ -2,6 +2,7 @@ #include "../Headers/net.minecraft.world.level.h" #include "GrassTile.h" #include "PlantTile.h" +#include "Util/AABB.h" void Bush::_init() { setTicking(true); @@ -52,7 +53,7 @@ bool Bush::canSurvive(Level* level, int x, int y, int z) { mayPlaceOn(level->getTile(x, y - 1, z)); } -AABB* Bush::getAABB(Level* level, int x, int y, int z) { return NULL; } +std::optional Bush::getAABB(Level* level, int x, int y, int z) { return std::nullopt; } bool Bush::blocksLight() { return false; } diff --git a/Minecraft.World/Blocks/PlantTile.h b/Minecraft.World/Blocks/PlantTile.h index 53ebbcb46..72c134196 100644 --- a/Minecraft.World/Blocks/PlantTile.h +++ b/Minecraft.World/Blocks/PlantTile.h @@ -32,7 +32,7 @@ protected: public: virtual bool canSurvive(Level* level, int x, int y, int z); - virtual AABB* getAABB(Level* level, int x, int y, int z); + virtual std::optional getAABB(Level* level, int x, int y, int z); virtual bool blocksLight(); virtual bool isSolidRender(bool isServerLevel = false); diff --git a/Minecraft.World/Blocks/PortalTile.cpp b/Minecraft.World/Blocks/PortalTile.cpp index 994e79a24..bd4f199b3 100644 --- a/Minecraft.World/Blocks/PortalTile.cpp +++ b/Minecraft.World/Blocks/PortalTile.cpp @@ -4,6 +4,9 @@ #include "../Headers/net.minecraft.world.level.dimension.h" #include "../Headers/net.minecraft.world.item.h" #include "PortalTile.h" +#include + +#include "Util/AABB.h" #include "FireTile.h" PortalTile::PortalTile(int id) @@ -34,7 +37,7 @@ void PortalTile::tick(Level* level, int x, int y, int z, Random* random) { } } -AABB* PortalTile::getAABB(Level* level, int x, int y, int z) { return NULL; } +std::optional PortalTile::getAABB(Level* level, int x, int y, int z) { return std::nullopt; } void PortalTile::updateShape( LevelSource* level, int x, int y, int z, int forceData, diff --git a/Minecraft.World/Blocks/PortalTile.h b/Minecraft.World/Blocks/PortalTile.h index b498fb1ac..c62fb1033 100644 --- a/Minecraft.World/Blocks/PortalTile.h +++ b/Minecraft.World/Blocks/PortalTile.h @@ -1,4 +1,5 @@ #pragma once +#include #include "HalfTransparentTile.h" #include "../Util/Definitions.h" @@ -8,7 +9,7 @@ class PortalTile : public HalfTransparentTile { public: PortalTile(int id); virtual void tick(Level* level, int x, int y, int z, Random* random); - virtual AABB* getAABB(Level* level, int x, int y, int z); + virtual std::optional getAABB(Level* level, int x, int y, int z); virtual void updateShape( LevelSource* level, int x, int y, int z, int forceData = -1, std::shared_ptr forceEntity = std::shared_ptr< diff --git a/Minecraft.World/Blocks/RedStoneDustTile.cpp b/Minecraft.World/Blocks/RedStoneDustTile.cpp index f4e3ce074..581469f50 100644 --- a/Minecraft.World/Blocks/RedStoneDustTile.cpp +++ b/Minecraft.World/Blocks/RedStoneDustTile.cpp @@ -1,6 +1,8 @@ #include "../Platform/stdafx.h" #include "../../Minecraft.Client/Minecraft.h" #include "RedStoneDustTile.h" +#include +#include #include "../Headers/net.minecraft.world.item.h" #include "../Headers/net.minecraft.world.level.h" #include "../Headers/net.minecraft.world.level.redstone.h" @@ -9,6 +11,7 @@ #include "../Headers/net.minecraft.h" #include "../Util/Direction.h" #include "DiodeTile.h" +#include "Util/AABB.h" // AP - added for Vita to set Alpha Cut out #include "../IO/Streams/IntBuffer.h" @@ -36,8 +39,9 @@ void RedStoneDustTile::updateDefaultShape() { setShape(0, 0, 0, 1, 1 / 16.0f, 1); } -AABB* RedStoneDustTile::getAABB(Level* level, int x, int y, int z) { - return NULL; +std::optional RedStoneDustTile::getAABB(Level* level, int x, int y, + int z) { + return std::nullopt; } bool RedStoneDustTile::isSolidRender(bool isServerLevel) { return false; } diff --git a/Minecraft.World/Blocks/RedStoneDustTile.h b/Minecraft.World/Blocks/RedStoneDustTile.h index 872f9ea58..e9656d395 100644 --- a/Minecraft.World/Blocks/RedStoneDustTile.h +++ b/Minecraft.World/Blocks/RedStoneDustTile.h @@ -1,4 +1,5 @@ #pragma once +#include #include "Tile.h" #include "../Util/Definitions.h" @@ -26,7 +27,7 @@ private: public: RedStoneDustTile(int id); virtual void updateDefaultShape(); // 4J Added override - virtual AABB* getAABB(Level* level, int x, int y, int z); + virtual std::optional getAABB(Level* level, int x, int y, int z); virtual bool isSolidRender(bool isServerLevel = false); virtual bool isCubeShaped(); virtual int getRenderShape(); diff --git a/Minecraft.World/Blocks/ReedTile.cpp b/Minecraft.World/Blocks/ReedTile.cpp index c9297caf4..7961dbaeb 100644 --- a/Minecraft.World/Blocks/ReedTile.cpp +++ b/Minecraft.World/Blocks/ReedTile.cpp @@ -5,6 +5,7 @@ #include "../Headers/net.minecraft.world.level.material.h" #include "../Headers/net.minecraft.world.phys.h" #include "ReedTile.h" +#include ReedTile::ReedTile(int id) : Tile(id, Material::plant, false) { this->updateDefaultShape(); @@ -64,7 +65,7 @@ bool ReedTile::canSurvive(Level* level, int x, int y, int z) { return mayPlace(level, x, y, z); } -AABB* ReedTile::getAABB(Level* level, int x, int y, int z) { return NULL; } +std::optional ReedTile::getAABB(Level* level, int x, int y, int z) { return std::nullopt; } int ReedTile::getResource(int data, Random* random, int playerBonusLevel) { return Item::reeds->id; diff --git a/Minecraft.World/Blocks/ReedTile.h b/Minecraft.World/Blocks/ReedTile.h index dd3a3bab4..4fbe21aa3 100644 --- a/Minecraft.World/Blocks/ReedTile.h +++ b/Minecraft.World/Blocks/ReedTile.h @@ -1,5 +1,6 @@ #pragma once +#include #include "Tile.h" #include "../Util/Definitions.h" @@ -28,7 +29,7 @@ public: bool canSurvive(Level* level, int x, int y, int z); public: - AABB* getAABB(Level* level, int x, int y, int z); + std::optional getAABB(Level* level, int x, int y, int z); public: int getResource(int data, Random* random, int playerBonusLevel); diff --git a/Minecraft.World/Blocks/SignTile.cpp b/Minecraft.World/Blocks/SignTile.cpp index 0ffd3e7b9..2004f9e4a 100644 --- a/Minecraft.World/Blocks/SignTile.cpp +++ b/Minecraft.World/Blocks/SignTile.cpp @@ -4,6 +4,9 @@ #include "Material.h" #include "TileEntities/SignTileEntity.h" #include "SignTile.h" +#include "Util/AABB.h" + +#include SignTile::SignTile(int id, eINSTANCEOF clas, bool onGround) : BaseEntityTile(id, Material::wood, false) { @@ -22,7 +25,7 @@ void SignTile::updateDefaultShape() { this->setShape(0.5f - r, 0, 0.5f - r, 0.5f + r, h, 0.5f + r); } -AABB* SignTile::getAABB(Level* level, int x, int y, int z) { return NULL; } +std::optional SignTile::getAABB(Level* level, int x, int y, int z) { return std::nullopt; } AABB* SignTile::getTileAABB(Level* level, int x, int y, int z) { updateShape(level, x, y, z); @@ -109,4 +112,4 @@ int SignTile::cloneTileId(Level* level, int x, int y, int z) { void SignTile::registerIcons(IconRegister* iconRegister) { // None -} \ No newline at end of file +} diff --git a/Minecraft.World/Blocks/SignTile.h b/Minecraft.World/Blocks/SignTile.h index b3e5ec372..9e4c009d2 100644 --- a/Minecraft.World/Blocks/SignTile.h +++ b/Minecraft.World/Blocks/SignTile.h @@ -1,5 +1,6 @@ #pragma once +#include #include "BaseEntityTile.h" #include "TileEntities/TileEntity.h" @@ -19,7 +20,7 @@ protected: public: Icon* getTexture(int face, int data); virtual void updateDefaultShape(); - AABB* getAABB(Level* level, int x, int y, int z); + std::optional getAABB(Level* level, int x, int y, int z); AABB* getTileAABB(Level* level, int x, int y, int z); void updateShape(LevelSource* level, int x, int y, int z, int forceData = -1, @@ -39,4 +40,4 @@ public: void neighborChanged(Level* level, int x, int y, int z, int type); int cloneTileId(Level* level, int x, int y, int z); void registerIcons(IconRegister* iconRegister); -}; \ No newline at end of file +}; diff --git a/Minecraft.World/Blocks/SkullTile.cpp b/Minecraft.World/Blocks/SkullTile.cpp index 251cb7833..1a0340b7d 100644 --- a/Minecraft.World/Blocks/SkullTile.cpp +++ b/Minecraft.World/Blocks/SkullTile.cpp @@ -49,7 +49,7 @@ void SkullTile::updateShape(LevelSource* level, int x, int y, int z, } } -AABB* SkullTile::getAABB(Level* level, int x, int y, int z) { +std::optional SkullTile::getAABB(Level* level, int x, int y, int z) { updateShape(level, x, y, z); return BaseEntityTile::getAABB(level, x, y, z); } @@ -316,4 +316,4 @@ Icon* SkullTile::getTexture(int face, int data) { std::wstring SkullTile::getTileItemIconName() { return getIconName() + L"_" + SkullItem::ICON_NAMES[0]; -} \ No newline at end of file +} diff --git a/Minecraft.World/Blocks/SkullTile.h b/Minecraft.World/Blocks/SkullTile.h index 5c2642b01..f8fea1299 100644 --- a/Minecraft.World/Blocks/SkullTile.h +++ b/Minecraft.World/Blocks/SkullTile.h @@ -26,7 +26,7 @@ public: int forceData = -1, std::shared_ptr forceEntity = std::shared_ptr()); - AABB* getAABB(Level* level, int x, int y, int z); + std::optional getAABB(Level* level, int x, int y, int z); void setPlacedBy(Level* level, int x, int y, int z, std::shared_ptr by); std::shared_ptr newTileEntity(Level* level); diff --git a/Minecraft.World/Blocks/SoulSandTile.cpp b/Minecraft.World/Blocks/SoulSandTile.cpp index 22b4f8509..b9f7b48df 100644 --- a/Minecraft.World/Blocks/SoulSandTile.cpp +++ b/Minecraft.World/Blocks/SoulSandTile.cpp @@ -5,9 +5,9 @@ SoulSandTile::SoulSandTile(int id) : Tile(id, Material::sand) {} -AABB* SoulSandTile::getAABB(Level* level, int x, int y, int z) { +std::optional SoulSandTile::getAABB(Level* level, int x, int y, int z) { float r = 2 / 16.0f; - return AABB::newTemp(x, y, z, x + 1, y + 1 - r, z + 1); + return AABB(x, y, z, x + 1, y + 1 - r, z + 1); } void SoulSandTile::entityInside(Level* level, int x, int y, int z, diff --git a/Minecraft.World/Blocks/SoulSandTile.h b/Minecraft.World/Blocks/SoulSandTile.h index 62d6b1e45..b45c8dc53 100644 --- a/Minecraft.World/Blocks/SoulSandTile.h +++ b/Minecraft.World/Blocks/SoulSandTile.h @@ -5,7 +5,7 @@ class SoulSandTile : public Tile { public: SoulSandTile(int id); - virtual AABB* getAABB(Level* level, int x, int y, int z); + virtual std::optional getAABB(Level* level, int x, int y, int z); virtual void entityInside(Level* level, int x, int y, int z, std::shared_ptr entity); -}; \ No newline at end of file +}; diff --git a/Minecraft.World/Blocks/Tile.cpp b/Minecraft.World/Blocks/Tile.cpp index a2033379b..66d58c632 100644 --- a/Minecraft.World/Blocks/Tile.cpp +++ b/Minecraft.World/Blocks/Tile.cpp @@ -2015,16 +2015,16 @@ AABB* Tile::getTileAABB(Level* level, int x, int y, int z) { void Tile::addAABBs(Level* level, int x, int y, int z, AABB* box, AABBList* boxes, std::shared_ptr source) { - AABB* aabb = getAABB(level, x, y, z); - if (aabb != NULL && box->intersects(*aabb)) boxes->push_back(*aabb); + auto aabb = getAABB(level, x, y, z); + if (aabb.has_value() && box->intersects(*aabb)) boxes->push_back(*aabb); } -AABB* Tile::getAABB(Level* level, int x, int y, int z) { +std::optional Tile::getAABB(Level* level, int x, int y, int z) { ThreadStorage* tls = m_tlsShape; // 4J Stu - Added this so that the TLS shape is correct for this tile if (tls->tileId != this->id) updateDefaultShape(); - return AABB::newTemp(x + tls->xx0, y + tls->yy0, z + tls->zz0, x + tls->xx1, - y + tls->yy1, z + tls->zz1); + return AABB{x + tls->xx0, y + tls->yy0, z + tls->zz0, + x + tls->xx1, y + tls->yy1, z + tls->zz1}; } bool Tile::isSolidRender(bool isServerLevel) { return true; } diff --git a/Minecraft.World/Blocks/Tile.h b/Minecraft.World/Blocks/Tile.h index b46748ff5..4346f6d26 100644 --- a/Minecraft.World/Blocks/Tile.h +++ b/Minecraft.World/Blocks/Tile.h @@ -4,6 +4,7 @@ #include "../Util/Definitions.h" #include "../Util/SoundTypes.h" #include +#include class GrassTile; class LeafTile; @@ -633,7 +634,7 @@ public: virtual AABB* getTileAABB(Level* level, int x, int y, int z); virtual void addAABBs(Level* level, int x, int y, int z, AABB* box, AABBList* boxes, std::shared_ptr source); - virtual AABB* getAABB(Level* level, int x, int y, int z); + virtual std::optional getAABB(Level* level, int x, int y, int z); virtual bool isSolidRender( bool isServerLevel = false); // 4J - Added isServerLevel param virtual bool mayPick(int data, bool liquid); diff --git a/Minecraft.World/Blocks/TileEntities/PistonPieceTileEntity.cpp b/Minecraft.World/Blocks/TileEntities/PistonPieceTileEntity.cpp index fb49032ca..84d73b9c7 100644 --- a/Minecraft.World/Blocks/TileEntities/PistonPieceTileEntity.cpp +++ b/Minecraft.World/Blocks/TileEntities/PistonPieceTileEntity.cpp @@ -5,6 +5,7 @@ #include "../../Headers/net.minecraft.world.level.h" #include "../../Util/Facing.h" #include "../Tile.h" +#include "../../Util/AABB.h" PistonPieceEntity::PistonPieceEntity() { // for the tile entity loader @@ -81,11 +82,11 @@ void PistonPieceEntity::moveCollidedEntities(float progress, float amount) { progress = progress - 1.0f; } - AABB* aabb = + auto aabb = Tile::pistonMovingPiece->getAABB(level, x, y, z, id, progress, facing); - if (aabb != NULL) { + if (aabb.has_value()) { std::vector >* entities = - level->getEntities(nullptr, aabb); + level->getEntities(nullptr, &*aabb); if (!entities->empty()) { std::vector > collisionHolder; for (AUTO_VAR(it, entities->begin()); it != entities->end(); it++) { diff --git a/Minecraft.World/Blocks/TopSnowTile.cpp b/Minecraft.World/Blocks/TopSnowTile.cpp index 8ba44c61b..cd5182116 100644 --- a/Minecraft.World/Blocks/TopSnowTile.cpp +++ b/Minecraft.World/Blocks/TopSnowTile.cpp @@ -21,11 +21,11 @@ void TopSnowTile::registerIcons(IconRegister* iconRegister) { icon = iconRegister->registerIcon(L"snow"); } -AABB* TopSnowTile::getAABB(Level* level, int x, int y, int z) { +std::optional TopSnowTile::getAABB(Level* level, int x, int y, int z) { int height = level->getData(x, y, z) & HEIGHT_MASK; float offset = 2.0f / SharedConstants::WORLD_RESOLUTION; ThreadStorage* tls = m_tlsShape; - return AABB::newTemp(x + tls->xx0, y + tls->yy0, z + tls->zz0, x + tls->xx1, + return AABB(x + tls->xx0, y + tls->yy0, z + tls->zz0, x + tls->xx1, y + (height * offset), z + tls->zz1); } diff --git a/Minecraft.World/Blocks/TopSnowTile.h b/Minecraft.World/Blocks/TopSnowTile.h index 710aab8b8..bfa529d76 100644 --- a/Minecraft.World/Blocks/TopSnowTile.h +++ b/Minecraft.World/Blocks/TopSnowTile.h @@ -16,7 +16,7 @@ protected: public: void registerIcons(IconRegister* iconRegister); - AABB* getAABB(Level* level, int x, int y, int z); + std::optional getAABB(Level* level, int x, int y, int z); public: static float getHeight(Level* level, int x, int y, int z); diff --git a/Minecraft.World/Blocks/TorchTile.cpp b/Minecraft.World/Blocks/TorchTile.cpp index bca94562f..556370789 100644 --- a/Minecraft.World/Blocks/TorchTile.cpp +++ b/Minecraft.World/Blocks/TorchTile.cpp @@ -3,12 +3,14 @@ #include "../Headers/net.minecraft.world.level.h" #include "../Headers/net.minecraft.world.level.tile.h" #include "TorchTile.h" +#include +#include "Util/AABB.h" TorchTile::TorchTile(int id) : Tile(id, Material::decoration, false) { this->setTicking(true); } -AABB* TorchTile::getAABB(Level* level, int x, int y, int z) { return NULL; } +std::optional TorchTile::getAABB(Level* level, int x, int y, int z) { return std::nullopt; } AABB* TorchTile::getTileAABB(Level* level, int x, int y, int z) { updateShape(level, x, y, z); diff --git a/Minecraft.World/Blocks/TorchTile.h b/Minecraft.World/Blocks/TorchTile.h index 0369a3584..3f7d0a4d1 100644 --- a/Minecraft.World/Blocks/TorchTile.h +++ b/Minecraft.World/Blocks/TorchTile.h @@ -12,7 +12,7 @@ protected: TorchTile(int id); public: - virtual AABB* getAABB(Level* level, int x, int y, int z); + virtual std::optional getAABB(Level* level, int x, int y, int z); virtual AABB* getTileAABB(Level* level, int x, int y, int z); virtual void updateShape( LevelSource* level, int x, int y, int z, int forceData = -1, diff --git a/Minecraft.World/Blocks/TrapDoorTile.cpp b/Minecraft.World/Blocks/TrapDoorTile.cpp index eb685504d..bca1ce813 100644 --- a/Minecraft.World/Blocks/TrapDoorTile.cpp +++ b/Minecraft.World/Blocks/TrapDoorTile.cpp @@ -4,6 +4,7 @@ #include "../Headers/net.minecraft.world.level.tile.h" #include "../Headers/net.minecraft.h" #include "TrapDoorTile.h" +#include "Util/AABB.h" TrapDoorTile::TrapDoorTile(int id, Material* material) : Tile(id, material, false) { @@ -29,7 +30,7 @@ AABB* TrapDoorTile::getTileAABB(Level* level, int x, int y, int z) { return Tile::getTileAABB(level, x, y, z); } -AABB* TrapDoorTile::getAABB(Level* level, int x, int y, int z) { +std::optional TrapDoorTile::getAABB(Level* level, int x, int y, int z) { updateShape(level, x, y, z); return Tile::getAABB(level, x, y, z); } @@ -175,4 +176,4 @@ bool TrapDoorTile::attachesTo(int id) { tile == Tile::glowstone || (dynamic_cast(tile) != NULL) || (dynamic_cast(tile) != NULL); -} \ No newline at end of file +} diff --git a/Minecraft.World/Blocks/TrapDoorTile.h b/Minecraft.World/Blocks/TrapDoorTile.h index f2e978759..9765b61c6 100644 --- a/Minecraft.World/Blocks/TrapDoorTile.h +++ b/Minecraft.World/Blocks/TrapDoorTile.h @@ -40,7 +40,7 @@ public: AABB* getTileAABB(Level* level, int x, int y, int z); public: - AABB* getAABB(Level* level, int x, int y, int z); + std::optional getAABB(Level* level, int x, int y, int z); public: void updateShape(LevelSource* level, int x, int y, int z, @@ -91,4 +91,4 @@ public: private: static bool attachesTo(int id); -}; \ No newline at end of file +}; diff --git a/Minecraft.World/Blocks/TripWireSourceTile.cpp b/Minecraft.World/Blocks/TripWireSourceTile.cpp index 14fc620b9..c9115901e 100644 --- a/Minecraft.World/Blocks/TripWireSourceTile.cpp +++ b/Minecraft.World/Blocks/TripWireSourceTile.cpp @@ -4,14 +4,16 @@ #include "../Headers/net.minecraft.world.level.tile.h" #include "../Headers/net.minecraft.world.level.redstone.h" #include "TripWireSourceTile.h" +#include "optional" +#include "Util/AABB.h" TripWireSourceTile::TripWireSourceTile(int id) : Tile(id, Material::decoration, false) { this->setTicking(true); } -AABB* TripWireSourceTile::getAABB(Level* level, int x, int y, int z) { - return NULL; +std::optional TripWireSourceTile::getAABB(Level* level, int x, int y, int z) { + return std::nullopt; } bool TripWireSourceTile::blocksLight() { return false; } diff --git a/Minecraft.World/Blocks/TripWireSourceTile.h b/Minecraft.World/Blocks/TripWireSourceTile.h index 9cce09eb6..e23c61feb 100644 --- a/Minecraft.World/Blocks/TripWireSourceTile.h +++ b/Minecraft.World/Blocks/TripWireSourceTile.h @@ -14,7 +14,7 @@ public: TripWireSourceTile(int id); - AABB* getAABB(Level* level, int x, int y, int z); + std::optional getAABB(Level* level, int x, int y, int z); bool blocksLight(); bool isSolidRender(bool isServerLevel = false); bool isCubeShaped(); diff --git a/Minecraft.World/Blocks/TripWireTile.cpp b/Minecraft.World/Blocks/TripWireTile.cpp index 0e5755e47..e72ea5cdd 100644 --- a/Minecraft.World/Blocks/TripWireTile.cpp +++ b/Minecraft.World/Blocks/TripWireTile.cpp @@ -4,6 +4,7 @@ #include "../Headers/net.minecraft.world.level.tile.h" #include "../Headers/net.minecraft.world.phys.h" #include "TripWireTile.h" +#include TripWireTile::TripWireTile(int id) : Tile(id, Material::decoration, false) { setShape(0, 0, 0, 1, 2.5f / 16.0f, 1); @@ -16,7 +17,7 @@ int TripWireTile::getTickDelay(Level* level) { return 20; // 10; } -AABB* TripWireTile::getAABB(Level* level, int x, int y, int z) { return NULL; } +std::optional TripWireTile::getAABB(Level* level, int x, int y, int z) { return std::nullopt; } bool TripWireTile::blocksLight() { return false; } diff --git a/Minecraft.World/Blocks/TripWireTile.h b/Minecraft.World/Blocks/TripWireTile.h index f6c7becef..6963d0305 100644 --- a/Minecraft.World/Blocks/TripWireTile.h +++ b/Minecraft.World/Blocks/TripWireTile.h @@ -14,7 +14,7 @@ public: TripWireTile(int id); int getTickDelay(Level* level); - AABB* getAABB(Level* level, int x, int y, int z); + std::optional getAABB(Level* level, int x, int y, int z); bool blocksLight(); bool isSolidRender(bool isServerLevel = false); bool isCubeShaped(); diff --git a/Minecraft.World/Blocks/VineTile.cpp b/Minecraft.World/Blocks/VineTile.cpp index d2febbaa9..787fb4588 100644 --- a/Minecraft.World/Blocks/VineTile.cpp +++ b/Minecraft.World/Blocks/VineTile.cpp @@ -7,6 +7,7 @@ #include "../Headers/net.minecraft.world.item.h" #include "../Headers/net.minecraft.stats.h" #include "../Headers/net.minecraft.world.level.biome.h" +#include "Util/AABB.h" VineTile::VineTile(int id) : Tile(id, Material::replaceable_plant, false) { @@ -85,7 +86,7 @@ void VineTile::updateShape( setShape(minX, minY, minZ, maxX, maxY, maxZ); } -AABB* VineTile::getAABB(Level* level, int x, int y, int z) { return NULL; } +std::optional VineTile::getAABB(Level* level, int x, int y, int z) { return std::nullopt; } bool VineTile::mayPlace(Level* level, int x, int y, int z, int face) { switch (face) { diff --git a/Minecraft.World/Blocks/VineTile.h b/Minecraft.World/Blocks/VineTile.h index 965eba70f..dc123a38c 100644 --- a/Minecraft.World/Blocks/VineTile.h +++ b/Minecraft.World/Blocks/VineTile.h @@ -21,7 +21,7 @@ public: LevelSource* level, int x, int y, int z, int forceData = -1, std::shared_ptr forceEntity = std::shared_ptr< TileEntity>()); // 4J added forceData, forceEntity param - virtual AABB* getAABB(Level* level, int x, int y, int z); + virtual std::optional getAABB(Level* level, int x, int y, int z); virtual bool mayPlace(Level* level, int x, int y, int z, int face); private: @@ -43,4 +43,4 @@ public: virtual int getResourceCount(Random* random); virtual void playerDestroy(Level* level, std::shared_ptr player, int x, int y, int z, int data); -}; \ No newline at end of file +}; diff --git a/Minecraft.World/Blocks/WallTile.cpp b/Minecraft.World/Blocks/WallTile.cpp index 67d3c0bae..a072b82c8 100644 --- a/Minecraft.World/Blocks/WallTile.cpp +++ b/Minecraft.World/Blocks/WallTile.cpp @@ -80,7 +80,7 @@ void WallTile::updateShape(LevelSource* level, int x, int y, int z, setShape(west, 0, north, east, up, south); } -AABB* WallTile::getAABB(Level* level, int x, int y, int z) { +std::optional WallTile::getAABB(Level* level, int x, int y, int z) { // 4J-JEV: Changed to avoid race conditions associated with calling update // shape. @@ -125,7 +125,7 @@ AABB* WallTile::getAABB(Level* level, int x, int y, int z) { // south = .5f + WALL_WIDTH; } - return AABB::newTemp(x + west, y, z + north, x + east, y + 1.5f, z + south); + return AABB(x + west, y, z + north, x + east, y + 1.5f, z + south); } bool WallTile::connectsTo(LevelSource* level, int x, int y, int z) { diff --git a/Minecraft.World/Blocks/WallTile.h b/Minecraft.World/Blocks/WallTile.h index 634253966..7f5a963c6 100644 --- a/Minecraft.World/Blocks/WallTile.h +++ b/Minecraft.World/Blocks/WallTile.h @@ -25,9 +25,9 @@ public: int forceData = -1, std::shared_ptr forceEntity = std::shared_ptr()); - AABB* getAABB(Level* level, int x, int y, int z); + std::optional getAABB(Level* level, int x, int y, int z); bool connectsTo(LevelSource* level, int x, int y, int z); int getSpawnResourcesAuxValue(int data); bool shouldRenderFace(LevelSource* level, int x, int y, int z, int face); void registerIcons(IconRegister* iconRegister); -}; \ No newline at end of file +}; diff --git a/Minecraft.World/Blocks/WaterLilyTile.cpp b/Minecraft.World/Blocks/WaterLilyTile.cpp index 3ea6660a4..ce0a7d2be 100644 --- a/Minecraft.World/Blocks/WaterLilyTile.cpp +++ b/Minecraft.World/Blocks/WaterLilyTile.cpp @@ -23,11 +23,11 @@ void WaterlilyTile::addAABBs(Level* level, int x, int y, int z, AABB* box, } } -AABB* WaterlilyTile::getAABB(Level* level, int x, int y, int z) { +std::optional WaterlilyTile::getAABB(Level* level, int x, int y, int z) { ThreadStorage* tls = m_tlsShape; // 4J Stu - Added this so that the TLS shape is correct for this tile if (tls->tileId != this->id) updateDefaultShape(); - return AABB::newTemp(x + tls->xx0, y + tls->yy0, z + tls->zz0, x + tls->xx1, + return AABB(x + tls->xx0, y + tls->yy0, z + tls->zz0, x + tls->xx1, y + tls->yy1, z + tls->zz1); } diff --git a/Minecraft.World/Blocks/WaterLilyTile.h b/Minecraft.World/Blocks/WaterLilyTile.h index 81143ddfd..23b39fdc0 100644 --- a/Minecraft.World/Blocks/WaterLilyTile.h +++ b/Minecraft.World/Blocks/WaterLilyTile.h @@ -12,7 +12,7 @@ public: virtual int getRenderShape(); virtual void addAABBs(Level* level, int x, int y, int z, AABB* box, AABBList* boxes, std::shared_ptr source); - virtual AABB* getAABB(Level* level, int x, int y, int z); + virtual std::optional getAABB(Level* level, int x, int y, int z); virtual int getColor() const; virtual int getColor(int auxData); virtual int getColor(LevelSource* level, int x, int y, int z); diff --git a/Minecraft.World/Blocks/WebTile.cpp b/Minecraft.World/Blocks/WebTile.cpp index ffc4137d5..26e8e909a 100644 --- a/Minecraft.World/Blocks/WebTile.cpp +++ b/Minecraft.World/Blocks/WebTile.cpp @@ -2,6 +2,7 @@ #include "../Headers/net.minecraft.world.entity.h" #include "../Headers/net.minecraft.world.item.h" #include "WebTile.h" +#include "Util/AABB.h" WebTile::WebTile(int id) : Tile(id, Material::web) {} @@ -12,7 +13,7 @@ void WebTile::entityInside(Level* level, int x, int y, int z, bool WebTile::isSolidRender(bool isServerLevel) { return false; } -AABB* WebTile::getAABB(Level* level, int x, int y, int z) { return NULL; } +std::optional WebTile::getAABB(Level* level, int x, int y, int z) { return std::nullopt; } int WebTile::getRenderShape() { return Tile::SHAPE_CROSS_TEXTURE; } @@ -25,4 +26,4 @@ int WebTile::getResource(int data, Random* random, int playerBonusLevel) { return Item::string->id; } -bool WebTile::isSilkTouchable() { return true; } \ No newline at end of file +bool WebTile::isSilkTouchable() { return true; } diff --git a/Minecraft.World/Blocks/WebTile.h b/Minecraft.World/Blocks/WebTile.h index 1512cd92d..5b8049d6b 100644 --- a/Minecraft.World/Blocks/WebTile.h +++ b/Minecraft.World/Blocks/WebTile.h @@ -14,7 +14,7 @@ public: bool isSolidRender(bool isServerLevel = false); public: - AABB* getAABB(Level* level, int x, int y, int z); + std::optional getAABB(Level* level, int x, int y, int z); public: int getRenderShape(); @@ -25,4 +25,4 @@ public: protected: bool isSilkTouchable(); -}; \ No newline at end of file +}; diff --git a/Minecraft.World/Blocks/WoolCarpetTile.cpp b/Minecraft.World/Blocks/WoolCarpetTile.cpp index 2800a94c0..030285d7f 100644 --- a/Minecraft.World/Blocks/WoolCarpetTile.cpp +++ b/Minecraft.World/Blocks/WoolCarpetTile.cpp @@ -15,13 +15,13 @@ Icon* WoolCarpetTile::getTexture(int face, int data) { return Tile::wool->getTexture(face, data); } -AABB* WoolCarpetTile::getAABB(Level* level, int x, int y, int z) { +std::optional WoolCarpetTile::getAABB(Level* level, int x, int y, int z) { int height = 0; float offset = 1.0f / SharedConstants::WORLD_RESOLUTION; ThreadStorage* tls = m_tlsShape; // 4J Stu - Added this so that the TLS shape is correct for this tile if (tls->tileId != this->id) updateDefaultShape(); - return AABB::newTemp(x + tls->xx0, y + tls->yy0, z + tls->zz0, x + tls->xx1, + return AABB(x + tls->xx0, y + tls->yy0, z + tls->zz0, x + tls->xx1, y + (height * offset), z + tls->zz1); } diff --git a/Minecraft.World/Blocks/WoolCarpetTile.h b/Minecraft.World/Blocks/WoolCarpetTile.h index 7ad28797c..cb473c2f1 100644 --- a/Minecraft.World/Blocks/WoolCarpetTile.h +++ b/Minecraft.World/Blocks/WoolCarpetTile.h @@ -1,5 +1,6 @@ #pragma once +#include #include "Tile.h" class WoolCarpetTile : public Tile { @@ -10,7 +11,7 @@ protected: public: Icon* getTexture(int face, int data); - AABB* getAABB(Level* level, int x, int y, int z); + std::optional getAABB(Level* level, int x, int y, int z); bool blocksLight(); bool isSolidRender(bool isServerLevel = false); bool isCubeShaped(); @@ -37,4 +38,4 @@ public: static int getTileDataForItemAuxValue(int auxValue); static int getItemAuxValueForTileData(int data); void registerIcons(IconRegister* iconRegister); -}; \ No newline at end of file +}; diff --git a/Minecraft.World/Entities/Mobs/Arrow.cpp b/Minecraft.World/Entities/Mobs/Arrow.cpp index 6c02a0eea..471ee3a2e 100644 --- a/Minecraft.World/Entities/Mobs/Arrow.cpp +++ b/Minecraft.World/Entities/Mobs/Arrow.cpp @@ -183,9 +183,9 @@ void Arrow::tick() { int t = level->getTile(xTile, yTile, zTile); if (t > 0) { Tile::tiles[t]->updateShape(level, xTile, yTile, zTile); - AABB* aabb = Tile::tiles[t]->getAABB(level, xTile, yTile, zTile); + auto aabb = Tile::tiles[t]->getAABB(level, xTile, yTile, zTile); Vec3 pos{x, y, z}; - if (aabb != NULL && aabb->contains(pos)) { + if (aabb.has_value() && aabb->contains(pos)) { inGround = true; } } diff --git a/Minecraft.World/Items/SnowItem.cpp b/Minecraft.World/Items/SnowItem.cpp index b6196253e..66524f9b4 100644 --- a/Minecraft.World/Items/SnowItem.cpp +++ b/Minecraft.World/Items/SnowItem.cpp @@ -3,6 +3,7 @@ #include "../Headers/net.minecraft.world.level.tile.h" #include "../Headers/net.minecraft.world.level.h" #include "SnowItem.h" +#include "Util/AABB.h" SnowItem::SnowItem(int id, Tile* parentTile) : AuxDataTileItem(id, parentTile) {} @@ -22,8 +23,9 @@ bool SnowItem::useOn(std::shared_ptr instance, int currentData = level->getData(x, y, z); int currentHeight = currentData & TopSnowTile::HEIGHT_MASK; + auto snow_bb = snowTile->getAABB(level, x, y, z); if (currentHeight <= TopSnowTile::MAX_HEIGHT && - level->isUnobstructed(snowTile->getAABB(level, x, y, z))) { + level->isUnobstructed(snow_bb.has_value() ? &*snow_bb : nullptr)) { if (!bTestUseOnOnly) { // Increase snow tile height if (level->setData( @@ -46,4 +48,4 @@ bool SnowItem::useOn(std::shared_ptr instance, return AuxDataTileItem::useOn(instance, player, level, x, y, z, face, clickX, clickY, clickZ, bTestUseOnOnly); -} \ No newline at end of file +} diff --git a/Minecraft.World/Items/TileItems/StoneSlabTileItem.cpp b/Minecraft.World/Items/TileItems/StoneSlabTileItem.cpp index 86940cbff..e7e83fa93 100644 --- a/Minecraft.World/Items/TileItems/StoneSlabTileItem.cpp +++ b/Minecraft.World/Items/TileItems/StoneSlabTileItem.cpp @@ -6,6 +6,7 @@ #include "../../Headers/net.minecraft.world.level.tile.h" #include "../../Headers/net.minecraft.h" #include "StoneSlabTileItem.h" +#include "../../Util/AABB.h" StoneSlabTileItem::StoneSlabTileItem(int id, HalfSlabTile* halfTile, HalfSlabTile* fullTile, bool full) @@ -55,7 +56,8 @@ bool StoneSlabTileItem::useOn(std::shared_ptr instance, return true; } - if (level->isUnobstructed(fullTile->getAABB(level, x, y, z)) && + auto tile_bb = fullTile->getAABB(level, x, y, z); + if (level->isUnobstructed(tile_bb.has_value() ? &*tile_bb : nullptr) && level->setTileAndData(x, y, z, fullTile->id, slabType, Tile::UPDATE_ALL)) { level->playSound(x + 0.5f, y + 0.5f, z + 0.5f, @@ -127,7 +129,8 @@ bool StoneSlabTileItem::tryConvertTargetTile( if (bTestUseOnOnly) { return true; } - if (level->isUnobstructed(fullTile->getAABB(level, x, y, z)) && + auto tile_bb = fullTile->getAABB(level, x, y, z); + if (level->isUnobstructed(tile_bb.has_value() ? &*tile_bb : nullptr) && level->setTileAndData(x, y, z, fullTile->id, slabType, Tile::UPDATE_ALL)) { level->playSound(x + 0.5f, y + 0.5f, z + 0.5f, @@ -140,4 +143,4 @@ bool StoneSlabTileItem::tryConvertTargetTile( } return false; -} \ No newline at end of file +} diff --git a/Minecraft.World/Level/Level.cpp b/Minecraft.World/Level/Level.cpp index bfaab0c3d..ab251a833 100644 --- a/Minecraft.World/Level/Level.cpp +++ b/Minecraft.World/Level/Level.cpp @@ -41,6 +41,7 @@ #include #include #include +#include // 4J : WESTY : Added for time played stats. #include "../Headers/net.minecraft.stats.h" @@ -1391,7 +1392,7 @@ HitResult* Level::clip(Vec3* a, Vec3* b, bool liquid, bool solidOnly) { int data = getData(xTile0, yTile0, zTile0); Tile* tile = Tile::tiles[t]; if (solidOnly && tile != NULL && - tile->getAABB(this, xTile0, yTile0, zTile0) == NULL) { + !tile->getAABB(this, xTile0, yTile0, zTile0).has_value()) { // No collision } else if (t > 0 && tile->mayPick(data, liquid)) { @@ -1499,7 +1500,7 @@ HitResult* Level::clip(Vec3* a, Vec3* b, bool liquid, bool solidOnly) { int data = getData(xTile0, yTile0, zTile0); Tile* tile = Tile::tiles[t]; if (solidOnly && tile != NULL && - tile->getAABB(this, xTile0, yTile0, zTile0) == NULL) { + !tile->getAABB(this, xTile0, yTile0, zTile0).has_value()) { // No collision } else if (t > 0 && tile->mayPick(data, liquid)) { @@ -2796,8 +2797,8 @@ bool Level::isFullAABBTile(int x, int y, int z) { if (tile == 0 || Tile::tiles[tile] == NULL) { return false; } - AABB* aabb = Tile::tiles[tile]->getAABB(this, x, y, z); - return aabb != NULL && aabb->getSize() >= 1; + auto aabb = Tile::tiles[tile]->getAABB(this, x, y, z); + return aabb.has_value() && aabb->getSize() >= 1; } bool Level::isTopSolidBlocking(int x, int y, int z) { @@ -3664,9 +3665,9 @@ bool Level::mayPlace(int tileId, int x, int y, int z, bool ignoreEntities, Tile* tile = Tile::tiles[tileId]; - AABB* aabb = tile->getAABB(this, x, y, z); - if (ignoreEntities) aabb = NULL; - if (aabb != NULL && !isUnobstructed(aabb, ignoreEntity)) return false; + auto aabb = tile->getAABB(this, x, y, z); + if (ignoreEntities) aabb = std::nullopt; + if (aabb.has_value() && !isUnobstructed(&*aabb, ignoreEntity)) return false; if (targetTile != NULL && (targetTile == Tile::water || targetTile == Tile::calmWater || targetTile == Tile::lava || targetTile == Tile::calmLava || From ddfe9b3d48486155dfe94eafa4480e3291aa7c16 Mon Sep 17 00:00:00 2001 From: orng Date: Sat, 28 Mar 2026 00:30:07 -0500 Subject: [PATCH 032/170] refactor: make `Tile::getTileAABB` return `AABB` --- Minecraft.Client/Rendering/LevelRenderer.cpp | 2 +- Minecraft.World/Blocks/CactusTile.cpp | 4 ++-- Minecraft.World/Blocks/CactusTile.h | 2 +- Minecraft.World/Blocks/CakeTile.cpp | 4 ++-- Minecraft.World/Blocks/CakeTile.h | 2 +- Minecraft.World/Blocks/CocoaTile.cpp | 2 +- Minecraft.World/Blocks/CocoaTile.h | 2 +- Minecraft.World/Blocks/DoorTile.cpp | 5 ++--- Minecraft.World/Blocks/DoorTile.h | 2 +- Minecraft.World/Blocks/LadderTile.cpp | 2 +- Minecraft.World/Blocks/LadderTile.h | 2 +- Minecraft.World/Blocks/SignTile.cpp | 2 +- Minecraft.World/Blocks/SignTile.h | 2 +- Minecraft.World/Blocks/StairTile.cpp | 2 +- Minecraft.World/Blocks/StairTile.h | 2 +- Minecraft.World/Blocks/Tile.cpp | 4 ++-- Minecraft.World/Blocks/Tile.h | 2 +- Minecraft.World/Blocks/TorchTile.cpp | 2 +- Minecraft.World/Blocks/TorchTile.h | 2 +- Minecraft.World/Blocks/TrapDoorTile.cpp | 2 +- Minecraft.World/Blocks/TrapDoorTile.h | 2 +- 21 files changed, 25 insertions(+), 26 deletions(-) diff --git a/Minecraft.Client/Rendering/LevelRenderer.cpp b/Minecraft.Client/Rendering/LevelRenderer.cpp index 927a8b71f..d970c3f3b 100644 --- a/Minecraft.Client/Rendering/LevelRenderer.cpp +++ b/Minecraft.Client/Rendering/LevelRenderer.cpp @@ -2482,7 +2482,7 @@ void LevelRenderer::renderHitOutline(std::shared_ptr player, AABB bb = Tile::tiles[tileId] ->getTileAABB(level[iPad], h->x, h->y, h->z) - ->grow(ss, ss, ss) + .grow(ss, ss, ss) .move(-xo, -yo, -zo); render(&bb); diff --git a/Minecraft.World/Blocks/CactusTile.cpp b/Minecraft.World/Blocks/CactusTile.cpp index 43aaa0062..229c52e6a 100644 --- a/Minecraft.World/Blocks/CactusTile.cpp +++ b/Minecraft.World/Blocks/CactusTile.cpp @@ -38,9 +38,9 @@ std::optional CactusTile::getAABB(Level* level, int x, int y, int z) { return AABB{x + r, static_cast(y), z + r, x + 1 - r, y + 1 - r, z + 1 - r}; } -AABB* CactusTile::getTileAABB(Level* level, int x, int y, int z) { +AABB CactusTile::getTileAABB(Level* level, int x, int y, int z) { float r = 1 / 16.0f; - return AABB::newTemp(x + r, y, z + r, x + 1 - r, y + 1, z + 1 - r); + return AABB(x + r, y, z + r, x + 1 - r, y + 1, z + 1 - r); } Icon* CactusTile::getTexture(int face, int data) { diff --git a/Minecraft.World/Blocks/CactusTile.h b/Minecraft.World/Blocks/CactusTile.h index ef0cf69f9..c35dc18a2 100644 --- a/Minecraft.World/Blocks/CactusTile.h +++ b/Minecraft.World/Blocks/CactusTile.h @@ -21,7 +21,7 @@ protected: public: virtual void tick(Level* level, int x, int y, int z, Random* random); virtual std::optional getAABB(Level* level, int x, int y, int z); - virtual AABB* getTileAABB(Level* level, int x, int y, int z); + virtual AABB getTileAABB(Level* level, int x, int y, int z); virtual Icon* getTexture(int face, int data); virtual bool isCubeShaped(); virtual bool isSolidRender(bool isServerLevel = false); diff --git a/Minecraft.World/Blocks/CakeTile.cpp b/Minecraft.World/Blocks/CakeTile.cpp index f35919594..53e2e41e3 100644 --- a/Minecraft.World/Blocks/CakeTile.cpp +++ b/Minecraft.World/Blocks/CakeTile.cpp @@ -42,12 +42,12 @@ std::optional CakeTile::getAABB(Level* level, int x, int y, int z) { return AABB{x + r2, static_cast(y), z + r, x + 1 - r, y + h - r, z + 1 - r}; } -AABB* CakeTile::getTileAABB(Level* level, int x, int y, int z) { +AABB CakeTile::getTileAABB(Level* level, int x, int y, int z) { int d = level->getData(x, y, z); float r = 1 / 16.0f; float r2 = (1 + d * 2) / 16.0f; float h = 8 / 16.0f; - return AABB::newTemp(x + r2, y, z + r, x + 1 - r, y + h, z + 1 - r); + return AABB(x + r2, y, z + r, x + 1 - r, y + h, z + 1 - r); } Icon* CakeTile::getTexture(int face, int data) { diff --git a/Minecraft.World/Blocks/CakeTile.h b/Minecraft.World/Blocks/CakeTile.h index ebd33baf2..b2f2a3655 100644 --- a/Minecraft.World/Blocks/CakeTile.h +++ b/Minecraft.World/Blocks/CakeTile.h @@ -25,7 +25,7 @@ protected: TileEntity>()); // 4J added forceData, forceEntity param virtual void updateDefaultShape(); virtual std::optional getAABB(Level* level, int x, int y, int z); - virtual AABB* getTileAABB(Level* level, int x, int y, int z); + virtual AABB getTileAABB(Level* level, int x, int y, int z); virtual Icon* getTexture(int face, int data); //@Override void registerIcons(IconRegister* iconRegister); diff --git a/Minecraft.World/Blocks/CocoaTile.cpp b/Minecraft.World/Blocks/CocoaTile.cpp index 6250508a8..73449170d 100644 --- a/Minecraft.World/Blocks/CocoaTile.cpp +++ b/Minecraft.World/Blocks/CocoaTile.cpp @@ -62,7 +62,7 @@ std::optional CocoaTile::getAABB(Level* level, int x, int y, int z) { return DirectionalTile::getAABB(level, x, y, z); } -AABB* CocoaTile::getTileAABB(Level* level, int x, int y, int z) { +AABB CocoaTile::getTileAABB(Level* level, int x, int y, int z) { updateShape(level, x, y, z); return DirectionalTile::getTileAABB(level, x, y, z); } diff --git a/Minecraft.World/Blocks/CocoaTile.h b/Minecraft.World/Blocks/CocoaTile.h index 7ff5c81ee..ff8c02c6f 100644 --- a/Minecraft.World/Blocks/CocoaTile.h +++ b/Minecraft.World/Blocks/CocoaTile.h @@ -23,7 +23,7 @@ public: virtual bool isCubeShaped(); virtual bool isSolidRender(bool isServerLevel = false); virtual std::optional getAABB(Level* level, int x, int y, int z); - virtual AABB* getTileAABB(Level* level, int x, int y, int z); + virtual AABB getTileAABB(Level* level, int x, int y, int z); virtual void updateShape(LevelSource* level, int x, int y, int z, int forceData = -1, std::shared_ptr forceEntity = diff --git a/Minecraft.World/Blocks/DoorTile.cpp b/Minecraft.World/Blocks/DoorTile.cpp index df461bb6b..1c2692370 100644 --- a/Minecraft.World/Blocks/DoorTile.cpp +++ b/Minecraft.World/Blocks/DoorTile.cpp @@ -85,10 +85,9 @@ bool DoorTile::isCubeShaped() { return false; } int DoorTile::getRenderShape() { return Tile::SHAPE_DOOR; } -AABB* DoorTile::getTileAABB(Level* level, int x, int y, int z) { +AABB DoorTile::getTileAABB(Level* level, int x, int y, int z) { updateShape(level, x, y, z); - AABB* retval = Tile::getTileAABB(level, x, y, z); - return retval; + return Tile::getTileAABB(level, x, y, z); } std::optional DoorTile::getAABB(Level* level, int x, int y, int z) { diff --git a/Minecraft.World/Blocks/DoorTile.h b/Minecraft.World/Blocks/DoorTile.h index 339775515..3f844a27d 100644 --- a/Minecraft.World/Blocks/DoorTile.h +++ b/Minecraft.World/Blocks/DoorTile.h @@ -40,7 +40,7 @@ public: virtual bool isSolidRender(bool isServerLevel = false); virtual bool isCubeShaped(); virtual int getRenderShape(); - virtual AABB* getTileAABB(Level* level, int x, int y, int z); + virtual AABB getTileAABB(Level* level, int x, int y, int z); virtual std::optional getAABB(Level* level, int x, int y, int z); virtual void updateShape( LevelSource* level, int x, int y, int z, int forceData = -1, diff --git a/Minecraft.World/Blocks/LadderTile.cpp b/Minecraft.World/Blocks/LadderTile.cpp index f95650843..06b016284 100644 --- a/Minecraft.World/Blocks/LadderTile.cpp +++ b/Minecraft.World/Blocks/LadderTile.cpp @@ -11,7 +11,7 @@ std::optional LadderTile::getAABB(Level* level, int x, int y, int z) { return Tile::getAABB(level, x, y, z); } -AABB* LadderTile::getTileAABB(Level* level, int x, int y, int z) { +AABB LadderTile::getTileAABB(Level* level, int x, int y, int z) { updateShape(level, x, y, z); return Tile::getTileAABB(level, x, y, z); } diff --git a/Minecraft.World/Blocks/LadderTile.h b/Minecraft.World/Blocks/LadderTile.h index 133c01230..9bde7712d 100644 --- a/Minecraft.World/Blocks/LadderTile.h +++ b/Minecraft.World/Blocks/LadderTile.h @@ -12,7 +12,7 @@ protected: public: virtual std::optional getAABB(Level* level, int x, int y, int z); - virtual AABB* getTileAABB(Level* level, int x, int y, int z); + virtual AABB getTileAABB(Level* level, int x, int y, int z); virtual void updateShape( LevelSource* level, int x, int y, int z, int forceData = -1, std::shared_ptr forceEntity = std::shared_ptr< diff --git a/Minecraft.World/Blocks/SignTile.cpp b/Minecraft.World/Blocks/SignTile.cpp index 2004f9e4a..7a62f9248 100644 --- a/Minecraft.World/Blocks/SignTile.cpp +++ b/Minecraft.World/Blocks/SignTile.cpp @@ -27,7 +27,7 @@ void SignTile::updateDefaultShape() { std::optional SignTile::getAABB(Level* level, int x, int y, int z) { return std::nullopt; } -AABB* SignTile::getTileAABB(Level* level, int x, int y, int z) { +AABB SignTile::getTileAABB(Level* level, int x, int y, int z) { updateShape(level, x, y, z); return BaseEntityTile::getTileAABB(level, x, y, z); } diff --git a/Minecraft.World/Blocks/SignTile.h b/Minecraft.World/Blocks/SignTile.h index 9e4c009d2..952b5e1cc 100644 --- a/Minecraft.World/Blocks/SignTile.h +++ b/Minecraft.World/Blocks/SignTile.h @@ -21,7 +21,7 @@ public: Icon* getTexture(int face, int data); virtual void updateDefaultShape(); std::optional getAABB(Level* level, int x, int y, int z); - AABB* getTileAABB(Level* level, int x, int y, int z); + AABB getTileAABB(Level* level, int x, int y, int z); void updateShape(LevelSource* level, int x, int y, int z, int forceData = -1, std::shared_ptr forceEntity = diff --git a/Minecraft.World/Blocks/StairTile.cpp b/Minecraft.World/Blocks/StairTile.cpp index 2990ada14..244c58895 100644 --- a/Minecraft.World/Blocks/StairTile.cpp +++ b/Minecraft.World/Blocks/StairTile.cpp @@ -326,7 +326,7 @@ Icon* StairTile::getTexture(int face, int data) { int StairTile::getTickDelay(Level* level) { return base->getTickDelay(level); } -AABB* StairTile::getTileAABB(Level* level, int x, int y, int z) { +AABB StairTile::getTileAABB(Level* level, int x, int y, int z) { return base->getTileAABB(level, x, y, z); } diff --git a/Minecraft.World/Blocks/StairTile.h b/Minecraft.World/Blocks/StairTile.h index 23d906835..690b52bd2 100644 --- a/Minecraft.World/Blocks/StairTile.h +++ b/Minecraft.World/Blocks/StairTile.h @@ -65,7 +65,7 @@ public: virtual int getRenderLayer(); virtual Icon* getTexture(int face, int data); virtual int getTickDelay(Level* level); - virtual AABB* getTileAABB(Level* level, int x, int y, int z); + virtual AABB getTileAABB(Level* level, int x, int y, int z); virtual void handleEntityInside(Level* level, int x, int y, int z, std::shared_ptr e, Vec3* current); virtual bool mayPick(); diff --git a/Minecraft.World/Blocks/Tile.cpp b/Minecraft.World/Blocks/Tile.cpp index 66d58c632..d12283e69 100644 --- a/Minecraft.World/Blocks/Tile.cpp +++ b/Minecraft.World/Blocks/Tile.cpp @@ -2005,11 +2005,11 @@ Icon* Tile::getTexture(int face, int data) { return icon; } Icon* Tile::getTexture(int face) { return getTexture(face, 0); } -AABB* Tile::getTileAABB(Level* level, int x, int y, int z) { +AABB Tile::getTileAABB(Level* level, int x, int y, int z) { ThreadStorage* tls = m_tlsShape; // 4J Stu - Added this so that the TLS shape is correct for this tile if (tls->tileId != this->id) updateDefaultShape(); - return AABB::newTemp(x + tls->xx0, y + tls->yy0, z + tls->zz0, x + tls->xx1, + return AABB(x + tls->xx0, y + tls->yy0, z + tls->zz0, x + tls->xx1, y + tls->yy1, z + tls->zz1); } diff --git a/Minecraft.World/Blocks/Tile.h b/Minecraft.World/Blocks/Tile.h index 4346f6d26..2b94b9ffe 100644 --- a/Minecraft.World/Blocks/Tile.h +++ b/Minecraft.World/Blocks/Tile.h @@ -631,7 +631,7 @@ public: virtual Icon* getTexture(LevelSource* level, int x, int y, int z, int face); virtual Icon* getTexture(int face, int data); virtual Icon* getTexture(int face); - virtual AABB* getTileAABB(Level* level, int x, int y, int z); + virtual AABB getTileAABB(Level* level, int x, int y, int z); virtual void addAABBs(Level* level, int x, int y, int z, AABB* box, AABBList* boxes, std::shared_ptr source); virtual std::optional getAABB(Level* level, int x, int y, int z); diff --git a/Minecraft.World/Blocks/TorchTile.cpp b/Minecraft.World/Blocks/TorchTile.cpp index 556370789..4932ff4fc 100644 --- a/Minecraft.World/Blocks/TorchTile.cpp +++ b/Minecraft.World/Blocks/TorchTile.cpp @@ -12,7 +12,7 @@ TorchTile::TorchTile(int id) : Tile(id, Material::decoration, false) { std::optional TorchTile::getAABB(Level* level, int x, int y, int z) { return std::nullopt; } -AABB* TorchTile::getTileAABB(Level* level, int x, int y, int z) { +AABB TorchTile::getTileAABB(Level* level, int x, int y, int z) { updateShape(level, x, y, z); return Tile::getTileAABB(level, x, y, z); } diff --git a/Minecraft.World/Blocks/TorchTile.h b/Minecraft.World/Blocks/TorchTile.h index 3f7d0a4d1..525f851cc 100644 --- a/Minecraft.World/Blocks/TorchTile.h +++ b/Minecraft.World/Blocks/TorchTile.h @@ -13,7 +13,7 @@ protected: public: virtual std::optional getAABB(Level* level, int x, int y, int z); - virtual AABB* getTileAABB(Level* level, int x, int y, int z); + virtual AABB getTileAABB(Level* level, int x, int y, int z); virtual void updateShape( LevelSource* level, int x, int y, int z, int forceData = -1, std::shared_ptr forceEntity = std::shared_ptr< diff --git a/Minecraft.World/Blocks/TrapDoorTile.cpp b/Minecraft.World/Blocks/TrapDoorTile.cpp index bca1ce813..7a6e46e5a 100644 --- a/Minecraft.World/Blocks/TrapDoorTile.cpp +++ b/Minecraft.World/Blocks/TrapDoorTile.cpp @@ -25,7 +25,7 @@ bool TrapDoorTile::isPathfindable(LevelSource* level, int x, int y, int z) { int TrapDoorTile::getRenderShape() { return Tile::SHAPE_BLOCK; } -AABB* TrapDoorTile::getTileAABB(Level* level, int x, int y, int z) { +AABB TrapDoorTile::getTileAABB(Level* level, int x, int y, int z) { updateShape(level, x, y, z); return Tile::getTileAABB(level, x, y, z); } diff --git a/Minecraft.World/Blocks/TrapDoorTile.h b/Minecraft.World/Blocks/TrapDoorTile.h index 9765b61c6..8ef150568 100644 --- a/Minecraft.World/Blocks/TrapDoorTile.h +++ b/Minecraft.World/Blocks/TrapDoorTile.h @@ -37,7 +37,7 @@ public: int getRenderShape(); public: - AABB* getTileAABB(Level* level, int x, int y, int z); + AABB getTileAABB(Level* level, int x, int y, int z); public: std::optional getAABB(Level* level, int x, int y, int z); From e48a05bb8fa6fb918ef1abe738a3e02dbdbf3ea4 Mon Sep 17 00:00:00 2001 From: orng Date: Sat, 28 Mar 2026 00:50:56 -0500 Subject: [PATCH 033/170] refactor: remove the last `AABB::newTemp` --- Minecraft.World/Blocks/BasePressurePlateTile.cpp | 7 ++++--- Minecraft.World/Blocks/BasePressurePlateTile.h | 2 +- Minecraft.World/Blocks/PressurePlateTile.cpp | 13 ++++++------- .../Blocks/WeightedPressurePlateTile.cpp | 6 ++++-- 4 files changed, 15 insertions(+), 13 deletions(-) diff --git a/Minecraft.World/Blocks/BasePressurePlateTile.cpp b/Minecraft.World/Blocks/BasePressurePlateTile.cpp index 434ce8e56..212fbb914 100644 --- a/Minecraft.World/Blocks/BasePressurePlateTile.cpp +++ b/Minecraft.World/Blocks/BasePressurePlateTile.cpp @@ -40,7 +40,8 @@ int BasePressurePlateTile::getTickDelay(Level* level) { return SharedConstants::TICKS_PER_SECOND; } -std::optional BasePressurePlateTile::getAABB(Level* level, int x, int y, int z) { +std::optional BasePressurePlateTile::getAABB(Level* level, int x, int y, + int z) { return std::nullopt; } @@ -113,9 +114,9 @@ void BasePressurePlateTile::checkPressed(Level* level, int x, int y, int z, } } -AABB* BasePressurePlateTile::getSensitiveAABB(int x, int y, int z) { +AABB BasePressurePlateTile::getSensitiveAABB(int x, int y, int z) { float b = 2 / 16.0f; - return AABB::newTemp(x + b, y, z + b, x + 1 - b, y + 0.25, z + 1 - b); + return AABB(x + b, y, z + b, x + 1 - b, y + 0.25, z + 1 - b); } void BasePressurePlateTile::onRemove(Level* level, int x, int y, int z, int id, diff --git a/Minecraft.World/Blocks/BasePressurePlateTile.h b/Minecraft.World/Blocks/BasePressurePlateTile.h index e42ff69eb..254f72e1d 100644 --- a/Minecraft.World/Blocks/BasePressurePlateTile.h +++ b/Minecraft.World/Blocks/BasePressurePlateTile.h @@ -33,7 +33,7 @@ public: protected: virtual void checkPressed(Level* level, int x, int y, int z, int oldSignal); - virtual AABB* getSensitiveAABB(int x, int y, int z); + virtual AABB getSensitiveAABB(int x, int y, int z); public: virtual void onRemove(Level* level, int x, int y, int z, int id, int data); diff --git a/Minecraft.World/Blocks/PressurePlateTile.cpp b/Minecraft.World/Blocks/PressurePlateTile.cpp index ef1223bb3..48a273f0d 100644 --- a/Minecraft.World/Blocks/PressurePlateTile.cpp +++ b/Minecraft.World/Blocks/PressurePlateTile.cpp @@ -2,6 +2,7 @@ #include "../Headers/net.minecraft.world.level.h" #include "../Headers/net.minecraft.world.level.redstone.h" #include "PressurePlateTile.h" +#include "Util/AABB.h" PressurePlateTile::PressurePlateTile(int id, const std::wstring& tex, Material* material, @@ -23,15 +24,13 @@ int PressurePlateTile::getSignalForData(int data) { int PressurePlateTile::getSignalStrength(Level* level, int x, int y, int z) { std::vector >* entities = NULL; - + AABB at_bb = getSensitiveAABB(x, y, z); if (sensitivity == everything) - entities = level->getEntities(nullptr, getSensitiveAABB(x, y, z)); + entities = level->getEntities(nullptr, &at_bb); else if (sensitivity == mobs) - entities = level->getEntitiesOfClass(typeid(LivingEntity), - getSensitiveAABB(x, y, z)); + entities = level->getEntitiesOfClass(typeid(LivingEntity), &at_bb); else if (sensitivity == players) - entities = level->getEntitiesOfClass(typeid(Player), - getSensitiveAABB(x, y, z)); + entities = level->getEntitiesOfClass(typeid(Player), &at_bb); else __debugbreak(); // 4J-JEV: We're going to delete something at a random // location. @@ -48,4 +47,4 @@ int PressurePlateTile::getSignalStrength(Level* level, int x, int y, int z) { if (sensitivity != everything) delete entities; return Redstone::SIGNAL_NONE; -} \ No newline at end of file +} diff --git a/Minecraft.World/Blocks/WeightedPressurePlateTile.cpp b/Minecraft.World/Blocks/WeightedPressurePlateTile.cpp index 55e1b5a15..e31a7c451 100644 --- a/Minecraft.World/Blocks/WeightedPressurePlateTile.cpp +++ b/Minecraft.World/Blocks/WeightedPressurePlateTile.cpp @@ -5,6 +5,7 @@ #include "../Headers/net.minecraft.world.item.h" #include "../Entities/Entity.h" #include "WeightedPressurePlateTile.h" +#include "Util/AABB.h" WeightedPressurePlateTile::WeightedPressurePlateTile(int id, const std::wstring& tex, @@ -19,8 +20,9 @@ WeightedPressurePlateTile::WeightedPressurePlateTile(int id, int WeightedPressurePlateTile::getSignalStrength(Level* level, int x, int y, int z) { + AABB at_bb = getSensitiveAABB(x, y, z); int weightOfEntities = - level->getEntitiesOfClass(typeid(Entity), getSensitiveAABB(x, y, z)) + level->getEntitiesOfClass(typeid(Entity), &at_bb) ->size(); int count = std::min(weightOfEntities, maxWeight); @@ -38,4 +40,4 @@ int WeightedPressurePlateTile::getDataForSignal(int signal) { return signal; } int WeightedPressurePlateTile::getTickDelay(Level* level) { return SharedConstants::TICKS_PER_SECOND / 2; -} \ No newline at end of file +} From 939310be641fbf506eb34924f21c66e9c5be2c0f Mon Sep 17 00:00:00 2001 From: Tropical <42101043+tropicaaal@users.noreply.github.com> Date: Sat, 28 Mar 2026 02:13:27 -0500 Subject: [PATCH 034/170] refactor: rework meson options, fix ENABLE_VSYNC --- Minecraft.Client/GameState/Options.cpp | 23 +++++++++++++++------ Minecraft.Client/Rendering/GameRenderer.cpp | 9 +++++++- Minecraft.Client/meson.build | 8 ++----- meson.options | 14 +++++-------- 4 files changed, 32 insertions(+), 22 deletions(-) diff --git a/Minecraft.Client/GameState/Options.cpp b/Minecraft.Client/GameState/Options.cpp index e8e24827d..289fdecb0 100644 --- a/Minecraft.Client/GameState/Options.cpp +++ b/Minecraft.Client/GameState/Options.cpp @@ -89,8 +89,15 @@ const std::wstring Options::DIFFICULTY_NAMES[] = { const std::wstring Options::GUI_SCALE[] = { L"options.guiScale.auto", L"options.guiScale.small", L"options.guiScale.normal", L"options.guiScale.large"}; + +#ifdef ENABLE_VSYNC const std::wstring Options::FRAMERATE_LIMITS[] = { L"performance.max", L"performance.balanced", L"performance.powersaver"}; +#else +const std::wstring Options::FRAMERATE_LIMITS[] = { + L"performance.max", L"performance.balanced", L"performance.powersaver", + L"performance.unlimited"}; +#endif const std::wstring Options::PARTICLES[] = {L"options.particles.all", L"options.particles.decreased", @@ -237,15 +244,19 @@ void Options::toggle(const Options::Option* option, int dir) { if (option == Option::RENDER_CLOUDS) renderClouds = !renderClouds; if (option == Option::ADVANCED_OPENGL) { advancedOpengl = !advancedOpengl; - // 4jcraft: ensure level exists before applying - if(minecraft->level) minecraft->levelRenderer->allChanged(); + // 4jcraft: ensure level exists before applying + if (minecraft->level) minecraft->levelRenderer->allChanged(); } if (option == Option::ANAGLYPH) { anaglyph3d = !anaglyph3d; minecraft->textures->reloadAll(); } if (option == Option::FRAMERATE_LIMIT) +#ifdef ENABLE_VSYNC framerateLimit = (framerateLimit + dir + 3) % 3; +#else + framerateLimit = (framerateLimit + dir + 4) % 4; +#endif // 4J-PB - Change for Xbox // if (option == Option::DIFFICULTY) difficulty = (difficulty + dir) & 3; @@ -255,13 +266,13 @@ void Options::toggle(const Options::Option* option, int dir) { if (option == Option::GRAPHICS) { fancyGraphics = !fancyGraphics; - // 4jcraft: ensure level exists before applying - if(minecraft->level) minecraft->levelRenderer->allChanged(); + // 4jcraft: ensure level exists before applying + if (minecraft->level) minecraft->levelRenderer->allChanged(); } if (option == Option::AMBIENT_OCCLUSION) { ambientOcclusion = !ambientOcclusion; - // 4jcraft: ensure level exists before applying - if(minecraft->level) minecraft->levelRenderer->allChanged(); + // 4jcraft: ensure level exists before applying + if (minecraft->level) minecraft->levelRenderer->allChanged(); } // 4J-PB - don't do the file save on the xbox diff --git a/Minecraft.Client/Rendering/GameRenderer.cpp b/Minecraft.Client/Rendering/GameRenderer.cpp index d228b1030..a9f91daf6 100644 --- a/Minecraft.Client/Rendering/GameRenderer.cpp +++ b/Minecraft.Client/Rendering/GameRenderer.cpp @@ -1060,7 +1060,11 @@ void GameRenderer::render(float a, bool bFirst) { int maxFps = getFpsCap(mc->options->framerateLimit); if (mc->level != NULL) { - if (mc->options->framerateLimit == 0) { + if (mc->options->framerateLimit == 0 +#ifndef ENABLE_VSYNC + || mc->options->framerateLimit == 3 +#endif + ) { renderLevel(a, 0); } else { renderLevel(a, lastNsTime + 1000000000 / maxFps); @@ -2134,6 +2138,9 @@ int GameRenderer::getFpsCap(int option) { int maxFps = 200; if (option == 1) maxFps = 120; if (option == 2) maxFps = 35; +#ifndef ENABLE_VSYNC + if (option == 3) maxFps = std::numeric_limits::max(); +#endif return maxFps; } diff --git a/Minecraft.Client/meson.build b/Minecraft.Client/meson.build index f81dddddd..8bcc874b1 100644 --- a/Minecraft.Client/meson.build +++ b/Minecraft.Client/meson.build @@ -75,7 +75,7 @@ if get_option('enable_vsync') global_cpp_defs += '-DENABLE_VSYNC' endif -if get_option('enable_shiggy') +if get_option('ui_backend') == 'shiggy' shiggy_dep = dependency( 'shiggy', fallback : ['shiggy', 'shiggy_dep'], @@ -85,14 +85,10 @@ if get_option('enable_shiggy') client_dependencies += shiggy_dep endif -if get_option('enable_java_guis') +if get_option('ui_backend') == 'java' global_cpp_defs += '-DENABLE_JAVA_GUIS' endif -if get_option('enable_shiggy') and get_option('enable_java_guis') - error('You cannot use the Iggy and Java UI at the same time, please choose one.') -endif - client = executable('Minecraft.Client', client_sources + platform_sources + localisation[1], include_directories : [include_directories('Platform', 'Platform/Linux/Iggy/include'),stb], diff --git a/meson.options b/meson.options index 74de97f98..545d2a159 100644 --- a/meson.options +++ b/meson.options @@ -1,14 +1,10 @@ -option('enable_java_guis', - type : 'boolean', - value : false, - description : 'Re-enable the Java UI remnants in the code (for testing only)') +option('ui_backend', + type : 'combo', + choices: ['shiggy', 'java'], + value : 'shiggy', + description : 'Specifies a backend implementation for the game UI.') option('enable_vsync', type : 'boolean', value : true, description : 'Toggles V-Sync and adds options to unlock maximum in-game framerate.') - -option('enable_shiggy', - type : 'boolean', - value : true, - description : 'Toggles shimmed PS4 Iggy binaries and UI for x86_64 Linux.') From 7101d03c6ab11fa91cc5d84b2f350ee4ce6d1850 Mon Sep 17 00:00:00 2001 From: orng Date: Sat, 28 Mar 2026 02:58:56 -0500 Subject: [PATCH 035/170] refactor: remove heap-allocated `AABB`s --- Minecraft.Client/Network/ClientConnection.cpp | 2 +- Minecraft.Client/Network/PlayerConnection.cpp | 6 +- Minecraft.Client/Network/PlayerList.cpp | 6 +- .../ApplySchematicRuleDefinition.cpp | 19 +-- .../GameRules/ApplySchematicRuleDefinition.h | 4 +- .../GameRules/NamedAreaRuleDefinition.cpp | 44 ++++--- .../GameRules/NamedAreaRuleDefinition.h | 6 +- .../Common/Tutorial/AreaConstraint.cpp | 18 +-- .../Platform/Common/Tutorial/AreaConstraint.h | 7 +- .../Platform/Common/Tutorial/AreaHint.cpp | 6 +- .../Platform/Common/Tutorial/AreaHint.h | 5 +- .../Common/Tutorial/ChangeStateConstraint.cpp | 7 +- .../Common/Tutorial/ChangeStateConstraint.h | 2 +- Minecraft.Client/Player/LocalPlayer.cpp | 8 +- .../Player/MultiPlayerLocalPlayer.cpp | 8 +- Minecraft.Client/Rendering/Chunk.cpp | 36 ++---- Minecraft.Client/Rendering/Chunk.h | 3 +- .../EntityRenderers/EntityRenderer.cpp | 4 +- .../EntityRenderers/FireballRenderer.cpp | 4 +- Minecraft.Client/Rendering/GameRenderer.cpp | 4 +- Minecraft.Client/Rendering/LevelRenderer.cpp | 4 +- .../Rendering/Particles/CritParticle.cpp | 8 +- .../Particles/PlayerCloudParticle.cpp | 6 +- Minecraft.World/AI/Control/LookControl.cpp | 4 +- Minecraft.World/AI/Control/MoveControl.cpp | 4 +- Minecraft.World/AI/Goals/AvoidPlayerGoal.cpp | 2 +- Minecraft.World/AI/Goals/BreedGoal.cpp | 2 +- Minecraft.World/AI/Goals/FleeSunGoal.cpp | 4 +- Minecraft.World/AI/Goals/FollowOwnerGoal.cpp | 2 +- Minecraft.World/AI/Goals/FollowParentGoal.cpp | 2 +- Minecraft.World/AI/Goals/LookAtPlayerGoal.cpp | 5 +- Minecraft.World/AI/Goals/MakeLoveGoal.cpp | 5 +- Minecraft.World/AI/Goals/MeleeAttackGoal.cpp | 4 +- .../AI/Goals/NearestAttackableTargetGoal.cpp | 5 +- Minecraft.World/AI/Goals/OcelotAttackGoal.cpp | 2 +- Minecraft.World/AI/Goals/OfferFlowerGoal.cpp | 5 +- Minecraft.World/AI/Goals/PlayGoal.cpp | 5 +- Minecraft.World/AI/Goals/RangedAttackGoal.cpp | 4 +- Minecraft.World/AI/Goals/TakeFlowerGoal.cpp | 4 +- Minecraft.World/AI/Navigation/PathFinder.cpp | 10 +- .../AI/Navigation/PathNavigation.cpp | 8 +- Minecraft.World/Blocks/FallingTile.cpp | 4 +- Minecraft.World/Entities/Entity.cpp | 114 +++++++++--------- Minecraft.World/Entities/Entity.h | 3 +- Minecraft.World/Entities/FlyingMob.cpp | 6 +- Minecraft.World/Entities/HangingEntity.cpp | 8 +- Minecraft.World/Entities/ItemEntity.cpp | 8 +- Minecraft.World/Entities/LivingEntity.cpp | 44 +++---- Minecraft.World/Entities/MinecartHopper.cpp | 2 +- Minecraft.World/Entities/Mob.cpp | 18 +-- Minecraft.World/Entities/Mobs/Animal.cpp | 8 +- Minecraft.World/Entities/Mobs/Arrow.cpp | 4 +- Minecraft.World/Entities/Mobs/Bat.cpp | 4 +- Minecraft.World/Entities/Mobs/Blaze.cpp | 8 +- Minecraft.World/Entities/Mobs/Boat.cpp | 12 +- .../Entities/Mobs/DragonFireball.cpp | 2 +- Minecraft.World/Entities/Mobs/EnderDragon.cpp | 48 ++++---- Minecraft.World/Entities/Mobs/EnderDragon.h | 2 +- Minecraft.World/Entities/Mobs/EnderMan.cpp | 8 +- Minecraft.World/Entities/Mobs/EntityHorse.cpp | 2 +- .../Entities/Mobs/ExperienceOrb.cpp | 6 +- .../Entities/Mobs/EyeOfEnderSignal.cpp | 4 +- Minecraft.World/Entities/Mobs/Fireball.cpp | 6 +- Minecraft.World/Entities/Mobs/FishingHook.cpp | 16 +-- Minecraft.World/Entities/Mobs/Ghast.cpp | 3 +- Minecraft.World/Entities/Mobs/LavaSlime.cpp | 8 +- Minecraft.World/Entities/Mobs/Minecart.cpp | 4 +- Minecraft.World/Entities/Mobs/MushroomCow.cpp | 2 +- Minecraft.World/Entities/Mobs/Ocelot.cpp | 8 +- Minecraft.World/Entities/Mobs/PigZombie.cpp | 8 +- Minecraft.World/Entities/Mobs/Silverfish.cpp | 6 +- Minecraft.World/Entities/Mobs/Slime.cpp | 2 +- Minecraft.World/Entities/Mobs/Squid.cpp | 2 +- .../Entities/Mobs/ThrownPotion.cpp | 2 +- .../Entities/Mobs/VillagerGolem.cpp | 4 +- Minecraft.World/Entities/Mobs/Witch.cpp | 2 +- Minecraft.World/Entities/Mobs/WitherBoss.cpp | 2 +- Minecraft.World/Entities/Mobs/Wolf.cpp | 4 +- Minecraft.World/Entities/Mobs/Zombie.cpp | 8 +- Minecraft.World/Entities/Monster.cpp | 8 +- Minecraft.World/Entities/PathfinderMob.cpp | 4 +- Minecraft.World/Entities/Throwable.cpp | 6 +- Minecraft.World/Entities/WaterAnimal.cpp | 4 +- Minecraft.World/Items/BoatItem.cpp | 6 +- Minecraft.World/Level/Explosion.cpp | 4 +- Minecraft.World/Level/LevelChunk.cpp | 6 +- Minecraft.World/Player/Player.cpp | 4 +- Minecraft.World/Util/CombatTracker.cpp | 2 +- 88 files changed, 353 insertions(+), 387 deletions(-) diff --git a/Minecraft.Client/Network/ClientConnection.cpp b/Minecraft.Client/Network/ClientConnection.cpp index 8494759de..e41f43d77 100644 --- a/Minecraft.Client/Network/ClientConnection.cpp +++ b/Minecraft.Client/Network/ClientConnection.cpp @@ -1010,7 +1010,7 @@ void ClientConnection::handleMovePlayer( player->xd = player->yd = player->zd = 0; player->absMoveTo(x, y, z, yRot, xRot); packet->x = player->x; - packet->y = player->bb->y0; + packet->y = player->bb.y0; packet->z = player->z; packet->yView = player->y; connection->send(packet); diff --git a/Minecraft.Client/Network/PlayerConnection.cpp b/Minecraft.Client/Network/PlayerConnection.cpp index 5a4d5d3d7..cb70ca016 100644 --- a/Minecraft.Client/Network/PlayerConnection.cpp +++ b/Minecraft.Client/Network/PlayerConnection.cpp @@ -272,7 +272,7 @@ void PlayerConnection::handleMovePlayer( */ float r = 1 / 16.0f; - AABB shrunk = player->bb->shrink(r, r, r); + AABB shrunk = player->bb.shrink(r, r, r); bool oldOk = level->getCubes(player, &shrunk) ->empty(); @@ -326,7 +326,7 @@ void PlayerConnection::handleMovePlayer( player->absMoveTo(xt, yt, zt, yRotT, xRotT); // TODO: check if this can be elided - shrunk = player->bb->shrink(r, r, r); + shrunk = player->bb.shrink(r, r, r); bool newOk = level->getCubes(player, &shrunk) ->empty(); @@ -334,7 +334,7 @@ void PlayerConnection::handleMovePlayer( teleport(xLastOk, yLastOk, zLastOk, yRotT, xRotT); return; } - AABB testBox = (*player->bb).grow(r, r, r).expand(0, -0.55, 0); + AABB testBox = player->bb.grow(r, r, r).expand(0, -0.55, 0); // && server.level.getCubes(player, testBox).size() == 0 if (!server->isFlightAllowed() && !player->gameMode->isCreative() && !level->containsAnyBlocks(&testBox) && !player->isAllowedToFly()) { diff --git a/Minecraft.Client/Network/PlayerList.cpp b/Minecraft.Client/Network/PlayerList.cpp index c3286234c..2eadfa824 100644 --- a/Minecraft.Client/Network/PlayerList.cpp +++ b/Minecraft.Client/Network/PlayerList.cpp @@ -416,7 +416,7 @@ void PlayerList::validatePlayerSpawnPosition( player->y, player->z, player->dimension); ServerLevel* level = server->getLevel(player->dimension); - while (level->getCubes(player, player->bb)->size() != 0) { + while (level->getCubes(player, &player->bb)->size() != 0) { player->setPos(player->x, player->y + 1, player->z); } app.DebugPrintf("Final pos is %f, %f, %f in dimension %d\n", player->x, @@ -456,7 +456,7 @@ void PlayerList::validatePlayerSpawnPosition( } delete bedPosition; } - while (level->getCubes(player, player->bb)->size() != 0) { + while (level->getCubes(player, &player->bb)->size() != 0) { player->setPos(player->x, player->y + 1, player->z); } @@ -749,7 +749,7 @@ std::shared_ptr PlayerList::respawn( // Ensure the area the player is spawning in is loaded! level->cache->create(((int)player->x) >> 4, ((int)player->z) >> 4); - while (!level->getCubes(player, player->bb)->empty()) { + while (!level->getCubes(player, &player->bb)->empty()) { player->setPos(player->x, player->y + 1, player->z); } diff --git a/Minecraft.Client/Platform/Common/GameRules/ApplySchematicRuleDefinition.cpp b/Minecraft.Client/Platform/Common/GameRules/ApplySchematicRuleDefinition.cpp index f2c5b4360..2101756d7 100644 --- a/Minecraft.Client/Platform/Common/GameRules/ApplySchematicRuleDefinition.cpp +++ b/Minecraft.Client/Platform/Common/GameRules/ApplySchematicRuleDefinition.cpp @@ -8,12 +8,13 @@ #include "ApplySchematicRuleDefinition.h" #include "LevelGenerationOptions.h" #include "ConsoleSchematicFile.h" +#include "../../Minecraft.World/Util/AABB.h" ApplySchematicRuleDefinition::ApplySchematicRuleDefinition( LevelGenerationOptions* levelGenOptions) { m_levelGenOptions = levelGenOptions; m_location = Vec3(0, 0, 0); - m_locationBox = NULL; + m_locationBox = std::nullopt; m_totalBlocksChanged = 0; m_totalBlocksChangedLighting = 0; m_rotation = ConsoleSchematicFile::eSchematicRot_0; @@ -130,7 +131,7 @@ void ApplySchematicRuleDefinition::updateLocationBox() { if (m_schematic == NULL) m_schematic = m_levelGenOptions->getSchematicFile(m_schematicName); - m_locationBox = new AABB(0, 0, 0, 0, 0, 0); + m_locationBox = AABB(0, 0, 0, 0, 0, 0); m_locationBox->x0 = m_location.x; m_locationBox->y0 = m_location.y; @@ -162,7 +163,7 @@ void ApplySchematicRuleDefinition::processSchematic(AABB* chunkBox, if (m_schematic == NULL) m_schematic = m_levelGenOptions->getSchematicFile(m_schematicName); - if (m_locationBox == NULL) updateLocationBox(); + if (!m_locationBox.has_value()) updateLocationBox(); if (chunkBox->intersects(*m_locationBox)) { m_locationBox->y1 = std::min((double)Level::maxBuildHeight, m_locationBox->y1); @@ -173,12 +174,12 @@ void ApplySchematicRuleDefinition::processSchematic(AABB* chunkBox, #endif PIXBeginNamedEvent(0, "Applying blocks and data"); m_totalBlocksChanged += m_schematic->applyBlocksAndData( - chunk, chunkBox, m_locationBox, m_rotation); + chunk, chunkBox, &*m_locationBox, m_rotation); PIXEndNamedEvent(); // Add the tileEntities PIXBeginNamedEvent(0, "Applying tile entities"); - m_schematic->applyTileEntities(chunk, chunkBox, m_locationBox, + m_schematic->applyTileEntities(chunk, chunkBox, &*m_locationBox, m_rotation); PIXEndNamedEvent(); @@ -206,7 +207,7 @@ void ApplySchematicRuleDefinition::processSchematicLighting(AABB* chunkBox, if (m_schematic == NULL) m_schematic = m_levelGenOptions->getSchematicFile(m_schematicName); - if (m_locationBox == NULL) updateLocationBox(); + if (!m_locationBox.has_value()) updateLocationBox(); if (chunkBox->intersects(*m_locationBox)) { m_locationBox->y1 = std::min((double)Level::maxBuildHeight, m_locationBox->y1); @@ -217,7 +218,7 @@ void ApplySchematicRuleDefinition::processSchematicLighting(AABB* chunkBox, #endif PIXBeginNamedEvent(0, "Patching lighting"); m_totalBlocksChangedLighting += m_schematic->applyLighting( - chunk, chunkBox, m_locationBox, m_rotation); + chunk, chunkBox, &*m_locationBox, m_rotation); PIXEndNamedEvent(); // TODO This does not take into account things that go outside the @@ -237,12 +238,12 @@ void ApplySchematicRuleDefinition::processSchematicLighting(AABB* chunkBox, bool ApplySchematicRuleDefinition::checkIntersects(int x0, int y0, int z0, int x1, int y1, int z1) { - if (m_locationBox == NULL) updateLocationBox(); + if (!m_locationBox.has_value()) updateLocationBox(); return m_locationBox->intersects(x0, y0, z0, x1, y1, z1); } int ApplySchematicRuleDefinition::getMinY() { - if (m_locationBox == NULL) updateLocationBox(); + if (!m_locationBox.has_value()) updateLocationBox(); return m_locationBox->y0; } diff --git a/Minecraft.Client/Platform/Common/GameRules/ApplySchematicRuleDefinition.h b/Minecraft.Client/Platform/Common/GameRules/ApplySchematicRuleDefinition.h index 283c19586..1f5a5cbc1 100644 --- a/Minecraft.Client/Platform/Common/GameRules/ApplySchematicRuleDefinition.h +++ b/Minecraft.Client/Platform/Common/GameRules/ApplySchematicRuleDefinition.h @@ -1,6 +1,8 @@ #pragma once +#include #include "GameRuleDefinition.h" #include "ConsoleSchematicFile.h" +#include "../../Minecraft.World/Util/AABB.h" class AABB; class Vec3; @@ -14,7 +16,7 @@ private: std::wstring m_schematicName; ConsoleSchematicFile* m_schematic; Vec3 m_location; - AABB* m_locationBox; + std::optional m_locationBox; ConsoleSchematicFile::ESchematicRotation m_rotation; int m_dimension; diff --git a/Minecraft.Client/Platform/Common/GameRules/NamedAreaRuleDefinition.cpp b/Minecraft.Client/Platform/Common/GameRules/NamedAreaRuleDefinition.cpp index aefc12453..da0524ff7 100644 --- a/Minecraft.Client/Platform/Common/GameRules/NamedAreaRuleDefinition.cpp +++ b/Minecraft.Client/Platform/Common/GameRules/NamedAreaRuleDefinition.cpp @@ -5,11 +5,9 @@ NamedAreaRuleDefinition::NamedAreaRuleDefinition() { m_name = L""; - m_area = new AABB(0, 0, 0, 0, 0, 0); + m_area = AABB(0, 0, 0, 0, 0, 0); } -NamedAreaRuleDefinition::~NamedAreaRuleDefinition() { delete m_area; } - void NamedAreaRuleDefinition::writeAttributes(DataOutputStream* dos, unsigned int numAttributes) { GameRuleDefinition::writeAttributes(dos, numAttributes + 7); @@ -18,18 +16,18 @@ void NamedAreaRuleDefinition::writeAttributes(DataOutputStream* dos, dos->writeUTF(m_name); ConsoleGameRules::write(dos, ConsoleGameRules::eGameRuleAttr_x0); - dos->writeUTF(_toString(m_area->x0)); + dos->writeUTF(_toString(m_area.x0)); ConsoleGameRules::write(dos, ConsoleGameRules::eGameRuleAttr_y0); - dos->writeUTF(_toString(m_area->y0)); + dos->writeUTF(_toString(m_area.y0)); ConsoleGameRules::write(dos, ConsoleGameRules::eGameRuleAttr_z0); - dos->writeUTF(_toString(m_area->z0)); + dos->writeUTF(_toString(m_area.z0)); ConsoleGameRules::write(dos, ConsoleGameRules::eGameRuleAttr_x1); - dos->writeUTF(_toString(m_area->x1)); + dos->writeUTF(_toString(m_area.x1)); ConsoleGameRules::write(dos, ConsoleGameRules::eGameRuleAttr_y1); - dos->writeUTF(_toString(m_area->y1)); + dos->writeUTF(_toString(m_area.y1)); ConsoleGameRules::write(dos, ConsoleGameRules::eGameRuleAttr_z1); - dos->writeUTF(_toString(m_area->z1)); + dos->writeUTF(_toString(m_area.z1)); } void NamedAreaRuleDefinition::addAttribute(const std::wstring& attributeName, @@ -41,31 +39,31 @@ void NamedAreaRuleDefinition::addAttribute(const std::wstring& attributeName, m_name.c_str()); #endif } else if (attributeName.compare(L"x0") == 0) { - m_area->x0 = _fromString(attributeValue); + m_area.x0 = _fromString(attributeValue); app.DebugPrintf("NamedAreaRuleDefinition: Adding parameter x0=%f\n", - m_area->x0); + m_area.x0); } else if (attributeName.compare(L"y0") == 0) { - m_area->y0 = _fromString(attributeValue); - if (m_area->y0 < 0) m_area->y0 = 0; + m_area.y0 = _fromString(attributeValue); + if (m_area.y0 < 0) m_area.y0 = 0; app.DebugPrintf("NamedAreaRuleDefinition: Adding parameter y0=%f\n", - m_area->y0); + m_area.y0); } else if (attributeName.compare(L"z0") == 0) { - m_area->z0 = _fromString(attributeValue); + m_area.z0 = _fromString(attributeValue); app.DebugPrintf("NamedAreaRuleDefinition: Adding parameter z0=%f\n", - m_area->z0); + m_area.z0); } else if (attributeName.compare(L"x1") == 0) { - m_area->x1 = _fromString(attributeValue); + m_area.x1 = _fromString(attributeValue); app.DebugPrintf("NamedAreaRuleDefinition: Adding parameter x1=%f\n", - m_area->x1); + m_area.x1); } else if (attributeName.compare(L"y1") == 0) { - m_area->y1 = _fromString(attributeValue); - if (m_area->y1 < 0) m_area->y1 = 0; + m_area.y1 = _fromString(attributeValue); + if (m_area.y1 < 0) m_area.y1 = 0; app.DebugPrintf("NamedAreaRuleDefinition: Adding parameter y1=%f\n", - m_area->y1); + m_area.y1); } else if (attributeName.compare(L"z1") == 0) { - m_area->z1 = _fromString(attributeValue); + m_area.z1 = _fromString(attributeValue); app.DebugPrintf("NamedAreaRuleDefinition: Adding parameter z1=%f\n", - m_area->z1); + m_area.z1); } else { GameRuleDefinition::addAttribute(attributeName, attributeValue); } diff --git a/Minecraft.Client/Platform/Common/GameRules/NamedAreaRuleDefinition.h b/Minecraft.Client/Platform/Common/GameRules/NamedAreaRuleDefinition.h index 93f8a0c47..81be6c4bc 100644 --- a/Minecraft.Client/Platform/Common/GameRules/NamedAreaRuleDefinition.h +++ b/Minecraft.Client/Platform/Common/GameRules/NamedAreaRuleDefinition.h @@ -1,15 +1,15 @@ #pragma once #include "GameRuleDefinition.h" +#include "../../Minecraft.World/Util/AABB.h" class NamedAreaRuleDefinition : public GameRuleDefinition { private: std::wstring m_name; - AABB* m_area; + AABB m_area; public: NamedAreaRuleDefinition(); - ~NamedAreaRuleDefinition(); virtual void writeAttributes(DataOutputStream* dos, unsigned int numAttributes); @@ -21,6 +21,6 @@ public: virtual void addAttribute(const std::wstring& attributeName, const std::wstring& attributeValue); - AABB* getArea() { return m_area; } + AABB* getArea() { return &m_area; } std::wstring getName() { return m_name; } }; diff --git a/Minecraft.Client/Platform/Common/Tutorial/AreaConstraint.cpp b/Minecraft.Client/Platform/Common/Tutorial/AreaConstraint.cpp index 36c53aa47..2cf4ab5ee 100644 --- a/Minecraft.Client/Platform/Common/Tutorial/AreaConstraint.cpp +++ b/Minecraft.Client/Platform/Common/Tutorial/AreaConstraint.cpp @@ -10,25 +10,19 @@ AreaConstraint::AreaConstraint(int descriptionId, double x0, double y0, bool contains /*= true*/, bool restrictsMovement /*=true*/) : TutorialConstraint(descriptionId) { - messageArea = - new AABB(x0 + 2, y0 + 2, z0 + 2, x1 - 2, y1 - 2, z1 - 2); - movementArea = new AABB(x0, y0, z0, x1, y1, z1); + messageArea = AABB(x0 + 2, y0 + 2, z0 + 2, x1 - 2, y1 - 2, z1 - 2); + movementArea = AABB(x0, y0, z0, x1, y1, z1); this->contains = contains; m_restrictsMovement = restrictsMovement; } -AreaConstraint::~AreaConstraint() { - delete messageArea; - delete movementArea; -} - bool AreaConstraint::isConstraintSatisfied(int iPad) { Minecraft* minecraft = Minecraft::GetInstance(); // TODO: check if this can be elided Vec3 ipad_player = minecraft->localplayers[iPad]->getPos(1); - return messageArea->contains(ipad_player) == contains; + return messageArea.contains(ipad_player) == contains; } bool AreaConstraint::isConstraintRestrictive(int iPad) { @@ -42,12 +36,12 @@ bool AreaConstraint::canMoveToPosition(double xo, double yo, double zo, Vec3 targetPos(xt, yt, zt); Minecraft* minecraft = Minecraft::GetInstance(); - if (movementArea->contains(targetPos) == contains) { + if (movementArea.contains(targetPos) == contains) { return true; } Vec3 origPos(xo, yo, zo); - double currDist = origPos.distanceTo(movementArea); - double targetDist = targetPos.distanceTo(movementArea); + double currDist = origPos.distanceTo(&movementArea); + double targetDist = targetPos.distanceTo(&movementArea); return targetDist < currDist; } diff --git a/Minecraft.Client/Platform/Common/Tutorial/AreaConstraint.h b/Minecraft.Client/Platform/Common/Tutorial/AreaConstraint.h index 721ab6eb1..05265b73f 100644 --- a/Minecraft.Client/Platform/Common/Tutorial/AreaConstraint.h +++ b/Minecraft.Client/Platform/Common/Tutorial/AreaConstraint.h @@ -6,8 +6,8 @@ class AABB; class AreaConstraint : public TutorialConstraint { private: - AABB* movementArea; - AABB* messageArea; + AABB movementArea; + AABB messageArea; bool contains; // If true we must stay in this area, if false must stay out // of this area bool m_restrictsMovement; @@ -18,10 +18,9 @@ public: AreaConstraint(int descriptionId, double x0, double y0, double z0, double x1, double y1, double z1, bool contains = true, bool restrictsMovement = true); - ~AreaConstraint(); virtual bool isConstraintSatisfied(int iPad); virtual bool isConstraintRestrictive(int iPad); virtual bool canMoveToPosition(double xo, double yo, double zo, double xt, double yt, double zt); -}; \ No newline at end of file +}; diff --git a/Minecraft.Client/Platform/Common/Tutorial/AreaHint.cpp b/Minecraft.Client/Platform/Common/Tutorial/AreaHint.cpp index b6bae48d3..b3ebdf65a 100644 --- a/Minecraft.Client/Platform/Common/Tutorial/AreaHint.cpp +++ b/Minecraft.Client/Platform/Common/Tutorial/AreaHint.cpp @@ -12,7 +12,7 @@ AreaHint::AreaHint(eTutorial_Hint id, Tutorial* tutorial, double x1, double y1, double z1, bool allowFade /*= false*/, bool contains /*= true*/) : TutorialHint(id, tutorial, descriptionId, e_Hint_Area, allowFade) { - area = new AABB(x0, y0, z0, x1, y1, z1); + area = AABB(x0, y0, z0, x1, y1, z1); this->contains = contains; @@ -20,15 +20,13 @@ AreaHint::AreaHint(eTutorial_Hint id, Tutorial* tutorial, m_completeState = completeState; } -AreaHint::~AreaHint() { delete area; } - int AreaHint::tick() { Minecraft* minecraft = Minecraft::GetInstance(); Vec3 player_pos = minecraft->player->getPos(1); if ((m_displayState == e_Tutorial_State_Any || m_tutorial->getCurrentState() == m_displayState) && - m_hintNeeded && area->contains(player_pos) == contains) { + m_hintNeeded && area.contains(player_pos) == contains) { if (m_completeState == e_Tutorial_State_None) { m_hintNeeded = false; } else if (m_tutorial->isStateCompleted(m_completeState)) { diff --git a/Minecraft.Client/Platform/Common/Tutorial/AreaHint.h b/Minecraft.Client/Platform/Common/Tutorial/AreaHint.h index 71d8219f2..68ec72ba5 100644 --- a/Minecraft.Client/Platform/Common/Tutorial/AreaHint.h +++ b/Minecraft.Client/Platform/Common/Tutorial/AreaHint.h @@ -6,7 +6,7 @@ class AABB; class AreaHint : public TutorialHint { private: - AABB* area; + AABB area; bool contains; // If true we must stay in this area, if false must stay out // of this area @@ -21,7 +21,6 @@ public: eTutorial_State displayState, eTutorial_State completeState, int descriptionId, double x0, double y0, double z0, double x1, double y1, double z1, bool allowFade = true, bool contains = true); - ~AreaHint(); virtual int tick(); -}; \ No newline at end of file +}; diff --git a/Minecraft.Client/Platform/Common/Tutorial/ChangeStateConstraint.cpp b/Minecraft.Client/Platform/Common/Tutorial/ChangeStateConstraint.cpp index 5934505e8..4296a04bd 100644 --- a/Minecraft.Client/Platform/Common/Tutorial/ChangeStateConstraint.cpp +++ b/Minecraft.Client/Platform/Common/Tutorial/ChangeStateConstraint.cpp @@ -16,7 +16,7 @@ ChangeStateConstraint::ChangeStateConstraint( bool contains /*= true*/, bool changeGameMode /*= false*/, GameType* targetGameMode /*= 0*/) : TutorialConstraint(-1) { - movementArea = new AABB(x0, y0, z0, x1, y1, z1); + movementArea = AABB(x0, y0, z0, x1, y1, z1); this->contains = contains; @@ -40,7 +40,6 @@ ChangeStateConstraint::ChangeStateConstraint( } ChangeStateConstraint::~ChangeStateConstraint() { - delete movementArea; if (m_sourceStatesCount > 0) delete[] m_sourceStates; } @@ -89,7 +88,7 @@ void ChangeStateConstraint::tick(int iPad) { // TODO: check if this can be elided Vec3 ipad_player = minecraft->localplayers[iPad]->getPos(1); if (!m_bHasChanged && inASourceState && - movementArea->contains(ipad_player) == contains) { + movementArea.contains(ipad_player) == contains) { m_bHasChanged = true; m_changedFromState = m_tutorial->getCurrentState(); m_tutorial->changeTutorialState(m_targetState); @@ -127,7 +126,7 @@ void ChangeStateConstraint::tick(int iPad) { } } } else if (m_bHasChanged && - movementArea->contains(ipad_player) != contains) { + movementArea.contains(ipad_player) != contains) { m_bHasChanged = false; m_tutorial->changeTutorialState(m_changedFromState); diff --git a/Minecraft.Client/Platform/Common/Tutorial/ChangeStateConstraint.h b/Minecraft.Client/Platform/Common/Tutorial/ChangeStateConstraint.h index 5ec51d437..44c9b410b 100644 --- a/Minecraft.Client/Platform/Common/Tutorial/ChangeStateConstraint.h +++ b/Minecraft.Client/Platform/Common/Tutorial/ChangeStateConstraint.h @@ -11,7 +11,7 @@ class GameType; class ChangeStateConstraint : public TutorialConstraint { private: - AABB* movementArea; + AABB movementArea; bool contains; // If true we must stay in this area, if false must stay out // of this area bool m_changeGameMode; diff --git a/Minecraft.Client/Player/LocalPlayer.cpp b/Minecraft.Client/Player/LocalPlayer.cpp index 4a8e126e5..a02033d66 100644 --- a/Minecraft.Client/Player/LocalPlayer.cpp +++ b/Minecraft.Client/Player/LocalPlayer.cpp @@ -245,10 +245,10 @@ void LocalPlayer::aiStep() { if (ySlideOffset < 0.2f) ySlideOffset = 0.2f; } - checkInTile(x - bbWidth * 0.35, bb->y0 + 0.5, z + bbWidth * 0.35); - checkInTile(x - bbWidth * 0.35, bb->y0 + 0.5, z - bbWidth * 0.35); - checkInTile(x + bbWidth * 0.35, bb->y0 + 0.5, z - bbWidth * 0.35); - checkInTile(x + bbWidth * 0.35, bb->y0 + 0.5, z + bbWidth * 0.35); + checkInTile(x - bbWidth * 0.35, bb.y0 + 0.5, z + bbWidth * 0.35); + checkInTile(x - bbWidth * 0.35, bb.y0 + 0.5, z - bbWidth * 0.35); + checkInTile(x + bbWidth * 0.35, bb.y0 + 0.5, z - bbWidth * 0.35); + checkInTile(x + bbWidth * 0.35, bb.y0 + 0.5, z + bbWidth * 0.35); bool enoughFoodToSprint = getFoodData()->getFoodLevel() > diff --git a/Minecraft.Client/Player/MultiPlayerLocalPlayer.cpp b/Minecraft.Client/Player/MultiPlayerLocalPlayer.cpp index 4d287b9cc..e6dd6f9a9 100644 --- a/Minecraft.Client/Player/MultiPlayerLocalPlayer.cpp +++ b/Minecraft.Client/Player/MultiPlayerLocalPlayer.cpp @@ -140,7 +140,7 @@ void MultiplayerLocalPlayer::sendPosition() { } double xdd = x - xLast; - double ydd1 = bb->y0 - yLast1; + double ydd1 = bb.y0 - yLast1; double zdd = z - zLast; double rydd = yRot - yRotLast; @@ -158,11 +158,11 @@ void MultiplayerLocalPlayer::sendPosition() { if (move && rot) { connection->send( std::shared_ptr(new MovePlayerPacket::PosRot( - x, bb->y0, y, z, yRot, xRot, onGround, abilities.flying))); + x, bb.y0, y, z, yRot, xRot, onGround, abilities.flying))); } else if (move) { connection->send( std::shared_ptr(new MovePlayerPacket::Pos( - x, bb->y0, y, z, onGround, abilities.flying))); + x, bb.y0, y, z, onGround, abilities.flying))); } else if (rot) { connection->send( std::shared_ptr(new MovePlayerPacket::Rot( @@ -178,7 +178,7 @@ void MultiplayerLocalPlayer::sendPosition() { if (move) { xLast = x; - yLast1 = bb->y0; + yLast1 = bb.y0; yLast2 = y; zLast = z; positionReminder = 0; diff --git a/Minecraft.Client/Rendering/Chunk.cpp b/Minecraft.Client/Rendering/Chunk.cpp index 95e060ed9..a52ac7459 100644 --- a/Minecraft.Client/Rendering/Chunk.cpp +++ b/Minecraft.Client/Rendering/Chunk.cpp @@ -43,7 +43,8 @@ Chunk::Chunk(Level* level, LevelRenderer::rteMap& globalRenderableTileEntities, : globalRenderableTileEntities(&globalRenderableTileEntities), globalRenderableTileEntities_cs(&globalRenderableTileEntities_cs) { clipChunk->visible = false; - bb = NULL; + const double g = 6; + bb = AABB(-g, -g, -g, XZSIZE + g, SIZE + g, XZSIZE + g); id = 0; this->level = level; @@ -92,21 +93,13 @@ void Chunk::setPos(int x, int y, int z) { #endif float g = 6.0f; - // 4J - changed to just set the value rather than make a new one, if we've - // already created storage - if (bb == NULL) { - bb = new AABB(-g, -g, -g, XZSIZE + g, SIZE + g, XZSIZE + g); - } else { - // 4J MGH - bounds are relative to the position now, so the AABB will be - // setup already, either above, or from the tesselator bounds. - // bb->set(-g, -g, -g, SIZE+g, SIZE+g, SIZE+g); - } - clipChunk->aabb[0] = bb->x0 + x; - clipChunk->aabb[1] = bb->y0 + y; - clipChunk->aabb[2] = bb->z0 + z; - clipChunk->aabb[3] = bb->x1 + x; - clipChunk->aabb[4] = bb->y1 + y; - clipChunk->aabb[5] = bb->z1 + z; + + clipChunk->aabb[0] = bb.x0 + x; + clipChunk->aabb[1] = bb.y0 + y; + clipChunk->aabb[2] = bb.z0 + z; + clipChunk->aabb[3] = bb.x1 + x; + clipChunk->aabb[4] = bb.y1 + y; + clipChunk->aabb[5] = bb.z1 + z; assigned = true; @@ -508,11 +501,8 @@ void Chunk::rebuild() { // 4J MGH - added this to take the bound from the value calc'd in the // tesselator - if (bb) { - *bb = {bounds.boundingBox[0], bounds.boundingBox[1], - bounds.boundingBox[2], bounds.boundingBox[3], - bounds.boundingBox[4], bounds.boundingBox[5]}; - } + bb = {bounds.boundingBox[0], bounds.boundingBox[1], bounds.boundingBox[2], + bounds.boundingBox[3], bounds.boundingBox[4], bounds.boundingBox[5]}; delete tileRenderer; delete region; @@ -1033,7 +1023,7 @@ int Chunk::getList(int layer) { return -1; } -void Chunk::cull(Culler* culler) { clipChunk->visible = culler->isVisible(bb); } +void Chunk::cull(Culler* culler) { clipChunk->visible = culler->isVisible(&bb); } void Chunk::renderBB() { // glCallList(lists + 2); // 4J - removed - TODO put back in @@ -1064,8 +1054,6 @@ void Chunk::clearDirty() { #endif } -Chunk::~Chunk() { delete bb; } - bool Chunk::emptyFlagSet(int layer) { return levelRenderer->getGlobalChunkFlag( x, y, z, level, LevelRenderer::CHUNK_FLAG_EMPTY0, layer); diff --git a/Minecraft.Client/Rendering/Chunk.h b/Minecraft.Client/Rendering/Chunk.h index 379b258ba..e6d214ab2 100644 --- a/Minecraft.Client/Rendering/Chunk.h +++ b/Minecraft.Client/Rendering/Chunk.h @@ -46,7 +46,7 @@ public: int xRenderOffs, yRenderOffs, zRenderOffs; int xm, ym, zm; - AABB* bb; + AABB bb; ClipChunk* clipChunk; int id; @@ -88,5 +88,4 @@ public: void setDirty(); void clearDirty(); // 4J added bool emptyFlagSet(int layer); - ~Chunk(); }; diff --git a/Minecraft.Client/Rendering/EntityRenderers/EntityRenderer.cpp b/Minecraft.Client/Rendering/EntityRenderers/EntityRenderer.cpp index 9b4d7bda3..86c76a334 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/EntityRenderer.cpp +++ b/Minecraft.Client/Rendering/EntityRenderers/EntityRenderer.cpp @@ -91,7 +91,7 @@ void EntityRenderer::renderFlame(std::shared_ptr e, double x, double y, float xo = 0.0f; float h = e->bbHeight / s; - float yo = (float)(e->y - e->bb->y0); + float yo = (float)(e->y - e->bb.y0); glRotatef(-entityRenderDispatcher->playerRotY, 0, 1, 0); @@ -394,4 +394,4 @@ void EntityRenderer::registerTerrainTextures(IconRegister* iconRegister) {} ResourceLocation* EntityRenderer::getTextureLocation( std::shared_ptr mob) { return NULL; -} \ No newline at end of file +} diff --git a/Minecraft.Client/Rendering/EntityRenderers/FireballRenderer.cpp b/Minecraft.Client/Rendering/EntityRenderers/FireballRenderer.cpp index 87251b8c9..fd1dce90c 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/FireballRenderer.cpp +++ b/Minecraft.Client/Rendering/EntityRenderers/FireballRenderer.cpp @@ -78,7 +78,7 @@ void FireballRenderer::renderFlame(std::shared_ptr e, double x, // float yo = 0.0f; float h = e->bbHeight / s; - float yo = (float)(e->y - e->bb->y0); + float yo = (float)(e->y - e->bb.y0); // glRotatef(-entityRenderDispatcher->playerRotY, 0, 1, 0); @@ -118,4 +118,4 @@ void FireballRenderer::renderFlame(std::shared_ptr e, double x, ResourceLocation* FireballRenderer::getTextureLocation( std::shared_ptr mob) { return &TextureAtlas::LOCATION_ITEMS; -} \ No newline at end of file +} diff --git a/Minecraft.Client/Rendering/GameRenderer.cpp b/Minecraft.Client/Rendering/GameRenderer.cpp index b2f589b88..e405931b0 100644 --- a/Minecraft.Client/Rendering/GameRenderer.cpp +++ b/Minecraft.Client/Rendering/GameRenderer.cpp @@ -310,7 +310,7 @@ void GameRenderer::pick(float a) { hovered = nullptr; float overlap = 1; AABB grown = mc->cameraTargetPlayer->bb - ->expand(b.x * (range), b.y * (range), b.z * (range)) + .expand(b.x * (range), b.y * (range), b.z * (range)) .grow(overlap, overlap, overlap); std::vector >* objects = @@ -323,7 +323,7 @@ void GameRenderer::pick(float a) { if (!e->isPickable()) continue; float rr = e->getPickRadius(); - AABB bb = e->bb->grow(rr, rr, rr); + AABB bb = e->bb.grow(rr, rr, rr); HitResult* p = bb.clip(from, to); if (bb.contains(from)) { if (0 < nearest || nearest == 0) { diff --git a/Minecraft.Client/Rendering/LevelRenderer.cpp b/Minecraft.Client/Rendering/LevelRenderer.cpp index d970c3f3b..556d83ec7 100644 --- a/Minecraft.Client/Rendering/LevelRenderer.cpp +++ b/Minecraft.Client/Rendering/LevelRenderer.cpp @@ -585,14 +585,14 @@ void LevelRenderer::renderEntities(Vec3* cam, Culler* culler, float a) { bool shouldRender = (entity->shouldRender(cam) && - (entity->noCulling || culler->isVisible(entity->bb))); + (entity->noCulling || culler->isVisible(&entity->bb))); // Render the mob if the mob's leash holder is within the culler if (!shouldRender && entity->instanceof(eTYPE_MOB)) { std::shared_ptr mob = std::dynamic_pointer_cast(entity); if (mob->isLeashed() && (mob->getLeashHolder() != NULL)) { std::shared_ptr leashHolder = mob->getLeashHolder(); - shouldRender = culler->isVisible(leashHolder->bb); + shouldRender = culler->isVisible(&leashHolder->bb); } } diff --git a/Minecraft.Client/Rendering/Particles/CritParticle.cpp b/Minecraft.Client/Rendering/Particles/CritParticle.cpp index 11457da37..fba87aca0 100644 --- a/Minecraft.Client/Rendering/Particles/CritParticle.cpp +++ b/Minecraft.Client/Rendering/Particles/CritParticle.cpp @@ -16,14 +16,14 @@ void CritParticle::_init(Level* level, std::shared_ptr entity, } CritParticle::CritParticle(Level* level, std::shared_ptr entity) - : Particle(level, entity->x, entity->bb->y0 + entity->bbHeight / 2, + : Particle(level, entity->x, entity->bb.y0 + entity->bbHeight / 2, entity->z, entity->xd, entity->yd, entity->zd) { _init(level, entity, eParticleType_crit); } CritParticle::CritParticle(Level* level, std::shared_ptr entity, ePARTICLE_TYPE type) - : Particle(level, entity->x, entity->bb->y0 + entity->bbHeight / 2, + : Particle(level, entity->x, entity->bb.y0 + entity->bbHeight / 2, entity->z, entity->xd, entity->yd, entity->zd) { _init(level, entity, type); } @@ -43,7 +43,7 @@ void CritParticle::tick() { if (xa * xa + ya * ya + za * za > 1) continue; double x = entity->x + xa * entity->bbWidth / 4; double y = - entity->bb->y0 + entity->bbHeight / 2 + ya * entity->bbHeight / 4; + entity->bb.y0 + entity->bbHeight / 2 + ya * entity->bbHeight / 4; double z = entity->z + za * entity->bbWidth / 4; level->addParticle(particleName, x, y, z, xa, ya + 0.2, za); } @@ -55,4 +55,4 @@ void CritParticle::tick() { int CritParticle::getParticleTexture() { return ParticleEngine::ENTITY_PARTICLE_TEXTURE; -} \ No newline at end of file +} diff --git a/Minecraft.Client/Rendering/Particles/PlayerCloudParticle.cpp b/Minecraft.Client/Rendering/Particles/PlayerCloudParticle.cpp index 145630db1..a38775947 100644 --- a/Minecraft.Client/Rendering/Particles/PlayerCloudParticle.cpp +++ b/Minecraft.Client/Rendering/Particles/PlayerCloudParticle.cpp @@ -52,8 +52,8 @@ void PlayerCloudParticle::tick() { zd *= 0.96f; std::shared_ptr p = level->getNearestPlayer(shared_from_this(), 2); if (p != NULL) { - if (y > p->bb->y0) { - y += (p->bb->y0 - y) * 0.2; + if (y > p->bb.y0) { + y += (p->bb.y0 - y) * 0.2; yd += (p->yd - yd) * 0.2; setPos(x, y, z); } @@ -63,4 +63,4 @@ void PlayerCloudParticle::tick() { xd *= 0.7f; zd *= 0.7f; } -} \ No newline at end of file +} diff --git a/Minecraft.World/AI/Control/LookControl.cpp b/Minecraft.World/AI/Control/LookControl.cpp index f5b7519b1..c956da61d 100644 --- a/Minecraft.World/AI/Control/LookControl.cpp +++ b/Minecraft.World/AI/Control/LookControl.cpp @@ -20,7 +20,7 @@ void LookControl::setLookAt(std::shared_ptr target, float yMax, target->y + std::dynamic_pointer_cast(target)->getHeadHeight(); else - wantedY = (target->bb->y0 + target->bb->y1) / 2; + wantedY = (target->bb.y0 + target->bb.y1) / 2; wantedZ = target->z; this->yMax = yMax; this->xMax = xMax; @@ -88,4 +88,4 @@ double LookControl::getWantedX() { return wantedX; } double LookControl::getWantedY() { return wantedY; } -double LookControl::getWantedZ() { return wantedZ; } \ No newline at end of file +double LookControl::getWantedZ() { return wantedZ; } diff --git a/Minecraft.World/AI/Control/MoveControl.cpp b/Minecraft.World/AI/Control/MoveControl.cpp index 3834ed6a4..684ccd498 100644 --- a/Minecraft.World/AI/Control/MoveControl.cpp +++ b/Minecraft.World/AI/Control/MoveControl.cpp @@ -38,7 +38,7 @@ void MoveControl::tick() { if (!_hasWanted) return; _hasWanted = false; - int yFloor = floor(mob->bb->y0 + .5f); + int yFloor = floor(mob->bb.y0 + .5f); double xd = wantedX - mob->x; double zd = wantedZ - mob->z; @@ -66,4 +66,4 @@ float MoveControl::rotlerp(float a, float b, float max) { diff = -max; } return a + diff; -} \ No newline at end of file +} diff --git a/Minecraft.World/AI/Goals/AvoidPlayerGoal.cpp b/Minecraft.World/AI/Goals/AvoidPlayerGoal.cpp index cf595ea05..af58f48ec 100644 --- a/Minecraft.World/AI/Goals/AvoidPlayerGoal.cpp +++ b/Minecraft.World/AI/Goals/AvoidPlayerGoal.cpp @@ -53,7 +53,7 @@ bool AvoidPlayerGoal::canUse() { mob->level->getNearestPlayer(mob->shared_from_this(), maxDist)); if (toAvoid.lock() == NULL) return false; } else { - AABB grown_bb = mob->bb->grow(maxDist, 3, maxDist); + AABB grown_bb = mob->bb.grow(maxDist, 3, maxDist); std::vector >* entities = mob->level->getEntitiesOfClass( avoidType, &grown_bb, entitySelector); diff --git a/Minecraft.World/AI/Goals/BreedGoal.cpp b/Minecraft.World/AI/Goals/BreedGoal.cpp index 1ec4f59fc..7c9fc4ce7 100644 --- a/Minecraft.World/AI/Goals/BreedGoal.cpp +++ b/Minecraft.World/AI/Goals/BreedGoal.cpp @@ -48,7 +48,7 @@ void BreedGoal::tick() { std::shared_ptr BreedGoal::getFreePartner() { float r = 8; - AABB grown_bb = animal->bb->grow(r, r, r); + AABB grown_bb = animal->bb.grow(r, r, r); std::vector >* others = level->getEntitiesOfClass(typeid(*animal), &grown_bb); double dist = std::numeric_limits::max(); diff --git a/Minecraft.World/AI/Goals/FleeSunGoal.cpp b/Minecraft.World/AI/Goals/FleeSunGoal.cpp index fdddfd6e0..4f35fb567 100644 --- a/Minecraft.World/AI/Goals/FleeSunGoal.cpp +++ b/Minecraft.World/AI/Goals/FleeSunGoal.cpp @@ -17,7 +17,7 @@ FleeSunGoal::FleeSunGoal(PathfinderMob* mob, double speedModifier) { bool FleeSunGoal::canUse() { if (!level->isDay()) return false; if (!mob->isOnFire()) return false; - if (!level->canSeeSky(Mth::floor(mob->x), (int)mob->bb->y0, + if (!level->canSeeSky(Mth::floor(mob->x), (int)mob->bb.y0, Mth::floor(mob->z))) return false; @@ -39,7 +39,7 @@ std::optional FleeSunGoal::getHidePos() { Random* random = mob->getRandom(); for (int i = 0; i < 10; i++) { int xt = Mth::floor(mob->x + random->nextInt(20) - 10); - int yt = Mth::floor(mob->bb->y0 + random->nextInt(6) - 3); + int yt = Mth::floor(mob->bb.y0 + random->nextInt(6) - 3); int zt = Mth::floor(mob->z + random->nextInt(20) - 10); if (!level->canSeeSky(xt, yt, zt) && mob->getWalkTargetValue(xt, yt, zt) < 0) diff --git a/Minecraft.World/AI/Goals/FollowOwnerGoal.cpp b/Minecraft.World/AI/Goals/FollowOwnerGoal.cpp index a0ddb3ccb..62c0431ab 100644 --- a/Minecraft.World/AI/Goals/FollowOwnerGoal.cpp +++ b/Minecraft.World/AI/Goals/FollowOwnerGoal.cpp @@ -69,7 +69,7 @@ void FollowOwnerGoal::tick() { // find a good spawn position nearby the owner int sx = Mth::floor(owner.lock()->x) - 2; int sz = Mth::floor(owner.lock()->z) - 2; - int y = Mth::floor(owner.lock()->bb->y0); + int y = Mth::floor(owner.lock()->bb.y0); for (int x = 0; x <= 4; x++) { for (int z = 0; z <= 4; z++) { if (x >= 1 && z >= 1 && x <= 3 && z <= 3) { diff --git a/Minecraft.World/AI/Goals/FollowParentGoal.cpp b/Minecraft.World/AI/Goals/FollowParentGoal.cpp index 0a740a35c..bcdc860ae 100644 --- a/Minecraft.World/AI/Goals/FollowParentGoal.cpp +++ b/Minecraft.World/AI/Goals/FollowParentGoal.cpp @@ -16,7 +16,7 @@ FollowParentGoal::FollowParentGoal(Animal* animal, double speedModifier) { bool FollowParentGoal::canUse() { if (animal->getAge() >= 0) return false; - AABB grown_bb = animal->bb->grow(8, 4, 8); + AABB grown_bb = animal->bb.grow(8, 4, 8); std::vector >* parents = animal->level->getEntitiesOfClass(typeid(*animal), &grown_bb); diff --git a/Minecraft.World/AI/Goals/LookAtPlayerGoal.cpp b/Minecraft.World/AI/Goals/LookAtPlayerGoal.cpp index b073212c2..8ab999411 100644 --- a/Minecraft.World/AI/Goals/LookAtPlayerGoal.cpp +++ b/Minecraft.World/AI/Goals/LookAtPlayerGoal.cpp @@ -37,10 +37,9 @@ bool LookAtPlayerGoal::canUse() { lookAt = mob->level->getNearestPlayer(mob->shared_from_this(), lookDistance); } else { - AABB mob_bb = mob->bb->grow(lookDistance, 3, lookDistance); + AABB mob_bb = mob->bb.grow(lookDistance, 3, lookDistance); lookAt = std::weak_ptr(mob->level->getClosestEntityOfClass( - lookAtType, &mob_bb, - mob->shared_from_this())); + lookAtType, &mob_bb, mob->shared_from_this())); } return lookAt.lock() != NULL; } diff --git a/Minecraft.World/AI/Goals/MakeLoveGoal.cpp b/Minecraft.World/AI/Goals/MakeLoveGoal.cpp index 0357f7113..af3dd10e3 100644 --- a/Minecraft.World/AI/Goals/MakeLoveGoal.cpp +++ b/Minecraft.World/AI/Goals/MakeLoveGoal.cpp @@ -29,10 +29,9 @@ bool MakeLoveGoal::canUse() { if (village.lock() == NULL) return false; if (!villageNeedsMoreVillagers()) return false; - AABB villager_bb = villager->bb->grow(8, 3, 8); + AABB villager_bb = villager->bb.grow(8, 3, 8); std::shared_ptr mate = level->getClosestEntityOfClass( - typeid(Villager), &villager_bb, - villager->shared_from_this()); + typeid(Villager), &villager_bb, villager->shared_from_this()); if (mate == NULL) return false; partner = diff --git a/Minecraft.World/AI/Goals/MeleeAttackGoal.cpp b/Minecraft.World/AI/Goals/MeleeAttackGoal.cpp index b3f059d8e..3c9b28244 100644 --- a/Minecraft.World/AI/Goals/MeleeAttackGoal.cpp +++ b/Minecraft.World/AI/Goals/MeleeAttackGoal.cpp @@ -41,7 +41,7 @@ bool MeleeAttackGoal::canUse() { std::shared_ptr target = mob->getTarget(); if (target == NULL) return false; if (!target->isAlive()) return false; - if (attackType != eTYPE_NOTSET && !target->instanceof (attackType)) + if (attackType != eTYPE_NOTSET && !target->instanceof(attackType)) return false; path.reset(mob->getNavigation()->createPath(target)); return path != nullptr; @@ -79,7 +79,7 @@ void MeleeAttackGoal::tick() { double meleeRadiusSqr = (mob->bbWidth * 2) * (mob->bbWidth * 2) + target->bbWidth; - if (mob->distanceToSqr(target->x, target->bb->y0, target->z) > + if (mob->distanceToSqr(target->x, target->bb.y0, target->z) > meleeRadiusSqr) return; if (attackTime > 0) return; diff --git a/Minecraft.World/AI/Goals/NearestAttackableTargetGoal.cpp b/Minecraft.World/AI/Goals/NearestAttackableTargetGoal.cpp index 938102d3e..a1126b45e 100644 --- a/Minecraft.World/AI/Goals/NearestAttackableTargetGoal.cpp +++ b/Minecraft.World/AI/Goals/NearestAttackableTargetGoal.cpp @@ -55,10 +55,9 @@ bool NearestAttackableTargetGoal::canUse() { return false; double within = getFollowDistance(); - AABB mob_bb = mob->bb->grow(within, 4, within); + AABB mob_bb = mob->bb.grow(within, 4, within); std::vector >* entities = - mob->level->getEntitiesOfClass( - targetType, &mob_bb, selector); + mob->level->getEntitiesOfClass(targetType, &mob_bb, selector); bool result = false; if (entities != NULL && !entities->empty()) { diff --git a/Minecraft.World/AI/Goals/OcelotAttackGoal.cpp b/Minecraft.World/AI/Goals/OcelotAttackGoal.cpp index d14d3bc9d..6753e64e3 100644 --- a/Minecraft.World/AI/Goals/OcelotAttackGoal.cpp +++ b/Minecraft.World/AI/Goals/OcelotAttackGoal.cpp @@ -40,7 +40,7 @@ void OcelotAttackGoal::tick() { mob->getLookControl()->setLookAt(target.lock(), 30, 30); double meleeRadiusSqr = (mob->bbWidth * 2) * (mob->bbWidth * 2); - double distSqr = mob->distanceToSqr(target.lock()->x, target.lock()->bb->y0, + double distSqr = mob->distanceToSqr(target.lock()->x, target.lock()->bb.y0, target.lock()->z); double speedModifier = Ocelot::WALK_SPEED_MOD; diff --git a/Minecraft.World/AI/Goals/OfferFlowerGoal.cpp b/Minecraft.World/AI/Goals/OfferFlowerGoal.cpp index 902b221ee..f78623fec 100644 --- a/Minecraft.World/AI/Goals/OfferFlowerGoal.cpp +++ b/Minecraft.World/AI/Goals/OfferFlowerGoal.cpp @@ -15,10 +15,9 @@ OfferFlowerGoal::OfferFlowerGoal(VillagerGolem* golem) { bool OfferFlowerGoal::canUse() { if (!golem->level->isDay()) return false; if (golem->getRandom()->nextInt(8000) != 0) return false; - AABB golem_bb = golem->bb->grow(6, 2, 6); + AABB golem_bb = golem->bb.grow(6, 2, 6); villager = std::weak_ptr(std::dynamic_pointer_cast( - golem->level->getClosestEntityOfClass(typeid(Villager), - &golem_bb, + golem->level->getClosestEntityOfClass(typeid(Villager), &golem_bb, golem->shared_from_this()))); return villager.lock() != NULL; } diff --git a/Minecraft.World/AI/Goals/PlayGoal.cpp b/Minecraft.World/AI/Goals/PlayGoal.cpp index 550f3bb6e..b748d7519 100644 --- a/Minecraft.World/AI/Goals/PlayGoal.cpp +++ b/Minecraft.World/AI/Goals/PlayGoal.cpp @@ -23,10 +23,9 @@ bool PlayGoal::canUse() { if (mob->getAge() >= 0) return false; if (mob->getRandom()->nextInt(400) != 0) return false; - AABB mob_bb = mob->bb->grow(6, 3, 6); + AABB mob_bb = mob->bb.grow(6, 3, 6); std::vector >* children = - mob->level->getEntitiesOfClass(typeid(Villager), - &mob_bb); + mob->level->getEntitiesOfClass(typeid(Villager), &mob_bb); double closestDistSqr = std::numeric_limits::max(); // for (Entity c : children) for (AUTO_VAR(it, children->begin()); it != children->end(); ++it) { diff --git a/Minecraft.World/AI/Goals/RangedAttackGoal.cpp b/Minecraft.World/AI/Goals/RangedAttackGoal.cpp index e58c59d1c..2c7f22d9e 100644 --- a/Minecraft.World/AI/Goals/RangedAttackGoal.cpp +++ b/Minecraft.World/AI/Goals/RangedAttackGoal.cpp @@ -67,7 +67,7 @@ void RangedAttackGoal::tick() { if (target.lock() == NULL) return; double targetDistSqr = mob->distanceToSqr( - target.lock()->x, target.lock()->bb->y0, target.lock()->z); + target.lock()->x, target.lock()->bb.y0, target.lock()->z); bool canSee = mob->getSensing()->canSee(target.lock()); if (canSee) { @@ -100,4 +100,4 @@ void RangedAttackGoal::tick() { attackTime = Mth::floor(dist * (attackIntervalMax - attackIntervalMin) + attackIntervalMin); } -} \ No newline at end of file +} diff --git a/Minecraft.World/AI/Goals/TakeFlowerGoal.cpp b/Minecraft.World/AI/Goals/TakeFlowerGoal.cpp index e4e9ed042..7c3a49f44 100644 --- a/Minecraft.World/AI/Goals/TakeFlowerGoal.cpp +++ b/Minecraft.World/AI/Goals/TakeFlowerGoal.cpp @@ -22,10 +22,10 @@ bool TakeFlowerGoal::canUse() { if (villager->getAge() >= 0) return false; if (!villager->level->isDay()) return false; - AABB villager_bb = villager->bb->grow(6, 2, 6); + AABB villager_bb = villager->bb.grow(6, 2, 6); std::vector >* golems = villager->level->getEntitiesOfClass(typeid(VillagerGolem), - &villager_bb); + &villager_bb); if (golems->size() == 0) { delete golems; return false; diff --git a/Minecraft.World/AI/Navigation/PathFinder.cpp b/Minecraft.World/AI/Navigation/PathFinder.cpp index 20a730c4a..429b99302 100644 --- a/Minecraft.World/AI/Navigation/PathFinder.cpp +++ b/Minecraft.World/AI/Navigation/PathFinder.cpp @@ -33,7 +33,7 @@ PathFinder::~PathFinder() { } Path* PathFinder::findPath(Entity* from, Entity* to, float maxDist) { - return findPath(from, to->x, to->bb->y0, to->z, maxDist); + return findPath(from, to->x, to->bb.y0, to->z, maxDist); } Path* PathFinder::findPath(Entity* from, int x, int y, int z, float maxDist) { @@ -46,9 +46,9 @@ Path* PathFinder::findPath(Entity* e, double xt, double yt, double zt, nodes.clear(); bool resetAvoidWater = avoidWater; - int startY = Mth::floor(e->bb->y0 + 0.5f); + int startY = Mth::floor(e->bb.y0 + 0.5f); if (canFloat && e->isInWater()) { - startY = (int)(e->bb->y0); + startY = (int)(e->bb.y0); int tileId = level->getTile((int)Mth::floor(e->x), startY, (int)Mth::floor(e->z)); while (tileId == Tile::water_Id || tileId == Tile::calmWater_Id) { @@ -59,9 +59,9 @@ Path* PathFinder::findPath(Entity* e, double xt, double yt, double zt, resetAvoidWater = avoidWater; avoidWater = false; } else - startY = Mth::floor(e->bb->y0 + 0.5f); + startY = Mth::floor(e->bb.y0 + 0.5f); - Node* from = getNode((int)floor(e->bb->x0), startY, (int)floor(e->bb->z0)); + Node* from = getNode((int)floor(e->bb.x0), startY, (int)floor(e->bb.z0)); Node* to = getNode((int)floor(xt - e->bbWidth / 2), (int)floor(yt), (int)floor(zt - e->bbWidth / 2)); diff --git a/Minecraft.World/AI/Navigation/PathNavigation.cpp b/Minecraft.World/AI/Navigation/PathNavigation.cpp index 62547c4f0..fc03d1948 100644 --- a/Minecraft.World/AI/Navigation/PathNavigation.cpp +++ b/Minecraft.World/AI/Navigation/PathNavigation.cpp @@ -188,9 +188,9 @@ Vec3 PathNavigation::getTempMobPos() { } int PathNavigation::getSurfaceY() { - if (!mob->isInWater() || !canFloat) return (int)(mob->bb->y0 + 0.5); + if (!mob->isInWater() || !canFloat) return (int)(mob->bb.y0 + 0.5); - int surface = (int)(mob->bb->y0); + int surface = (int)(mob->bb.y0); int tileId = level->getTile(Mth::floor(mob->x), surface, Mth::floor(mob->z)); int steps = 0; @@ -198,7 +198,7 @@ int PathNavigation::getSurfaceY() { ++surface; tileId = level->getTile(Mth::floor(mob->x), surface, Mth::floor(mob->z)); - if (++steps > 16) return (int)(mob->bb->y0); + if (++steps > 16) return (int)(mob->bb.y0); } return surface; } @@ -212,7 +212,7 @@ bool PathNavigation::isInLiquid() { } void PathNavigation::trimPathFromSun() { - if (level->canSeeSky(Mth::floor(mob->x), (int)(mob->bb->y0 + 0.5), + if (level->canSeeSky(Mth::floor(mob->x), (int)(mob->bb.y0 + 0.5), Mth::floor(mob->z))) return; diff --git a/Minecraft.World/Blocks/FallingTile.cpp b/Minecraft.World/Blocks/FallingTile.cpp index a57aa58d2..eb7adda42 100644 --- a/Minecraft.World/Blocks/FallingTile.cpp +++ b/Minecraft.World/Blocks/FallingTile.cpp @@ -168,7 +168,7 @@ void FallingTile::causeFallDamage(float distance) { // entities (invalidating our iterator) std::vector >* entities = new std::vector >( - *level->getEntities(shared_from_this(), bb)); + *level->getEntities(shared_from_this(), &bb)); DamageSource* source = tile == Tile::anvil_Id ? DamageSource::anvil : DamageSource::fallingBlock; @@ -242,4 +242,4 @@ Level* FallingTile::getLevel() { return level; } void FallingTile::setHurtsEntities(bool value) { this->hurtEntities = value; } -bool FallingTile::displayFireAnimation() { return false; } \ No newline at end of file +bool FallingTile::displayFireAnimation() { return false; } diff --git a/Minecraft.World/Entities/Entity.cpp b/Minecraft.World/Entities/Entity.cpp index d07f16799..216e49beb 100644 --- a/Minecraft.World/Entities/Entity.cpp +++ b/Minecraft.World/Entities/Entity.cpp @@ -268,7 +268,7 @@ void Entity::_init(bool useSmallId, Level* level) { xd = yd = zd = 0.0; yRot = xRot = 0.0f; yRotO = xRotO = 0.0f; - bb = new AABB(0, 0, 0, 0, 0, 0); // 4J Was final + bb = AABB(0, 0, 0, 0, 0, 0); // 4J Was final onGround = false; horizontalCollision = verticalCollision = false; collision = false; @@ -376,7 +376,6 @@ Entity::Entity(Level* level, Entity::~Entity() { freeSmallId(entityId); delete random; - delete bb; } std::shared_ptr Entity::getEntityData() { @@ -402,7 +401,7 @@ void Entity::resetPos() { std::shared_ptr sharedThis = shared_from_this(); while (true && y > 0) { setPos(x, y, z); - if (level->getCubes(sharedThis, bb)->empty()) break; + if (level->getCubes(sharedThis, &bb)->empty()) break; y += 1; } @@ -419,9 +418,9 @@ void Entity::setSize(float w, float h) { bbWidth = w; bbHeight = h; - bb->x1 = bb->x0 + bbWidth; - bb->z1 = bb->z0 + bbWidth; - bb->y1 = bb->y0 + bbHeight; + bb.x1 = bb.x0 + bbWidth; + bb.z1 = bb.z0 + bbWidth; + bb.y1 = bb.y0 + bbHeight; if (bbWidth > oldW && !firstTick && !level->isClientSide) { move(oldW - bbWidth, 0, oldW - bbWidth); @@ -463,7 +462,7 @@ void Entity::setPos(double x, double y, double z) { this->z = z; float w = bbWidth / 2; float h = bbHeight; - *bb = {x - w, y - heightOffset + ySlideOffset, z - w, x + w, + bb = {x - w, y - heightOffset + ySlideOffset, z - w, x + w, y - heightOffset + ySlideOffset + h, z + w}; } @@ -551,7 +550,7 @@ void Entity::baseTick() { if (t > 0) { level->addParticle(PARTICLE_TILECRACK(t, d), x + (random->nextFloat() - 0.5) * bbWidth, - bb->y0 + 0.1, + bb.y0 + 0.1, z + (random->nextFloat() - 0.5) * bbWidth, -xd * 4, 1.5, -zd * 4); } @@ -618,7 +617,7 @@ void Entity::clearFire() { onFire = 0; } void Entity::outOfWorld() { remove(); } bool Entity::isFree(float xa, float ya, float za, float grow) { - AABB box = bb->grow(grow, grow, grow).move(xa, ya, za); + AABB box = bb.grow(grow, grow, grow).move(xa, ya, za); AABBList* aABBs = level->getCubes(shared_from_this(), &box); if (!aABBs->empty()) return false; if (level->containsAnyLiquid(&box)) return false; @@ -626,7 +625,7 @@ bool Entity::isFree(float xa, float ya, float za, float grow) { } bool Entity::isFree(double xa, double ya, double za) { - AABB box = bb->move(xa, ya, za); + AABB box = bb.move(xa, ya, za); AABBList* aABBs = level->getCubes(shared_from_this(), &box); if (!aABBs->empty()) return false; if (level->containsAnyLiquid(&box)) return false; @@ -637,10 +636,10 @@ void Entity::move(double xa, double ya, double za, bool noEntityCubes) // 4J - added noEntityCubes parameter { if (noPhysics) { - *bb = bb->move(xa, ya, za); - x = (bb->x0 + bb->x1) / 2.0f; - y = bb->y0 + heightOffset - ySlideOffset; - z = (bb->z0 + bb->z1) / 2.0f; + bb = bb.move(xa, ya, za); + x = (bb.x0 + bb.x1) / 2.0f; + y = bb.y0 + heightOffset - ySlideOffset; + z = (bb.z0 + bb.z1) / 2.0f; return; } @@ -665,15 +664,13 @@ void Entity::move(double xa, double ya, double za, double yaOrg = ya; double zaOrg = za; - AABB bbOrg = *bb; - bool isPlayerSneaking = onGround && isSneaking() && instanceof(eTYPE_PLAYER); if (isPlayerSneaking) { double d = 0.05; - AABB translated_bb = bb->move(xa, -1.0, 0.0); + AABB translated_bb = bb.move(xa, -1.0, 0.0); while (xa != 0 && level->getCubes(shared_from_this(), &translated_bb)->empty()) { if (xa < d && xa >= -d) @@ -685,7 +682,7 @@ void Entity::move(double xa, double ya, double za, xaOrg = xa; } - translated_bb = bb->move(0, -1.0, za); + translated_bb = bb.move(0, -1.0, za); while (za != 0 && level->getCubes(shared_from_this(), &translated_bb)->empty()) { if (za < d && za >= -d) @@ -697,7 +694,7 @@ void Entity::move(double xa, double ya, double za, zaOrg = za; } - translated_bb = bb->move(xa, -1.0, za); + translated_bb = bb.move(xa, -1.0, za); while (xa != 0 && za != 0 && level->getCubes(shared_from_this(), &translated_bb)->empty()) { if (xa < d && xa >= -d) @@ -717,7 +714,7 @@ void Entity::move(double xa, double ya, double za, } } - AABB expanded = bb->expand(xa, ya, za); + AABB expanded = bb.expand(xa, ya, za); AABBList* aABBs = level->getCubes(shared_from_this(), &expanded, noEntityCubes, true); @@ -733,8 +730,8 @@ void Entity::move(double xa, double ya, double za, // But if we don't have the chunk data then all the collision info will // be incorrect as well for (AUTO_VAR(it, aABBs->begin()); it != itEndAABB; it++) - ya = it->clipYCollide(*bb, ya); - *bb = bb->move(0, ya, 0); + ya = it->clipYCollide(bb, ya); + bb = bb.move(0, ya, 0); } if (!slide && yaOrg != ya) { @@ -745,9 +742,9 @@ void Entity::move(double xa, double ya, double za, itEndAABB = aABBs->end(); for (AUTO_VAR(it, aABBs->begin()); it != itEndAABB; it++) - xa = it->clipXCollide(*bb, xa); + xa = it->clipXCollide(bb, xa); - *bb = bb->move(xa, 0, 0); + bb = bb.move(xa, 0, 0); if (!slide && xaOrg != xa) { xa = ya = za = 0; @@ -755,8 +752,8 @@ void Entity::move(double xa, double ya, double za, itEndAABB = aABBs->end(); for (AUTO_VAR(it, aABBs->begin()); it != itEndAABB; it++) - za = it->clipZCollide(*bb, za); - *bb = bb->move(0, 0, za); + za = it->clipZCollide(bb, za); + bb = bb.move(0, 0, za); if (!slide && zaOrg != za) { xa = ya = za = 0; @@ -772,13 +769,11 @@ void Entity::move(double xa, double ya, double za, ya = footSize; za = zaOrg; - AABB normal = *bb; - *bb = bbOrg; // 4J - added extra expand, as if we don't move up by footSize by // hitting a block above us, then overall we could be trying to move as // much as footSize downwards, so we'd better include cubes under our // feet in this list of things we might possibly collide with - AABB expanded = bb->expand(xa, ya, za).expand(0, -ya, 0); + AABB expanded = bb.expand(xa, ya, za).expand(0, -ya, 0); aABBs = level->getCubes(shared_from_this(), &expanded, false, true); // LAND FIRST, then x and z @@ -789,8 +784,8 @@ void Entity::move(double xa, double ya, double za, // all! But if we don't have the chunk data then all the collision // info will be incorrect as well for (AUTO_VAR(it, aABBs->begin()); it != itEndAABB; it++) - ya = it->clipYCollide(*bb, ya); - *bb = bb->move(0, ya, 0); + ya = it->clipYCollide(bb, ya); + bb = bb.move(0, ya, 0); } if (!slide && yaOrg != ya) { @@ -799,8 +794,8 @@ void Entity::move(double xa, double ya, double za, itEndAABB = aABBs->end(); for (AUTO_VAR(it, aABBs->begin()); it != itEndAABB; it++) - xa = it->clipXCollide(*bb, xa); - *bb = bb->move(xa, 0, 0); + xa = it->clipXCollide(bb, xa); + bb = bb.move(xa, 0, 0); if (!slide && xaOrg != xa) { xa = ya = za = 0; @@ -808,8 +803,8 @@ void Entity::move(double xa, double ya, double za, itEndAABB = aABBs->end(); for (AUTO_VAR(it, aABBs->begin()); it != itEndAABB; it++) - za = it->clipZCollide(*bb, za); - *bb = bb->move(0, 0, za); + za = it->clipZCollide(bb, za); + bb = bb.move(0, 0, za); if (!slide && zaOrg != za) { xa = ya = za = 0; @@ -822,21 +817,20 @@ void Entity::move(double xa, double ya, double za, // LAND FIRST, then x and z itEndAABB = aABBs->end(); for (AUTO_VAR(it, aABBs->begin()); it != itEndAABB; it++) - ya = it->clipYCollide(*bb, ya); - *bb = bb->move(0, ya, 0); + ya = it->clipYCollide(bb, ya); + bb = bb.move(0, ya, 0); } if (xaN * xaN + zaN * zaN >= xa * xa + za * za) { xa = xaN; ya = yaN; za = zaN; - *bb = normal; } } - x = (bb->x0 + bb->x1) / 2.0f; - y = bb->y0 + heightOffset - ySlideOffset; - z = (bb->z0 + bb->z1) / 2.0f; + x = (bb.x0 + bb.x1) / 2.0f; + y = bb.y0 + heightOffset - ySlideOffset; + z = (bb.z0 + bb.z1) / 2.0f; horizontalCollision = (xaOrg != xa) || (zaOrg != za); verticalCollision = !m_ignoreVerticalCollisions && (yaOrg != ya); @@ -891,8 +885,8 @@ void Entity::move(double xa, double ya, double za, checkInsideTiles(); bool water = isInWaterOrRain(); - const AABB& shrunk = bb->shrink(0.001, 0.001, 0.001); - if (level->containsFireTile(bb)) { + const AABB& shrunk = bb.shrink(0.001, 0.001, 0.001); + if (level->containsFireTile(&bb)) { burn(1); if (!water) { onFire++; @@ -912,12 +906,12 @@ void Entity::move(double xa, double ya, double za, } void Entity::checkInsideTiles() { - int x0 = Mth::floor(bb->x0 + 0.001); - int y0 = Mth::floor(bb->y0 + 0.001); - int z0 = Mth::floor(bb->z0 + 0.001); - int x1 = Mth::floor(bb->x1 - 0.001); - int y1 = Mth::floor(bb->y1 - 0.001); - int z1 = Mth::floor(bb->z1 - 0.001); + int x0 = Mth::floor(bb.x0 + 0.001); + int y0 = Mth::floor(bb.y0 + 0.001); + int z0 = Mth::floor(bb.z0 + 0.001); + int x1 = Mth::floor(bb.x1 - 0.001); + int y1 = Mth::floor(bb.y1 - 0.001); + int z1 = Mth::floor(bb.z1 - 0.001); if (level->hasChunksAt(x0, y0, z0, x1, y1, z1)) { for (int x = x0; x <= x1; x++) @@ -1000,7 +994,7 @@ bool Entity::isInWaterOrRain() { bool Entity::isInWater() { return wasInWater; } bool Entity::updateInWaterState() { - AABB shrunk = bb->grow(0, -0.4, 0).shrink(0.001, 0.001, 0.001); + AABB shrunk = bb.grow(0, -0.4, 0).shrink(0.001, 0.001, 0.001); if (level->checkAndHandleWater(&shrunk, Material::water, shared_from_this())) { if (!wasInWater && !firstTick && canCreateParticles()) { @@ -1011,7 +1005,7 @@ bool Entity::updateInWaterState() { playSound(eSoundType_RANDOM_SPLASH, speed, 1 + (random->nextFloat() - random->nextFloat()) * 0.4f); MemSect(0); - float yt = (float)Mth::floor(bb->y0); + float yt = (float)Mth::floor(bb.y0); for (int i = 0; i < 1 + bbWidth * 20; i++) { float xo = (random->nextFloat() * 2 - 1) * bbWidth; float zo = (random->nextFloat() * 2 - 1) * bbWidth; @@ -1052,7 +1046,7 @@ bool Entity::isUnderLiquid(Material* material) { float Entity::getHeadHeight() { return 0; } bool Entity::isInLava() { - AABB mat_bounds = bb->grow(-0.1, -0.4, -0.1); + AABB mat_bounds = bb.grow(-0.1, -0.4, -0.1); return level->containsMaterial(&mat_bounds, Material::lava); } @@ -1079,7 +1073,7 @@ int Entity::getLightColor(float a) { int zTile = Mth::floor(z); if (level->hasChunkAt(xTile, 0, zTile)) { - double hh = (bb->y1 - bb->y0) * 0.66; + double hh = (bb.y1 - bb.y0) * 0.66; int yTile = Mth::floor(y - heightOffset + hh); return level->getLightColor(xTile, yTile, zTile, 0); } @@ -1091,7 +1085,7 @@ float Entity::getBrightness(float a) { int xTile = Mth::floor(x); int zTile = Mth::floor(z); if (level->hasChunkAt(xTile, 0, zTile)) { - double hh = (bb->y1 - bb->y0) * 0.66; + double hh = (bb.y1 - bb.y0) * 0.66; int yTile = Mth::floor(y - heightOffset + hh); return level->getBrightness(xTile, yTile, zTile); } @@ -1200,7 +1194,7 @@ bool Entity::hurt(DamageSource* source, float damage) { bool Entity::intersects(double x0, double y0, double z0, double x1, double y1, double z1) { - return bb->intersects(x0, y0, z0, x1, y1, z1); + return bb.intersects(x0, y0, z0, x1, y1, z1); } bool Entity::isPickable() { return false; } @@ -1220,7 +1214,7 @@ bool Entity::shouldRender(Vec3* c) { } bool Entity::shouldRenderAtSqrDistance(double distance) { - double size = bb->getSize(); + double size = bb.getSize(); size *= 64.0f * viewScale; return distance < size * size; } @@ -1497,7 +1491,7 @@ void Entity::ride(std::shared_ptr e) { // 4J Stu - Position should already be updated before the // SetEntityLinkPacket comes in if (!level->isClientSide) - moveTo(riding->x, riding->bb->y0 + riding->bbHeight, riding->z, + moveTo(riding->x, riding->bb.y0 + riding->bbHeight, riding->z, yRot, xRot); riding->rider = std::weak_ptr(); } @@ -1520,7 +1514,7 @@ void Entity::lerpTo(double x, double y, double z, float yRot, float xRot, // its definitely bad news for arrows as they are actually Meant to // intersect the geometry they land in slightly. if (GetType() != eTYPE_ARROW) { - AABB shrunk = bb->shrink(1 / 32.0, 0.0, 1 / 32.0); + AABB shrunk = bb.shrink(1 / 32.0, 0.0, 1 / 32.0); AABBList* collisions = level->getCubes(shared_from_this(), &shrunk); if (!collisions->empty()) { double yTop = 0; @@ -1529,7 +1523,7 @@ void Entity::lerpTo(double x, double y, double z, float yRot, float xRot, if (it->y1 > yTop) yTop = it->y1; } - y += yTop - bb->y0; + y += yTop - bb.y0; setPos(x, y, z); } } @@ -1667,7 +1661,7 @@ bool Entity::checkInTile(double x, double y, double z) { double yd = y - (yTile); double zd = z - (zTile); - auto* cubes = level->getTileCubes(bb); + auto* cubes = level->getTileCubes(&bb); if ((cubes && !cubes->empty()) || level->isFullAABBTile(xTile, yTile, zTile)) { bool west = !level->isFullAABBTile(xTile - 1, yTile, zTile); diff --git a/Minecraft.World/Entities/Entity.h b/Minecraft.World/Entities/Entity.h index df348f5cd..485a2ae57 100644 --- a/Minecraft.World/Entities/Entity.h +++ b/Minecraft.World/Entities/Entity.h @@ -5,6 +5,7 @@ #include "../IO/NBT/FloatTag.h" #include "../Util/Vec3.h" #include "../Util/Definitions.h" +#include "../Util/AABB.h" #include #include @@ -72,7 +73,7 @@ public: double xd, yd, zd; float yRot, xRot; float yRotO, xRotO; - /*const*/ AABB* bb; // 4J Was final + /*const*/ AABB bb; // 4J Was final bool onGround; bool horizontalCollision, verticalCollision; bool collision; diff --git a/Minecraft.World/Entities/FlyingMob.cpp b/Minecraft.World/Entities/FlyingMob.cpp index 752c68047..6a38c457d 100644 --- a/Minecraft.World/Entities/FlyingMob.cpp +++ b/Minecraft.World/Entities/FlyingMob.cpp @@ -34,7 +34,7 @@ void FlyingMob::travel(float xa, float ya) { float friction = 0.91f; if (onGround) { friction = 0.6f * 0.91f; - int t = level->getTile(Mth::floor(x), Mth::floor(bb->y0) - 1, + int t = level->getTile(Mth::floor(x), Mth::floor(bb.y0) - 1, Mth::floor(z)); if (t > 0) { friction = Tile::tiles[t]->friction * 0.91f; @@ -48,7 +48,7 @@ void FlyingMob::travel(float xa, float ya) { friction = 0.91f; if (onGround) { friction = 0.6f * 0.91f; - int t = level->getTile(Mth::floor(x), Mth::floor(bb->y0) - 1, + int t = level->getTile(Mth::floor(x), Mth::floor(bb.y0) - 1, Mth::floor(z)); if (t > 0) { friction = Tile::tiles[t]->friction * 0.91f; @@ -70,4 +70,4 @@ void FlyingMob::travel(float xa, float ya) { walkAnimPos += walkAnimSpeed; } -bool FlyingMob::onLadder() { return false; } \ No newline at end of file +bool FlyingMob::onLadder() { return false; } diff --git a/Minecraft.World/Entities/HangingEntity.cpp b/Minecraft.World/Entities/HangingEntity.cpp index b94d8fdf1..aa693de88 100644 --- a/Minecraft.World/Entities/HangingEntity.cpp +++ b/Minecraft.World/Entities/HangingEntity.cpp @@ -74,8 +74,8 @@ void HangingEntity::setDir(int dir) { float y1 = y + h + ss; float z0 = z - d - ss; float z1 = z + d + ss; - *bb = {std::min(x0, x1), std::min(y0, y1), std::min(z0, z1), - std::max(x0, x1), std::max(y0, y1), std::max(z0, z1)}; + bb = {std::min(x0, x1), std::min(y0, y1), std::min(z0, z1), + std::max(x0, x1), std::max(y0, y1), std::max(z0, z1)}; } float HangingEntity::offs(int w) { @@ -98,7 +98,7 @@ void HangingEntity::tick() { } bool HangingEntity::survives() { - if (level->getCubes(shared_from_this(), bb)->size() != 0) // isEmpty()) + if (level->getCubes(shared_from_this(), &bb)->size() != 0) // isEmpty()) { return false; } else { @@ -128,7 +128,7 @@ bool HangingEntity::survives() { } std::vector >* entities = - level->getEntities(shared_from_this(), bb); + level->getEntities(shared_from_this(), &bb); if (entities != NULL && entities->size() > 0) { AUTO_VAR(itEnd, entities->end()); diff --git a/Minecraft.World/Entities/ItemEntity.cpp b/Minecraft.World/Entities/ItemEntity.cpp index 880971f67..8d4706e39 100644 --- a/Minecraft.World/Entities/ItemEntity.cpp +++ b/Minecraft.World/Entities/ItemEntity.cpp @@ -68,7 +68,7 @@ void ItemEntity::tick() { zo = z; yd -= 0.04f; - noPhysics = checkInTile(x, (bb->y0 + bb->y1) / 2, z); + noPhysics = checkInTile(x, (bb.y0 + bb.y1) / 2, z); // 4J - added parameter here so that these don't care about colliding with // other entities @@ -96,7 +96,7 @@ void ItemEntity::tick() { float friction = 0.98f; if (onGround) { friction = 0.6f * 0.98f; - int t = level->getTile(Mth::floor(x), Mth::floor(bb->y0) - 1, + int t = level->getTile(Mth::floor(x), Mth::floor(bb.y0) - 1, Mth::floor(z)); if (t > 0) { friction = Tile::tiles[t]->friction * 0.98f; @@ -119,7 +119,7 @@ void ItemEntity::tick() { } void ItemEntity::mergeWithNeighbours() { - AABB grown = bb->grow(0.5, 0, 0.5); + AABB grown = bb.grow(0.5, 0, 0.5); std::vector >* neighbours = level->getEntitiesOfClass(typeid(*this), &grown); for (AUTO_VAR(it, neighbours->begin()); it != neighbours->end(); ++it) { @@ -164,7 +164,7 @@ void ItemEntity::setShortLifeTime() { } bool ItemEntity::updateInWaterState() { - return level->checkAndHandleWater(bb, Material::water, shared_from_this()); + return level->checkAndHandleWater(&bb, Material::water, shared_from_this()); } void ItemEntity::burn(int dmg) { hurt(DamageSource::inFire, dmg); } diff --git a/Minecraft.World/Entities/LivingEntity.cpp b/Minecraft.World/Entities/LivingEntity.cpp index c30033456..e0646a26a 100644 --- a/Minecraft.World/Entities/LivingEntity.cpp +++ b/Minecraft.World/Entities/LivingEntity.cpp @@ -897,7 +897,7 @@ void LivingEntity::dropDeathLoot(bool wasKilledByPlayer, int playerBonusLevel) { bool LivingEntity::onLadder() { int xt = Mth::floor(x); - int yt = Mth::floor(bb->y0); + int yt = Mth::floor(bb.y0); int zt = Mth::floor(z); // 4J-PB - TU9 - add climbable vines @@ -1166,7 +1166,7 @@ void LivingEntity::teleportTo(double x, double y, double z) { void LivingEntity::findStandUpPosition(std::shared_ptr vehicle) { AABB boundingBox; double fallbackX = vehicle->x; - double fallbackY = vehicle->bb->y0 + vehicle->bbHeight; + double fallbackY = vehicle->bb.y0 + vehicle->bbHeight; double fallbackZ = vehicle->z; for (double xDiff = -1.5; xDiff < 2; xDiff += 1.5) { @@ -1177,7 +1177,7 @@ void LivingEntity::findStandUpPosition(std::shared_ptr vehicle) { int xToInt = (int)(x + xDiff); int zToInt = (int)(z + zDiff); - boundingBox = bb->move(xDiff, 1, zDiff); + boundingBox = bb.move(xDiff, 1, zDiff); if (level->getTileCubes(&boundingBox, true)->empty()) { if (level->isTopSolidBlocking(xToInt, (int)y, zToInt)) { @@ -1259,7 +1259,7 @@ void LivingEntity::travel(float xa, float ya) { float friction = 0.91f; if (onGround) { friction = 0.6f * 0.91f; - int t = level->getTile(Mth::floor(x), Mth::floor(bb->y0) - 1, + int t = level->getTile(Mth::floor(x), Mth::floor(bb.y0) - 1, Mth::floor(z)); if (t > 0) { friction = Tile::tiles[t]->friction * 0.91f; @@ -1281,7 +1281,7 @@ void LivingEntity::travel(float xa, float ya) { friction = 0.91f; if (onGround) { friction = 0.6f * 0.91f; - int t = level->getTile(Mth::floor(x), Mth::floor(bb->y0) - 1, + int t = level->getTile(Mth::floor(x), Mth::floor(bb.y0) - 1, Mth::floor(z)); if (t > 0) { friction = Tile::tiles[t]->friction * 0.91f; @@ -1337,13 +1337,13 @@ void LivingEntity::travel(float xa, float ya) { // and out of lit areas, for example when bobbing in the water. int LivingEntity::getLightColor(float a) { float accum[2] = {0, 0}; - float totVol = (bb->x1 - bb->x0) * (bb->y1 - bb->y0) * (bb->z1 - bb->z0); - int xmin = Mth::floor(bb->x0); - int xmax = Mth::floor(bb->x1); - int ymin = Mth::floor(bb->y0); - int ymax = Mth::floor(bb->y1); - int zmin = Mth::floor(bb->z0); - int zmax = Mth::floor(bb->z1); + float totVol = (bb.x1 - bb.x0) * (bb.y1 - bb.y0) * (bb.z1 - bb.z0); + int xmin = Mth::floor(bb.x0); + int xmax = Mth::floor(bb.x1); + int ymin = Mth::floor(bb.y0); + int ymax = Mth::floor(bb.y1); + int zmin = Mth::floor(bb.z0); + int zmax = Mth::floor(bb.z1); for (int xt = xmin; xt <= xmax; xt++) for (int yt = ymin; yt <= ymax; yt++) for (int zt = zmin; zt <= zmax; zt++) { @@ -1353,12 +1353,12 @@ int LivingEntity::getLightColor(float a) { float tileymax = (float)(yt + 1); float tilezmin = (float)zt; float tilezmax = (float)(zt + 1); - if (tilexmin < bb->x0) tilexmin = bb->x0; - if (tilexmax > bb->x1) tilexmax = bb->x1; - if (tileymin < bb->y0) tileymin = bb->y0; - if (tileymax > bb->y1) tileymax = bb->y1; - if (tilezmin < bb->z0) tilezmin = bb->z0; - if (tilezmax > bb->z1) tilezmax = bb->z1; + if (tilexmin < bb.x0) tilexmin = bb.x0; + if (tilexmax > bb.x1) tilexmax = bb.x1; + if (tileymin < bb.y0) tileymin = bb.y0; + if (tileymax > bb.y1) tileymax = bb.y1; + if (tilezmin < bb.z0) tilezmin = bb.z0; + if (tilezmax > bb.z1) tilezmax = bb.z1; float tileVol = (tilexmax - tilexmin) * (tileymax - tileymin) * (tilezmax - tilezmin); float frac = tileVol / totVol; @@ -1508,10 +1508,10 @@ void LivingEntity::aiStep() { // 4J - this collision is carried out to try and stop the lerping push // the mob through the floor, in which case gravity can then carry on // moving the mob because the collision just won't work anymore. BB for - // collision used to be calculated as: bb->shrink(1 / 32.0, 0, 1 / 32.0) + // collision used to be calculated as: bb.shrink(1 / 32.0, 0, 1 / 32.0) // now using a reduced BB to try and get rid of some issues where mobs // pop up the sides of walls, undersides of trees etc. - AABB shrinkbb = bb->shrink(0.1, 0, 0.1); + AABB shrinkbb = bb.shrink(0.1, 0, 0.1); shrinkbb.y1 = shrinkbb.y0 + 0.1; AABBList* collisions = level->getCubes(shared_from_this(), &shrinkbb); if (collisions->size() > 0) { @@ -1521,7 +1521,7 @@ void LivingEntity::aiStep() { if (it->y1 > yTop) yTop = it->y1; } - yt += yTop - bb->y0; + yt += yTop - bb.y0; setPos(xt, yt, zt); } } else if (!isEffectiveAi()) { @@ -1581,7 +1581,7 @@ void LivingEntity::aiStep() { void LivingEntity::newServerAiStep() {} void LivingEntity::pushEntities() { - AABB grown = bb->grow(0.2, 0, 0.2); + AABB grown = bb.grow(0.2, 0, 0.2); std::vector >* entities = level->getEntities(shared_from_this(), &grown); if (entities != NULL && !entities->empty()) { diff --git a/Minecraft.World/Entities/MinecartHopper.cpp b/Minecraft.World/Entities/MinecartHopper.cpp index 43707b810..ef70622c7 100644 --- a/Minecraft.World/Entities/MinecartHopper.cpp +++ b/Minecraft.World/Entities/MinecartHopper.cpp @@ -85,7 +85,7 @@ void MinecartHopper::tick() { bool MinecartHopper::suckInItems() { if (HopperTileEntity::suckInItems(this)) return true; - AABB grown = bb->grow(0.25, 0, 0.25); + AABB grown = bb.grow(0.25, 0, 0.25); std::vector >* items = level->getEntitiesOfClass(typeid(ItemEntity), &grown, EntitySelector::ENTITY_STILL_ALIVE); diff --git a/Minecraft.World/Entities/Mob.cpp b/Minecraft.World/Entities/Mob.cpp index b7fe61e1a..4ebcf21ac 100644 --- a/Minecraft.World/Entities/Mob.cpp +++ b/Minecraft.World/Entities/Mob.cpp @@ -301,7 +301,7 @@ void Mob::aiStep() { if (!level->isClientSide && canPickUpLoot() && !dead && level->getGameRules()->getBoolean(GameRules::RULE_MOBGRIEFING)) { - AABB grown = bb->grow(1, 0, 1); + AABB grown = bb.grow(1, 0, 1); std::vector >* entities = level->getEntitiesOfClass(typeid(ItemEntity), &grown); for (AUTO_VAR(it, entities->begin()); it != entities->end(); ++it) { @@ -499,7 +499,7 @@ void Mob::lookAt(std::shared_ptr e, float yMax, float xMax) { std::dynamic_pointer_cast(e); yd = (mob->y + mob->getHeadHeight()) - (y + getHeadHeight()); } else { - yd = (e->bb->y0 + e->bb->y1) / 2 - (y + getHeadHeight()); + yd = (e->bb.y0 + e->bb.y1) / 2 - (y + getHeadHeight()); } double sd = Mth::sqrt(xd * xd + zd * zd); @@ -527,9 +527,9 @@ float Mob::rotlerp(float a, float b, float max) { bool Mob::canSpawn() { // 4J - altered to use special containsAnyLiquid variant - return level->isUnobstructed(bb) && - level->getCubes(shared_from_this(), bb)->empty() && - !level->containsAnyLiquid_NoLoad(bb); + return level->isUnobstructed(&bb) && + level->getCubes(shared_from_this(), &bb)->empty() && + !level->containsAnyLiquid_NoLoad(&bb); } float Mob::getSizeScale() { return 1.0f; } @@ -848,7 +848,7 @@ void Mob::restoreLeashFromSave() { if (_isLeashed && leashInfoTag != NULL) { if (leashInfoTag->contains(L"UUID")) { std::wstring leashUuid = leashInfoTag->getString(L"UUID"); - AABB grown = bb->grow(10, 10, 10); + AABB grown = bb.grow(10, 10, 10); std::vector >* livingEnts = level->getEntitiesOfClass(typeid(LivingEntity), &grown); @@ -889,9 +889,9 @@ void Mob::restoreLeashFromSave() { // resolve bug 10327 :Gameplay: NPCs can spawn over chunks that have not yet // been streamed and display jitter. bool Mob::shouldRender(Vec3* c) { - if (!level->reallyHasChunksAt(Mth::floor(bb->x0), Mth::floor(bb->y0), - Mth::floor(bb->z0), Mth::floor(bb->x1), - Mth::floor(bb->y1), Mth::floor(bb->z1))) { + if (!level->reallyHasChunksAt(Mth::floor(bb.x0), Mth::floor(bb.y0), + Mth::floor(bb.z0), Mth::floor(bb.x1), + Mth::floor(bb.y1), Mth::floor(bb.z1))) { return false; } return Entity::shouldRender(c); diff --git a/Minecraft.World/Entities/Mobs/Animal.cpp b/Minecraft.World/Entities/Mobs/Animal.cpp index 8df5245d2..a2ce25b5b 100644 --- a/Minecraft.World/Entities/Mobs/Animal.cpp +++ b/Minecraft.World/Entities/Mobs/Animal.cpp @@ -216,7 +216,7 @@ std::shared_ptr Animal::findAttackTarget() { float r = 8; if (getInLoveValue() > 0) { - AABB grown = bb->grow(r, r, r); + AABB grown = bb.grow(r, r, r); std::vector >* others = level->getEntitiesOfClass(typeid(*this), &grown); // for (int i = 0; i < others->size(); i++) @@ -230,7 +230,7 @@ std::shared_ptr Animal::findAttackTarget() { delete others; } else { if (getAge() == 0) { - AABB grown = bb->grow(r, r, r); + AABB grown = bb.grow(r, r, r); std::vector >* players = level->getEntitiesOfClass(typeid(Player), &grown); // for (int i = 0; i < players.size(); i++) @@ -247,7 +247,7 @@ std::shared_ptr Animal::findAttackTarget() { } delete players; } else if (getAge() > 0) { - AABB grown = bb->grow(r, r, r); + AABB grown = bb.grow(r, r, r); std::vector >* others = level->getEntitiesOfClass(typeid(*this), &grown); // for (int i = 0; i < others.size(); i++) @@ -267,7 +267,7 @@ std::shared_ptr Animal::findAttackTarget() { bool Animal::canSpawn() { int xt = Mth::floor(x); - int yt = Mth::floor(bb->y0); + int yt = Mth::floor(bb.y0); int zt = Mth::floor(z); return level->getTile(xt, yt - 1, zt) == Tile::grass_Id && level->getDaytimeRawBrightness(xt, yt, zt) > 8 && diff --git a/Minecraft.World/Entities/Mobs/Arrow.cpp b/Minecraft.World/Entities/Mobs/Arrow.cpp index 471ee3a2e..4c8977b66 100644 --- a/Minecraft.World/Entities/Mobs/Arrow.cpp +++ b/Minecraft.World/Entities/Mobs/Arrow.cpp @@ -230,7 +230,7 @@ void Arrow::tick() { } std::shared_ptr hitEntity = nullptr; - AABB grown = bb->expand(xd, yd, zd).grow(1, 1, 1); + AABB grown = bb.expand(xd, yd, zd).grow(1, 1, 1); std::vector >* objects = level->getEntities(shared_from_this(), &grown); double nearest = 0; @@ -240,7 +240,7 @@ void Arrow::tick() { if (!e->isPickable() || (e == owner && flightTime < 5)) continue; float rr = 0.3f; - AABB bb = e->bb->grow(rr, rr, rr); + AABB bb = e->bb.grow(rr, rr, rr); HitResult* p = bb.clip(from, to); if (p != NULL) { double dd = from.distanceTo(p->pos); diff --git a/Minecraft.World/Entities/Mobs/Bat.cpp b/Minecraft.World/Entities/Mobs/Bat.cpp index 43c180678..5835875af 100644 --- a/Minecraft.World/Entities/Mobs/Bat.cpp +++ b/Minecraft.World/Entities/Mobs/Bat.cpp @@ -185,7 +185,7 @@ void Bat::addAdditonalSaveData(CompoundTag* entityTag) { } bool Bat::canSpawn() { - int yt = Mth::floor(bb->y0); + int yt = Mth::floor(bb.y0); if (yt >= level->seaLevel) return false; int xt = Mth::floor(x); @@ -205,4 +205,4 @@ bool Bat::canSpawn() { if (br > random->nextInt(maxLight)) return false; return AmbientCreature::canSpawn(); -} \ No newline at end of file +} diff --git a/Minecraft.World/Entities/Mobs/Blaze.cpp b/Minecraft.World/Entities/Mobs/Blaze.cpp index 2ac264dbd..ce7fec922 100644 --- a/Minecraft.World/Entities/Mobs/Blaze.cpp +++ b/Minecraft.World/Entities/Mobs/Blaze.cpp @@ -93,14 +93,14 @@ void Blaze::aiStep() { } void Blaze::checkHurtTarget(std::shared_ptr target, float d) { - if (attackTime <= 0 && d < 2.0f && target->bb->y1 > bb->y0 && - target->bb->y0 < bb->y1) { + if (attackTime <= 0 && d < 2.0f && target->bb.y1 > bb.y0 && + target->bb.y0 < bb.y1) { attackTime = 20; doHurtTarget(target); } else if (d < 30) { double xd = target->x - x; double yd = - (target->bb->y0 + target->bbHeight / 2) - (y + bbHeight / 2); + (target->bb.y0 + target->bbHeight / 2) - (y + bbHeight / 2); double zd = target->z - z; if (attackTime == 0) { @@ -181,4 +181,4 @@ void Blaze::setCharged(bool value) { entityData->set(DATA_FLAGS_ID, flags); } -bool Blaze::isDarkEnoughToSpawn() { return true; } \ No newline at end of file +bool Blaze::isDarkEnoughToSpawn() { return true; } diff --git a/Minecraft.World/Entities/Mobs/Boat.cpp b/Minecraft.World/Entities/Mobs/Boat.cpp index d04c7f33e..4b21065e9 100644 --- a/Minecraft.World/Entities/Mobs/Boat.cpp +++ b/Minecraft.World/Entities/Mobs/Boat.cpp @@ -44,10 +44,10 @@ void Boat::defineSynchedData() { } AABB* Boat::getCollideAgainstBox(std::shared_ptr entity) { - return entity->bb; + return &entity->bb; } -AABB* Boat::getCollideBox() { return bb; } +AABB* Boat::getCollideBox() { return &bb; } bool Boat::isPushable() { return true; } @@ -165,9 +165,9 @@ void Boat::tick() { int steps = 5; double waterPercentage = 0; for (int i = 0; i < steps; i++) { - double y0 = bb->y0 + (bb->y1 - bb->y0) * (i + 0) / steps - 2 / 16.0f; - double y1 = bb->y0 + (bb->y1 - bb->y0) * (i + 1) / steps - 2 / 16.0f; - AABB bb2(bb->x0, y0, bb->z0, bb->x1, y1, bb->z1); + double y0 = bb.y0 + (bb.y1 - bb.y0) * (i + 0) / steps - 2 / 16.0f; + double y1 = bb.y0 + (bb.y1 - bb.y0) * (i + 1) / steps - 2 / 16.0f; + AABB bb2(bb.x0, y0, bb.z0, bb.x1, y1, bb.z1); if (level->containsLiquid(&bb2, Material::water)) { waterPercentage += 1.0 / steps; } @@ -345,7 +345,7 @@ void Boat::tick() { if (level->isClientSide) return; - AABB grown = bb->grow(0.2, 0, 0.2); + AABB grown = bb.grow(0.2, 0, 0.2); std::vector >* entities = level->getEntities(shared_from_this(), &grown); if (entities != NULL && !entities->empty()) { diff --git a/Minecraft.World/Entities/Mobs/DragonFireball.cpp b/Minecraft.World/Entities/Mobs/DragonFireball.cpp index 11607882a..19486ffbe 100644 --- a/Minecraft.World/Entities/Mobs/DragonFireball.cpp +++ b/Minecraft.World/Entities/Mobs/DragonFireball.cpp @@ -29,7 +29,7 @@ DragonFireball::DragonFireball(Level* level, double x, double y, double z, void DragonFireball::onHit(HitResult* res) { if (!level->isClientSide) { - AABB aoe = bb->grow(SPLASH_RANGE, SPLASH_RANGE / 2, SPLASH_RANGE); + AABB aoe = bb.grow(SPLASH_RANGE, SPLASH_RANGE / 2, SPLASH_RANGE); std::vector >* entitiesOfClass = level->getEntitiesOfClass(typeid(LivingEntity), &aoe); diff --git a/Minecraft.World/Entities/Mobs/EnderDragon.cpp b/Minecraft.World/Entities/Mobs/EnderDragon.cpp index abcab5c46..7aa192c13 100644 --- a/Minecraft.World/Entities/Mobs/EnderDragon.cpp +++ b/Minecraft.World/Entities/Mobs/EnderDragon.cpp @@ -73,7 +73,7 @@ void EnderDragon::_init() { m_actionTicks = 0; m_sittingDamageReceived = 0; m_headYRot = 0.0; - m_acidArea = new AABB(-4, -10, -3, 6, 3, 3); + m_acidArea = AABB(-4, -10, -3, 6, 3, 3); m_flameAttacks = 0; for (int i = 0; i < positionsLength; i++) { @@ -324,7 +324,7 @@ void EnderDragon::aiStep() { { xP = head->x; // - vN->x * d; yP = - head->bb->y0 + + head->bb.y0 + head->bbHeight / 2; // - vN->y * d; //head->y + // head->bbHeight / 2 + 0.5f - v->y * d; @@ -346,7 +346,7 @@ void EnderDragon::aiStep() { for (unsigned int j = 0; j < 6; ++j) { xP = head->x; // - vN->x * d; yP = - head->bb->y0 + + head->bb.y0 + head->bbHeight / 2; // - vN->y * d; //head->y + // head->bbHeight / 2 + 0.5f - v->y * d; @@ -462,7 +462,7 @@ void EnderDragon::aiStep() { getSynchedAction() == e_EnderdragonAction_Landing) { if (m_actionTicks < (FLAME_TICKS - 10)) { std::vector >* targets = - level->getEntities(shared_from_this(), m_acidArea); + level->getEntities(shared_from_this(), &m_acidArea); for (AUTO_VAR(it, targets->begin()); it != targets->end(); ++it) { @@ -491,7 +491,7 @@ void EnderDragon::aiStep() { if (angleDegs < 0 || angleDegs > 10) { double xdd = attackTarget->x - head->x; - // double ydd = (attackTarget->bb->y0 + + // double ydd = (attackTarget->bb.y0 + // attackTarget->bbHeight / 2) - (head->y + head->bbHeight / // 2); double zdd = attackTarget->z - head->z; @@ -541,7 +541,7 @@ void EnderDragon::aiStep() { double sd = sqrt(xd * xd + zd * zd); double ho = 0.4f + sd / 80.0f - 1; if (ho > 10) ho = 10; - yTarget = attackTarget->bb->y0 + ho; + yTarget = attackTarget->bb.y0 + ho; } else { // xTarget += random->nextGaussian() * 2; // zTarget += random->nextGaussian() * 2; @@ -646,13 +646,13 @@ void EnderDragon::aiStep() { if (!level->isClientSide) checkAttack(); if (!level->isClientSide && hurtDuration == 0) { - AABB wing_mov = wing1->bb->grow(4, 2, 4).move(0, -2, 0); + AABB wing_mov = wing1->bb.grow(4, 2, 4).move(0, -2, 0); knockBack(level->getEntities(shared_from_this(), &wing_mov)); - wing_mov = wing2->bb->grow(4, 2, 4).move(0, -2, 0); + wing_mov = wing2->bb.grow(4, 2, 4).move(0, -2, 0); knockBack(level->getEntities(shared_from_this(), &wing_mov)); - AABB neck_bb = neck->bb->grow(1, 1, 1); - AABB head_bb = head->bb->grow(1, 1, 1); + AABB neck_bb = neck->bb.grow(1, 1, 1); + AABB head_bb = head->bb.grow(1, 1, 1); hurt(level->getEntities(shared_from_this(), &neck_bb)); hurt(level->getEntities(shared_from_this(), &head_bb)); } @@ -687,19 +687,19 @@ void EnderDragon::aiStep() { double acidX = x + ss * 9.5f * ccTilt; double acidY = y + yOffset + ssTilt * 10.5f; double acidZ = z - cc * 9.5f * ccTilt; - *m_acidArea = {acidX - 5, acidY - 17, acidZ - 5, + m_acidArea = {acidX - 5, acidY - 17, acidZ - 5, acidX + 5, acidY + 4, acidZ + 5}; // app.DebugPrintf("\nDragon is %s, yRot = %f, yRotA = %f, ss = %f, cc = // %f, ccTilt = %f\n",level->isClientSide?"client":"server", yRot, // yRotA, ss, cc, ccTilt); app.DebugPrintf("Body (%f,%f,%f) to - // (%f,%f,%f)\n", body->bb->x0, body->bb->y0, body->bb->z0, - // body->bb->x1, body->bb->y1, body->bb->z1); app.DebugPrintf("Neck - // (%f,%f,%f) to (%f,%f,%f)\n", neck->bb->x0, neck->bb->y0, - // neck->bb->z0, neck->bb->x1, neck->bb->y1, neck->bb->z1); - // app.DebugPrintf("Head (%f,%f,%f) to (%f,%f,%f)\n", head->bb->x0, - // head->bb->y0, head->bb->z0, head->bb->x1, head->bb->y1, - // head->bb->z1); app.DebugPrintf("Acid (%f,%f,%f) to (%f,%f,%f)\n\n", + // (%f,%f,%f)\n", body->bb.x0, body->bb.y0, body->bb.z0, + // body->bb.x1, body->bb.y1, body->bb.z1); app.DebugPrintf("Neck + // (%f,%f,%f) to (%f,%f,%f)\n", neck->bb.x0, neck->bb.y0, + // neck->bb.z0, neck->bb.x1, neck->bb.y1, neck->bb.z1); + // app.DebugPrintf("Head (%f,%f,%f) to (%f,%f,%f)\n", head->bb.x0, + // head->bb.y0, head->bb.z0, head->bb.x1, head->bb.y1, + // head->bb.z1); app.DebugPrintf("Acid (%f,%f,%f) to (%f,%f,%f)\n\n", // m_acidArea->x0, m_acidArea->y0, m_acidArea->z0, m_acidArea->x1, // m_acidArea->y1, m_acidArea->z1); } @@ -757,7 +757,7 @@ void EnderDragon::aiStep() { double xdd = attackTarget->x - startingX; double ydd = - (attackTarget->bb->y0 + attackTarget->bbHeight / 2) - + (attackTarget->bb.y0 + attackTarget->bbHeight / 2) - (startingY + head->bbHeight / 2); double zdd = attackTarget->z - startingZ; @@ -795,7 +795,7 @@ void EnderDragon::aiStep() { if (!level->isClientSide) { inWall = - checkWalls(head->bb) | checkWalls(neck->bb) | checkWalls(body->bb); + checkWalls(&head->bb) | checkWalls(&neck->bb) | checkWalls(&body->bb); } } @@ -814,7 +814,7 @@ void EnderDragon::checkCrystals() { if (random->nextInt(10) == 0) { float maxDist = 32; - AABB grown = bb->grow(maxDist, maxDist, maxDist); + AABB grown = bb.grow(maxDist, maxDist, maxDist); std::vector >* crystals = level->getEntitiesOfClass(typeid(EnderCrystal), &grown); @@ -851,9 +851,9 @@ void EnderDragon::checkAttack() { } void EnderDragon::knockBack(std::vector >* entities) { - double xm = (body->bb->x0 + body->bb->x1) / 2; + double xm = (body->bb.x0 + body->bb.x1) / 2; // double ym = (body.bb.y0 + body.bb.y1) / 2; - double zm = (body->bb->z0 + body->bb->z1) / 2; + double zm = (body->bb.z0 + body->bb.z1) / 2; // for (Entity e : entities) for (AUTO_VAR(it, entities->begin()); it != entities->end(); ++it) { @@ -1475,7 +1475,7 @@ void EnderDragon::strafeAttackTarget() { double sd = sqrt(xd * xd + zd * zd); double ho = 0.4f + sd / 80.0f - 1; if (ho > 10) ho = 10; - int finalYTarget = attackTarget->bb->y0 + ho; + int finalYTarget = attackTarget->bb.y0 + ho; Node finalNode(finalXTarget, finalYTarget, finalZTarget); diff --git a/Minecraft.World/Entities/Mobs/EnderDragon.h b/Minecraft.World/Entities/Mobs/EnderDragon.h index e8270dcae..1e8479407 100644 --- a/Minecraft.World/Entities/Mobs/EnderDragon.h +++ b/Minecraft.World/Entities/Mobs/EnderDragon.h @@ -59,7 +59,7 @@ private: int m_iGrowlTimer; double m_headYRot; - AABB* m_acidArea; + AABB m_acidArea; NodeArray* m_nodes; int m_nodeAdjacency[24]; diff --git a/Minecraft.World/Entities/Mobs/EnderMan.cpp b/Minecraft.World/Entities/Mobs/EnderMan.cpp index 9762254f9..c83c478f5 100644 --- a/Minecraft.World/Entities/Mobs/EnderMan.cpp +++ b/Minecraft.World/Entities/Mobs/EnderMan.cpp @@ -117,7 +117,7 @@ bool EnderMan::isLookingAtMe(std::shared_ptr player) { Vec3 look = player->getViewVector(1).normalize(); Vec3 dir{x - player->x, - (bb->y0 + bbHeight / 2) - (player->y + player->getHeadHeight()), + (bb.y0 + bbHeight / 2) - (player->y + player->getHeadHeight()), z - player->z}; double dist = dir.length(); @@ -250,7 +250,7 @@ bool EnderMan::teleport() { } bool EnderMan::teleportTowards(std::shared_ptr e) { - Vec3 dir{x - e->x, bb->y0 + bbHeight / 2 - e->y + e->getHeadHeight(), + Vec3 dir{x - e->x, bb.y0 + bbHeight / 2 - e->y + e->getHeadHeight(), z - e->z}; dir = dir.normalize(); double d = 16; @@ -286,8 +286,8 @@ bool EnderMan::teleport(double xx, double yy, double zz) { } if (landed) { setPos(x, y, z); - if (level->getCubes(shared_from_this(), bb)->empty() && - !level->containsAnyLiquid(bb)) { + if (level->getCubes(shared_from_this(), &bb)->empty() && + !level->containsAnyLiquid(&bb)) { ok = true; } } diff --git a/Minecraft.World/Entities/Mobs/EntityHorse.cpp b/Minecraft.World/Entities/Mobs/EntityHorse.cpp index cd2563466..2692045da 100644 --- a/Minecraft.World/Entities/Mobs/EntityHorse.cpp +++ b/Minecraft.World/Entities/Mobs/EntityHorse.cpp @@ -420,7 +420,7 @@ std::shared_ptr EntityHorse::getClosestMommy( double closestDistance = std::numeric_limits::max(); std::shared_ptr mommy = nullptr; - AABB expanded = baby->bb->expand(searchRadius, searchRadius, searchRadius); + AABB expanded = baby->bb.expand(searchRadius, searchRadius, searchRadius); std::vector >* list = level->getEntities(baby, &expanded, PARENT_HORSE_SELECTOR); diff --git a/Minecraft.World/Entities/Mobs/ExperienceOrb.cpp b/Minecraft.World/Entities/Mobs/ExperienceOrb.cpp index 26418c28e..fb7755f52 100644 --- a/Minecraft.World/Entities/Mobs/ExperienceOrb.cpp +++ b/Minecraft.World/Entities/Mobs/ExperienceOrb.cpp @@ -84,7 +84,7 @@ void ExperienceOrb::tick() { playSound(eSoundType_RANDOM_FIZZ, 0.4f, 2.0f + random->nextFloat() * 0.4f); } - checkInTile(x, (bb->y0 + bb->y1) / 2, z); + checkInTile(x, (bb.y0 + bb.y1) / 2, z); double maxDist = 8; // 4J - PC Comment @@ -121,7 +121,7 @@ void ExperienceOrb::tick() { float friction = 0.98f; if (onGround) { friction = 0.6f * 0.98f; - int t = level->getTile(Mth::floor(x), Mth::floor(bb->y0) - 1, + int t = level->getTile(Mth::floor(x), Mth::floor(bb.y0) - 1, Mth::floor(z)); if (t > 0) { friction = Tile::tiles[t]->friction * 0.98f; @@ -145,7 +145,7 @@ void ExperienceOrb::tick() { } bool ExperienceOrb::updateInWaterState() { - return level->checkAndHandleWater(bb, Material::water, shared_from_this()); + return level->checkAndHandleWater(&bb, Material::water, shared_from_this()); } void ExperienceOrb::burn(int dmg) { hurt(DamageSource::inFire, dmg); } diff --git a/Minecraft.World/Entities/Mobs/EyeOfEnderSignal.cpp b/Minecraft.World/Entities/Mobs/EyeOfEnderSignal.cpp index 71981b9b9..ed3311a2c 100644 --- a/Minecraft.World/Entities/Mobs/EyeOfEnderSignal.cpp +++ b/Minecraft.World/Entities/Mobs/EyeOfEnderSignal.cpp @@ -28,7 +28,7 @@ EyeOfEnderSignal::EyeOfEnderSignal(Level* level) : Entity(level) { void EyeOfEnderSignal::defineSynchedData() {} bool EyeOfEnderSignal::shouldRenderAtSqrDistance(double distance) { - double size = bb->getSize() * 4; + double size = bb.getSize() * 4; size *= 64.0f; return distance < size * size; } @@ -159,4 +159,4 @@ float EyeOfEnderSignal::getBrightness(float a) { return 1.0f; } int EyeOfEnderSignal::getLightColor(float a) { return 15 << 20 | 15 << 4; } -bool EyeOfEnderSignal::isAttackable() { return false; } \ No newline at end of file +bool EyeOfEnderSignal::isAttackable() { return false; } diff --git a/Minecraft.World/Entities/Mobs/Fireball.cpp b/Minecraft.World/Entities/Mobs/Fireball.cpp index b6613549c..86ebfd150 100644 --- a/Minecraft.World/Entities/Mobs/Fireball.cpp +++ b/Minecraft.World/Entities/Mobs/Fireball.cpp @@ -39,7 +39,7 @@ Fireball::Fireball(Level* level) : Entity(level) { void Fireball::defineSynchedData() {} bool Fireball::shouldRenderAtSqrDistance(double distance) { - double size = bb->getSize() * 4; + double size = bb.getSize() * 4; size *= 64.0f; return distance < size * size; } @@ -176,7 +176,7 @@ void Fireball::tick() { to = Vec3{res->pos.x, res->pos.y, res->pos.z}; } std::shared_ptr hitEntity = nullptr; - AABB grown = bb->expand(xd, yd, zd).grow(1, 1, 1); + AABB grown = bb.expand(xd, yd, zd).grow(1, 1, 1); std::vector >* objects = level->getEntities(shared_from_this(), &grown); double nearest = 0; @@ -188,7 +188,7 @@ void Fireball::tick() { // && flightTime < 25)) continue; float rr = 0.3f; - AABB bb = e->bb->grow(rr, rr, rr); + AABB bb = e->bb.grow(rr, rr, rr); HitResult* p = bb.clip(from, to); if (p != NULL) { double dd = from.distanceTo(p->pos); diff --git a/Minecraft.World/Entities/Mobs/FishingHook.cpp b/Minecraft.World/Entities/Mobs/FishingHook.cpp index fe8ff9b8b..617f363e8 100644 --- a/Minecraft.World/Entities/Mobs/FishingHook.cpp +++ b/Minecraft.World/Entities/Mobs/FishingHook.cpp @@ -88,7 +88,7 @@ FishingHook::FishingHook(Level* level, std::shared_ptr mob) void FishingHook::defineSynchedData() {} bool FishingHook::shouldRenderAtSqrDistance(double distance) { - double size = bb->getSize() * 4; + double size = bb.getSize() * 4; size *= 64.0f; return distance < size * size; } @@ -175,7 +175,7 @@ void FishingHook::tick() { hookedIn = nullptr; else { x = hookedIn->x; - y = hookedIn->bb->y0 + hookedIn->bbHeight * 0.8; + y = hookedIn->bb.y0 + hookedIn->bbHeight * 0.8; z = hookedIn->z; return; } @@ -213,7 +213,7 @@ void FishingHook::tick() { to = Vec3(res->pos.x, res->pos.y, res->pos.z); } std::shared_ptr hitEntity = nullptr; - AABB grown = bb->expand(xd, yd, zd).grow(1, 1, 1); + AABB grown = bb.expand(xd, yd, zd).grow(1, 1, 1); std::vector >* objects = level->getEntities(shared_from_this(), &grown); double nearest = 0; @@ -223,7 +223,7 @@ void FishingHook::tick() { if (!e->isPickable() || (e == owner && flightTime < 5)) continue; float rr = 0.3f; - AABB bb = e->bb->grow(rr, rr, rr); + AABB bb = e->bb.grow(rr, rr, rr); HitResult* p = bb.clip(from, to); if (p != NULL) { double dd = from.distanceTo(p->pos); @@ -284,11 +284,11 @@ void FishingHook::tick() { int steps = 5; double waterPercentage = 0; for (int i = 0; i < steps; i++) { - double y0 = bb->y0 + (bb->y1 - bb->y0) * (i + 0) / steps - 2 / 16.0f + + double y0 = bb.y0 + (bb.y1 - bb.y0) * (i + 0) / steps - 2 / 16.0f + 2 / 16.0f; - double y1 = bb->y0 + (bb->y1 - bb->y0) * (i + 1) / steps - 2 / 16.0f + + double y1 = bb.y0 + (bb.y1 - bb.y0) * (i + 1) / steps - 2 / 16.0f + 2 / 16.0f; - AABB bb2(bb->x0, y0, bb->z0, bb->x1, y1, bb->z1); + AABB bb2(bb.x0, y0, bb.z0, bb.x1, y1, bb.z1); if (level->containsLiquid(&bb2, Material::water)) { waterPercentage += 1.0 / steps; } @@ -309,7 +309,7 @@ void FishingHook::tick() { playSound( eSoundType_RANDOM_SPLASH, 0.25f, 1 + (random->nextFloat() - random->nextFloat()) * 0.4f); - float yt = (float)Mth::floor(bb->y0); + float yt = (float)Mth::floor(bb.y0); for (int i = 0; i < 1 + bbWidth * 20; i++) { float xo = (random->nextFloat() * 2 - 1) * bbWidth; float zo = (random->nextFloat() * 2 - 1) * bbWidth; diff --git a/Minecraft.World/Entities/Mobs/Ghast.cpp b/Minecraft.World/Entities/Mobs/Ghast.cpp index 40c65a43c..e6a36730c 100644 --- a/Minecraft.World/Entities/Mobs/Ghast.cpp +++ b/Minecraft.World/Entities/Mobs/Ghast.cpp @@ -119,7 +119,7 @@ void Ghast::serverAiStep() { target->distanceToSqr(shared_from_this()) < maxDist * maxDist) { double xdd = target->x - x; double ydd = - (target->bb->y0 + target->bbHeight / 2) - (y + bbHeight / 2); + (target->bb.y0 + target->bbHeight / 2) - (y + bbHeight / 2); double zdd = target->z - z; yBodyRot = yRot = -(float)atan2(xdd, zdd) * 180 / PI; @@ -170,7 +170,6 @@ bool Ghast::canReach(double xt, double yt, double zt, double dist) { double yd = (yTarget - y) / dist; double zd = (zTarget - z) / dist; - AABB bb = *this->bb; for (int d = 1; d < dist; d++) { bb.move(xd, yd, zd); if (!level->getCubes(shared_from_this(), &bb)->empty()) return false; diff --git a/Minecraft.World/Entities/Mobs/LavaSlime.cpp b/Minecraft.World/Entities/Mobs/LavaSlime.cpp index a84116c43..bcf420571 100644 --- a/Minecraft.World/Entities/Mobs/LavaSlime.cpp +++ b/Minecraft.World/Entities/Mobs/LavaSlime.cpp @@ -27,9 +27,9 @@ void LavaSlime::registerAttributes() { bool LavaSlime::canSpawn() { return level->difficulty > Difficulty::PEACEFUL && - level->isUnobstructed(bb) && - level->getCubes(shared_from_this(), bb)->empty() && - !level->containsAnyLiquid(bb); + level->isUnobstructed(&bb) && + level->getCubes(shared_from_this(), &bb)->empty() && + !level->containsAnyLiquid(&bb); } int LavaSlime::getArmorValue() { return getSize() * 3; } @@ -102,4 +102,4 @@ bool LavaSlime::isInLava() { return false; } -bool LavaSlime::doPlayLandSound() { return true; } \ No newline at end of file +bool LavaSlime::doPlayLandSound() { return true; } diff --git a/Minecraft.World/Entities/Mobs/Minecart.cpp b/Minecraft.World/Entities/Mobs/Minecart.cpp index 16dcbb183..7c6b1e24c 100644 --- a/Minecraft.World/Entities/Mobs/Minecart.cpp +++ b/Minecraft.World/Entities/Mobs/Minecart.cpp @@ -98,7 +98,7 @@ void Minecart::defineSynchedData() { AABB* Minecart::getCollideAgainstBox(std::shared_ptr entity) { if (entity->isPushable()) { - return entity->bb; + return &entity->bb; } return NULL; } @@ -305,7 +305,7 @@ void Minecart::tick() { } setRot(yRot, xRot); - AABB grown = bb->grow(0.2, 0, 0.2); + AABB grown = bb.grow(0.2, 0, 0.2); std::vector >* entities = level->getEntities(shared_from_this(), &grown); if (entities != NULL && !entities->empty()) { diff --git a/Minecraft.World/Entities/Mobs/MushroomCow.cpp b/Minecraft.World/Entities/Mobs/MushroomCow.cpp index fe8bed57b..5ab441782 100644 --- a/Minecraft.World/Entities/Mobs/MushroomCow.cpp +++ b/Minecraft.World/Entities/Mobs/MushroomCow.cpp @@ -67,7 +67,7 @@ bool MushroomCow::mobInteract(std::shared_ptr player) { // already really bool MushroomCow::canSpawn() { int xt = Mth::floor(x); - int yt = Mth::floor(bb->y0); + int yt = Mth::floor(bb.y0); int zt = Mth::floor(z); return (level->getTile(xt, yt - 1, zt) == Tile::grass_Id || level->getTile(xt, yt - 1, zt) == Tile::mycel_Id) && diff --git a/Minecraft.World/Entities/Mobs/Ocelot.cpp b/Minecraft.World/Entities/Mobs/Ocelot.cpp index b31798af2..ea104f5e5 100644 --- a/Minecraft.World/Entities/Mobs/Ocelot.cpp +++ b/Minecraft.World/Entities/Mobs/Ocelot.cpp @@ -240,11 +240,11 @@ bool Ocelot::canSpawn() { if (level->random->nextInt(3) == 0) { return false; } - if (level->isUnobstructed(bb) && - level->getCubes(shared_from_this(), bb)->empty() && - !level->containsAnyLiquid(bb)) { + if (level->isUnobstructed(&bb) && + level->getCubes(shared_from_this(), &bb)->empty() && + !level->containsAnyLiquid(&bb)) { int xt = Mth::floor(x); - int yt = Mth::floor(bb->y0); + int yt = Mth::floor(bb.y0); int zt = Mth::floor(z); if (yt < level->seaLevel) { return false; diff --git a/Minecraft.World/Entities/Mobs/PigZombie.cpp b/Minecraft.World/Entities/Mobs/PigZombie.cpp index 0c016c83f..f88d30044 100644 --- a/Minecraft.World/Entities/Mobs/PigZombie.cpp +++ b/Minecraft.World/Entities/Mobs/PigZombie.cpp @@ -69,9 +69,9 @@ void PigZombie::tick() { bool PigZombie::canSpawn() { return level->difficulty > Difficulty::PEACEFUL && - level->isUnobstructed(bb) && - level->getCubes(shared_from_this(), bb)->empty() && - !level->containsAnyLiquid(bb); + level->isUnobstructed(&bb) && + level->getCubes(shared_from_this(), &bb)->empty() && + !level->containsAnyLiquid(&bb); } void PigZombie::addAdditonalSaveData(CompoundTag* tag) { @@ -100,7 +100,7 @@ std::shared_ptr PigZombie::findAttackTarget() { bool PigZombie::hurt(DamageSource* source, float dmg) { std::shared_ptr sourceEntity = source->getEntity(); if (sourceEntity != NULL && sourceEntity->instanceof(eTYPE_PLAYER)) { - AABB grown = bb->grow(32, 32, 32); + AABB grown = bb.grow(32, 32, 32); std::vector >* nearby = level->getEntities(shared_from_this(), &grown); AUTO_VAR(itEnd, nearby->end()); diff --git a/Minecraft.World/Entities/Mobs/Silverfish.cpp b/Minecraft.World/Entities/Mobs/Silverfish.cpp index 2ced041aa..ec0e014da 100644 --- a/Minecraft.World/Entities/Mobs/Silverfish.cpp +++ b/Minecraft.World/Entities/Mobs/Silverfish.cpp @@ -69,8 +69,8 @@ bool Silverfish::hurt(DamageSource* source, float dmg) { void Silverfish::checkHurtTarget(std::shared_ptr target, float d) { // super.checkHurtTarget(target, d); - if (attackTime <= 0 && d < 1.2f && target->bb->y1 > bb->y0 && - target->bb->y0 < bb->y1) { + if (attackTime <= 0 && d < 1.2f && target->bb.y1 > bb.y0 && + target->bb.y0 < bb.y1) { attackTime = 20; doHurtTarget(target); } @@ -192,4 +192,4 @@ bool Silverfish::canSpawn() { return false; } -MobType Silverfish::getMobType() { return ARTHROPOD; } \ No newline at end of file +MobType Silverfish::getMobType() { return ARTHROPOD; } diff --git a/Minecraft.World/Entities/Mobs/Slime.cpp b/Minecraft.World/Entities/Mobs/Slime.cpp index 6db5e5c4b..de4816ea7 100644 --- a/Minecraft.World/Entities/Mobs/Slime.cpp +++ b/Minecraft.World/Entities/Mobs/Slime.cpp @@ -91,7 +91,7 @@ void Slime::tick() { float d = random->nextFloat() * 0.5f + 0.5f; float xd = Mth::sin(dir) * size * 0.5f * d; float zd = Mth::cos(dir) * size * 0.5f * d; - level->addParticle(getParticleName(), x + xd, bb->y0, z + zd, 0, 0, + level->addParticle(getParticleName(), x + xd, bb.y0, z + zd, 0, 0, 0); } diff --git a/Minecraft.World/Entities/Mobs/Squid.cpp b/Minecraft.World/Entities/Mobs/Squid.cpp index 7cb96c08d..c04bba6eb 100644 --- a/Minecraft.World/Entities/Mobs/Squid.cpp +++ b/Minecraft.World/Entities/Mobs/Squid.cpp @@ -65,7 +65,7 @@ void Squid::dropDeathLoot(bool wasKilledByPlayer, int playerBonusLevel) { } bool Squid::isInWater() { - AABB grown = bb->grow(0, -0.6, 0); + AABB grown = bb.grow(0, -0.6, 0); return level->checkAndHandleWater(&grown, Material::water, shared_from_this()); } diff --git a/Minecraft.World/Entities/Mobs/ThrownPotion.cpp b/Minecraft.World/Entities/Mobs/ThrownPotion.cpp index da329189c..71020e479 100644 --- a/Minecraft.World/Entities/Mobs/ThrownPotion.cpp +++ b/Minecraft.World/Entities/Mobs/ThrownPotion.cpp @@ -82,7 +82,7 @@ void ThrownPotion::onHit(HitResult* res) { Item::potion->getMobEffects(potionItem); if (mobEffects != NULL && !mobEffects->empty()) { - AABB aoe = bb->grow(SPLASH_RANGE, SPLASH_RANGE / 2, SPLASH_RANGE); + AABB aoe = bb.grow(SPLASH_RANGE, SPLASH_RANGE / 2, SPLASH_RANGE); std::vector >* entitiesOfClass = level->getEntitiesOfClass(typeid(LivingEntity), &aoe); diff --git a/Minecraft.World/Entities/Mobs/VillagerGolem.cpp b/Minecraft.World/Entities/Mobs/VillagerGolem.cpp index 6f1880259..a9811005d 100644 --- a/Minecraft.World/Entities/Mobs/VillagerGolem.cpp +++ b/Minecraft.World/Entities/Mobs/VillagerGolem.cpp @@ -113,7 +113,7 @@ void VillagerGolem::aiStep() { if (t > 0) { level->addParticle(PARTICLE_TILECRACK(t, d), x + (random->nextFloat() - 0.5) * bbWidth, - bb->y0 + 0.1, + bb.y0 + 0.1, z + (random->nextFloat() - 0.5) * bbWidth, 4 * (random->nextFloat() - 0.5), .5, (random->nextFloat() - 0.5) * 4); @@ -226,4 +226,4 @@ bool VillagerGolem::hurt(DamageSource* source, float dmg) { } return Golem::hurt(source, dmg); -} \ No newline at end of file +} diff --git a/Minecraft.World/Entities/Mobs/Witch.cpp b/Minecraft.World/Entities/Mobs/Witch.cpp index 50950d57f..f8e970389 100644 --- a/Minecraft.World/Entities/Mobs/Witch.cpp +++ b/Minecraft.World/Entities/Mobs/Witch.cpp @@ -153,7 +153,7 @@ void Witch::handleEntityEvent(uint8_t id) { for (int i = 0; i < random->nextInt(35) + 10; i++) { level->addParticle(eParticleType_witchMagic, x + random->nextGaussian() * .13f, - bb->y1 + 0.5f + random->nextGaussian() * .13f, + bb.y1 + 0.5f + random->nextGaussian() * .13f, z + random->nextGaussian() * .13f, 0, 0, 0); } } else { diff --git a/Minecraft.World/Entities/Mobs/WitherBoss.cpp b/Minecraft.World/Entities/Mobs/WitherBoss.cpp index 80316042e..1263662d9 100644 --- a/Minecraft.World/Entities/Mobs/WitherBoss.cpp +++ b/Minecraft.World/Entities/Mobs/WitherBoss.cpp @@ -252,7 +252,7 @@ void WitherBoss::newServerAiStep() { idleHeadUpdates[i - 1] = 0; } } else { - AABB grown = bb->grow(20, 8, 20); + AABB grown = bb.grow(20, 8, 20); std::vector >* entities = level->getEntitiesOfClass(typeid(LivingEntity), &grown, livingEntitySelector); diff --git a/Minecraft.World/Entities/Mobs/Wolf.cpp b/Minecraft.World/Entities/Mobs/Wolf.cpp index e5ce60cd5..bccbe462e 100644 --- a/Minecraft.World/Entities/Mobs/Wolf.cpp +++ b/Minecraft.World/Entities/Mobs/Wolf.cpp @@ -182,7 +182,7 @@ void Wolf::tick() { } if (shakeAnim > 0.4f) { - float yt = (float)bb->y0; + float yt = (float)bb.y0; int shakeCount = (int)(Mth::sin((shakeAnim - 0.4f) * PI) * 7.0f); for (int i = 0; i < shakeCount; i++) { @@ -503,4 +503,4 @@ bool Wolf::wantsToAttack(std::shared_ptr target, return false; } return true; -} \ No newline at end of file +} diff --git a/Minecraft.World/Entities/Mobs/Zombie.cpp b/Minecraft.World/Entities/Mobs/Zombie.cpp index d6d15644d..c67e1ccfd 100644 --- a/Minecraft.World/Entities/Mobs/Zombie.cpp +++ b/Minecraft.World/Entities/Mobs/Zombie.cpp @@ -176,10 +176,10 @@ bool Zombie::hurt(DamageSource* source, float dmg) { level->getRawBrightness(xt, yt, zt) < 10) { reinforcement->setPos(xt, yt, zt); - if (level->isUnobstructed(reinforcement->bb) && - level->getCubes(reinforcement, reinforcement->bb) + if (level->isUnobstructed(&reinforcement->bb) && + level->getCubes(reinforcement, &reinforcement->bb) ->empty() && - !level->containsAnyLiquid(reinforcement->bb)) { + !level->containsAnyLiquid(&reinforcement->bb)) { level->addEntity(reinforcement); reinforcement->setTarget(target); reinforcement->finalizeMobSpawn(NULL); @@ -492,4 +492,4 @@ int Zombie::getConversionProgress() { Zombie::ZombieGroupData::ZombieGroupData(bool baby, bool villager) { isBaby = baby; isVillager = villager; -} \ No newline at end of file +} diff --git a/Minecraft.World/Entities/Monster.cpp b/Minecraft.World/Entities/Monster.cpp index 2b89198e5..a0e98c5d5 100644 --- a/Minecraft.World/Entities/Monster.cpp +++ b/Minecraft.World/Entities/Monster.cpp @@ -113,8 +113,8 @@ bool Monster::doHurtTarget(std::shared_ptr target) { } void Monster::checkHurtTarget(std::shared_ptr target, float distance) { - if (attackTime <= 0 && distance < 2.0f && target->bb->y1 > bb->y0 && - target->bb->y0 < bb->y1) { + if (attackTime <= 0 && distance < 2.0f && target->bb.y1 > bb.y0 && + target->bb.y0 < bb.y1) { attackTime = 20; doHurtTarget(target); } @@ -126,7 +126,7 @@ float Monster::getWalkTargetValue(int x, int y, int z) { bool Monster::isDarkEnoughToSpawn() { int xt = Mth::floor(x); - int yt = Mth::floor(bb->y0); + int yt = Mth::floor(bb.y0); int zt = Mth::floor(z); if (level->getBrightness(LightLayer::Sky, xt, yt, zt) > random->nextInt(32)) return false; @@ -152,4 +152,4 @@ void Monster::registerAttributes() { PathfinderMob::registerAttributes(); getAttributes()->registerAttribute(SharedMonsterAttributes::ATTACK_DAMAGE); -} \ No newline at end of file +} diff --git a/Minecraft.World/Entities/PathfinderMob.cpp b/Minecraft.World/Entities/PathfinderMob.cpp index aec748483..b2dbbdca6 100644 --- a/Minecraft.World/Entities/PathfinderMob.cpp +++ b/Minecraft.World/Entities/PathfinderMob.cpp @@ -109,7 +109,7 @@ void PathfinderMob::serverAiStep() { // protected. considerForExtraWandering(isDespawnProtected()); - int yFloor = Mth::floor(bb->y0 + 0.5f); + int yFloor = Mth::floor(bb.y0 + 0.5f); bool inWater = isInWater(); bool inLava = isInLava(); @@ -226,7 +226,7 @@ std::shared_ptr PathfinderMob::findAttackTarget() { bool PathfinderMob::canSpawn() { int xt = Mth::floor(x); - int yt = Mth::floor(bb->y0); + int yt = Mth::floor(bb.y0); int zt = Mth::floor(z); return this->Mob::canSpawn() && getWalkTargetValue(xt, yt, zt) >= 0; } diff --git a/Minecraft.World/Entities/Throwable.cpp b/Minecraft.World/Entities/Throwable.cpp index 056129287..973c7d8d7 100644 --- a/Minecraft.World/Entities/Throwable.cpp +++ b/Minecraft.World/Entities/Throwable.cpp @@ -27,7 +27,7 @@ Throwable::Throwable(Level* level) : Entity(level) { void Throwable::defineSynchedData() {} bool Throwable::shouldRenderAtSqrDistance(double distance) { - double size = bb->getSize() * 4; + double size = bb.getSize() * 4; size *= 64.0f; return distance < size * size; } @@ -147,7 +147,7 @@ void Throwable::tick() { if (!level->isClientSide) { std::shared_ptr hitEntity = nullptr; - AABB grown = bb->expand(xd, yd, zd).grow(1, 1, 1); + AABB grown = bb.expand(xd, yd, zd).grow(1, 1, 1); std::vector >* objects = level->getEntities(shared_from_this(), &grown); double nearest = 0; @@ -157,7 +157,7 @@ void Throwable::tick() { if (!e->isPickable() || (e == owner && flightTime < 5)) continue; float rr = 0.3f; - AABB bb = e->bb->grow(rr, rr, rr); + AABB bb = e->bb.grow(rr, rr, rr); HitResult* p = bb.clip(from, to); if (p != NULL) { double dd = from.distanceTo(p->pos); diff --git a/Minecraft.World/Entities/WaterAnimal.cpp b/Minecraft.World/Entities/WaterAnimal.cpp index 7cdd2ed31..71470f35b 100644 --- a/Minecraft.World/Entities/WaterAnimal.cpp +++ b/Minecraft.World/Entities/WaterAnimal.cpp @@ -18,7 +18,7 @@ bool WaterAnimal::isWaterMob() { return true; // prevent drowning } -bool WaterAnimal::canSpawn() { return level->isUnobstructed(bb); } +bool WaterAnimal::canSpawn() { return level->isUnobstructed(&bb); } int WaterAnimal::getAmbientSoundInterval() { return 20 * 6; } @@ -42,4 +42,4 @@ void WaterAnimal::baseTick() { } else { setAirSupply(TOTAL_AIR_SUPPLY); } -} \ No newline at end of file +} diff --git a/Minecraft.World/Items/BoatItem.cpp b/Minecraft.World/Items/BoatItem.cpp index 0c4d6a1b9..313b658e1 100644 --- a/Minecraft.World/Items/BoatItem.cpp +++ b/Minecraft.World/Items/BoatItem.cpp @@ -83,7 +83,7 @@ std::shared_ptr BoatItem::use( Vec3 b = player->getViewVector(a); bool hitEntity = false; float overlap = 1; - AABB grown = player->bb->expand(b.x * (range), b.y * (range), b.z * (range)) + AABB grown = player->bb.expand(b.x * (range), b.y * (range), b.z * (range)) .grow(overlap, overlap, overlap); std::vector >* objects = level->getEntities(player, &grown); @@ -93,7 +93,7 @@ std::shared_ptr BoatItem::use( if (!e->isPickable()) continue; float rr = e->getPickRadius(); - AABB bb = e->bb->grow(rr, rr, rr); + AABB bb = e->bb.grow(rr, rr, rr); if (bb.contains(from)) { hitEntity = true; } @@ -116,7 +116,7 @@ std::shared_ptr BoatItem::use( boat->yRot = ((Mth::floor(player->yRot * 4.0F / 360.0F + 0.5) & 0x3) - 1) * 90; - AABB grown = boat->bb->grow(-0.1, -0.1, -0.1); + AABB grown = boat->bb.grow(-0.1, -0.1, -0.1); if (!level->getCubes(boat, &grown)->empty()) { return itemInstance; } diff --git a/Minecraft.World/Level/Explosion.cpp b/Minecraft.World/Level/Explosion.cpp index bdc17689d..9be40d49b 100644 --- a/Minecraft.World/Level/Explosion.cpp +++ b/Minecraft.World/Level/Explosion.cpp @@ -118,7 +118,7 @@ void Explosion::explode() { // walls bool canDamage = false; for (AUTO_VAR(it2, toBlow.begin()); it2 != toBlow.end(); ++it2) { - if (e->bb->intersects(it2->x, it2->y, it2->z, it2->x + 1, + if (e->bb.intersects(it2->x, it2->y, it2->z, it2->x + 1, it2->y + 1, it2->z + 1)) { canDamage = true; break; @@ -144,7 +144,7 @@ void Explosion::explode() { za /= da; } - double sp = level->getSeenPercent(¢er, e->bb); + double sp = level->getSeenPercent(¢er, &e->bb); double pow = (1 - dist) * sp; if (canDamage) e->hurt(DamageSource::explosion(this), diff --git a/Minecraft.World/Level/LevelChunk.cpp b/Minecraft.World/Level/LevelChunk.cpp index c5c0632ef..5f95fd9d2 100644 --- a/Minecraft.World/Level/LevelChunk.cpp +++ b/Minecraft.World/Level/LevelChunk.cpp @@ -1691,7 +1691,7 @@ void LevelChunk::getEntities(std::shared_ptr except, AABB* bb, AUTO_VAR(itEnd, entities->end()); for (AUTO_VAR(it, entities->begin()); it != itEnd; it++) { std::shared_ptr e = *it; // entities->at(i); - if (e != except && e->bb->intersects(*bb) && + if (e != except && e->bb.intersects(*bb) && (selector == NULL || selector->matches(e))) { es.push_back(e); std::vector >* subs = @@ -1699,7 +1699,7 @@ void LevelChunk::getEntities(std::shared_ptr except, AABB* bb, if (subs != NULL) { for (int j = 0; j < subs->size(); j++) { e = subs->at(j); - if (e != except && e->bb->intersects(*bb) && + if (e != except && e->bb.intersects(*bb) && (selector == NULL || selector->matches(e))) { es.push_back(e); } @@ -1765,7 +1765,7 @@ void LevelChunk::getEntitiesOfClass(const std::type_info& ec, AABB* bb, else if (Entity* entity = e.get(); entity != NULL && ec == typeid(*entity)) isAssignableFrom = true; - if (isAssignableFrom && e->bb->intersects(*bb)) { + if (isAssignableFrom && e->bb.intersects(*bb)) { if (selector == NULL || selector->matches(e)) { es.push_back(e); } diff --git a/Minecraft.World/Player/Player.cpp b/Minecraft.World/Player/Player.cpp index f36caeefa..13c1354e3 100644 --- a/Minecraft.World/Player/Player.cpp +++ b/Minecraft.World/Player/Player.cpp @@ -965,9 +965,9 @@ void Player::aiStep() { if (riding != NULL && !riding->removed) { // if the player is riding, also touch entities under the // pig/horse - pickupArea = bb->minmax(*riding->bb).grow(1, 0, 1); + pickupArea = bb.minmax(riding->bb).grow(1, 0, 1); } else { - pickupArea = bb->grow(1, .5, 1); + pickupArea = bb.grow(1, .5, 1); } std::vector >* entities = diff --git a/Minecraft.World/Util/CombatTracker.cpp b/Minecraft.World/Util/CombatTracker.cpp index 0dbc0a2d3..80b0a3072 100644 --- a/Minecraft.World/Util/CombatTracker.cpp +++ b/Minecraft.World/Util/CombatTracker.cpp @@ -19,7 +19,7 @@ void CombatTracker::prepareForDamage() { if (mob->onLadder()) { int type = mob->level->getTile( - Mth::floor(mob->x), Mth::floor(mob->bb->y0), Mth::floor(mob->z)); + Mth::floor(mob->x), Mth::floor(mob->bb.y0), Mth::floor(mob->z)); if (type == Tile::ladder->id) { nextLocation = eLocation_LADDER; From a0be2e2fb5793a16323f0c1bae4d56d02bd2e9bb Mon Sep 17 00:00:00 2001 From: orng Date: Sat, 28 Mar 2026 03:05:06 -0500 Subject: [PATCH 036/170] refactor: remove aabb tls --- Minecraft.Client/Minecraft.cpp | 4 -- Minecraft.Client/MinecraftServer.cpp | 4 -- .../Platform/Common/Consoles_App.cpp | 2 - .../Common/Network/GameNetworkManager.cpp | 5 --- .../Platform/Common/UI/IUIScene_PauseMenu.cpp | 2 - .../Platform/Common/XUI/XUI_Death.cpp | 1 - .../Platform/Common/XUI/XUI_PauseMenu.cpp | 2 - .../Platform/Durango/Durango_Minecraft.cpp | 1 - .../Platform/Linux/Linux_Minecraft.cpp | 1 - .../Platform/Orbis/Orbis_Minecraft.cpp | 2 - .../Platform/PS3/PS3_Minecraft.cpp | 1 - .../Platform/PS3/Xbox_Minecraft.cpp | 1 - .../Platform/PSVita/PSVita_Minecraft.cpp | 1 - .../Windows64/Windows64_Minecraft.cpp | 1 - .../Platform/Xbox/Xbox_Minecraft.cpp | 1 - Minecraft.Client/Rendering/GameRenderer.cpp | 2 - Minecraft.Client/Rendering/LevelRenderer.cpp | 1 - Minecraft.World/Util/AABB.cpp | 41 ------------------- Minecraft.World/Util/AABB.h | 25 ----------- 19 files changed, 98 deletions(-) diff --git a/Minecraft.Client/Minecraft.cpp b/Minecraft.Client/Minecraft.cpp index 722d2eafb..65d5e87dd 100644 --- a/Minecraft.Client/Minecraft.cpp +++ b/Minecraft.Client/Minecraft.cpp @@ -726,7 +726,6 @@ void Minecraft::run() { // try { // 4J - removed try/catch // if (minecraftApplet != null && !minecraftApplet.isActive()) break; // 4J - removed - AABB::resetPool(); // if (parent == NULL && Display.isCloseRequested()) { // 4J - removed // stop(); @@ -1282,7 +1281,6 @@ void Minecraft::run_middle() { // try { // 4J - removed try/catch // if (minecraftApplet != null && // !minecraftApplet.isActive()) break; // 4J - removed - AABB::resetPool(); // if (parent == NULL && Display.isCloseRequested()) { // // 4J - removed @@ -2226,7 +2224,6 @@ void Minecraft::run_end() { destroy(); } void Minecraft::emergencySave() { // 4J - lots of try/catches removed here, and garbage collector things levelRenderer->clear(); - AABB::clearPool(); setLevel(NULL); } @@ -2402,7 +2399,6 @@ void Minecraft::levelTickUpdateFunc(void* pParam) { } void Minecraft::levelTickThreadInitFunc() { - AABB::CreateNewThreadStorage(); Compression::UseDefaultThreadStorage(); } diff --git a/Minecraft.Client/MinecraftServer.cpp b/Minecraft.Client/MinecraftServer.cpp index 23cd23251..7009e71ef 100644 --- a/Minecraft.Client/MinecraftServer.cpp +++ b/Minecraft.Client/MinecraftServer.cpp @@ -316,7 +316,6 @@ int MinecraftServer::runPostUpdate(void* lpParam) { MinecraftServer* server = (MinecraftServer*)lpParam; Entity::useSmallIds(); // This thread can end up spawning entities as // resources - AABB::CreateNewThreadStorage(); Compression::UseDefaultThreadStorage(); Level::enableLightingCache(); Tile::CreateNewThreadStorage(); @@ -365,7 +364,6 @@ int MinecraftServer::runPostUpdate(void* lpParam) { LeaveCriticalSection(&server->m_postProcessCS); // #endif //__PS3__ Tile::ReleaseThreadStorage(); - AABB::ReleaseThreadStorage(); Level::destroyLightingCache(); ShutdownManager::HasFinished(ShutdownManager::ePostProcessThread); @@ -1650,8 +1648,6 @@ void MinecraftServer::tick() { ironTimers.erase(toRemove[i]); } - AABB::resetPool(); - tickCount++; // 4J We need to update client difficulty levels based on the servers diff --git a/Minecraft.Client/Platform/Common/Consoles_App.cpp b/Minecraft.Client/Platform/Common/Consoles_App.cpp index a1cdfa0d3..24b4c72a5 100644 --- a/Minecraft.Client/Platform/Common/Consoles_App.cpp +++ b/Minecraft.Client/Platform/Common/Consoles_App.cpp @@ -4707,7 +4707,6 @@ int CMinecraftApp::EthernetDisconnectReturned( int CMinecraftApp::SignoutExitWorldThreadProc(void* lpParameter) { // Share AABB & Vec3 pools with default (main thread) - should be ok as long // as we don't tick the main thread whilst this thread is running - AABB::UseDefaultThreadStorage(); Compression::UseDefaultThreadStorage(); // app.SetGameStarted(false); @@ -7698,7 +7697,6 @@ void CMinecraftApp::LeaveSaveNotificationSection() { int CMinecraftApp::RemoteSaveThreadProc(void* lpParameter) { // The game should be stopped while we are doing this, but the connections // ticks may try to create some AABB's or Vec3's - AABB::UseDefaultThreadStorage(); Compression::UseDefaultThreadStorage(); // 4J-PB - Xbox 360 - 163153 - [CRASH] TU17: Code: Multiplayer: During the diff --git a/Minecraft.Client/Platform/Common/Network/GameNetworkManager.cpp b/Minecraft.Client/Platform/Common/Network/GameNetworkManager.cpp index 180049628..06bf5ffec 100644 --- a/Minecraft.Client/Platform/Common/Network/GameNetworkManager.cpp +++ b/Minecraft.Client/Platform/Common/Network/GameNetworkManager.cpp @@ -950,7 +950,6 @@ bool CGameNetworkManager::IsNetworkThreadRunning() { int CGameNetworkManager::RunNetworkGameThreadProc(void* lpParameter) { // Share AABB & Vec3 pools with default (main thread) - should be ok as long // as we don't tick the main thread whilst this thread is running - AABB::UseDefaultThreadStorage(); Compression::UseDefaultThreadStorage(); Tile::CreateNewThreadStorage(); @@ -1009,7 +1008,6 @@ int CGameNetworkManager::ServerThreadProc(void* lpParameter) { } SetThreadName(-1, "Minecraft Server thread"); - AABB::CreateNewThreadStorage(); Compression::UseDefaultThreadStorage(); OldChunkStorage::UseDefaultThreadStorage(); Entity::useSmallIds(); @@ -1022,7 +1020,6 @@ int CGameNetworkManager::ServerThreadProc(void* lpParameter) { lpParameter); // saveData, app.GetGameHostOption(eGameHostOption_All)); Tile::ReleaseThreadStorage(); - AABB::ReleaseThreadStorage(); Level::destroyLightingCache(); if (lpParameter != NULL) delete (NetworkGameInitData*)lpParameter; @@ -1033,7 +1030,6 @@ int CGameNetworkManager::ServerThreadProc(void* lpParameter) { int CGameNetworkManager::ExitAndJoinFromInviteThreadProc(void* lpParam) { // Share AABB & Vec3 pools with default (main thread) - should be ok as long // as we don't tick the main thread whilst this thread is running - AABB::UseDefaultThreadStorage(); Compression::UseDefaultThreadStorage(); // app.SetGameStarted(false); @@ -1185,7 +1181,6 @@ void CGameNetworkManager::_LeaveGame() { int CGameNetworkManager::ChangeSessionTypeThreadProc(void* lpParam) { // Share AABB & Vec3 pools with default (main thread) - should be ok as long // as we don't tick the main thread whilst this thread is running - AABB::UseDefaultThreadStorage(); Compression::UseDefaultThreadStorage(); Minecraft* pMinecraft = Minecraft::GetInstance(); diff --git a/Minecraft.Client/Platform/Common/UI/IUIScene_PauseMenu.cpp b/Minecraft.Client/Platform/Common/UI/IUIScene_PauseMenu.cpp index f748a6343..e815d7a5c 100644 --- a/Minecraft.Client/Platform/Common/UI/IUIScene_PauseMenu.cpp +++ b/Minecraft.Client/Platform/Common/UI/IUIScene_PauseMenu.cpp @@ -383,7 +383,6 @@ int IUIScene_PauseMenu::SaveWorldThreadProc(void* lpParameter) { // Share AABB & Vec3 pools with default (main thread) - should be ok as long // as we don't tick the main thread whilst this thread is running - AABB::UseDefaultThreadStorage(); Compression::UseDefaultThreadStorage(); Minecraft* pMinecraft = Minecraft::GetInstance(); @@ -420,7 +419,6 @@ int IUIScene_PauseMenu::SaveWorldThreadProc(void* lpParameter) { int IUIScene_PauseMenu::ExitWorldThreadProc(void* lpParameter) { // Share AABB & Vec3 pools with default (main thread) - should be ok as long // as we don't tick the main thread whilst this thread is running - AABB::UseDefaultThreadStorage(); Compression::UseDefaultThreadStorage(); // app.SetGameStarted(false); diff --git a/Minecraft.Client/Platform/Common/XUI/XUI_Death.cpp b/Minecraft.Client/Platform/Common/XUI/XUI_Death.cpp index df7adb806..738499468 100644 --- a/Minecraft.Client/Platform/Common/XUI/XUI_Death.cpp +++ b/Minecraft.Client/Platform/Common/XUI/XUI_Death.cpp @@ -222,7 +222,6 @@ HRESULT CScene_Death::OnKeyDown(XUIMessageInput* pInputData, BOOL& rfHandled) { } int CScene_Death::RespawnThreadProc(void* lpParameter) { - AABB::UseDefaultThreadStorage(); Compression::UseDefaultThreadStorage(); size_t iPad = (size_t)lpParameter; diff --git a/Minecraft.Client/Platform/Common/XUI/XUI_PauseMenu.cpp b/Minecraft.Client/Platform/Common/XUI/XUI_PauseMenu.cpp index 01b8b4405..a0c633adb 100644 --- a/Minecraft.Client/Platform/Common/XUI/XUI_PauseMenu.cpp +++ b/Minecraft.Client/Platform/Common/XUI/XUI_PauseMenu.cpp @@ -1075,7 +1075,6 @@ int UIScene_PauseMenu::SaveWorldThreadProc(LPVOID lpParameter) { // Share AABB & Vec3 pools with default (main thread) - should be ok as long // as we don't tick the main thread whilst this thread is running - AABB::UseDefaultThreadStorage(); Compression::UseDefaultThreadStorage(); Minecraft* pMinecraft = Minecraft::GetInstance(); @@ -1107,7 +1106,6 @@ int UIScene_PauseMenu::SaveWorldThreadProc(LPVOID lpParameter) { int UIScene_PauseMenu::ExitWorldThreadProc(void* lpParameter) { // Share AABB & Vec3 pools with default (main thread) - should be ok as long // as we don't tick the main thread whilst this thread is running - AABB::UseDefaultThreadStorage(); Compression::UseDefaultThreadStorage(); // app.SetGameStarted(false); diff --git a/Minecraft.Client/Platform/Durango/Durango_Minecraft.cpp b/Minecraft.Client/Platform/Durango/Durango_Minecraft.cpp index e7f5179c4..30b9c8eb7 100644 --- a/Minecraft.Client/Platform/Durango/Durango_Minecraft.cpp +++ b/Minecraft.Client/Platform/Durango/Durango_Minecraft.cpp @@ -794,7 +794,6 @@ void oldWinMainInit() { // Initialise TLS for tesselator, for this main thread Tesselator::CreateNewThreadStorage(1024 * 1024); // Initialise TLS for AABB and Vec3 pools, for this main thread - AABB::CreateNewThreadStorage(); OldChunkStorage::CreateNewThreadStorage(); Level::enableLightingCache(); Tile::CreateNewThreadStorage(); diff --git a/Minecraft.Client/Platform/Linux/Linux_Minecraft.cpp b/Minecraft.Client/Platform/Linux/Linux_Minecraft.cpp index 290b4626e..f7cb7d184 100644 --- a/Minecraft.Client/Platform/Linux/Linux_Minecraft.cpp +++ b/Minecraft.Client/Platform/Linux/Linux_Minecraft.cpp @@ -856,7 +856,6 @@ return -1; // Initialise TLS for tesselator, for this main thread Tesselator::CreateNewThreadStorage(1024 * 1024); // Initialise TLS for AABB and Vec3 pools, for this main thread - AABB::CreateNewThreadStorage(); Compression::CreateNewThreadStorage(); OldChunkStorage::CreateNewThreadStorage(); Level::enableLightingCache(); diff --git a/Minecraft.Client/Platform/Orbis/Orbis_Minecraft.cpp b/Minecraft.Client/Platform/Orbis/Orbis_Minecraft.cpp index 84e6fbf12..5744dc9d9 100644 --- a/Minecraft.Client/Platform/Orbis/Orbis_Minecraft.cpp +++ b/Minecraft.Client/Platform/Orbis/Orbis_Minecraft.cpp @@ -1040,7 +1040,6 @@ void RegisterAwardsWithProfileManager() { } int StartMinecraftThreadProc(void* lpParameter) { - AABB::UseDefaultThreadStorage(); Tesselator::CreateNewThreadStorage(1024 * 1024); RenderManager.InitialiseContext(); Minecraft::start(std::wstring(), std::wstring()); @@ -1376,7 +1375,6 @@ int main(int argc, const char* argv[]) { // Initialise TLS for tesselator, for this main thread Tesselator::CreateNewThreadStorage(1024 * 1024); // Initialise TLS for AABB and Vec3 pools, for this main thread - AABB::CreateNewThreadStorage(); Compression::CreateNewThreadStorage(); OldChunkStorage::CreateNewThreadStorage(); Level::enableLightingCache(); diff --git a/Minecraft.Client/Platform/PS3/PS3_Minecraft.cpp b/Minecraft.Client/Platform/PS3/PS3_Minecraft.cpp index e2200c8a8..6aaced5fd 100644 --- a/Minecraft.Client/Platform/PS3/PS3_Minecraft.cpp +++ b/Minecraft.Client/Platform/PS3/PS3_Minecraft.cpp @@ -1210,7 +1210,6 @@ int main() { // Initialise TLS for tesselator, for this main thread Tesselator::CreateNewThreadStorage(1024 * 1024); // Initialise TLS for AABB and Vec3 pools, for this main thread - AABB::CreateNewThreadStorage(); OldChunkStorage::CreateNewThreadStorage(); Level::enableLightingCache(); Tile::CreateNewThreadStorage(); diff --git a/Minecraft.Client/Platform/PS3/Xbox_Minecraft.cpp b/Minecraft.Client/Platform/PS3/Xbox_Minecraft.cpp index 90c153b8d..968ab073a 100644 --- a/Minecraft.Client/Platform/PS3/Xbox_Minecraft.cpp +++ b/Minecraft.Client/Platform/PS3/Xbox_Minecraft.cpp @@ -660,7 +660,6 @@ int APIENTRY _tWinMain(_In_ HINSTANCE hInstance, // Initialise TLS for tesselator, for this main thread Tesselator::CreateNewThreadStorage(1024 * 1024); // Initialise TLS for AABB and Vec3 pools, for this main thread - AABB::CreateNewThreadStorage(); Level::enableLightingCache(); Minecraft::main(); diff --git a/Minecraft.Client/Platform/PSVita/PSVita_Minecraft.cpp b/Minecraft.Client/Platform/PSVita/PSVita_Minecraft.cpp index 9065eccb7..4849f15a1 100644 --- a/Minecraft.Client/Platform/PSVita/PSVita_Minecraft.cpp +++ b/Minecraft.Client/Platform/PSVita/PSVita_Minecraft.cpp @@ -895,7 +895,6 @@ int main() { // Initialise TLS for tesselator, for this main thread Tesselator::CreateNewThreadStorage(1024 * 1024); // Initialise TLS for AABB and Vec3 pools, for this main thread - AABB::CreateNewThreadStorage(); Compression::CreateNewThreadStorage(); OldChunkStorage::CreateNewThreadStorage(); Level::enableLightingCache(); diff --git a/Minecraft.Client/Platform/Windows64/Windows64_Minecraft.cpp b/Minecraft.Client/Platform/Windows64/Windows64_Minecraft.cpp index 0e009e4ce..4fc3b34db 100644 --- a/Minecraft.Client/Platform/Windows64/Windows64_Minecraft.cpp +++ b/Minecraft.Client/Platform/Windows64/Windows64_Minecraft.cpp @@ -940,7 +940,6 @@ int APIENTRY _tWinMain(_In_ HINSTANCE hInstance, // Initialise TLS for tesselator, for this main thread Tesselator::CreateNewThreadStorage(1024 * 1024); // Initialise TLS for AABB and Vec3 pools, for this main thread - AABB::CreateNewThreadStorage(); Compression::CreateNewThreadStorage(); OldChunkStorage::CreateNewThreadStorage(); Level::enableLightingCache(); diff --git a/Minecraft.Client/Platform/Xbox/Xbox_Minecraft.cpp b/Minecraft.Client/Platform/Xbox/Xbox_Minecraft.cpp index 1b2cdd997..9a1530c85 100644 --- a/Minecraft.Client/Platform/Xbox/Xbox_Minecraft.cpp +++ b/Minecraft.Client/Platform/Xbox/Xbox_Minecraft.cpp @@ -699,7 +699,6 @@ int __cdecl main() { // Initialise TLS for tesselator, for this main thread Tesselator::CreateNewThreadStorage(1024 * 1024); // Initialise TLS for AABB and Vec3 pools, for this main thread - AABB::CreateNewThreadStorage(); Compression::CreateNewThreadStorage(); OldChunkStorage::CreateNewThreadStorage(); Level::enableLightingCache(); diff --git a/Minecraft.Client/Rendering/GameRenderer.cpp b/Minecraft.Client/Rendering/GameRenderer.cpp index e405931b0..7b1ac303b 100644 --- a/Minecraft.Client/Rendering/GameRenderer.cpp +++ b/Minecraft.Client/Rendering/GameRenderer.cpp @@ -1121,7 +1121,6 @@ void GameRenderer::FinishedReassigning() { int GameRenderer::runUpdate(void* lpParam) { Minecraft* minecraft = Minecraft::GetInstance(); - AABB::CreateNewThreadStorage(); Tesselator::CreateNewThreadStorage(1024 * 1024); Compression::UseDefaultThreadStorage(); RenderManager.InitialiseContext(); @@ -1200,7 +1199,6 @@ int GameRenderer::runUpdate(void* lpParam) { // PIXEndNamedEvent(); - AABB::resetPool(); m_updateEvents->Set(eUpdateEventIsFinished); } diff --git a/Minecraft.Client/Rendering/LevelRenderer.cpp b/Minecraft.Client/Rendering/LevelRenderer.cpp index 556d83ec7..0d5e9afa7 100644 --- a/Minecraft.Client/Rendering/LevelRenderer.cpp +++ b/Minecraft.Client/Rendering/LevelRenderer.cpp @@ -4030,7 +4030,6 @@ void LevelRenderer::staticCtor() { } int LevelRenderer::rebuildChunkThreadProc(void* lpParam) { - AABB::CreateNewThreadStorage(); Tesselator::CreateNewThreadStorage(1024 * 1024); RenderManager.InitialiseContext(); Chunk::CreateNewThreadStorage(); diff --git a/Minecraft.World/Util/AABB.cpp b/Minecraft.World/Util/AABB.cpp index 2cf5236e5..a31d27728 100644 --- a/Minecraft.World/Util/AABB.cpp +++ b/Minecraft.World/Util/AABB.cpp @@ -12,47 +12,6 @@ #include "HitResult.h" #include "Util/Vec3.h" -thread_local AABB::ThreadStorage* AABB::m_tlsPool = nullptr; -AABB::ThreadStorage* AABB::m_tlsPoolDefault = nullptr; - -AABB::ThreadStorage::ThreadStorage() { - pool = new AABB[POOL_SIZE]; // 4jcraft, needs to be deleted with delete[] - poolPointer = 0; -} - -AABB::ThreadStorage::~ThreadStorage() { - delete[] pool; // 4jcraft, changed to [] -} - -void AABB::CreateNewThreadStorage() { - ThreadStorage* tls = new ThreadStorage(); - if (m_tlsPoolDefault == nullptr) { - m_tlsPoolDefault = tls; - } - m_tlsPool = tls; -} - -void AABB::UseDefaultThreadStorage() { m_tlsPool = m_tlsPoolDefault; } - -void AABB::ReleaseThreadStorage() { - if (m_tlsPool != m_tlsPoolDefault) { - delete m_tlsPool; - } -} - -void AABB::clearPool() {} - -void AABB::resetPool() {} - -AABB* AABB::newTemp(double x0, double y0, double z0, double x1, double y1, - double z1) { - ThreadStorage* tls = m_tlsPool; - AABB* thisAABB = &tls->pool[tls->poolPointer]; - *thisAABB = {x0, y0, z0, x1, y1, z1}; - tls->poolPointer = (tls->poolPointer + 1) % ThreadStorage::POOL_SIZE; - return thisAABB; -} - AABB::AABB(double x0, double y0, double z0, double x1, double y1, double z1) { this->x0 = x0; this->y0 = y0; diff --git a/Minecraft.World/Util/AABB.h b/Minecraft.World/Util/AABB.h index 61d8446cd..fb62056d8 100644 --- a/Minecraft.World/Util/AABB.h +++ b/Minecraft.World/Util/AABB.h @@ -6,38 +6,13 @@ class HitResult; class AABB { - // 4J added so we can have separate pools for different threads - class ThreadStorage { - public: - static const int POOL_SIZE = 1024; - AABB* pool; - unsigned int poolPointer; - ThreadStorage(); - ~ThreadStorage(); - }; - static thread_local ThreadStorage* m_tlsPool; - static ThreadStorage* m_tlsPoolDefault; - public: - // Each new thread that needs to use Vec3 pools will need to call one of the - // following 2 functions, to either create its own local storage, or share - // the default storage already allocated by the main thread - static void CreateNewThreadStorage(); - static void UseDefaultThreadStorage(); - static void ReleaseThreadStorage(); - - static void clearPool(); - static void resetPool(); - static AABB* newTemp(double x0, double y0, double z0, double x1, double y1, - double z1); - double x0, y0, z0; double x1, y1, z1; AABB() {} AABB(double x0, double y0, double z0, double x1, double y1, double z1); -public: AABB expand(double xa, double ya, double za) const; AABB grow(double xa, double ya, double za) const; AABB minmax(const AABB& other) const; From c12f32f637ebebfbf8ce4bc69f3fd9e844f17b69 Mon Sep 17 00:00:00 2001 From: MatthewBeshay <92357869+MatthewBeshay@users.noreply.github.com> Date: Sat, 28 Mar 2026 20:29:12 +1100 Subject: [PATCH 037/170] fix: restore ghast reach checks and fire collision bounds after AABB refactor --- Minecraft.World/Entities/Entity.cpp | 4 ++-- Minecraft.World/Entities/Mobs/Ghast.cpp | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/Minecraft.World/Entities/Entity.cpp b/Minecraft.World/Entities/Entity.cpp index 216e49beb..007d82209 100644 --- a/Minecraft.World/Entities/Entity.cpp +++ b/Minecraft.World/Entities/Entity.cpp @@ -885,8 +885,8 @@ void Entity::move(double xa, double ya, double za, checkInsideTiles(); bool water = isInWaterOrRain(); - const AABB& shrunk = bb.shrink(0.001, 0.001, 0.001); - if (level->containsFireTile(&bb)) { + AABB shrunk = bb.shrink(0.001, 0.001, 0.001); + if (level->containsFireTile(&shrunk)) { burn(1); if (!water) { onFire++; diff --git a/Minecraft.World/Entities/Mobs/Ghast.cpp b/Minecraft.World/Entities/Mobs/Ghast.cpp index e6a36730c..7808df292 100644 --- a/Minecraft.World/Entities/Mobs/Ghast.cpp +++ b/Minecraft.World/Entities/Mobs/Ghast.cpp @@ -169,10 +169,11 @@ bool Ghast::canReach(double xt, double yt, double zt, double dist) { double xd = (xTarget - x) / dist; double yd = (yTarget - y) / dist; double zd = (zTarget - z) / dist; + AABB probe = bb; for (int d = 1; d < dist; d++) { - bb.move(xd, yd, zd); - if (!level->getCubes(shared_from_this(), &bb)->empty()) return false; + probe = probe.move(xd, yd, zd); + if (!level->getCubes(shared_from_this(), &probe)->empty()) return false; } return true; From f195fc555f19641d05b1e054238199d1089f529e Mon Sep 17 00:00:00 2001 From: milomc123 <33701036+milomc123@users.noreply.github.com> Date: Sat, 28 Mar 2026 09:59:48 +0000 Subject: [PATCH 038/170] fix(nix flake): Fix Nix build phase errors - postUnpack: use $sourceRoot instead of hardcoded "source/" so subprojects are copied into the actual unpacked directory - installPhase: call makeWrapper directly, it is a setup hook injected by nativeBuildInputs, not a bin/ binary - nativeBuildInputs: add makeWrapper and unzip --- flake.nix | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/flake.nix b/flake.nix index 24a17ed0b..fd8af4473 100644 --- a/flake.nix +++ b/flake.nix @@ -58,15 +58,15 @@ # 4jcraft - Meson expects this subprojects structure postUnpack = '' - mkdir -p source/subprojects + mkdir -p $sourceRoot/subprojects - cp -r ${inputs.shiggy} source/subprojects/shiggy - cp -r ${inputs."4jlibs"} source/subprojects/4jlibs - cp -r ${inputs.stb} source/subprojects/stb - cp -r ${inputs.simdutf} source/subprojects/simdutf - cp -r ${inputs.miniaudio} source/subprojects/miniaudio + cp -r ${inputs.shiggy} $sourceRoot/subprojects/shiggy + cp -r ${inputs."4jlibs"} $sourceRoot/subprojects/4jlibs + cp -r ${inputs.stb} $sourceRoot/subprojects/stb + cp -r ${inputs.simdutf} $sourceRoot/subprojects/simdutf + cp -r ${inputs.miniaudio} $sourceRoot/subprojects/miniaudio - chmod -R u+w source/subprojects + chmod -R u+w $sourceRoot/subprojects ''; # 4jcraft - `stb` and `simdutf` patches @@ -75,7 +75,7 @@ cp subprojects/packagefiles/simdutf/meson.build subprojects/simdutf/meson.build cp subprojects/packagefiles/simdutf/meson.options subprojects/simdutf/meson.options - ${pkgs.unzip} ${inputs.miniaudio-patch} -d miniaudio-patch-tmp + unzip ${inputs.miniaudio-patch} -d miniaudio-patch-tmp cp -r miniaudio-patch-tmp/*/. subprojects/miniaudio/ cat > subprojects/miniaudio.wrap < Date: Sat, 28 Mar 2026 12:53:07 -0500 Subject: [PATCH 039/170] refactor: remove `VertexArray` --- Minecraft.Client/Rendering/Cube.cpp | 89 ++++++++++++-------------- Minecraft.Client/Rendering/Cube.h | 8 +-- Minecraft.Client/Rendering/Polygon.cpp | 69 +++++++++----------- Minecraft.Client/Rendering/Polygon.h | 14 ++-- Minecraft.Client/Rendering/Vertex.cpp | 21 +----- Minecraft.Client/Rendering/Vertex.h | 23 +++++-- Minecraft.World/Util/ArrayWithLength.h | 1 - 7 files changed, 104 insertions(+), 121 deletions(-) diff --git a/Minecraft.Client/Rendering/Cube.cpp b/Minecraft.Client/Rendering/Cube.cpp index 259eb9cac..07222aa43 100644 --- a/Minecraft.Client/Rendering/Cube.cpp +++ b/Minecraft.Client/Rendering/Cube.cpp @@ -1,18 +1,9 @@ #include "../Platform/stdafx.h" #include "Models/Model.h" #include "Models/ModelPart.h" +#include "Rendering/Vertex.h" #include "Cube.h" - -// 4J - added - helper function to set up vertex arrays -VertexArray Cube::VertexArray4(Vertex* v0, Vertex* v1, Vertex* v2, Vertex* v3) { - VertexArray ret = VertexArray(4); - ret[0] = v0; - ret[1] = v1; - ret[2] = v2; - ret[3] = v3; - - return ret; -} +#include // void Cube::addBox(float x0, float y0, float z0, int w, int h, int d, float g) Cube::Cube(ModelPart* modelPart, int xTexOffs, int yTexOffs, float x0, float y0, @@ -25,7 +16,11 @@ Cube::Cube(ModelPart* modelPart, int xTexOffs, int yTexOffs, float x0, float y0, z0(z0), x1(x0 + w), y1(y0 + h), - z1(z0 + d) { + z1(z0 + d), + vertices({Vertex{0, 0, 0, 0, 0}, Vertex{0, 0, 0, 0, 0}, + Vertex{0, 0, 0, 0, 0}, Vertex{0, 0, 0, 0, 0}, + Vertex{0, 0, 0, 0, 0}, Vertex{0, 0, 0, 0, 0}, + Vertex{0, 0, 0, 0, 0}, Vertex{0, 0, 0, 0, 0}}) { // this->x0 = x0; // this->y0 = y0; // this->z0 = z0; @@ -33,7 +28,6 @@ Cube::Cube(ModelPart* modelPart, int xTexOffs, int yTexOffs, float x0, float y0, // this->y1 = y0 + h; // this->z1 = z0 + d; - vertices = VertexArray(8); polygons = PolygonArray(6); float x1 = x0 + w; @@ -53,15 +47,15 @@ Cube::Cube(ModelPart* modelPart, int xTexOffs, int yTexOffs, float x0, float y0, x0 = tmp; } - Vertex* u0 = new Vertex(x0, y0, z0, 0, 0); - Vertex* u1 = new Vertex(x1, y0, z0, 0, 8); - Vertex* u2 = new Vertex(x1, y1, z0, 8, 8); - Vertex* u3 = new Vertex(x0, y1, z0, 8, 0); + const Vertex u0 = Vertex(x0, y0, z0, 0, 0); + const Vertex u1 = Vertex(x1, y0, z0, 0, 8); + const Vertex u2 = Vertex(x1, y1, z0, 8, 8); + const Vertex u3 = Vertex(x0, y1, z0, 8, 0); - Vertex* l0 = new Vertex(x0, y0, z1, 0, 0); - Vertex* l1 = new Vertex(x1, y0, z1, 0, 8); - Vertex* l2 = new Vertex(x1, y1, z1, 8, 8); - Vertex* l3 = new Vertex(x0, y1, z1, 8, 0); + const Vertex l0 = Vertex(x0, y0, z1, 0, 0); + const Vertex l1 = Vertex(x1, y0, z1, 0, 8); + const Vertex l2 = Vertex(x1, y1, z1, 8, 8); + const Vertex l3 = Vertex(x0, y1, z1, 8, 0); vertices[0] = u0; vertices[1] = u1; @@ -75,42 +69,43 @@ Cube::Cube(ModelPart* modelPart, int xTexOffs, int yTexOffs, float x0, float y0, // 4J - added ability to mask individual faces int faceCount = 0; if (faceMask & 1) - polygons[faceCount++] = - new _Polygon(VertexArray4(l1, u1, u2, l2), xTexOffs + d + w, - yTexOffs + d, xTexOffs + d + w + d, yTexOffs + d + h, - modelPart->xTexSize, modelPart->yTexSize); // Right + polygons[faceCount++] = new _Polygon( + std::array{l1, u1, u2, l2}, xTexOffs + d + w, + yTexOffs + d, xTexOffs + d + w + d, yTexOffs + d + h, + modelPart->xTexSize, modelPart->yTexSize); // Right if (faceMask & 2) - polygons[faceCount++] = - new _Polygon(VertexArray4(u0, l0, l3, u3), xTexOffs + 0, - yTexOffs + d, xTexOffs + d, yTexOffs + d + h, - modelPart->xTexSize, modelPart->yTexSize); // Left + polygons[faceCount++] = new _Polygon( + std::array{u0, l0, l3, u3}, xTexOffs + 0, + yTexOffs + d, xTexOffs + d, yTexOffs + d + h, modelPart->xTexSize, + modelPart->yTexSize); // Left if (faceMask & 4) - polygons[faceCount++] = - new _Polygon(VertexArray4(l1, l0, u0, u1), xTexOffs + d, - yTexOffs + 0, xTexOffs + d + w, yTexOffs + d, - modelPart->xTexSize, modelPart->yTexSize); // Up + polygons[faceCount++] = new _Polygon( + std::array{l1, l0, u0, u1}, xTexOffs + d, + yTexOffs + 0, xTexOffs + d + w, yTexOffs + d, modelPart->xTexSize, + modelPart->yTexSize); // Up if (bFlipPoly3UVs) { if (faceMask & 8) - polygons[faceCount++] = - new _Polygon(VertexArray4(u2, u3, l3, l2), xTexOffs + d + w, - yTexOffs + 0, xTexOffs + d + w + w, yTexOffs + d, - modelPart->xTexSize, modelPart->yTexSize); // Down + polygons[faceCount++] = new _Polygon( + std::array{u2, u3, l3, l2}, xTexOffs + d + w, + yTexOffs + 0, xTexOffs + d + w + w, yTexOffs + d, + modelPart->xTexSize, modelPart->yTexSize); // Down } else { if (faceMask & 8) - polygons[faceCount++] = - new _Polygon(VertexArray4(u2, u3, l3, l2), xTexOffs + d + w, - yTexOffs + d, xTexOffs + d + w + w, yTexOffs + 0, - modelPart->xTexSize, modelPart->yTexSize); // Down + polygons[faceCount++] = new _Polygon( + std::array{u2, u3, l3, l2}, xTexOffs + d + w, + yTexOffs + d, xTexOffs + d + w + w, yTexOffs + 0, + modelPart->xTexSize, modelPart->yTexSize); // Down } if (faceMask & 16) - polygons[faceCount++] = - new _Polygon(VertexArray4(u1, u0, u3, u2), xTexOffs + d, - yTexOffs + d, xTexOffs + d + w, yTexOffs + d + h, - modelPart->xTexSize, modelPart->yTexSize); // Front + polygons[faceCount++] = new _Polygon( + std::array{u1, u0, u3, u2}, xTexOffs + d, + yTexOffs + d, xTexOffs + d + w, yTexOffs + d + h, + modelPart->xTexSize, modelPart->yTexSize); // Front if (faceMask & 32) polygons[faceCount++] = new _Polygon( - VertexArray4(l0, l1, l2, l3), xTexOffs + d + w + d, yTexOffs + d, - xTexOffs + d + w + d + w, yTexOffs + d + h, modelPart->xTexSize, + std::array{l0, l1, l2, l3}, xTexOffs + d + w + d, + yTexOffs + d, xTexOffs + d + w + d + w, yTexOffs + d + h, + modelPart->xTexSize, modelPart->yTexSize); // Back polygons.length = faceCount; diff --git a/Minecraft.Client/Rendering/Cube.h b/Minecraft.Client/Rendering/Cube.h index 549672e45..1debdc556 100644 --- a/Minecraft.Client/Rendering/Cube.h +++ b/Minecraft.Client/Rendering/Cube.h @@ -1,4 +1,5 @@ #pragma once +#include #include "../../Minecraft.World/Util/ArrayWithLength.h" #include "Vertex.h" #include "Polygon.h" @@ -7,7 +8,7 @@ class Model; class Cube { private: - VertexArray vertices; + std::array vertices; PolygonArray polygons; public: @@ -19,11 +20,6 @@ public: float z0, int w, int h, int d, float g, int faceMask = 63, bool bFlipPoly3UVs = false); // 4J - added faceMask -private: - VertexArray VertexArray4(Vertex* v0, Vertex* v1, Vertex* v2, - Vertex* v3); // 4J added - -public: void render(Tesselator* t, float scale); Cube* setId(const std::wstring& id); }; diff --git a/Minecraft.Client/Rendering/Polygon.cpp b/Minecraft.Client/Rendering/Polygon.cpp index 44d65648b..bcfa26b37 100644 --- a/Minecraft.Client/Rendering/Polygon.cpp +++ b/Minecraft.Client/Rendering/Polygon.cpp @@ -1,52 +1,44 @@ -#include "../Platform/stdafx.h" +#include "Rendering/Vertex.h" #include "Polygon.h" +#include +#include +#include -// 4J added for common init code -void _Polygon::_init(VertexArray vertices) { - vertexCount = 0; - _flipNormal = false; - - this->vertices = vertices; - vertexCount = vertices.length; -} - -_Polygon::_Polygon(VertexArray vertices) { _init(vertices); } - -_Polygon::_Polygon(VertexArray vertices, int u0, int v0, int u1, int v1, - float xTexSize, float yTexSize) { - _init(vertices); +_Polygon::_Polygon(const std::span vertices) + : vertexCount(vertices.size()), vertices(vertices.begin(), vertices.end()) {} +_Polygon::_Polygon(const std::span vertices, int u0, int v0, + int u1, int v1, float xTexSize, float yTexSize) + : vertexCount(vertices.size()) { // 4J - added - don't assume that u1 > u0, v1 > v0 float us = (u1 > u0) ? (0.1f / xTexSize) : (-0.1f / xTexSize); float vs = (v1 > v0) ? (0.1f / yTexSize) : (-0.1f / yTexSize); - vertices[0] = vertices[0]->remap(u1 / xTexSize - us, v0 / yTexSize + vs); - vertices[1] = vertices[1]->remap(u0 / xTexSize + us, v0 / yTexSize + vs); - vertices[2] = vertices[2]->remap(u0 / xTexSize + us, v1 / yTexSize - vs); - vertices[3] = vertices[3]->remap(u1 / xTexSize - us, v1 / yTexSize - vs); + this->vertices = { + vertices[0].remap(u1 / xTexSize - us, v0 / yTexSize + vs), + vertices[1].remap(u0 / xTexSize + us, v0 / yTexSize + vs), + vertices[2].remap(u0 / xTexSize + us, v1 / yTexSize - vs), + vertices[3].remap(u1 / xTexSize - us, v1 / yTexSize - vs), + }; } -_Polygon::_Polygon(VertexArray vertices, float u0, float v0, float u1, - float v1) { - _init(vertices); - - vertices[0] = vertices[0]->remap(u1, v0); - vertices[1] = vertices[1]->remap(u0, v0); - vertices[2] = vertices[2]->remap(u0, v1); - vertices[3] = vertices[3]->remap(u1, v1); -} +_Polygon::_Polygon(const std::span vertices, float u0, + float v0, float u1, float v1) + : vertexCount(vertices.size()), + vertices({ + vertices[0].remap(u1, v0), + vertices[1].remap(u0, v0), + vertices[2].remap(u0, v1), + vertices[3].remap(u1, v1), + }) {} void _Polygon::mirror() { - VertexArray newVertices = VertexArray(vertices.length); - for (unsigned int i = 0; i < vertices.length; i++) - newVertices[i] = vertices[vertices.length - i - 1]; - delete[] vertices.data; - vertices = newVertices; + std::reverse(vertices.begin(), vertices.end()); } void _Polygon::render(Tesselator* t, float scale) { - Vec3 v0 = vertices[1]->pos.vectorTo(vertices[0]->pos); - Vec3 v1 = vertices[1]->pos.vectorTo(vertices[2]->pos); + Vec3 v0 = vertices[1].pos.vectorTo(vertices[0].pos); + Vec3 v1 = vertices[1].pos.vectorTo(vertices[2].pos); Vec3 n = v1.cross(v0).normalize(); t->begin(); @@ -57,10 +49,11 @@ void _Polygon::render(Tesselator* t, float scale) { } for (int i = 0; i < 4; i++) { - Vertex* v = vertices[i]; - t->vertexUV((float)(v->pos.x * scale), (float)(v->pos.y * scale), - (float)(v->pos.z * scale), (float)(v->u), (float)(v->v)); + Vertex v = vertices[i]; + t->vertexUV((float)(v.pos.x * scale), (float)(v.pos.y * scale), + (float)(v.pos.z * scale), (float)(v.u), (float)(v.v)); } + t->end(); } diff --git a/Minecraft.Client/Rendering/Polygon.h b/Minecraft.Client/Rendering/Polygon.h index 38c6e9094..77c4a90a5 100644 --- a/Minecraft.Client/Rendering/Polygon.h +++ b/Minecraft.Client/Rendering/Polygon.h @@ -1,22 +1,24 @@ #pragma once + +#include +#include #include "Vertex.h" #include "Tesselator.h" #include "../../Minecraft.World/Util/ArrayWithLength.h" class _Polygon { public: - VertexArray vertices; + std::vector vertices; int vertexCount; private: bool _flipNormal; public: - void _init(VertexArray vertices); // 4J added for common init code - _Polygon(VertexArray vertices); - _Polygon(VertexArray vertices, int u0, int v0, int u1, int v1, - float xTexSize, float yTexSize); - _Polygon(VertexArray vertices, float u0, float v0, float u1, float v1); + _Polygon(std::span vertices); + _Polygon(std::span vertices, int u0, int v0, int u1, + int v1, float xTexSize, float yTexSize); + _Polygon(std::span vertices, float u0, float v0, float u1, float v1); void mirror(); void render(Tesselator* t, float scale); _Polygon* flipNormal(); diff --git a/Minecraft.Client/Rendering/Vertex.cpp b/Minecraft.Client/Rendering/Vertex.cpp index 7222ed172..b323c0f79 100644 --- a/Minecraft.Client/Rendering/Vertex.cpp +++ b/Minecraft.Client/Rendering/Vertex.cpp @@ -1,22 +1,5 @@ -#include "../Platform/stdafx.h" #include "Vertex.h" -Vertex::Vertex(float x, float y, float z, float u, float v) { - this->pos = Vec3(x, y, z); - this->u = u; - this->v = v; -} - -Vertex* Vertex::remap(float u, float v) { return new Vertex(this, u, v); } - -Vertex::Vertex(Vertex* vertex, float u, float v) { - this->pos = vertex->pos; - this->u = u; - this->v = v; -} - -Vertex::Vertex(Vec3* pos, float u, float v) { - this->pos = *pos; - this->u = u; - this->v = v; +Vertex Vertex::remap(const float u, const float v) const { + return Vertex(pos.x, pos.y, pos.z, u, v); } diff --git a/Minecraft.Client/Rendering/Vertex.h b/Minecraft.Client/Rendering/Vertex.h index 7c4492a8d..7a175011f 100644 --- a/Minecraft.Client/Rendering/Vertex.h +++ b/Minecraft.Client/Rendering/Vertex.h @@ -7,8 +7,23 @@ public: float u, v; public: - Vertex(float x, float y, float z, float u, float v); - Vertex* remap(float u, float v); - Vertex(Vertex* vertex, float u, float v); - Vertex(Vec3* pos, float u, float v); + constexpr Vertex(float x, float y, float z, float u, float v) + : pos({x, y, z}) + , u(u) + , v(v) + {} + + constexpr Vertex(Vertex* vertex, float u, float v) + : pos(vertex->pos) + , u(u) + , v(v) + {} + + constexpr Vertex(Vec3* pos, float u, float v) + : pos(*pos) + , u(u) + , v(v) + {} + + Vertex remap(float u, float v) const; }; diff --git a/Minecraft.World/Util/ArrayWithLength.h b/Minecraft.World/Util/ArrayWithLength.h index d433329f1..8f3668342 100644 --- a/Minecraft.World/Util/ArrayWithLength.h +++ b/Minecraft.World/Util/ArrayWithLength.h @@ -114,7 +114,6 @@ typedef arrayWithLength TileArray; typedef arrayWithLength StatArray; typedef arrayWithLength MobCategoryArray; typedef arrayWithLength FileArray; -typedef arrayWithLength VertexArray; typedef arrayWithLength<_Polygon*> PolygonArray; typedef arrayWithLength ServerLevelArray; typedef arrayWithLength MultiPlayerLevelArray; From f614e661d2001a5ca789fa59a7fd5976e94a9f2e Mon Sep 17 00:00:00 2001 From: orng Date: Sat, 28 Mar 2026 13:34:20 -0500 Subject: [PATCH 040/170] refactor: remove `PolygonArray` --- Minecraft.Client/Rendering/Cube.cpp | 35 ++++++++++---------------- Minecraft.Client/Rendering/Cube.h | 2 +- Minecraft.Client/Rendering/Polygon.h | 1 + Minecraft.World/Util/ArrayWithLength.h | 1 - 4 files changed, 15 insertions(+), 24 deletions(-) diff --git a/Minecraft.Client/Rendering/Cube.cpp b/Minecraft.Client/Rendering/Cube.cpp index 07222aa43..67222bf94 100644 --- a/Minecraft.Client/Rendering/Cube.cpp +++ b/Minecraft.Client/Rendering/Cube.cpp @@ -20,16 +20,8 @@ Cube::Cube(ModelPart* modelPart, int xTexOffs, int yTexOffs, float x0, float y0, vertices({Vertex{0, 0, 0, 0, 0}, Vertex{0, 0, 0, 0, 0}, Vertex{0, 0, 0, 0, 0}, Vertex{0, 0, 0, 0, 0}, Vertex{0, 0, 0, 0, 0}, Vertex{0, 0, 0, 0, 0}, - Vertex{0, 0, 0, 0, 0}, Vertex{0, 0, 0, 0, 0}}) { - // this->x0 = x0; - // this->y0 = y0; - // this->z0 = z0; - // this->x1 = x0 + w; - // this->y1 = y0 + h; - // this->z1 = z0 + d; - - polygons = PolygonArray(6); - + Vertex{0, 0, 0, 0, 0}, Vertex{0, 0, 0, 0, 0}}), + polygons({}) { float x1 = x0 + w; float y1 = y0 + h; float z1 = z0 + d; @@ -69,55 +61,54 @@ Cube::Cube(ModelPart* modelPart, int xTexOffs, int yTexOffs, float x0, float y0, // 4J - added ability to mask individual faces int faceCount = 0; if (faceMask & 1) - polygons[faceCount++] = new _Polygon( + polygons[faceCount++] = _Polygon( std::array{l1, u1, u2, l2}, xTexOffs + d + w, yTexOffs + d, xTexOffs + d + w + d, yTexOffs + d + h, modelPart->xTexSize, modelPart->yTexSize); // Right if (faceMask & 2) - polygons[faceCount++] = new _Polygon( + polygons[faceCount++] = _Polygon( std::array{u0, l0, l3, u3}, xTexOffs + 0, yTexOffs + d, xTexOffs + d, yTexOffs + d + h, modelPart->xTexSize, modelPart->yTexSize); // Left if (faceMask & 4) - polygons[faceCount++] = new _Polygon( + polygons[faceCount++] = _Polygon( std::array{l1, l0, u0, u1}, xTexOffs + d, yTexOffs + 0, xTexOffs + d + w, yTexOffs + d, modelPart->xTexSize, modelPart->yTexSize); // Up if (bFlipPoly3UVs) { if (faceMask & 8) - polygons[faceCount++] = new _Polygon( + polygons[faceCount++] = _Polygon( std::array{u2, u3, l3, l2}, xTexOffs + d + w, yTexOffs + 0, xTexOffs + d + w + w, yTexOffs + d, modelPart->xTexSize, modelPart->yTexSize); // Down } else { if (faceMask & 8) - polygons[faceCount++] = new _Polygon( + polygons[faceCount++] = _Polygon( std::array{u2, u3, l3, l2}, xTexOffs + d + w, yTexOffs + d, xTexOffs + d + w + w, yTexOffs + 0, modelPart->xTexSize, modelPart->yTexSize); // Down } if (faceMask & 16) - polygons[faceCount++] = new _Polygon( + polygons[faceCount++] = _Polygon( std::array{u1, u0, u3, u2}, xTexOffs + d, yTexOffs + d, xTexOffs + d + w, yTexOffs + d + h, modelPart->xTexSize, modelPart->yTexSize); // Front if (faceMask & 32) - polygons[faceCount++] = new _Polygon( + polygons[faceCount++] = _Polygon( std::array{l0, l1, l2, l3}, xTexOffs + d + w + d, yTexOffs + d, xTexOffs + d + w + d + w, yTexOffs + d + h, modelPart->xTexSize, modelPart->yTexSize); // Back - polygons.length = faceCount; if (modelPart->bMirror) { - for (unsigned int i = 0; i < polygons.length; i++) - polygons[i]->mirror(); + for (unsigned int i = 0; i < polygons.size(); i++) + polygons[i].mirror(); } } void Cube::render(Tesselator* t, float scale) { - for (int i = 0; i < polygons.length; i++) { - polygons[i]->render(t, scale); + for (int i = 0; i < polygons.size(); i++) { + polygons[i].render(t, scale); } } diff --git a/Minecraft.Client/Rendering/Cube.h b/Minecraft.Client/Rendering/Cube.h index 1debdc556..1a3974275 100644 --- a/Minecraft.Client/Rendering/Cube.h +++ b/Minecraft.Client/Rendering/Cube.h @@ -9,7 +9,7 @@ class Model; class Cube { private: std::array vertices; - PolygonArray polygons; + std::array<_Polygon, 6> polygons; public: const float x0, y0, z0, x1, y1, z1; diff --git a/Minecraft.Client/Rendering/Polygon.h b/Minecraft.Client/Rendering/Polygon.h index 77c4a90a5..a9ecf5638 100644 --- a/Minecraft.Client/Rendering/Polygon.h +++ b/Minecraft.Client/Rendering/Polygon.h @@ -15,6 +15,7 @@ private: bool _flipNormal; public: + _Polygon() = default; _Polygon(std::span vertices); _Polygon(std::span vertices, int u0, int v0, int u1, int v1, float xTexSize, float yTexSize); diff --git a/Minecraft.World/Util/ArrayWithLength.h b/Minecraft.World/Util/ArrayWithLength.h index 8f3668342..c476a372f 100644 --- a/Minecraft.World/Util/ArrayWithLength.h +++ b/Minecraft.World/Util/ArrayWithLength.h @@ -114,7 +114,6 @@ typedef arrayWithLength TileArray; typedef arrayWithLength StatArray; typedef arrayWithLength MobCategoryArray; typedef arrayWithLength FileArray; -typedef arrayWithLength<_Polygon*> PolygonArray; typedef arrayWithLength ServerLevelArray; typedef arrayWithLength MultiPlayerLevelArray; typedef arrayWithLength LevelArray; From 659b9c32cbde78228e93bd3772c8120861091990 Mon Sep 17 00:00:00 2001 From: orng Date: Sat, 28 Mar 2026 13:50:35 -0500 Subject: [PATCH 041/170] fix: OOB when iterating over all cube faces --- Minecraft.Client/Rendering/Cube.cpp | 4 ++-- Minecraft.Client/Rendering/Cube.h | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/Minecraft.Client/Rendering/Cube.cpp b/Minecraft.Client/Rendering/Cube.cpp index 67222bf94..2291d0923 100644 --- a/Minecraft.Client/Rendering/Cube.cpp +++ b/Minecraft.Client/Rendering/Cube.cpp @@ -59,7 +59,7 @@ Cube::Cube(ModelPart* modelPart, int xTexOffs, int yTexOffs, float x0, float y0, vertices[7] = l3; // 4J - added ability to mask individual faces - int faceCount = 0; + faceCount = 0; if (faceMask & 1) polygons[faceCount++] = _Polygon( std::array{l1, u1, u2, l2}, xTexOffs + d + w, @@ -107,7 +107,7 @@ Cube::Cube(ModelPart* modelPart, int xTexOffs, int yTexOffs, float x0, float y0, } void Cube::render(Tesselator* t, float scale) { - for (int i = 0; i < polygons.size(); i++) { + for (int i = 0; i < faceCount; i++) { polygons[i].render(t, scale); } } diff --git a/Minecraft.Client/Rendering/Cube.h b/Minecraft.Client/Rendering/Cube.h index 1a3974275..9075d0950 100644 --- a/Minecraft.Client/Rendering/Cube.h +++ b/Minecraft.Client/Rendering/Cube.h @@ -1,5 +1,6 @@ #pragma once #include +#include #include "../../Minecraft.World/Util/ArrayWithLength.h" #include "Vertex.h" #include "Polygon.h" @@ -10,6 +11,7 @@ class Cube { private: std::array vertices; std::array<_Polygon, 6> polygons; + uint8_t faceCount; public: const float x0, y0, z0, x1, y1, z1; From 75d83a455608eedcd27d43a6ea15a33c0071775a Mon Sep 17 00:00:00 2001 From: aedanmills <40202903+aedanmills@users.noreply.github.com> Date: Sat, 28 Mar 2026 21:01:28 -0400 Subject: [PATCH 042/170] Fixed broken quit game button again. --- Minecraft.Assets/Windows64Media/loc/en-EN/strings.lang | 6 ++++++ Minecraft.Client/Platform/Common/UI/UIScene_MainMenu.cpp | 7 ++++--- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/Minecraft.Assets/Windows64Media/loc/en-EN/strings.lang b/Minecraft.Assets/Windows64Media/loc/en-EN/strings.lang index 2a3a90f32..f29d1e6a8 100644 --- a/Minecraft.Assets/Windows64Media/loc/en-EN/strings.lang +++ b/Minecraft.Assets/Windows64Media/loc/en-EN/strings.lang @@ -7071,6 +7071,9 @@ All Ender Chests in a world are linked. Items placed into an Ender Chest are acc OK + + Cancel + SELECT @@ -7198,6 +7201,9 @@ You can upload a world save to the save transfer area using Minecraft: PlayStati Exit Game + + Are you sure you want to exit the game? + You have been returned to the title screen because your Xbox profile was signed out diff --git a/Minecraft.Client/Platform/Common/UI/UIScene_MainMenu.cpp b/Minecraft.Client/Platform/Common/UI/UIScene_MainMenu.cpp index 29fa2b306..d2d28903c 100644 --- a/Minecraft.Client/Platform/Common/UI/UIScene_MainMenu.cpp +++ b/Minecraft.Client/Platform/Common/UI/UIScene_MainMenu.cpp @@ -363,7 +363,6 @@ void UIScene_MainMenu::handlePress(F64 controlId, F64 childId) { signInReturnedFunc = &UIScene_MainMenu::UnlockFullGame_SignInReturned; break; -#if defined _XBOX case eControl_Exit: if (ProfileManager.IsFullVersion()) { unsigned int uiIDA[2]; @@ -372,14 +371,16 @@ void UIScene_MainMenu::handlePress(F64 controlId, F64 childId) { ui.RequestErrorMessage( IDS_WARNING_ARCADE_TITLE, IDS_WARNING_ARCADE_TEXT, uiIDA, 2, XUSER_INDEX_ANY, &UIScene_MainMenu::ExitGameReturned, this); - } else { + } +#if defined _XBOX //|| _ENABLEIGGY + else { #ifdef _XBOX_ONE ui.ShowPlayerDisplayname(true); #endif ui.NavigateToScene(primaryPad, eUIScene_TrialExitUpsell); } - break; #endif + break; #ifdef _DURANGO case eControl_XboxHelp: From ad77a955c07eb12df89b9abbfbfc7623cca4fa68 Mon Sep 17 00:00:00 2001 From: Tropical <42101043+tropicaaal@users.noreply.github.com> Date: Sat, 28 Mar 2026 21:36:17 -0500 Subject: [PATCH 043/170] fix: correctly restore entity bounding boxes when computing movement physics --- Minecraft.World/Entities/Entity.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Minecraft.World/Entities/Entity.cpp b/Minecraft.World/Entities/Entity.cpp index 007d82209..0321c5ac7 100644 --- a/Minecraft.World/Entities/Entity.cpp +++ b/Minecraft.World/Entities/Entity.cpp @@ -664,6 +664,8 @@ void Entity::move(double xa, double ya, double za, double yaOrg = ya; double zaOrg = za; + AABB bbOrg = bb; + bool isPlayerSneaking = onGround && isSneaking() && instanceof(eTYPE_PLAYER); @@ -769,6 +771,9 @@ void Entity::move(double xa, double ya, double za, ya = footSize; za = zaOrg; + AABB normal = bb; + bb = bbOrg; + // 4J - added extra expand, as if we don't move up by footSize by // hitting a block above us, then overall we could be trying to move as // much as footSize downwards, so we'd better include cubes under our @@ -825,6 +830,7 @@ void Entity::move(double xa, double ya, double za, xa = xaN; ya = yaN; za = zaN; + bb = normal; } } From 2302f25e93e199ec34f1636d27136b37336961db Mon Sep 17 00:00:00 2001 From: Tropical <42101043+tropicaaal@users.noreply.github.com> Date: Sat, 28 Mar 2026 21:38:26 -0500 Subject: [PATCH 044/170] chore: fmt --- Minecraft.World/Entities/Entity.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Minecraft.World/Entities/Entity.cpp b/Minecraft.World/Entities/Entity.cpp index 0321c5ac7..64e5a0bb4 100644 --- a/Minecraft.World/Entities/Entity.cpp +++ b/Minecraft.World/Entities/Entity.cpp @@ -462,8 +462,8 @@ void Entity::setPos(double x, double y, double z) { this->z = z; float w = bbWidth / 2; float h = bbHeight; - bb = {x - w, y - heightOffset + ySlideOffset, z - w, x + w, - y - heightOffset + ySlideOffset + h, z + w}; + bb = {x - w, y - heightOffset + ySlideOffset, z - w, + x + w, y - heightOffset + ySlideOffset + h, z + w}; } void Entity::turn(float xo, float yo) { From 740f1b5c6444b9e7eeeef5b0675d6bc10e9e33e9 Mon Sep 17 00:00:00 2001 From: aedanmills <40202903+aedanmills@users.noreply.github.com> Date: Sat, 28 Mar 2026 22:53:15 -0400 Subject: [PATCH 045/170] Update --- Minecraft.Client/Platform/Common/UI/UIScene_MainMenu.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Minecraft.Client/Platform/Common/UI/UIScene_MainMenu.cpp b/Minecraft.Client/Platform/Common/UI/UIScene_MainMenu.cpp index d2d28903c..064805692 100644 --- a/Minecraft.Client/Platform/Common/UI/UIScene_MainMenu.cpp +++ b/Minecraft.Client/Platform/Common/UI/UIScene_MainMenu.cpp @@ -363,6 +363,7 @@ void UIScene_MainMenu::handlePress(F64 controlId, F64 childId) { signInReturnedFunc = &UIScene_MainMenu::UnlockFullGame_SignInReturned; break; +#if defined(_XBOX) || defined(__linux__) case eControl_Exit: if (ProfileManager.IsFullVersion()) { unsigned int uiIDA[2]; @@ -372,7 +373,6 @@ void UIScene_MainMenu::handlePress(F64 controlId, F64 childId) { IDS_WARNING_ARCADE_TITLE, IDS_WARNING_ARCADE_TEXT, uiIDA, 2, XUSER_INDEX_ANY, &UIScene_MainMenu::ExitGameReturned, this); } -#if defined _XBOX //|| _ENABLEIGGY else { #ifdef _XBOX_ONE ui.ShowPlayerDisplayname(true); From 3fc458c4bdfc5eac6f5475fb4e4490ca1c778a08 Mon Sep 17 00:00:00 2001 From: orng Date: Sat, 28 Mar 2026 22:50:30 -0500 Subject: [PATCH 046/170] ci: make `build-linux` use `flake.nix` --- .github/workflows/build-linux.yml | 132 +++--------------------------- 1 file changed, 13 insertions(+), 119 deletions(-) diff --git a/.github/workflows/build-linux.yml b/.github/workflows/build-linux.yml index 7d73c103d..acec27a69 100644 --- a/.github/workflows/build-linux.yml +++ b/.github/workflows/build-linux.yml @@ -1,132 +1,26 @@ -name: Build (Linux, x86_64) +name: Build (Linux x86/64) on: push: - paths: - - '**.cpp' - - '**.h' - - '**.c' - - '**/meson.build' - - 'meson.build' - - '**/CMakeLists.txt' - - 'CMakeLists.txt' - - '.github/workflows/build-linux.yml' - pull_request: - paths: - - '**.cpp' - - '**.h' - - '**.c' - - '**/meson.build' - - 'meson.build' - - '**/CMakeLists.txt' - - 'CMakeLists.txt' - - '.github/workflows/build-linux.yml' + - "**.cpp" + - "**.h" + - "**.meson.build" + - ".github/workflows/*" jobs: build-linux: runs-on: ubuntu-latest steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v5 - - name: Install system dependencies - run: | - sudo apt-get update - sudo apt-get install -y build-essential ccache python3 python3-pip ninja-build libsdl2-dev libgl-dev libglu1-mesa-dev libpthread-stubs0-dev - python -m pip install meson - # Set a reasonable ccache size - ccache -M 5G || true - - - name: Restore ccache - uses: actions/cache@v4 + - name: Install Nix + uses: cachix/install-nix-action@v31 with: - path: ~/.ccache - key: ${{ runner.os }}-ccache-${{ hashFiles('**/meson.build') }} + nix_path: nixpkgs=channel:nixos-unstable - - name: Restore meson cache - uses: actions/cache@v4 - with: - path: ~/.cache/meson - key: ${{ runner.os }}-meson-${{ hashFiles('**/meson.build') }} + - name: Build + run: nix build - - name: Configure Meson - env: - CC: "ccache clang" - CXX: "ccache clang++" - CCACHE_DIR: ${{ runner.temp }}/ccache - run: | - mkdir -p "$CCACHE_DIR" - export CCACHE_DIR="$CCACHE_DIR" - meson setup build_release --wipe --buildtype=release --native-file=./scripts/llvm_native.txt - - - name: Build with Meson - env: - CC: "ccache clang" - CXX: "ccache clang++" - CCACHE_DIR: ${{ runner.temp }}/ccache - run: | - export CCACHE_DIR="${{ runner.temp }}/ccache" - # Use all available cores for faster parallel builds - meson compile -C build_release -j $(nproc) -v Minecraft.Client - - - name: Install patchelf - run: sudo apt-get install -y patchelf - - - name: Upload artifact - uses: actions/upload-artifact@v4 - with: - name: minecraft-client-linux-release_exe-${{ github.sha }} - path: build_release/Minecraft.Client/Minecraft.Client - retention-days: 7 - build-linux-debug: - runs-on: ubuntu-latest - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Install system dependencies - run: | - sudo apt-get update - sudo apt-get install -y build-essential ccache python3 python3-pip ninja-build libsdl2-dev libgl-dev libglu1-mesa-dev libpthread-stubs0-dev - python -m pip install meson - # Set a reasonable ccache size - ccache -M 5G || true - - - name: Restore ccache - uses: actions/cache@v4 - with: - path: ~/.ccache - key: ${{ runner.os }}-ccache-debug-${{ hashFiles('**/meson.build') }} - - - name: Restore meson cache - uses: actions/cache@v4 - with: - path: ~/.cache/meson - key: ${{ runner.os }}-meson-debug-${{ hashFiles('**/meson.build') }} - - - name: Configure Meson (debug) - env: - CC: "ccache clang" - CXX: "ccache clang++" - CCACHE_DIR: ${{ runner.temp }}/ccache - run: | - mkdir -p "$CCACHE_DIR" - export CCACHE_DIR="$CCACHE_DIR" - meson setup build_debug --wipe --buildtype=debug --native-file=./scripts/llvm_native.txt - - - name: Build Debug with Meson - env: - CC: "ccache clang" - CXX: "ccache clang++" - CCACHE_DIR: ${{ runner.temp }}/ccache - run: | - export CCACHE_DIR="${{ runner.temp }}/ccache" - # Use all available cores for faster parallel builds - meson compile -C build_debug -j $(nproc) -v Minecraft.Client - - - name: Upload debug executable - uses: actions/upload-artifact@v4 - with: - name: minecraft-client-linux-debug_exe-${{ github.sha }} - path: build_debug/Minecraft.Client/Minecraft.Client - retention-days: 7 + - name: Flake integrity + run: nix flake check From 3a736777fd168a15e1eb89363818205fa72a6a77 Mon Sep 17 00:00:00 2001 From: orng Date: Sat, 28 Mar 2026 22:50:45 -0500 Subject: [PATCH 047/170] ci: simplify `clang-format` --- .github/workflows/clang-format.yml | 72 ++++++------------------------ 1 file changed, 13 insertions(+), 59 deletions(-) diff --git a/.github/workflows/clang-format.yml b/.github/workflows/clang-format.yml index 4965d4b15..ed5f9a402 100644 --- a/.github/workflows/clang-format.yml +++ b/.github/workflows/clang-format.yml @@ -1,69 +1,23 @@ -name: Clang Format +name: Clang-Format (Linux x86/64) on: push: - paths: - - '**.cpp' - - '**.h' - - '**.c' - - '**.cc' - - '**.cxx' - - '**.hh' - - '**.hpp' - - '**.hxx' - - '**.inl' - - '.clang-format' - - '.github/workflows/clang-format.yml' - - '.github/scripts/check-clang-format.sh' - pull_request: - paths: - - '**.cpp' - - '**.h' - - '**.c' - - '**.cc' - - '**.cxx' - - '**.hh' - - '**.hpp' - - '**.hxx' - - '**.inl' - - '.clang-format' - - '.github/workflows/clang-format.yml' - - '.github/scripts/check-clang-format.sh' + - "**.cpp" + - "**.h" + - "**.meson.build" + - ".github/workflows/*" jobs: - clang-format: - runs-on: ubuntu-24.04 - concurrency: - group: clang-format-${{ github.ref }} - cancel-in-progress: true + formatting-check: + runs-on: ubuntu-latest steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: fetch-depth: 0 - - name: Install clang-format - run: | - sudo apt-get update - sudo apt-get install -y clang-format-19 - - - name: Check changed files - env: - CLANG_FORMAT_BIN: clang-format-19 - EVENT_NAME: ${{ github.event_name }} - PR_BASE_REF: ${{ github.event.pull_request.base.ref }} - PR_BASE_SHA: ${{ github.event.pull_request.base.sha }} - BEFORE_SHA: ${{ github.event.before }} - CURRENT_SHA: ${{ github.sha }} - run: | - set -euo pipefail - - BASE_SHA="" - if [ "$EVENT_NAME" = "pull_request" ]; then - git fetch --no-tags origin "$PR_BASE_REF" - BASE_SHA="$(git merge-base "origin/$PR_BASE_REF" "$CURRENT_SHA")" - elif [ -n "$BEFORE_SHA" ] && [ "$BEFORE_SHA" != "0000000000000000000000000000000000000000" ]; then - BASE_SHA="$BEFORE_SHA" - fi - - bash ./.github/scripts/check-clang-format.sh "$BASE_SHA" "$CURRENT_SHA" + - name: Run clang-format style check + uses: jidicula/clang-format-action@v4.18.0 + with: + # keep this in line with the flake + clang-format-version: "21" From 09f3a33eddf82beacbb981eb46a5ba987d66a252 Mon Sep 17 00:00:00 2001 From: orng Date: Sat, 28 Mar 2026 22:59:03 -0500 Subject: [PATCH 048/170] test: push dummy file --- Minecraft.Client/really_good_cpp.cpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 Minecraft.Client/really_good_cpp.cpp diff --git a/Minecraft.Client/really_good_cpp.cpp b/Minecraft.Client/really_good_cpp.cpp new file mode 100644 index 000000000..d4244cd5b --- /dev/null +++ b/Minecraft.Client/really_good_cpp.cpp @@ -0,0 +1,15 @@ +// This is literally the best c++ code ever. I hope everyone reading this has a fantastic day. + +struct Foo { + Bar bar, baz, + + Foo() noexcept : bar(),baz() { delete Foo; } + + void qux() const { + print("Hello, world!") + } + + private: + + bool bob() { hi }; +}; From a954f3f61699184390c23365cbf58c6f492848a2 Mon Sep 17 00:00:00 2001 From: orng Date: Sat, 28 Mar 2026 23:01:06 -0500 Subject: [PATCH 049/170] chore: remove dummy file --- Minecraft.Client/really_good_cpp.cpp | 15 --------------- 1 file changed, 15 deletions(-) delete mode 100644 Minecraft.Client/really_good_cpp.cpp diff --git a/Minecraft.Client/really_good_cpp.cpp b/Minecraft.Client/really_good_cpp.cpp deleted file mode 100644 index d4244cd5b..000000000 --- a/Minecraft.Client/really_good_cpp.cpp +++ /dev/null @@ -1,15 +0,0 @@ -// This is literally the best c++ code ever. I hope everyone reading this has a fantastic day. - -struct Foo { - Bar bar, baz, - - Foo() noexcept : bar(),baz() { delete Foo; } - - void qux() const { - print("Hello, world!") - } - - private: - - bool bob() { hi }; -}; From 0e56f2c66008352113e68c7e586f9a9640bcbc45 Mon Sep 17 00:00:00 2001 From: Tropical <42101043+tropicaaal@users.noreply.github.com> Date: Sun, 29 Mar 2026 14:55:36 -0500 Subject: [PATCH 050/170] fix: regression in tile bounding box clip --- Minecraft.World/Blocks/Tile.cpp | 70 ++++++++++++++++----------------- Minecraft.World/Blocks/Tile.h | 6 +-- Minecraft.World/Util/AABB.cpp | 51 +++++++++++++----------- Minecraft.World/Util/AABB.h | 6 +-- 4 files changed, 67 insertions(+), 66 deletions(-) diff --git a/Minecraft.World/Blocks/Tile.cpp b/Minecraft.World/Blocks/Tile.cpp index d12283e69..e3416af3b 100644 --- a/Minecraft.World/Blocks/Tile.cpp +++ b/Minecraft.World/Blocks/Tile.cpp @@ -2010,7 +2010,7 @@ AABB Tile::getTileAABB(Level* level, int x, int y, int z) { // 4J Stu - Added this so that the TLS shape is correct for this tile if (tls->tileId != this->id) updateDefaultShape(); return AABB(x + tls->xx0, y + tls->yy0, z + tls->zz0, x + tls->xx1, - y + tls->yy1, z + tls->zz1); + y + tls->yy1, z + tls->zz1); } void Tile::addAABBs(Level* level, int x, int y, int z, AABB* box, @@ -2119,52 +2119,51 @@ float Tile::getExplosionResistance(std::shared_ptr source) { return explosionResistance / 5.0f; } -HitResult* Tile::clip(Level* level, int xt, int yt, int zt, Vec3* a, Vec3* b) { +HitResult* Tile::clip(Level* level, int xt, int yt, int zt, Vec3* a_, + Vec3* b_) { updateShape(level, xt, yt, zt); - *a = a->add(-xt, -yt, -zt); - *b = b->add(-xt, -yt, -zt); + Vec3 a = a_->add(-xt, -yt, -zt); + Vec3 b = b_->add(-xt, -yt, -zt); ThreadStorage* tls = m_tlsShape; - auto xh0 = a->clipX(*b, tls->xx0); - auto xh1 = a->clipX(*b, tls->xx1); - auto yh0 = a->clipY(*b, tls->yy0); - auto yh1 = a->clipY(*b, tls->yy1); + auto xh0 = a.clipX(b, tls->xx0); + auto xh1 = a.clipX(b, tls->xx1); - auto zh0 = a->clipZ(*b, tls->zz0); - auto zh1 = a->clipZ(*b, tls->zz1); + auto yh0 = a.clipY(b, tls->yy0); + auto yh1 = a.clipY(b, tls->yy1); + + auto zh0 = a.clipZ(b, tls->zz0); + auto zh1 = a.clipZ(b, tls->zz1); std::optional closest = std::nullopt; - if (xh0.has_value() and containsX(&*xh0) and - (!closest.has_value() or - a->distanceToSqr(*xh0) < a->distanceToSqr(*closest))) + // 4jcraft NOTE: containsX does a nullopt check and will short circuit so + // dereffing in distanceToSqr is fine. + + if (containsX(xh0) && (!closest.has_value() || + a.distanceToSqr(*xh0) < a.distanceToSqr(*closest))) closest = xh0; - if (xh1.has_value() and containsX(&*xh1) and - (!closest.has_value() or - a->distanceToSqr(*xh1) < a->distanceToSqr(*closest))) + if (containsX(xh1) && (!closest.has_value() || + a.distanceToSqr(*xh1) < a.distanceToSqr(*closest))) closest = xh1; - if (yh0.has_value() and containsY(&*yh0) and - (!closest.has_value() or - a->distanceToSqr(*yh0) < a->distanceToSqr(*closest))) + if (containsY(yh0) && (!closest.has_value() || + a.distanceToSqr(*yh0) < a.distanceToSqr(*closest))) closest = yh0; - if (yh1.has_value() and containsY(&*yh1) and - (!closest.has_value() or - a->distanceToSqr(*yh1) < a->distanceToSqr(*closest))) + if (containsY(yh1) && (!closest.has_value() || + a.distanceToSqr(*yh1) < a.distanceToSqr(*closest))) closest = yh1; - if (zh0.has_value() and containsZ(&*zh0) and - (!closest.has_value() or - a->distanceToSqr(*zh0) < a->distanceToSqr(*closest))) + if (containsZ(zh0) && (!closest.has_value() || + a.distanceToSqr(*zh0) < a.distanceToSqr(*closest))) closest = zh0; - if (zh1.has_value() and containsZ(&*zh1) and - (!closest.has_value() or - a->distanceToSqr(*zh1) < a->distanceToSqr(*closest))) + if (containsZ(zh1) && (!closest.has_value() || + a.distanceToSqr(*zh1) < a.distanceToSqr(*closest))) closest = zh1; if (!closest.has_value()) return nullptr; @@ -2178,12 +2177,11 @@ HitResult* Tile::clip(Level* level, int xt, int yt, int zt, Vec3* a, Vec3* b) { if (closest == zh0) face = Facing::NORTH; if (closest == zh1) face = Facing::SOUTH; - Vec3 res = closest->add(xt, yt, zt); - return new HitResult(xt, yt, zt, face, res); + return new HitResult(xt, yt, zt, face, closest->add(xt, yt, zt)); } -bool Tile::containsX(Vec3* v) { - if (v == NULL) return false; +bool Tile::containsX(const std::optional& v) { + if (!v.has_value()) return false; ThreadStorage* tls = m_tlsShape; // 4J Stu - Added this so that the TLS shape is correct for this tile @@ -2192,8 +2190,8 @@ bool Tile::containsX(Vec3* v) { v->z <= tls->zz1; } -bool Tile::containsY(Vec3* v) { - if (v == NULL) return false; +bool Tile::containsY(const std::optional& v) { + if (!v.has_value()) return false; ThreadStorage* tls = m_tlsShape; // 4J Stu - Added this so that the TLS shape is correct for this tile @@ -2202,8 +2200,8 @@ bool Tile::containsY(Vec3* v) { v->z <= tls->zz1; } -bool Tile::containsZ(Vec3* v) { - if (v == NULL) return false; +bool Tile::containsZ(const std::optional& v) { + if (!v.has_value()) return false; ThreadStorage* tls = m_tlsShape; // 4J Stu - Added this so that the TLS shape is correct for this tile diff --git a/Minecraft.World/Blocks/Tile.h b/Minecraft.World/Blocks/Tile.h index 2b94b9ffe..8c9d33566 100644 --- a/Minecraft.World/Blocks/Tile.h +++ b/Minecraft.World/Blocks/Tile.h @@ -668,9 +668,9 @@ public: Vec3* b); private: - virtual bool containsX(Vec3* v); - virtual bool containsY(Vec3* v); - virtual bool containsZ(Vec3* v); + virtual bool containsX(const std::optional& v); + virtual bool containsY(const std::optional& v); + virtual bool containsZ(const std::optional& v); public: virtual void wasExploded(Level* level, int x, int y, int z, diff --git a/Minecraft.World/Util/AABB.cpp b/Minecraft.World/Util/AABB.cpp index a31d27728..c9a58d1bb 100644 --- a/Minecraft.World/Util/AABB.cpp +++ b/Minecraft.World/Util/AABB.cpp @@ -184,37 +184,37 @@ HitResult* AABB::clip(const Vec3& a, const Vec3& b) const { auto zh0 = a.clipZ(b, z0); auto zh1 = a.clipZ(b, z1); - if (!(xh0.has_value() and containsX(*xh0))) xh0 = std::nullopt; - if (!(xh1.has_value() and containsX(*xh1))) xh1 = std::nullopt; - if (!(yh0.has_value() and containsY(*yh0))) yh0 = std::nullopt; - if (!(yh1.has_value() and containsY(*yh1))) yh1 = std::nullopt; - if (!(zh0.has_value() and containsZ(*zh0))) zh0 = std::nullopt; - if (!(zh1.has_value() and containsZ(*zh1))) zh1 = std::nullopt; + if (!containsX(xh0)) xh0 = std::nullopt; + if (!containsX(xh1)) xh1 = std::nullopt; + if (!containsY(yh0)) yh0 = std::nullopt; + if (!containsY(yh1)) yh1 = std::nullopt; + if (!containsZ(zh0)) zh0 = std::nullopt; + if (!containsZ(zh1)) zh1 = std::nullopt; std::optional closest = std::nullopt; - if (xh0.has_value() and (!closest.has_value() or - a.distanceToSqr(*xh0) < a.distanceToSqr(*closest))) + if (xh0.has_value() && (!closest.has_value() || + a.distanceToSqr(*xh0) < a.distanceToSqr(*closest))) closest = xh0; - if (xh1.has_value() and (!closest.has_value() or - a.distanceToSqr(*xh1) < a.distanceToSqr(*closest))) + if (xh1.has_value() && (!closest.has_value() || + a.distanceToSqr(*xh1) < a.distanceToSqr(*closest))) closest = xh1; - if (yh0.has_value() and (!closest.has_value() or - a.distanceToSqr(*yh0) < a.distanceToSqr(*closest))) + if (yh0.has_value() && (!closest.has_value() || + a.distanceToSqr(*yh0) < a.distanceToSqr(*closest))) closest = yh0; - if (yh1.has_value() and (!closest.has_value() or - a.distanceToSqr(*yh1) < a.distanceToSqr(*closest))) + if (yh1.has_value() && (!closest.has_value() || + a.distanceToSqr(*yh1) < a.distanceToSqr(*closest))) closest = yh1; - if (zh0.has_value() and (!closest.has_value() or - a.distanceToSqr(*zh0) < a.distanceToSqr(*closest))) + if (zh0.has_value() && (!closest.has_value() || + a.distanceToSqr(*zh0) < a.distanceToSqr(*closest))) closest = zh0; - if (zh1.has_value() and (!closest.has_value() or - a.distanceToSqr(*zh1) < a.distanceToSqr(*closest))) + if (zh1.has_value() && (!closest.has_value() || + a.distanceToSqr(*zh1) < a.distanceToSqr(*closest))) closest = zh1; if (!closest.has_value()) return nullptr; @@ -231,16 +231,19 @@ HitResult* AABB::clip(const Vec3& a, const Vec3& b) const { return new HitResult(0, 0, 0, face, *closest); } -bool AABB::containsX(const Vec3& v) const { - return v.y >= y0 && v.y <= y1 && v.z >= z0 && v.z <= z1; +bool AABB::containsX(const std::optional& v) const { + if (!v.has_value()) return false; + return v->y >= y0 && v->y <= y1 && v->z >= z0 && v->z <= z1; } -bool AABB::containsY(const Vec3& v) const { - return v.x >= x0 && v.x <= x1 && v.z >= z0 && v.z <= z1; +bool AABB::containsY(const std::optional& v) const { + if (!v.has_value()) return false; + return v->x >= x0 && v->x <= x1 && v->z >= z0 && v->z <= z1; } -bool AABB::containsZ(const Vec3& v) const { - return v.x >= x0 && v.x <= x1 && v.y >= y0 && v.y <= y1; +bool AABB::containsZ(const std::optional& v) const { + if (!v.has_value()) return false; + return v->x >= x0 && v->x <= x1 && v->y >= y0 && v->y <= y1; } std::wstring AABB::toString() const { diff --git a/Minecraft.World/Util/AABB.h b/Minecraft.World/Util/AABB.h index fb62056d8..83c32519a 100644 --- a/Minecraft.World/Util/AABB.h +++ b/Minecraft.World/Util/AABB.h @@ -28,8 +28,8 @@ public: double getSize() const; AABB shrink(double xa, double ya, double za) const; HitResult* clip(const Vec3& a, const Vec3& b) const; - bool containsX(const Vec3& v) const; - bool containsY(const Vec3& v) const; - bool containsZ(const Vec3& v) const; + bool containsX(const std::optional& v) const; + bool containsY(const std::optional& v) const; + bool containsZ(const std::optional& v) const; std::wstring toString() const; }; From 0728ac8731c65c2cad845a4968cb709bec830bd3 Mon Sep 17 00:00:00 2001 From: Sally Knight Date: Wed, 25 Mar 2026 18:26:31 +0300 Subject: [PATCH 051/170] fix(jui): tick screen even if not ingame required for title screen panorama --- Minecraft.Client/Minecraft.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/Minecraft.Client/Minecraft.cpp b/Minecraft.Client/Minecraft.cpp index 65d5e87dd..bb2610813 100644 --- a/Minecraft.Client/Minecraft.cpp +++ b/Minecraft.Client/Minecraft.cpp @@ -1965,13 +1965,12 @@ void Minecraft::run_middle() { // clear the stored button downs since the tick for this // player will now have actioned them player->ullButtonsPressed = 0LL; + } else if (screen != NULL) { + screen->updateEvents(); + screen->tick(); } } - if (screen != NULL) { - screen->updateEvents(); - } - ui.HandleGameTick(); setLocalPlayerIdx(ProfileManager.GetPrimaryPad()); From 3f2c6e0012f3f45e9fe654c256ecd1a1cb797a9f Mon Sep 17 00:00:00 2001 From: Sally Knight Date: Wed, 25 Mar 2026 19:31:36 +0300 Subject: [PATCH 052/170] feat(jui): add panorama and splashes to title screen Also moved the version string to the same height as the copyright message, matching Beta 1.8+ --- .../Common/res/1_2_2/title/bg/panorama.png | Bin 0 -> 159778 bytes Minecraft.Client/Textures/Textures.cpp | 5 + Minecraft.Client/Textures/Textures.h | 5 + Minecraft.Client/UI/Screens/TitleScreen.cpp | 147 ++++++++++++++---- Minecraft.Client/UI/Screens/TitleScreen.h | 16 ++ 5 files changed, 147 insertions(+), 26 deletions(-) create mode 100644 Minecraft.Assets/Common/res/1_2_2/title/bg/panorama.png diff --git a/Minecraft.Assets/Common/res/1_2_2/title/bg/panorama.png b/Minecraft.Assets/Common/res/1_2_2/title/bg/panorama.png new file mode 100644 index 0000000000000000000000000000000000000000..65ae6070c6b5a6ba0c01c1bec95a4aa7a9b3c3e8 GIT binary patch literal 159778 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%0DM{^I}f7k}~p`sFYFpS!#7XlajOp1_J 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

92QGs?h>IgF^Pn2Ea@rw*kM5@R9zMzmpq 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 s1!4 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 splashes; - /* -BufferedReader *br = new BufferedReader(new -InputStreamReader(InputStream::getResourceAsStream(L"res\\title\\splashes.txt"))); -//, Charset.forName("UTF-8") + // 4jcraft: copied over from UIScene_MainMenu + int splashIndex; -std::wstring line = L""; -while ( !(line = br->readLine()).empty() ) - { - line = trimString( line ); - if (line.length() > 0) - { - splashes.push_back(line); + std::wstring filename = L"splashes.txt"; + if (app.hasArchiveFile(filename)) { + byteArray splashesArray = app.getArchiveFile(filename); + ByteArrayInputStream bais(splashesArray); + InputStreamReader isr(&bais); + BufferedReader br(&isr); + + std::wstring line = L""; + while (!(line = br.readLine()).empty()) { + line = trimString(line); + if (line.length() > 0) { + splashes.push_back(line); + } + } + + br.close(); } - br->close(); - delete br; - */ + splashIndex = + eSplashRandomStart + 1 + + random->nextInt((int)splashes.size() - (eSplashRandomStart + 1)); - // splash = L""; //splashes.at(random->nextInt(splashes.size())); + // Override splash text on certain dates + SYSTEMTIME LocalSysTime; + GetLocalTime(&LocalSysTime); + if (LocalSysTime.wMonth == 11 && LocalSysTime.wDay == 9) { + splashIndex = eSplashHappyBirthdayEx; + } else if (LocalSysTime.wMonth == 6 && LocalSysTime.wDay == 1) { + splashIndex = eSplashHappyBirthdayNotch; + } else if (LocalSysTime.wMonth == 12 && + LocalSysTime.wDay == 24) // the Java game shows this on + // Christmas Eve, so we will too + { + splashIndex = eSplashMerryXmas; + } else if (LocalSysTime.wMonth == 1 && LocalSysTime.wDay == 1) { + splashIndex = eSplashHappyNewYear; + } - // } catch (Exception e) { - // } + splash = splashes.at(splashIndex); } void TitleScreen::tick() { - // vo += 1.0f; + vo += 1.0f; // if( vo > 100.0f ) minecraft->setScreen(new SelectWorldScreen(this)); // // 4J - temp testing } @@ -104,32 +124,105 @@ if (c.get(Calendar.MONTH) + 1 == 11 && c.get(Calendar.DAY_OF_MONTH) == 9) { void TitleScreen::buttonClicked(Button* button) { if (button->id == 0) { - app.DebugPrintf("TitleScreen::buttonClicked() 'Options...' if (button->id == 0)\n"); + app.DebugPrintf( + "TitleScreen::buttonClicked() 'Options...' if (button->id == 0)\n"); minecraft->setScreen(new OptionsScreen(this, minecraft->options)); } if (button->id == 1) { - app.DebugPrintf("TitleScreen::buttonClicked() 'Singleplayer' if (button->id == 1)\n"); + app.DebugPrintf( + "TitleScreen::buttonClicked() 'Singleplayer' if (button->id == " + "1)\n"); minecraft->setScreen(new SelectWorldScreen(this)); } if (button->id == 2) { - app.DebugPrintf("TitleScreen::buttonClicked() 'Multiplayer' if (button->id == 2)\n"); + app.DebugPrintf( + "TitleScreen::buttonClicked() 'Multiplayer' if (button->id == " + "2)\n"); minecraft->setScreen(new JoinMultiplayerScreen(this)); } if (button->id == 3) { - app.DebugPrintf("TitleScreen::buttonClicked() 'Texture Pack' if (button->id == 3)\n"); + app.DebugPrintf( + "TitleScreen::buttonClicked() 'Texture Pack' if (button->id == " + "3)\n"); // minecraft->setScreen(new TexturePackSelectScreen(this)); // // 4J - TODO put back in } if (button->id == 4) { - app.DebugPrintf("TitleScreen::buttonClicked() Exit Game if (button->id == 4)\n"); - RenderManager.Close(); //minecraft->stop(); + app.DebugPrintf( + "TitleScreen::buttonClicked() Exit Game if (button->id == 4)\n"); + RenderManager.Close(); // minecraft->stop(); } } +// 4jcraft: render our panorama +// uses the TU panorama instead of JE panorama and as such a different rendering +// method +void TitleScreen::renderPanorama() { + Tesselator* t = Tesselator::getInstance(); + + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + glOrtho(0, width, height, 0, 1000, 3000); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + glTranslatef(0, 0, -2000); + + glDisable(GL_LIGHTING); + glDisable(GL_FOG); + glEnable(GL_TEXTURE_2D); + glDisable(GL_ALPHA_TEST); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glDepthMask(false); + + glBindTexture(GL_TEXTURE_2D, + minecraft->textures->loadTexture(TN_TITLE_BG_PANORAMA)); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + float off = vo * 0.0001f; + + float screenAspect = (float)width / (float)height; + float texAspect = 1748.0f / 144.0f; + float scale; + if (screenAspect > texAspect) { + scale = (float)width / 1748.0f; + } else { + scale = (float)height / 144.0f; + } + + float texWidth = 1748.0f * scale; + float texHeight = 144.0f * scale; + float yOff = (height - texHeight) / 2.0f; + + float uMax = off + (texWidth / 1748.0f); + + t->begin(GL_QUADS); + t->color(0xffffff, 255); + t->vertexUV(0, yOff + texHeight, 0, off, 1.0f); + t->vertexUV(texWidth, yOff + texHeight, 0, uMax, 1.0f); + t->vertexUV(texWidth, yOff, 0, uMax, 0.0f); + t->vertexUV(0, yOff, 0, off, 0.0f); + t->end(); + + glDepthMask(true); + glDisable(GL_BLEND); + glEnable(GL_ALPHA_TEST); + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); +} + void TitleScreen::render(int xm, int ym, float a) { // 4J Unused - Iggy Flash UI renders the title screen on consoles #ifdef ENABLE_JAVA_GUIS - renderBackground(); + renderPanorama(); Tesselator* t = Tesselator::getInstance(); int logoWidth = 155 + 119; @@ -155,7 +248,9 @@ void TitleScreen::render(int xm, int ym, float a) { drawCenteredString(font, splash, 0, -8, 0xffff00); glPopMatrix(); - drawString(font, ClientConstants::VERSION_STRING, 2, 2, 0x505050); + drawString( + font, ClientConstants::VERSION_STRING, 2, height - 10, + 0xffffff); // 4jcraft: use the same height as the copyright message wstring msg = L"Copyright Mojang AB. Do not distribute."; drawString(font, msg, width - font->width(msg) - 2, height - 10, 0xffffff); diff --git a/Minecraft.Client/UI/Screens/TitleScreen.h b/Minecraft.Client/UI/Screens/TitleScreen.h index 6a27ae427..f729cea2e 100644 --- a/Minecraft.Client/UI/Screens/TitleScreen.h +++ b/Minecraft.Client/UI/Screens/TitleScreen.h @@ -12,6 +12,22 @@ private: std::wstring splash; Button* multiplayerButton; + // 4jcraft: panorama + void renderPanorama(); + + // 4jcraft: taken from UIScene_MainMenu + // 4J Added + enum eSplashIndexes { + eSplashHappyBirthdayEx = 0, + eSplashHappyBirthdayNotch, + eSplashMerryXmas, + eSplashHappyNewYear, + + // The start index in the splashes vector from which we can select a + // random splash + eSplashRandomStart, + }; + public: TitleScreen(); virtual void tick(); From 65ff6a97f0427c0d5aba6aa471635fd51b0166b7 Mon Sep 17 00:00:00 2001 From: Sally Knight Date: Wed, 25 Mar 2026 20:01:59 +0300 Subject: [PATCH 053/170] feat(jui): add horse inventory screen --- .../Common/res/1_2_2/gui/horse.png | Bin 0 -> 5654 bytes Minecraft.Client/Player/LocalPlayer.cpp | 9 +- Minecraft.Client/Textures/Textures.cpp | 1 + Minecraft.Client/Textures/Textures.h | 1 + .../UI/Screens/HorseInventoryScreen.cpp | 100 ++++++++++++++++++ .../UI/Screens/HorseInventoryScreen.h | 22 ++++ 6 files changed, 131 insertions(+), 2 deletions(-) create mode 100644 Minecraft.Assets/Common/res/1_2_2/gui/horse.png create mode 100644 Minecraft.Client/UI/Screens/HorseInventoryScreen.cpp create mode 100644 Minecraft.Client/UI/Screens/HorseInventoryScreen.h diff --git a/Minecraft.Assets/Common/res/1_2_2/gui/horse.png b/Minecraft.Assets/Common/res/1_2_2/gui/horse.png new file mode 100644 index 0000000000000000000000000000000000000000..194cc6bf6fcc7baee87038d57cb51f2254c640a8 GIT binary patch literal 5654 zcmb7IXHZk^w%!RKh*AU*r5O06h!iQ(k>H1b5doztD4ylj(ggMOwSmwM##Nk`g!RgY=?wAqzf2`(ER)=7~lJ>Qg98SG5o$J~{39KyYjI z&86d!^frUdOw|;Q2>S@f7!>MYU|`@|Gc&!tyA*d2 zvcE-Id5+@%7@)-$&z^w=1O(i7SI2y-X096>TUlD3+;h9o9p~Pcw;^L?3Iev40Us@l zpB852mRPze=z;rFSUJ%%f^l$><@wABWHZrA&F&hnA|EiV0UY9KldgzAf#(zpAuyjdYgh&Q2{AP+sE&dNq{smS4@$x@tR&0^5e=gkK(_`cA?mkLxWMVK$Rf{z` z!GUzkGs`GJp-{CWAshQoBK{2&z2;Nf6@c-3InoB#?7{-Jpy0VyKPd=9>dWsd3_StR zS$g@|*w`*yxbT5Hu>M{Q&s|^6f9CmLg9o)J{8k3b&Him*lR~k&d9!y$IEy>57n&k* zCi?z0g66S{pZ?$t+}Fpf3q;sIo??R$hO0biare{WP9Pb;7OU*|&HVhp+b5oD{(s2i z0D?eFNuEYB9kggT?rw-R>j%^3Qv6H3&`aQT2r}KVRd{Kul3Nz6#QvWIz$**Bl|S+8 zGnGHkKr9pbz(9|t;|t__YZX!02U+^7l=JnmlmB4rBf=PyK6u{`{co86yI%f@ zTOj$rakG6hh_Q;$Wc$0s6ept@i=r=3H>Bd*hnU5wEqFTf9MH$5KH4(gVi0+>W&8w= zg)8W&0-;TzzJfpB6f-=Nw-9F+VDCyIF?y4iEdN98+=4I!EfVDPcD8Z-$+rGg8o-=|BGCIeQ}k3zBQ_l zWy|OzM?l2VN875UXYw4=jBAPzcEkL00E4Acnv;{$($exO=6s-av2ANMS10ISG!HQ~ zdN2rFHhGcdXR;$J@-cn^VB&~o<&FA%LBiphgs$CwK|L3 z1p{S^@a!n{l;(|nJ5fb;BxRE5u#zA_3mXzxIi3cIii$Gy&NL0Urzr(lVd%^+wo3jZXJxuCJm6o@akati>O!#hT z!S5EzlhM5mbpr1D7u!&{Q^U@^?-|EqT1Rd%d3kbLAM*8Q)FV5whja0p^-s;n3i=4I^2(=`rBuY&^g-Tbhd&Lv_Bx5Km zD&a3J6Fmu;SR{u#YYUeV@DCkuIGHqB9vXN;9H3{<=W(0i*XpHt3;Y}S=n{%H>zH7s1!nwTI!gx zb8@h{U14Lu0qSNP1@5-YC*{lpDhvz`8aA$$ovK&~D!tHj6ru9-CZaw;`D;zrqxdj$ zncUk=o3;|(2{PXwqLlGy-S`s#2ss|SmV7Is!`pj|zlthJYEX4pe2g)kD5g%Qd9g{_ zi+W#@RjDJVd2#2jEx(YeFs(aYyx%f16=6?Rn_ktr@#{lXUx&+qJpu*IN@&K zk7Mh-5%&`-q8q`?@Op3#70n>_)YGMUCVBVX&PxNm4P6=UMhlkmPA2wifb&_(&{Zz? z`^_fhFQ^Cna5leJk>#qZUVpC*0=B|j3ST!$^YxvM)f2o~j2CY&5!{7vrtmMCy!sJq zUx+`T9R;>NG`99EZ3`yBmJs+DXy1NDQ$zjfHfj+I7{Gio9pZOOD^d75rO=@3Q#VkS zHL{xp_di$^^IuJW^y?@NO3>m~03mO04RY!<*vpcwF)XQr#we*CyWT09jEH+5VWwMQ z48jX6veb+m7(6m9JwNwg?trX_~}#c`Sa%&eX|zQ zpP2T)D9>)FJ*)Q-^fpcB8mhm)|AVy|c2xe+giMUU7DDF&urLm?*GaA8*K$*d{B9?u5HjzR$SF6FuKcDqV>d58ZOUmm%`k z^z?(d`T6UpYVV1X#>U2EmdTg5a1)v`#G-kr;O{%{tsTTJsn!(K@4p@&tIWgOI``y~ z2=1psH+)lz=+gt05J`91v|((A5{Y2UzxB=RG84EU>+=c=Pi;wiu|^5w%7 z`e;E7oLFpPD!RxCn=_>rxN9*t)#YHjq%D{Z4G+8VYd0;_=wsVD+y`Z)hJ|@uziATs zYWQ`v!bFDbM6G#t=^1&L*8Z>T{jF8AhJn3f{x(a&g>xv0qz-YsV*N>0Si5yD@rcJk zMCgz7r^V>hQG|Q$n$BhSPxmNmcTaBbN1gL3Cw7)QNi52$@LwWD@S}3p8p$K}8}Mi; zxwmNoY21qJyxBA^E_6J)=*tqks{v{!!T$tmLvo z8CqFP9s`rIW@-MZ%tK76i`#O{Sv0gefQmty=Bvzl7=2rC{y{0eRZpg4olRgU ziCAH!tFUNs54c}vjm@1q#Hs4EG!ZLnYdAi7$X@86b;-_Y18qrl&VF;Yco0W3J+rEY z(Xz^KOUG&Dxq9LiFCD}a%i}&_H+OaptV5pUib#v1Y3-h8qO+!_rwanVq=wITrl2+b z^WJEwdoV+?O>R)0bIOJEWKt`n?ejhIZmg{%=q_OgN~ss1mS5+g+TmFp zXFpmG=Ir#g09?r1`i=?mw_MXq>YaQ(m=5$We}7?XH83cv*;-U>ZPrgwQ{Pc`6}e#Q11)RGrVoLJ#YfQ}8^T&jKj@k3k}m$2G-6&01-)cVfZ1u4f%v*z|Jd*E$ax zu$DF%MIJ@ViH>TdiWwIx^%_#fyhBk8-L{X^+gwz1q4$uox>bW6Jkln=VJGeM6r z-7&Qt9UbxaPuteej>>l?2HYGj%MRsR_uzMR8{3io^O4Gf8FlsLfbBC}J=c<^R4Z3V zf=;k&9G(n1YR<2wc3^b$C0b2TBGO^)%)1B`aZ&BZ{I~C5D=$2?M;e_~j{?lBn?D{qip!Eadnv_R!Yf)sN zLasXZKo5kGX%~o~IO{Pqn>*%unGNFWq4MO)$SIl2V2&hzZ-JXF(^l^Ag*BoM80pSG&&jnc7(iN!oZN@6%Okd_eFRXBZBXg5|lv6)gJ z=UyS1*!uKxI4^6n&Ja->z;l`0=#SqG&un9;8a-^DCQ~AN2cmgu0%v5=p(AzPJEZFr z!8cn?C-?NqESlRZ+)GE%f3$~w!T#WJKLqgu?}T(7gFj`rw=k!D5Y>MU=Stt1&!}?A z8g>4aVc|+Yq~3Cv*M7X7DP@{AEaz-@)9xFHfir0lTLHVea|@5hc6lo&8e+5r?~C4TynRaK z^ml)tsp^lLdk4U&xloIpitxfsqC7)jv!dfsopJR2?>}#s4vb7pp9ew(0Q#})Q%wbR z7SfAdH52g?VxK7gWZ?LD3<$e z(89ujVwd2G!Ihye?|^+};4GEgFx)t@i*9WGNi$hx*yoV3ICa^aNqn9ErAL0%hGr=R zwAAs$2HY*Fc$j=~v5-?)0g*f?_R7GdSiW2$dCu+QuM|X*+S&7SZh+uzM?N3Qs&W@b zOWcRrZRgE-DWsA-6)nLC?SAkdd>tY_g0HGn zBlRb>IVq>i?Np}q9ip6s)3aDB47yges;a7fkhgs#kaR_M#o#5@;;^u&a+gkvxo#75 zve14IF|x!Lv9}@30u|O}7lZM1bz10Sjpn2;%vSE{X3z)ia74PM|NJ$S`I!B^cPUav z7TM#B+O%_^tr$(@Ku>9J?86IN^lp=S-y2aMcQ%xHgg$=Fv2+eqH6htmyKhru!Q#B_ zDc_C|El>l~8;iwWYu8ZKom4i8-Rwz3idWj1$$_FSnL$QpMiXjCKbk6BLo ze4H9P@5*YSij%Rab@oWH(<_6Lc_~a`>94_Z9^!!>a&t@Q3l1sh1Dy{k}R2c~&i1Vl24i container) { bool LocalPlayer::openHorseInventory(std::shared_ptr horse, std::shared_ptr container) { - // minecraft->setScreen(new HorseInventoryScreen(inventory, container, - // horse)); +#ifdef ENABLE_JAVA_GUIS + minecraft->setScreen(new HorseInventoryScreen(inventory, container, + horse)); + bool success = true; +#else bool success = app.LoadHorseMenu(GetXboxPad(), inventory, container, horse); if (success) ui.PlayUISFX(eSFX_Press); +#endif return success; } diff --git a/Minecraft.Client/Textures/Textures.cpp b/Minecraft.Client/Textures/Textures.cpp index 6314e33ff..8d879aac8 100644 --- a/Minecraft.Client/Textures/Textures.cpp +++ b/Minecraft.Client/Textures/Textures.cpp @@ -177,6 +177,7 @@ const wchar_t* Textures::preLoaded[TN_COUNT] = { // 4jcraft: 1.6.4 java UI #ifdef ENABLE_JAVA_GUIS + L"gui/horse", L"title/bg/panorama", #endif // L"item/christmas", diff --git a/Minecraft.Client/Textures/Textures.h b/Minecraft.Client/Textures/Textures.h index 0ef8f6729..0bf5e42d5 100644 --- a/Minecraft.Client/Textures/Textures.h +++ b/Minecraft.Client/Textures/Textures.h @@ -159,6 +159,7 @@ typedef enum _TEXTURE_NAME { // 4jcraft: 1.6.4 java UI #ifdef ENABLE_JAVA_GUIS + TN_GUI_HORSE, TN_TITLE_BG_PANORAMA, #endif // TN_TILE_XMAS_CHEST, diff --git a/Minecraft.Client/UI/Screens/HorseInventoryScreen.cpp b/Minecraft.Client/UI/Screens/HorseInventoryScreen.cpp new file mode 100644 index 000000000..ffdfaaeb9 --- /dev/null +++ b/Minecraft.Client/UI/Screens/HorseInventoryScreen.cpp @@ -0,0 +1,100 @@ +#include "../../Platform/stdafx.h" +#include "HorseInventoryScreen.h" +#include "../../Player/MultiPlayerLocalPlayer.h" +#include "../../Rendering/EntityRenderers/EntityRenderDispatcher.h" +#include "../../Rendering/Lighting.h" +#include "../../Textures/Textures.h" +#include "../../../Minecraft.World/Headers/net.minecraft.locale.h" +#include "../../../Minecraft.World/Containers/HorseInventoryMenu.h" + +// 4jcraft: referenced from MCP 8.11 (JE 1.6.4) and the existing InventoryScreen + +ResourceLocation GUI_HORSE_LOCATION = ResourceLocation(TN_GUI_HORSE); + +HorseInventoryScreen::HorseInventoryScreen( + std::shared_ptr inventory, + std::shared_ptr horseContainer, + std::shared_ptr horse) + : AbstractContainerScreen( + new HorseInventoryMenu(inventory, horseContainer, horse)) { + xMouse = yMouse = 0.0f; // 4J added + + this->inventory = inventory; + this->horseContainer = horseContainer; + this->horse = horse; + this->passEvents = false; +} + +void HorseInventoryScreen::init() { AbstractContainerScreen::init(); } + +void HorseInventoryScreen::renderLabels() { + font->draw(horseContainer->getName(), 8, 6, 0x404040); + font->draw(inventory->getName(), 8, imageHeight - 96 + 2, 0x404040); +} + +void HorseInventoryScreen::render(int xm, int ym, float a) { + AbstractContainerScreen::render(xm, ym, a); + this->xMouse = (float)xm; + this->yMouse = (float)ym; +} + +void HorseInventoryScreen::renderBg(float a) { + // 4J Unused +#ifdef ENABLE_JAVA_GUIS + glColor4f(1, 1, 1, 1); + minecraft->textures->bindTexture(&GUI_HORSE_LOCATION); + + int xo = (width - imageWidth) / 2; + int yo = (height - imageHeight) / 2; + blit(xo, yo, 0, 0, imageWidth, imageHeight); + + if (horse->isChestedHorse()) { + blit(xo + 79, yo + 17, 0, imageHeight, 90, 54); + } + + if (horse->canWearArmor()) { + blit(xo + 7, yo + 35, 0, imageHeight + 54, 18, 18); + } + + glEnable(GL_RESCALE_NORMAL); + glEnable(GL_COLOR_MATERIAL); + + glPushMatrix(); + glTranslatef((float)xo + 51, (float)yo + 60, 50); + float ss = 30; + glScalef(-ss, ss, ss); + glRotatef(180, 0, 0, 1); + + float oybr = horse->yBodyRot; + float oyr = horse->yRot; + float oxr = horse->xRot; + float oyh = horse->yHeadRot; + float oyhp = horse->yHeadRotO; + + float xd = (xo + 51) - xMouse; + float yd = (yo + 75 - 50) - yMouse; + + glRotatef(45 + 90, 0, 1, 0); + Lighting::turnOn(); + glRotatef(-45 - 90, 0, 1, 0); + + glRotatef(-(float)atan(yd / 40.0f) * 20, 1, 0, 0); + + horse->yBodyRot = (float)atan(xd / 40.0f) * 20; + horse->yRot = (float)atan(xd / 40.0f) * 40; + horse->xRot = -(float)atan(yd / 40.0f) * 20; + horse->yHeadRot = (float)atan(xd / 40.0f) * 40; + horse->yHeadRotO = (float)atan(xd / 40.0f) * 40; + glTranslatef(0, horse->heightOffset, 0); + EntityRenderDispatcher::instance->playerRotY = 180; + EntityRenderDispatcher::instance->render(horse, 0, 0, 0, 0, 1); + horse->yBodyRot = oybr; + horse->yRot = oyr; + horse->xRot = oxr; + horse->yHeadRot = oyh; + horse->yHeadRotO = oyhp; + glPopMatrix(); + Lighting::turnOff(); + glDisable(GL_RESCALE_NORMAL); +#endif +} \ No newline at end of file diff --git a/Minecraft.Client/UI/Screens/HorseInventoryScreen.h b/Minecraft.Client/UI/Screens/HorseInventoryScreen.h new file mode 100644 index 000000000..12b0e68a2 --- /dev/null +++ b/Minecraft.Client/UI/Screens/HorseInventoryScreen.h @@ -0,0 +1,22 @@ +#pragma once +#include +#include "AbstractContainerScreen.h" +#include "../../../Minecraft.World/Headers/net.minecraft.world.entity.animal.h" + +class HorseInventoryScreen : public AbstractContainerScreen { +public: + HorseInventoryScreen(std::shared_ptr inventory, + std::shared_ptr horseContainer, + std::shared_ptr horse); + + virtual void init() override; + virtual void renderLabels() override; + virtual void renderBg(float a) override; + virtual void render(int xm, int ym, float a) override; + +private: + std::shared_ptr inventory; + std::shared_ptr horseContainer; + std::shared_ptr horse; + float xMouse, yMouse; +}; \ No newline at end of file From 08a87c432a4de1db62251f01c374f378a63ccde6 Mon Sep 17 00:00:00 2001 From: Sally Knight Date: Wed, 25 Mar 2026 23:38:09 +0300 Subject: [PATCH 054/170] fix: put jui-specific texture usage behind ifdefs --- Minecraft.Client/Textures/Textures.cpp | 26 +++++++++---------- Minecraft.Client/Textures/Textures.h | 26 +++++++++---------- .../UI/Screens/HorseInventoryScreen.cpp | 3 ++- Minecraft.Client/UI/Screens/TitleScreen.cpp | 2 ++ 4 files changed, 30 insertions(+), 27 deletions(-) diff --git a/Minecraft.Client/Textures/Textures.cpp b/Minecraft.Client/Textures/Textures.cpp index 8d879aac8..f1e08232c 100644 --- a/Minecraft.Client/Textures/Textures.cpp +++ b/Minecraft.Client/Textures/Textures.cpp @@ -33,24 +33,12 @@ C4JRender::eTextureFormat Textures::TEXTURE_FORMAT = int Textures::preLoadedIdx[TN_COUNT]; const wchar_t* Textures::preLoaded[TN_COUNT] = { L"%blur%misc/pumpkinblur", - L"%blur%/misc/vignette", // Not currently used L"%clamp%misc/shadow", - L"/achievement/bg", // Not currently used L"art/kz", L"environment/clouds", L"environment/rain", L"environment/snow", L"gui/gui", - L"gui/background", - L"gui/inventory", - L"gui/container", - L"gui/crafting", - L"gui/furnace", - L"gui/creative_inventory/tabs", - L"gui/creative_inventory/tab_items", - L"gui/creative_inventory/tab_inventory", - L"gui/creative_inventory/tab_item_search", - L"title/mclogo", L"gui/icons", L"item/arrows", L"item/boat", @@ -175,8 +163,20 @@ const wchar_t* Textures::preLoaded[TN_COUNT] = { L"item/trapped", L"item/trapped_double", - // 4jcraft: 1.6.4 java UI + // 4jcraft: java UI specific #ifdef ENABLE_JAVA_GUIS + L"%blur%/misc/vignette", + L"/achievement/bg", + L"gui/background", + L"gui/inventory", + L"gui/container", + L"gui/crafting", + L"gui/furnace", + L"gui/creative_inventory/tabs", + L"gui/creative_inventory/tab_items", + L"gui/creative_inventory/tab_inventory", + L"gui/creative_inventory/tab_item_search", + L"title/mclogo", L"gui/horse", L"title/bg/panorama", #endif diff --git a/Minecraft.Client/Textures/Textures.h b/Minecraft.Client/Textures/Textures.h index 0bf5e42d5..ddf2ecf47 100644 --- a/Minecraft.Client/Textures/Textures.h +++ b/Minecraft.Client/Textures/Textures.h @@ -16,24 +16,12 @@ class ResourceLocation; typedef enum _TEXTURE_NAME { TN__BLUR__MISC_PUMPKINBLUR, - TN__BLUR__MISC_VIGNETTE, // Not currently used TN__CLAMP__MISC_SHADOW, - TN_ACHIEVEMENT_BG, // Not currently used TN_ART_KZ, TN_ENVIRONMENT_CLOUDS, TN_ENVIRONMENT_RAIN, TN_ENVIRONMENT_SNOW, TN_GUI_GUI, - TN_GUI_BACKGROUND, - TN_GUI_INVENTORY, - TN_GUI_CONTAINER, - TN_GUI_CRAFTING, - TN_GUI_FURNACE, - TN_GUI_CREATIVE_TABS, - TN_GUI_CREATIVE_TAB_ITEMS, - TN_GUI_CREATIVE_TAB_INVENTORY, - TN_GUI_CREATIVE_TAB_ITEM_SEARCH, - TN_TITLE_MCLOGO, TN_GUI_ICONS, TN_ITEM_ARROWS, TN_ITEM_BOAT, @@ -157,8 +145,20 @@ typedef enum _TEXTURE_NAME { TN_TILE_TRAP_CHEST, TN_TILE_LARGE_TRAP_CHEST, - // 4jcraft: 1.6.4 java UI + // 4jcraft: java UI specific #ifdef ENABLE_JAVA_GUIS + TN__BLUR__MISC_VIGNETTE, + TN_ACHIEVEMENT_BG, + TN_GUI_BACKGROUND, + TN_GUI_INVENTORY, + TN_GUI_CONTAINER, + TN_GUI_CRAFTING, + TN_GUI_FURNACE, + TN_GUI_CREATIVE_TABS, + TN_GUI_CREATIVE_TAB_ITEMS, + TN_GUI_CREATIVE_TAB_INVENTORY, + TN_GUI_CREATIVE_TAB_ITEM_SEARCH, + TN_TITLE_MCLOGO, TN_GUI_HORSE, TN_TITLE_BG_PANORAMA, #endif diff --git a/Minecraft.Client/UI/Screens/HorseInventoryScreen.cpp b/Minecraft.Client/UI/Screens/HorseInventoryScreen.cpp index ffdfaaeb9..1ce2e2fe1 100644 --- a/Minecraft.Client/UI/Screens/HorseInventoryScreen.cpp +++ b/Minecraft.Client/UI/Screens/HorseInventoryScreen.cpp @@ -8,8 +8,9 @@ #include "../../../Minecraft.World/Containers/HorseInventoryMenu.h" // 4jcraft: referenced from MCP 8.11 (JE 1.6.4) and the existing InventoryScreen - +#ifdef ENABLE_JAVA_GUIS ResourceLocation GUI_HORSE_LOCATION = ResourceLocation(TN_GUI_HORSE); +#endif HorseInventoryScreen::HorseInventoryScreen( std::shared_ptr inventory, diff --git a/Minecraft.Client/UI/Screens/TitleScreen.cpp b/Minecraft.Client/UI/Screens/TitleScreen.cpp index 78e292a58..600ee8199 100644 --- a/Minecraft.Client/UI/Screens/TitleScreen.cpp +++ b/Minecraft.Client/UI/Screens/TitleScreen.cpp @@ -158,6 +158,7 @@ void TitleScreen::buttonClicked(Button* button) { // uses the TU panorama instead of JE panorama and as such a different rendering // method void TitleScreen::renderPanorama() { +#ifdef ENABLE_JAVA_GUIS Tesselator* t = Tesselator::getInstance(); glMatrixMode(GL_PROJECTION); @@ -217,6 +218,7 @@ void TitleScreen::renderPanorama() { glPopMatrix(); glMatrixMode(GL_MODELVIEW); glPopMatrix(); +#endif } void TitleScreen::render(int xm, int ym, float a) { From 7a0ebe7e36057adc74d531c527cf40421bfd07c7 Mon Sep 17 00:00:00 2001 From: Sally Knight Date: Wed, 25 Mar 2026 23:41:45 +0300 Subject: [PATCH 055/170] fix(jui): remove debug world autocreate from CreateWorldScreen --- Minecraft.Client/UI/Screens/CreateWorldScreen.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Minecraft.Client/UI/Screens/CreateWorldScreen.cpp b/Minecraft.Client/UI/Screens/CreateWorldScreen.cpp index d38f3d067..8ca1690e9 100644 --- a/Minecraft.Client/UI/Screens/CreateWorldScreen.cpp +++ b/Minecraft.Client/UI/Screens/CreateWorldScreen.cpp @@ -30,8 +30,8 @@ void CreateWorldScreen::tick() { if (moreOptions) seedEdit->tick(); // 4J - debug code - to be removed - static int count = 0; - if (count++ == 100) buttonClicked(buttons[0]); + // static int count = 0; + // if (count++ == 100) buttonClicked(buttons[0]); } void CreateWorldScreen::init() { From 11e944f78b8d2317aba90e1055197246d83f31d8 Mon Sep 17 00:00:00 2001 From: Sally Knight Date: Thu, 26 Mar 2026 00:15:27 +0300 Subject: [PATCH 056/170] fix(jui): remove debug autoconfirm from ConfirmScreen --- Minecraft.Client/UI/Screens/ConfirmScreen.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Minecraft.Client/UI/Screens/ConfirmScreen.cpp b/Minecraft.Client/UI/Screens/ConfirmScreen.cpp index 16f4ffe9d..17133b288 100644 --- a/Minecraft.Client/UI/Screens/ConfirmScreen.cpp +++ b/Minecraft.Client/UI/Screens/ConfirmScreen.cpp @@ -47,9 +47,9 @@ void ConfirmScreen::render(int xm, int ym, float a) { Screen::render(xm, ym, a); // 4J - debug code - remove - static int count = 0; - if (count++ == 100) { - count = 0; - buttonClicked(buttons[0]); - } + // static int count = 0; + // if (count++ == 100) { + // count = 0; + // buttonClicked(buttons[0]); + // } } \ No newline at end of file From 5f5e7e7f99fb87daf77524495825e5d988c62a3b Mon Sep 17 00:00:00 2001 From: Sally Knight Date: Thu, 26 Mar 2026 03:10:10 +0300 Subject: [PATCH 057/170] feat(jui): add item switch tooltips --- Minecraft.Client/UI/Gui.cpp | 50 +++++++++++++++++++++++++++++++++++++ Minecraft.Client/UI/Gui.h | 4 +++ 2 files changed, 54 insertions(+) diff --git a/Minecraft.Client/UI/Gui.cpp b/Minecraft.Client/UI/Gui.cpp index 8d9d12071..728277092 100644 --- a/Minecraft.Client/UI/Gui.cpp +++ b/Minecraft.Client/UI/Gui.cpp @@ -56,6 +56,10 @@ Gui::Gui(Minecraft* minecraft) { tbr = 1.0f; fAlphaIncrementPerCent = 255.0f / 100.0f; + // 4jcraft: backported item switch tooltip display from 1.6.4 + remainingHighlightTicks = 0; + highlightingItemStack = nullptr; + this->minecraft = minecraft; lastTickA = 0.0f; @@ -816,6 +820,31 @@ void Gui::render(float a, bool mouseFree, int xMouse, int yMouse) { } #if RENDER_HUD + // 4jcraft: backported item switch tooltip display from 1.6.4 + if (remainingHighlightTicks > 0 && highlightingItemStack != nullptr) { + std::wstring displayName = highlightingItemStack->getHoverName(); + int x = (screenWidth - font->width(displayName)) / 2; + int y = screenHeight - 89; + + if (!minecraft->gameMode->canHurtPlayer()) { + y += 14; + } + + int alpha = (int)((float)remainingHighlightTicks * 256.0f / 10.0f); + if (alpha > 255) alpha = 255; + if (alpha > 0) { + glPushMatrix(); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + int color = 0xFFFFFF | (alpha << 24); + font->drawShadow(displayName, x, y, color); + + glDisable(GL_BLEND); + glPopMatrix(); + } + } + // Moved so the opacity blend is applied to it if (bDisplayGui && minecraft->gameMode->hasExperience() && minecraft->player->experienceLevel > 0) { @@ -1334,6 +1363,27 @@ void Gui::tick() { if (overlayMessageTime > 0) overlayMessageTime--; tickCount++; + // 4jcraft: backported item switch tooltip display from 1.6.4 + if (minecraft->player != nullptr) { + std::shared_ptr currentItem = + minecraft->player->inventory->getSelected(); + + if (currentItem == nullptr) { + remainingHighlightTicks = 0; + } else if (highlightingItemStack != nullptr && + currentItem->id == highlightingItemStack->id && + currentItem->sameItemWithTags(highlightingItemStack) && + (currentItem->isDamageableItem() || + currentItem->getDamageValue() == + highlightingItemStack->getDamageValue())) { + if (remainingHighlightTicks > 0) --remainingHighlightTicks; + } else { + remainingHighlightTicks = 40; + } + + highlightingItemStack = currentItem; + } + for (int iPad = 0; iPad < XUSER_MAX_COUNT; iPad++) { // 4J Stu - Fix for #10929 - MP LAB: Network Disconnects: Host does not // receive an error message stating the client left the game when diff --git a/Minecraft.Client/UI/Gui.h b/Minecraft.Client/UI/Gui.h index 81ee2b5f8..2ced840c3 100644 --- a/Minecraft.Client/UI/Gui.h +++ b/Minecraft.Client/UI/Gui.h @@ -34,6 +34,10 @@ private: float lastTickA; float fAlphaIncrementPerCent; + // 4jcraft: backported item switch tooltip display from 1.6.4 + int remainingHighlightTicks; + std::shared_ptr highlightingItemStack; + public: static float currentGuiBlendFactor; // 4J added static float currentGuiScaleFactor; // 4J added From 11f71c12b2368187b29b325372f6244ce873dc9f Mon Sep 17 00:00:00 2001 From: Sally Knight Date: Thu, 26 Mar 2026 03:20:32 +0300 Subject: [PATCH 058/170] chore: fmt --- Minecraft.Client/Player/LocalPlayer.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Minecraft.Client/Player/LocalPlayer.cpp b/Minecraft.Client/Player/LocalPlayer.cpp index de9cfe1c7..1e029e8ca 100644 --- a/Minecraft.Client/Player/LocalPlayer.cpp +++ b/Minecraft.Client/Player/LocalPlayer.cpp @@ -601,8 +601,7 @@ bool LocalPlayer::openHopper(std::shared_ptr container) { bool LocalPlayer::openHorseInventory(std::shared_ptr horse, std::shared_ptr container) { #ifdef ENABLE_JAVA_GUIS - minecraft->setScreen(new HorseInventoryScreen(inventory, container, - horse)); + minecraft->setScreen(new HorseInventoryScreen(inventory, container, horse)); bool success = true; #else bool success = app.LoadHorseMenu(GetXboxPad(), inventory, container, horse); From 2131c12de7a9a7f00d754014e8466302cded69c1 Mon Sep 17 00:00:00 2001 From: Sally Knight Date: Thu, 26 Mar 2026 05:27:50 +0300 Subject: [PATCH 059/170] feat(jui): make edit box background be able to get disabled --- Minecraft.Client/UI/EditBox.cpp | 33 +++++++++++++++++++++++++++------ Minecraft.Client/UI/EditBox.h | 5 +++++ 2 files changed, 32 insertions(+), 6 deletions(-) diff --git a/Minecraft.Client/UI/EditBox.cpp b/Minecraft.Client/UI/EditBox.cpp index 2ce3d3224..24b564e41 100644 --- a/Minecraft.Client/UI/EditBox.cpp +++ b/Minecraft.Client/UI/EditBox.cpp @@ -7,6 +7,9 @@ EditBox::EditBox(Screen* screen, Font* font, int x, int y, int width, // 4J - added initialisers maxLength = 0; frame = 0; + enableBackgroundDrawing = + true; // 4jcraft: for toggling the background rendering (from 1.6.4, + // mainly for RepairScreen) this->screen = screen; this->font = font; @@ -68,18 +71,36 @@ void EditBox::focus(bool newFocus) { } void EditBox::render() { - fill(x - 1, y - 1, x + width + 1, y + height + 1, 0xffa0a0a0); - fill(x, y, x + width, y + height, 0xff000000); + // 4jcraft: render the background conditionally + if (enableBackgroundDrawing) { + fill(x - 1, y - 1, x + width + 1, y + height + 1, 0xffa0a0a0); + fill(x, y, x + width, y + height, 0xff000000); + } + + // 4jcraft: offset conditionally + int textX = x; + int textY = y; + if (enableBackgroundDrawing) { + textX += 4; + textY += (height - 8) / 2; + } if (active) { bool renderUnderscore = inFocus && (frame / 6 % 2 == 0); - drawString(font, value + (renderUnderscore ? L"_" : L""), x + 4, - y + (height - 8) / 2, 0xe0e0e0); + drawString(font, value + (renderUnderscore ? L"_" : L""), textX, textY, + 0xe0e0e0); } else { - drawString(font, value, x + 4, y + (height - 8) / 2, 0x707070); + drawString(font, value, textX, textY, + (enableBackgroundDrawing ? 0xe0e0e0 : 0xffffff)); } } void EditBox::setMaxLength(int maxLength) { this->maxLength = maxLength; } -int EditBox::getMaxLength() { return maxLength; } \ No newline at end of file +int EditBox::getMaxLength() { return maxLength; } + +// 4jcraft: for toggling the background rendering (from 1.6.4, mainly for +// RepairScreen) +void EditBox::setEnableBackgroundDrawing(bool enable) { + enableBackgroundDrawing = enable; +} \ No newline at end of file diff --git a/Minecraft.Client/UI/EditBox.h b/Minecraft.Client/UI/EditBox.h index 1b78d424f..133bfc0f8 100644 --- a/Minecraft.Client/UI/EditBox.h +++ b/Minecraft.Client/UI/EditBox.h @@ -18,6 +18,8 @@ private: public: bool inFocus; bool active; + bool enableBackgroundDrawing; // 4jcraft: for toggling the background + // rendering (mainly for RepairScreen) private: Screen* screen; @@ -34,4 +36,7 @@ public: void render(); void setMaxLength(int maxLength); int getMaxLength(); + + // 4jcraft: for toggling the background rendering (mainly for RepairScreen) + void setEnableBackgroundDrawing(bool enable); }; \ No newline at end of file From a9a3cbb0f5bd89026a9a46fc95e8df89962d2d59 Mon Sep 17 00:00:00 2001 From: Sally Knight Date: Thu, 26 Mar 2026 06:09:38 +0300 Subject: [PATCH 060/170] fix(jui): disable isConstantBlended for hotbar slot rendering Fixes the issue where in the java UI hotbar, enchant glints make the item appear as a black texture --- Minecraft.Client/UI/Gui.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Minecraft.Client/UI/Gui.cpp b/Minecraft.Client/UI/Gui.cpp index 728277092..dea90b73c 100644 --- a/Minecraft.Client/UI/Gui.cpp +++ b/Minecraft.Client/UI/Gui.cpp @@ -1349,7 +1349,8 @@ void Gui::renderSlot(int slot, int x, int y, float a) { } itemRenderer->renderAndDecorateItem(minecraft->font, minecraft->textures, - item, x, y); + item, x, y, 1.0f, 1.0f, 1.0f, + item->isFoil(), false); if (pop > 0) { glPopMatrix(); From d18733b14c6fa4114756c1f3fd74aa9b29bc535d Mon Sep 17 00:00:00 2001 From: StevenSYS <139715581+StevenSYS@users.noreply.github.com> Date: Thu, 26 Mar 2026 06:28:39 +0000 Subject: [PATCH 061/170] Ported over the Java Edition's title screen panorama. --- Minecraft.Client/Minecraft.cpp | 6 +- Minecraft.Client/Textures/Texture.cpp | 12 +- Minecraft.Client/UI/Screens/TitleScreen.cpp | 180 +++++++++++++++----- Minecraft.Client/UI/Screens/TitleScreen.h | 7 +- 4 files changed, 154 insertions(+), 51 deletions(-) diff --git a/Minecraft.Client/Minecraft.cpp b/Minecraft.Client/Minecraft.cpp index bb2610813..ee7ac2623 100644 --- a/Minecraft.Client/Minecraft.cpp +++ b/Minecraft.Client/Minecraft.cpp @@ -1967,7 +1967,11 @@ void Minecraft::run_middle() { player->ullButtonsPressed = 0LL; } else if (screen != NULL) { screen->updateEvents(); - screen->tick(); + // 4jcraft: this fixes the title screen panorama running + // faster than it should + if (!idx) { + screen->tick(); + } } } diff --git a/Minecraft.Client/Textures/Texture.cpp b/Minecraft.Client/Textures/Texture.cpp index 5cd1fbbdd..5d54d9a09 100644 --- a/Minecraft.Client/Textures/Texture.cpp +++ b/Minecraft.Client/Textures/Texture.cpp @@ -471,10 +471,10 @@ void Texture::blit(int x, int y, Texture* source, bool rotated) { } void Texture::transferFromBuffer(intArray buffer) { - //if (depth == 1) { - // return; - //} - // 4jcraft - move pos out of loops + // if (depth == 1) { + // return; + // } + // 4jcraft - move pos out of loops data[0]->clear(); // #ifdef __PS3__ // int byteRemapRGBA[] = { 3, 0, 1, 2 }; @@ -487,7 +487,7 @@ void Texture::transferFromBuffer(intArray buffer) { int totalPixels = width * height * depth; - for (int i = 0; i < totalPixels; i++){ + for (int i = 0; i < totalPixels; i++) { int pixel = buffer[i]; int offset = i * 4; @@ -501,7 +501,7 @@ void Texture::transferFromBuffer(intArray buffer) { updateOnGPU(); } - + /* for (int z = 0; z < depth; z++) { int plane = z * height * width * 4; for (int y = 0; y < height; y++) { diff --git a/Minecraft.Client/UI/Screens/TitleScreen.cpp b/Minecraft.Client/UI/Screens/TitleScreen.cpp index 600ee8199..dcf055456 100644 --- a/Minecraft.Client/UI/Screens/TitleScreen.cpp +++ b/Minecraft.Client/UI/Screens/TitleScreen.cpp @@ -17,7 +17,8 @@ Random* TitleScreen::random = new Random(); TitleScreen::TitleScreen() { // 4J - added initialisers - vo = 0; + // vo = 0; // 4jcraft removed + panoramaTimer = 0.0f; multiplayerButton = NULL; splash = L"missingno"; @@ -66,10 +67,18 @@ TitleScreen::TitleScreen() { } splash = splashes.at(splashIndex); + + titlePanoramaPaths[0] = L"title/bg/panorama0.png"; + titlePanoramaPaths[1] = L"title/bg/panorama1.png"; + titlePanoramaPaths[2] = L"title/bg/panorama2.png"; + titlePanoramaPaths[3] = L"title/bg/panorama3.png"; + titlePanoramaPaths[4] = L"title/bg/panorama4.png"; + titlePanoramaPaths[5] = L"title/bg/panorama5.png"; } void TitleScreen::tick() { - vo += 1.0f; + panoramaTimer += 1.0f; + // vo += 1.0f; // 4jcraft removed // if( vo > 100.0f ) minecraft->setScreen(new SelectWorldScreen(this)); // // 4J - temp testing } @@ -78,6 +87,10 @@ void TitleScreen::keyPressed(wchar_t eventCharacter, int eventKey) {} void TitleScreen::init() { app.DebugPrintf("TitleScreen::init() START\n"); + + // 4jcraft: this is for the blured panorama background + viewportTexture = + minecraft->textures->getTexture(new BufferedImage(256, 256, 2)); /* 4J - removed Calendar c = Calendar.getInstance(); c.setTime(new Date()); @@ -157,80 +170,161 @@ void TitleScreen::buttonClicked(Button* button) { // 4jcraft: render our panorama // uses the TU panorama instead of JE panorama and as such a different rendering // method -void TitleScreen::renderPanorama() { +void TitleScreen::renderPanorama(float a) { #ifdef ENABLE_JAVA_GUIS Tesselator* t = Tesselator::getInstance(); glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); - glOrtho(0, width, height, 0, 1000, 3000); + gluPerspective(120.0f, 1.0f, 0.05f, 10.0f); glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); - glTranslatef(0, 0, -2000); - - glDisable(GL_LIGHTING); - glDisable(GL_FOG); - glEnable(GL_TEXTURE_2D); - glDisable(GL_ALPHA_TEST); + glColor4f(1.0f, 1.0f, 1.0f, 1.0f); + glRotatef(180.0f, 1.0f, 0.0f, 0.0f); glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glDisable(GL_ALPHA_TEST); + glDisable(GL_CULL_FACE); glDepthMask(false); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + char offsetPasses = 8; - glBindTexture(GL_TEXTURE_2D, - minecraft->textures->loadTexture(TN_TITLE_BG_PANORAMA)); + for (int i = 0; i < (offsetPasses * offsetPasses); i++) { + glPushMatrix(); + float x = + ((float)(i % offsetPasses) / (float)offsetPasses - 0.5f) / 64.0f; + float y = + ((float)(i / offsetPasses) / (float)offsetPasses - 0.5f) / 64.0f; + float z = 0.0f; + glTranslatef(x, y, z); + glRotatef(sin((panoramaTimer + a) / 400.0f) * 25.0f + 20.0f, 1.0f, 0.0f, + 0.0f); + glRotatef(-(panoramaTimer + a) * 0.1f, 0.0f, 1.0f, 0.0f); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + for (int j = 0; j < 6; j++) { + glPushMatrix(); - float off = vo * 0.0001f; + switch (j) { + case 1: + glRotatef(90.0f, 0.0f, 1.0f, 0.0f); + break; + case 2: + glRotatef(180.0f, 0.0f, 1.0f, 0.0f); + break; + case 3: + glRotatef(-90.0f, 0.0f, 1.0f, 0.0f); + break; + case 4: + glRotatef(90.0f, 1.0f, 0.0f, 0.0f); + break; + case 5: + glRotatef(-90.0f, 1.0f, 0.0f, 0.0f); + break; + default: + break; + } - float screenAspect = (float)width / (float)height; - float texAspect = 1748.0f / 144.0f; - float scale; - if (screenAspect > texAspect) { - scale = (float)width / 1748.0f; - } else { - scale = (float)height / 144.0f; + minecraft->textures->bindTexture(titlePanoramaPaths[j]); + t->begin(); + t->color(16777215, 255 / (i + 1)); + t->vertexUV(-1.0f, -1.0f, 1.0f, 0.0f, 0.0f); + t->vertexUV(1.0f, -1.0f, 1.0f, 1.0f, 0.0f); + t->vertexUV(1.0f, 1.0f, 1.0f, 1.0f, 1.0f); + t->vertexUV(-1.0f, 1.0f, 1.0f, 0.0f, 1.0f); + t->end(); + glPopMatrix(); + } + glPopMatrix(); + glColorMask(true, true, true, false); } - float texWidth = 1748.0f * scale; - float texHeight = 144.0f * scale; - float yOff = (height - texHeight) / 2.0f; - - float uMax = off + (texWidth / 1748.0f); - - t->begin(GL_QUADS); - t->color(0xffffff, 255); - t->vertexUV(0, yOff + texHeight, 0, off, 1.0f); - t->vertexUV(texWidth, yOff + texHeight, 0, uMax, 1.0f); - t->vertexUV(texWidth, yOff, 0, uMax, 0.0f); - t->vertexUV(0, yOff, 0, off, 0.0f); - t->end(); - - glDepthMask(true); - glDisable(GL_BLEND); - glEnable(GL_ALPHA_TEST); + t->offset(0.0f, 0.0f, 0.0f); + glColorMask(true, true, true, true); glMatrixMode(GL_PROJECTION); glPopMatrix(); glMatrixMode(GL_MODELVIEW); glPopMatrix(); + glDepthMask(true); + glEnable(GL_CULL_FACE); + glEnable(GL_ALPHA_TEST); + glEnable(GL_DEPTH_TEST); +#endif +} + +// 4jcraft +void TitleScreen::renderSkybox(float a) { + glViewport(0, 0, 256, 256); + renderPanorama(a); + glDisable(GL_TEXTURE_2D); + glEnable(GL_TEXTURE_2D); + + for (int i = 0; i < 8; i++) { + rotateAndBlur(a); + } + + glViewport(0, 0, minecraft->width, minecraft->height); + + Tesselator* t = Tesselator::getInstance(); + t->begin(); + float aspect = + width > height ? 120.0f / (float)width : 120.0f / (float)height; + float sWidth = (float)height * aspect / 256.0f; + float sHeight = (float)width * aspect / 256.0f; + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + t->color(1.0f, 1.0f, 1.0f, 1.0f); + t->vertexUV(0.0f, height, 0.0f, (0.5f - sWidth), (0.5f + sHeight)); + t->vertexUV(width, height, 0.0f, (0.5f - sWidth), (0.5f - sHeight)); + t->vertexUV(width, 0.0f, 0.0f, (0.5f + sWidth), (0.5f - sHeight)); + t->vertexUV(0.0f, 0.0f, 0.0f, (0.5f + sWidth), (0.5f + sHeight)); + t->end(); + return; +} + +// 4jcraft +void TitleScreen::rotateAndBlur(float a) { +#ifdef ENABLE_JAVA_GUIS + glBindTexture(GL_TEXTURE_2D, viewportTexture); + // this.mc.renderEngine.resetBoundTexture(); + glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 256, 256); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glColorMask(true, true, true, false); + Tesselator* t = Tesselator::getInstance(); + t->begin(); + char blurPasses = 3; + + for (int i = 0; i < blurPasses; i++) { + t->color(1.0f, 1.0f, 1.0f, 1.0f / (float)(i + 1)); + float offset = (float)(i - blurPasses / 2) / 256.0f; + t->vertexUV(width, height, 0.0f, (0.0f + offset), 0.0f); + t->vertexUV(width, 0.0f, 0.0f, (1.0f + offset), 0.0f); + t->vertexUV(0.0f, 0.0f, 0.0f, (1.0f + offset), 1.0f); + t->vertexUV(0.0f, height, 0.0f, (0.0f + offset), 1.0f); + } + + t->end(); + glColorMask(true, true, true, true); + // this.mc.renderEngine.resetBoundTexture(); #endif } void TitleScreen::render(int xm, int ym, float a) { // 4J Unused - Iggy Flash UI renders the title screen on consoles #ifdef ENABLE_JAVA_GUIS - renderPanorama(); + // 4jcraft: panorama + renderSkybox(a); + Tesselator* t = Tesselator::getInstance(); int logoWidth = 155 + 119; int logoX = width / 2 - logoWidth / 2; int logoY = 30; + // 4jcraft: gradient + fillGradient(0, 0, width, height, -2130706433, 16777215); + fillGradient(0, 0, width, height, 0, INT_MIN); + glBindTexture(GL_TEXTURE_2D, minecraft->textures->loadTexture(TN_TITLE_MCLOGO)); glColor4f(1, 1, 1, 1); diff --git a/Minecraft.Client/UI/Screens/TitleScreen.h b/Minecraft.Client/UI/Screens/TitleScreen.h index f729cea2e..9bb7ffdca 100644 --- a/Minecraft.Client/UI/Screens/TitleScreen.h +++ b/Minecraft.Client/UI/Screens/TitleScreen.h @@ -13,7 +13,12 @@ private: Button* multiplayerButton; // 4jcraft: panorama - void renderPanorama(); + void renderPanorama(float a); + void renderSkybox(float a); + void rotateAndBlur(float a); + int viewportTexture; + float panoramaTimer; + std::wstring titlePanoramaPaths[6]; // 4jcraft: taken from UIScene_MainMenu // 4J Added From 9a2062c70a4086bf3f1dc30b782494d87427dbd6 Mon Sep 17 00:00:00 2001 From: Sally Knight Date: Thu, 26 Mar 2026 15:48:52 +0300 Subject: [PATCH 062/170] fix(jui): always use white if background is disabled in EditBox --- Minecraft.Client/UI/EditBox.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Minecraft.Client/UI/EditBox.cpp b/Minecraft.Client/UI/EditBox.cpp index 24b564e41..da48457e7 100644 --- a/Minecraft.Client/UI/EditBox.cpp +++ b/Minecraft.Client/UI/EditBox.cpp @@ -88,7 +88,7 @@ void EditBox::render() { if (active) { bool renderUnderscore = inFocus && (frame / 6 % 2 == 0); drawString(font, value + (renderUnderscore ? L"_" : L""), textX, textY, - 0xe0e0e0); + (enableBackgroundDrawing ? 0xe0e0e0 : 0xffffff)); } else { drawString(font, value, textX, textY, (enableBackgroundDrawing ? 0xe0e0e0 : 0xffffff)); From fbbf086f71d4e0e81b3d91f4082e7b5b80b77172 Mon Sep 17 00:00:00 2001 From: Sally Knight Date: Thu, 26 Mar 2026 16:51:20 +0300 Subject: [PATCH 063/170] feat(jui): add anvil screen --- .../Common/res/1_2_2/gui/anvil.png | Bin 0 -> 1900 bytes Minecraft.Assets/Common/res/lang/en_US.lang | 3 + Minecraft.Client/Player/LocalPlayer.cpp | 4 +- Minecraft.Client/Textures/Textures.cpp | 3 +- Minecraft.Client/Textures/Textures.h | 3 +- Minecraft.Client/UI/Screens/RepairScreen.cpp | 191 ++++++++++++++++++ Minecraft.Client/UI/Screens/RepairScreen.h | 39 ++++ 7 files changed, 239 insertions(+), 4 deletions(-) create mode 100644 Minecraft.Assets/Common/res/1_2_2/gui/anvil.png create mode 100644 Minecraft.Client/UI/Screens/RepairScreen.cpp create mode 100644 Minecraft.Client/UI/Screens/RepairScreen.h diff --git a/Minecraft.Assets/Common/res/1_2_2/gui/anvil.png b/Minecraft.Assets/Common/res/1_2_2/gui/anvil.png new file mode 100644 index 0000000000000000000000000000000000000000..34e8f9f9f018814ce05dbe56d186f49e866f77df GIT binary patch literal 1900 zcma)52~d+q6y84u5~83~v4{vtG1vhGkI~3sLW{zWHJ}Ixh=~_sQ4%O4ks}G9)wYV7 z7->NTMT=r25mAvVKgEiO<2!B?_wC!ayWe}?d*1|7 zea#6r1OR|J?B}x$00dXuo`^R31$VHcde80GTVJ6mwYK>>!sRmOu)`dz>6 zy?skj&oSs}xV_#AH|@dfVwbmVG~>BechP$5&EZf5lgaG7A#UE3zcp4~CKzO;yb@`Z z@?AWoj32LN@#`EtJUk9ec(s>c+_Y`}p(|)fD{sD;vMAbF_2Ov+kh-^CKEFO?bW-3j zFwtH9FkZXOBG-%Y>#sBror>*sHg?^8qwO87`GPnX+98n3<^5{4dr;VBY?PC6cr^rZ zmuDg{Uvk*;cVXYtTt}Tw2lH~)F^I5QA<-P_>7ZUJd0_u~z&JMXmS`Mip=d&Y*u1Jt zKk&0Z{iTvo?@zz(%x!b#sG9SAVV*~#+7YhOHjWLiGxN#eOCPVxVi&> zNJq%)E}=(UTpL!9rALvw8nx$9t&$c7sAWT~MY}4K5`LB>y23-9)ftX;8n%|oQ&!Sa zI{RODL^*MI4=tl>lw-5FAyk8GxO|3)T-9DyCn>g~=o2Jt8BOuFHPj$Gy>MM-q}gQu zrF_L$&g{`k%`W?g0(|L7OFQ}8CSDyahn?6NEb*Y5h!Ouhwv5xVI*lKKVa`9GJ;bT} zD0-m=BNj9ipBHJg?e`~X5ujIqoDoURIcjU3y9Pv>J!4Z5C(~*|=d-fP%b^u%7EfEe zr9T4Cacuz4kvvhI$a7S1-nPR$Ns2+Vmy@cGP19Hm+`GYOBVM}oIueL6J5&PWFB-Np zJk)+h;x{y;*B{ND%k059gFF}wX0l-_p4S@9N{2G6K+`oVq$1hCf5uKk1olF}B?`f= zk;@#rP_`HYvc(vZ#*0ih0c+w+#KL4YLIBY%1jLJ6LIPX5l6#mCbYo1#X&l5hPSq6_ z%mI|Y1p4xjQ5dPFiwCUrY|d??X7up*g2{`*rCpvv3{~2)2vf@_3aOk)$MzgdQ=F6SPBTQBXC1H zFt&+T18DkeH_HZ{g4GiIQdvtt9l|0?9OS081Sb$>L8UwKSgsXR%G9&THC^In+$}S5 z%_^dCZAC~$wgVg-9L$p5+oi4A9Dxb@Avv!%p z4eRv%D%FBo(i^*4VnGanqQ|)GA=yST7>%UI>&Hl=g$XkO9xMi205BgAFr9PIljRA$ zY%mR!*+qUtdc1qJ6?9K!Q2k*9_H4*aI(EQ!C z3%gz1GZ&?K&Ul}XcUY$dh>52F?)>6U&c>}}+pa+EPu(5tmRd${apq2#>^QcFaq8~x zq$Aj&S^wnp{Wq`xi!4ED4}X$LdE7Q0S4t{S8=V%zY2Dvx= zV8zU)KzVGd|Gx|8&mf22=G&&uMh-l?avVZ)azl{C@?dEo^xw3;SAqX#>qCi4`9OmI c=RK}q!v1>Q*D;u|wqk%bcq7%P=relyA2O*3s{jB1 literal 0 HcmV?d00001 diff --git a/Minecraft.Assets/Common/res/lang/en_US.lang b/Minecraft.Assets/Common/res/lang/en_US.lang index 752a60f39..cc56540f8 100644 --- a/Minecraft.Assets/Common/res/lang/en_US.lang +++ b/Minecraft.Assets/Common/res/lang/en_US.lang @@ -595,6 +595,9 @@ container.crafting=Crafting container.dispenser=Dispenser container.furnace=Furnace container.enchant=Enchant +container.repair=Repair & Name +container.repair.cost=Enchantment Cost: %d +container.repair.expensive=Too Expensive! container.creative=Item Selection container.brewing=Brewing Stand container.chest=Chest diff --git a/Minecraft.Client/Player/LocalPlayer.cpp b/Minecraft.Client/Player/LocalPlayer.cpp index 1e029e8ca..d04c5f1f5 100644 --- a/Minecraft.Client/Player/LocalPlayer.cpp +++ b/Minecraft.Client/Player/LocalPlayer.cpp @@ -1,6 +1,7 @@ #include "../Platform/stdafx.h" #include "LocalPlayer.h" #include "UI/Screens/HorseInventoryScreen.h" +#include "UI/Screens/RepairScreen.h" #include "User.h" #include "../Input/Input.h" #include "../GameState/StatsCounter.h" @@ -644,8 +645,7 @@ bool LocalPlayer::startEnchanting(int x, int y, int z, bool LocalPlayer::startRepairing(int x, int y, int z) { #ifdef ENABLE_JAVA_GUIS - // minecraft.setScreen(new RepairScreen(inventory, level, x, y, z)); - // FUCK YOU 4J FIRST AND FOREMOST + minecraft->setScreen(new RepairScreen(inventory, level, x, y, z)); bool success = true; #else bool success = diff --git a/Minecraft.Client/Textures/Textures.cpp b/Minecraft.Client/Textures/Textures.cpp index f1e08232c..39e8cb4c7 100644 --- a/Minecraft.Client/Textures/Textures.cpp +++ b/Minecraft.Client/Textures/Textures.cpp @@ -163,7 +163,7 @@ const wchar_t* Textures::preLoaded[TN_COUNT] = { L"item/trapped", L"item/trapped_double", - // 4jcraft: java UI specific +// 4jcraft: java UI specific #ifdef ENABLE_JAVA_GUIS L"%blur%/misc/vignette", L"/achievement/bg", @@ -178,6 +178,7 @@ const wchar_t* Textures::preLoaded[TN_COUNT] = { L"gui/creative_inventory/tab_item_search", L"title/mclogo", L"gui/horse", + L"gui/anvil", L"title/bg/panorama", #endif // L"item/christmas", diff --git a/Minecraft.Client/Textures/Textures.h b/Minecraft.Client/Textures/Textures.h index ddf2ecf47..48a392444 100644 --- a/Minecraft.Client/Textures/Textures.h +++ b/Minecraft.Client/Textures/Textures.h @@ -145,7 +145,7 @@ typedef enum _TEXTURE_NAME { TN_TILE_TRAP_CHEST, TN_TILE_LARGE_TRAP_CHEST, - // 4jcraft: java UI specific +// 4jcraft: java UI specific #ifdef ENABLE_JAVA_GUIS TN__BLUR__MISC_VIGNETTE, TN_ACHIEVEMENT_BG, @@ -160,6 +160,7 @@ typedef enum _TEXTURE_NAME { TN_GUI_CREATIVE_TAB_ITEM_SEARCH, TN_TITLE_MCLOGO, TN_GUI_HORSE, + TN_GUI_ANVIL, TN_TITLE_BG_PANORAMA, #endif // TN_TILE_XMAS_CHEST, diff --git a/Minecraft.Client/UI/Screens/RepairScreen.cpp b/Minecraft.Client/UI/Screens/RepairScreen.cpp new file mode 100644 index 000000000..6fc1e8697 --- /dev/null +++ b/Minecraft.Client/UI/Screens/RepairScreen.cpp @@ -0,0 +1,191 @@ +#include "../../Platform/stdafx.h" +#include "RepairScreen.h" +#include +#include +#include +#include "../EditBox.h" +#include "../../Player/MultiPlayerLocalPlayer.h" +#include "../../Rendering/Lighting.h" +#include "../../Textures/Textures.h" +#include "../../../Minecraft.World/Headers/net.minecraft.locale.h" +#include "../../../Minecraft.World/Containers/AnvilMenu.h" +#include "../../../Minecraft.World/Containers/Slot.h" +#include "../../../Minecraft.Client/Network/ClientConnection.h" +#include "../../../Minecraft.Client/Minecraft.h" + +// 4jcraft: referenced from MCP 8.11 (JE 1.6.4) and the existing +// IUIScene_AnvilMenu (from iggy UI) +#ifdef ENABLE_JAVA_GUIS +ResourceLocation GUI_ANVIL_LOCATION = ResourceLocation(TN_GUI_ANVIL); +#endif + +RepairScreen::RepairScreen(std::shared_ptr inventory, Level* level, + int x, int y, int z) + : AbstractContainerScreen( + new AnvilMenu(inventory, level, x, y, z, + Minecraft::GetInstance()->localplayers[0])) { + this->inventory = inventory; + this->level = level; + this->repairMenu = static_cast(menu); + this->passEvents = false; +} + +RepairScreen::~RepairScreen() = default; + +void RepairScreen::init() { + AbstractContainerScreen::init(); + + int xo = (width - imageWidth) / 2; + int yo = (height - imageHeight) / 2; + editName = new EditBox(this, font, xo + 62, yo + 24, 103, 12, L""); + editName->setMaxLength(40); + editName->setEnableBackgroundDrawing(false); + editName->inFocus = true; + + repairMenu->removeSlotListener(this); + repairMenu->addSlotListener(this); +} + +void RepairScreen::removed() { + AbstractContainerScreen::removed(); + repairMenu->removeSlotListener(this); +} + +void RepairScreen::render(int xm, int ym, float a) { + AbstractContainerScreen::render(xm, ym, a); + glDisable(GL_LIGHTING); + if (editName) { + editName->render(); + } +} + +void RepairScreen::renderLabels() { + std::wstring title = + Language::getInstance()->getElement(L"container.repair"); + font->draw(title, 60, 6, 0x404040); + + if (repairMenu->cost > 0) { + int textColor = 0x80ff20; + bool showCost = true; + std::wstring costString; + + if (repairMenu->cost >= 40 && + !Minecraft::GetInstance()->localplayers[0]->abilities.instabuild) { + costString = Language::getInstance()->getElement( + L"container.repair.expensive"); + textColor = 0xff6060; + } else if (!repairMenu->getSlot(AnvilMenu::RESULT_SLOT)->hasItem()) { + showCost = false; + } else if (!repairMenu->getSlot(AnvilMenu::RESULT_SLOT) + ->mayPickup( + Minecraft::GetInstance()->localplayers[0])) { + textColor = 0xff6060; + } + + if (showCost) { + if (costString.empty()) { + costString = Language::getInstance()->getElement( + L"container.repair.cost", repairMenu->cost); + } + + int shadowColor = -0x00ffffff | ((textColor & 0xfcfcfc) >> 2) | + (textColor & -0x00ffffff); + int costX = imageWidth - 8 - font->width(costString); + int costY = 67; + + // if (this.fontRenderer.getUnicodeFlag()) + // { + // drawRect(i1 - 3, b0 - 2, this.xSize - 7, b0 + 10, -16777216); + // drawRect(i1 - 2, b0 - 1, this.xSize - 8, b0 + 9, -12895429); + // } + // else + // { + font->draw(costString, costX, costY + 1, shadowColor); + font->draw(costString, costX + 1, costY, shadowColor); + font->draw(costString, costX + 1, costY + 1, shadowColor); + font->draw(costString, costX, costY, textColor); + // } + } + } +} + +void RepairScreen::renderBg(float a) { +#ifdef ENABLE_JAVA_GUIS + glColor4f(1.0f, 1.0f, 1.0f, 1.0f); + Minecraft::GetInstance()->textures->bindTexture(&GUI_ANVIL_LOCATION); + int xo = (width - imageWidth) / 2; + int yo = (height - imageHeight) / 2; + blit(xo, yo, 0, 0, imageWidth, imageHeight); + + int texV = imageHeight + (repairMenu->getSlot(0)->hasItem() ? 0 : 16); + blit(xo + 59, yo + 20, 0, texV, 110, 16); + + if ((repairMenu->getSlot(AnvilMenu::INPUT_SLOT)->hasItem() || + repairMenu->getSlot(AnvilMenu::ADDITIONAL_SLOT)->hasItem()) && + !repairMenu->getSlot(AnvilMenu::RESULT_SLOT)->hasItem()) { + blit(xo + 99, yo + 45, imageWidth, 0, 28, 21); + } +#endif +} + +void RepairScreen::keyPressed(char ch, int eventKey) { + if (editName) { + editName->keyPressed(ch, eventKey); + updateItemName(); + } else { + AbstractContainerScreen::keyPressed(ch, eventKey); + } +} + +void RepairScreen::mouseClicked(int mouseX, int mouseY, int buttonNum) { + AbstractContainerScreen::mouseClicked(mouseX, mouseY, buttonNum); + if (editName) { + editName->mouseClicked(mouseX, mouseY, buttonNum); + } +} + +void RepairScreen::updateItemName() { + std::wstring itemName; + Slot* slot = repairMenu->getSlot(0); + if (slot != NULL && slot->hasItem()) { + if (!slot->getItem()->hasCustomHoverName() && + itemName == slot->getItem()->getHoverName()) { + itemName = L""; + } + } + + repairMenu->setItemName(itemName); + + ByteArrayOutputStream baos; + DataOutputStream dos(&baos); + dos.writeUTF(itemName); + Minecraft::GetInstance()->player->connection->send( + std::shared_ptr(new CustomPayloadPacket( + CustomPayloadPacket::SET_ITEM_NAME_PACKET, baos.toByteArray()))); +} + +// 4jcraft: these 3 are to implement Containerlistener (see IUIScene_AnvilMenu +// and net.minecraft.world.inventory.ContainerListener) +void RepairScreen::refreshContainer( + AbstractContainerMenu* container, + std::vector >* items) { + slotChanged(container, AnvilMenu::INPUT_SLOT, + container->getSlot(0)->getItem()); +} + +void RepairScreen::slotChanged(AbstractContainerMenu* container, int slotIndex, + std::shared_ptr item) { + if (slotIndex == AnvilMenu::INPUT_SLOT) { + std::wstring itemName = item == NULL ? L"" : item->getHoverName(); + editName->setValue(itemName); + if (item != NULL) { + editName->focus(true); + updateItemName(); + } else { + editName->focus(false); + } + } +} + +void RepairScreen::setContainerData(AbstractContainerMenu* container, int id, + int value) {} \ No newline at end of file diff --git a/Minecraft.Client/UI/Screens/RepairScreen.h b/Minecraft.Client/UI/Screens/RepairScreen.h new file mode 100644 index 000000000..b5352a939 --- /dev/null +++ b/Minecraft.Client/UI/Screens/RepairScreen.h @@ -0,0 +1,39 @@ +#pragma once + +#include "../../Platform/stdafx.h" +#include "AbstractContainerScreen.h" +#include "../../../Minecraft.World/Containers/AnvilMenu.h" +#include "../../../Minecraft.World/Headers/net.minecraft.world.inventory.ContainerListener.h" + +class EditBox; + +class RepairScreen : public AbstractContainerScreen, public ContainerListener { +public: + RepairScreen(std::shared_ptr inventory, Level* level, int x, + int y, int z); + virtual ~RepairScreen(); + + void init(); + void removed(); + void render(int xm, int ym, float a); + void renderLabels(); + void renderBg(float a); + void keyPressed(char ch, int eventKey); + void mouseClicked(int mouseX, int mouseY, int buttonNum); + + // 4jcraft: these 3 are to implement Containerlistener (see + // IUIScene_AnvilMenu and net.minecraft.world.inventory.ContainerListener) + void refreshContainer(AbstractContainerMenu* container, + std::vector >* items); + void slotChanged(AbstractContainerMenu* container, int slotIndex, + std::shared_ptr item); + void setContainerData(AbstractContainerMenu* container, int id, int value); + +private: + void updateItemName(); + + std::shared_ptr inventory; + Level* level; + AnvilMenu* repairMenu; + EditBox* editName; +}; \ No newline at end of file From 975f716f9c8f9e04e0faab260d7a7c83797e749e Mon Sep 17 00:00:00 2001 From: Sally Knight Date: Thu, 26 Mar 2026 17:28:29 +0300 Subject: [PATCH 064/170] feat(jui): re-enable and update TrapScreen (Dispenser and Dropper GUI) --- Minecraft.Client/Player/LocalPlayer.cpp | 6 ++++- Minecraft.Client/Textures/Textures.cpp | 1 + Minecraft.Client/Textures/Textures.h | 1 + Minecraft.Client/UI/Screens/TrapScreen.cpp | 26 +++++++++++++--------- Minecraft.Client/UI/Screens/TrapScreen.h | 5 +++++ 5 files changed, 28 insertions(+), 11 deletions(-) diff --git a/Minecraft.Client/Player/LocalPlayer.cpp b/Minecraft.Client/Player/LocalPlayer.cpp index d04c5f1f5..18f22d8dc 100644 --- a/Minecraft.Client/Player/LocalPlayer.cpp +++ b/Minecraft.Client/Player/LocalPlayer.cpp @@ -683,9 +683,13 @@ bool LocalPlayer::openBeacon(std::shared_ptr beacon) { } bool LocalPlayer::openTrap(std::shared_ptr trap) { +#ifdef ENABLE_JAVA_GUIS + minecraft->setScreen(new TrapScreen(inventory, trap)); + bool success = true; +#else bool success = app.LoadTrapMenu(GetXboxPad(), inventory, trap); if (success) ui.PlayUISFX(eSFX_Press); - // minecraft->setScreen(new TrapScreen(inventory, trap)); +#endif return success; } diff --git a/Minecraft.Client/Textures/Textures.cpp b/Minecraft.Client/Textures/Textures.cpp index 39e8cb4c7..25a502dcb 100644 --- a/Minecraft.Client/Textures/Textures.cpp +++ b/Minecraft.Client/Textures/Textures.cpp @@ -179,6 +179,7 @@ const wchar_t* Textures::preLoaded[TN_COUNT] = { L"title/mclogo", L"gui/horse", L"gui/anvil", + L"gui/trap", L"title/bg/panorama", #endif // L"item/christmas", diff --git a/Minecraft.Client/Textures/Textures.h b/Minecraft.Client/Textures/Textures.h index 48a392444..6c083cf70 100644 --- a/Minecraft.Client/Textures/Textures.h +++ b/Minecraft.Client/Textures/Textures.h @@ -161,6 +161,7 @@ typedef enum _TEXTURE_NAME { TN_TITLE_MCLOGO, TN_GUI_HORSE, TN_GUI_ANVIL, + TN_GUI_TRAP, TN_TITLE_BG_PANORAMA, #endif // TN_TILE_XMAS_CHEST, diff --git a/Minecraft.Client/UI/Screens/TrapScreen.cpp b/Minecraft.Client/UI/Screens/TrapScreen.cpp index 80de6d7e9..7a1afb6bd 100644 --- a/Minecraft.Client/UI/Screens/TrapScreen.cpp +++ b/Minecraft.Client/UI/Screens/TrapScreen.cpp @@ -6,23 +6,29 @@ #include "../../../Minecraft.World/Blocks/TileEntities/DispenserTileEntity.h" #include "../../../Minecraft.World/Headers/net.minecraft.world.h" +#ifdef ENABLE_JAVA_GUIS +ResourceLocation GUI_TRAP_LOCATION = ResourceLocation(TN_GUI_TRAP); +#endif + TrapScreen::TrapScreen(std::shared_ptr inventory, std::shared_ptr trap) - : AbstractContainerScreen(new TrapMenu(inventory, trap)) {} + : AbstractContainerScreen(new TrapMenu(inventory, trap)) { + this->trap = trap; + this->inventory = inventory; +} void TrapScreen::renderLabels() { - font->draw(L"Dispenser", 16 + 4 + 40, 2 + 2 + 2, 0x404040); - font->draw(L"Inventory", 8, imageHeight - 96 + 2, 0x404040); + font->draw(trap->getName(), 16 + 4 + 40, 2 + 2 + 2, 0x404040); + font->draw(inventory->getName(), 8, imageHeight - 96 + 2, 0x404040); } void TrapScreen::renderBg(float a) { // 4J Unused -#if 0 - int tex = minecraft->textures->loadTexture(L"/gui/trap.png"); - glColor4f(1, 1, 1, 1); - minecraft->textures->bind(tex); - int xo = (width - imageWidth) / 2; - int yo = (height - imageHeight) / 2; - this->blit(xo, yo, 0, 0, imageWidth, imageHeight); +#ifdef ENABLE_JAVA_GUIS + glColor4f(1, 1, 1, 1); + minecraft->textures->bindTexture(&GUI_TRAP_LOCATION); + int xo = (width - imageWidth) / 2; + int yo = (height - imageHeight) / 2; + this->blit(xo, yo, 0, 0, imageWidth, imageHeight); #endif } \ No newline at end of file diff --git a/Minecraft.Client/UI/Screens/TrapScreen.h b/Minecraft.Client/UI/Screens/TrapScreen.h index fcf8a33fa..ae2b02c89 100644 --- a/Minecraft.Client/UI/Screens/TrapScreen.h +++ b/Minecraft.Client/UI/Screens/TrapScreen.h @@ -1,4 +1,5 @@ #pragma once +#include #include "AbstractContainerScreen.h" class DispenserTileEntity; class Inventory; @@ -11,4 +12,8 @@ public: protected: virtual void renderLabels(); virtual void renderBg(float a); + +private: + std::shared_ptr inventory; + std::shared_ptr trap; }; \ No newline at end of file From b854af49c60fe84395705221a7b66c297ef07fd7 Mon Sep 17 00:00:00 2001 From: StevenSYS <139715581+StevenSYS@users.noreply.github.com> Date: Thu, 26 Mar 2026 15:49:52 +0000 Subject: [PATCH 065/170] Added option to use the TU panorama or the Java one. --- Minecraft.Assets/Common/res/lang/en_US.lang | 1 + Minecraft.Client/GameState/Options.cpp | 23 +- Minecraft.Client/GameState/Options.h | 4 +- .../Common/UI/UIScene_SettingsOptionsMenu.h | 8 +- Minecraft.Client/Textures/Textures.cpp | 8 +- Minecraft.Client/Textures/Textures.h | 8 +- Minecraft.Client/UI/Screens/TitleScreen.cpp | 305 +++++++++++------- Minecraft.Client/UI/Screens/TitleScreen.h | 2 - .../UI/Screens/VideoSettingsScreen.cpp | 27 +- 9 files changed, 240 insertions(+), 146 deletions(-) diff --git a/Minecraft.Assets/Common/res/lang/en_US.lang b/Minecraft.Assets/Common/res/lang/en_US.lang index cc56540f8..0b005e48c 100644 --- a/Minecraft.Assets/Common/res/lang/en_US.lang +++ b/Minecraft.Assets/Common/res/lang/en_US.lang @@ -189,6 +189,7 @@ options.renderDistance.short=Short options.renderDistance.normal=Normal options.renderDistance.far=Far options.viewBobbing=View Bobbing +options.classicPanorama=Classic Panorama options.ao=Smooth Lighting options.anaglyph=3D Anaglyph options.framerateLimit=Performance diff --git a/Minecraft.Client/GameState/Options.cpp b/Minecraft.Client/GameState/Options.cpp index 289fdecb0..3f6f4e4b1 100644 --- a/Minecraft.Client/GameState/Options.cpp +++ b/Minecraft.Client/GameState/Options.cpp @@ -16,7 +16,7 @@ // 4J - the Option sub-class used to be an java enumerated type, trying to // emulate that functionality here -const Options::Option Options::Option::options[17] = { +const Options::Option Options::Option::options[18] = { Options::Option(L"options.music", true, false), Options::Option(L"options.sound", true, false), Options::Option(L"options.invertMouse", false, true), @@ -34,6 +34,7 @@ const Options::Option Options::Option::options[17] = { Options::Option(L"options.gamma", true, false), Options::Option(L"options.renderClouds", false, true), Options::Option(L"options.particles", false, false), + Options::Option(L"options.classicPanorama", false, true), }; const Options::Option* Options::Option::MUSIC = &Options::Option::options[0]; @@ -65,6 +66,8 @@ const Options::Option* Options::Option::RENDER_CLOUDS = &Options::Option::options[15]; const Options::Option* Options::Option::PARTICLES = &Options::Option::options[16]; +const Options::Option* Options::Option::CLASSIC_PANORAMA = + &(Options::Option::options[17]); const Options::Option* Options::Option::getItem(int id) { return &options[id]; } @@ -111,6 +114,8 @@ void Options::init() { invertYMouse = false; viewDistance = 0; bobView = true; + // 4jcraft + classicPanorama = false; anaglyph3d = false; advancedOpengl = false; @@ -238,9 +243,12 @@ void Options::toggle(const Options::Option* option, int dir) { if (option == Option::PARTICLES) particles = (particles + dir) % 3; // 4J-PB - changing - // if (option == Option::VIEW_BOBBING) bobView = !bobView; - if (option == Option::VIEW_BOBBING) - ((dir == 0) ? bobView = false : bobView = true); + // 4jcraft: uncommented this so that the view bobbing option works + if (option == Option::VIEW_BOBBING) bobView = !bobView; + // 4jcraft + if (option == Option::CLASSIC_PANORAMA) { + classicPanorama = !classicPanorama; + } if (option == Option::RENDER_CLOUDS) renderClouds = !renderClouds; if (option == Option::ADVANCED_OPENGL) { advancedOpengl = !advancedOpengl; @@ -293,6 +301,8 @@ bool Options::getBooleanValue(const Options::Option* item) { // types if (item == Option::INVERT_MOUSE) return invertYMouse; if (item == Option::VIEW_BOBBING) return bobView; + // 4jcraft + if (item == Option::CLASSIC_PANORAMA) return classicPanorama; if (item == Option::ANAGLYPH) return anaglyph3d; if (item == Option::ADVANCED_OPENGL) return advancedOpengl; if (item == Option::AMBIENT_OCCLUSION) return ambientOcclusion; @@ -405,6 +415,8 @@ void Options::load() { if (cmds[0] == L"guiScale") guiScale = _fromString(cmds[1]); if (cmds[0] == L"particles") particles = _fromString(cmds[1]); if (cmds[0] == L"bobView") bobView = cmds[1] == L"true"; + // 4jcraft + if (cmds[0] == L"classicPanorama") classicPanorama = cmds[1] == L"true"; if (cmds[0] == L"anaglyph3d") anaglyph3d = cmds[1] == L"true"; if (cmds[0] == L"advancedOpengl") advancedOpengl = cmds[1] == L"true"; if (cmds[0] == L"fpsLimit") framerateLimit = _fromString(cmds[1]); @@ -459,6 +471,9 @@ void Options::save() { dos.writeChars(L"guiScale:" + _toString(guiScale)); dos.writeChars(L"particles:" + _toString(particles)); dos.writeChars(L"bobView:" + std::wstring(bobView ? L"true" : L"false")); + // 4jcraft + dos.writeChars(L"classicPanorama:" + + std::wstring(classicPanorama ? L"true" : L"false")); dos.writeChars(L"anaglyph3d:" + std::wstring(anaglyph3d ? L"true" : L"false")); dos.writeChars(L"advancedOpengl:" + diff --git a/Minecraft.Client/GameState/Options.h b/Minecraft.Client/GameState/Options.h index b727da4a0..bb84fc759 100644 --- a/Minecraft.Client/GameState/Options.h +++ b/Minecraft.Client/GameState/Options.h @@ -13,7 +13,7 @@ public: // 4J - this used to be an enum class Option { public: - static const Option options[17]; + static const Option options[18]; static const Option* MUSIC; static const Option* SOUND; static const Option* INVERT_MOUSE; @@ -31,6 +31,7 @@ public: static const Option* GAMMA; static const Option* RENDER_CLOUDS; static const Option* PARTICLES; + static const Option* CLASSIC_PANORAMA; private: const bool _isProgress; @@ -61,6 +62,7 @@ public: bool invertYMouse; int viewDistance; bool bobView; + bool classicPanorama; bool anaglyph3d; bool advancedOpengl; int framerateLimit; diff --git a/Minecraft.Client/Platform/Common/UI/UIScene_SettingsOptionsMenu.h b/Minecraft.Client/Platform/Common/UI/UIScene_SettingsOptionsMenu.h index 67c30660d..6bf721a2d 100644 --- a/Minecraft.Client/Platform/Common/UI/UIScene_SettingsOptionsMenu.h +++ b/Minecraft.Client/Platform/Common/UI/UIScene_SettingsOptionsMenu.h @@ -6,6 +6,8 @@ class UIScene_SettingsOptionsMenu : public UIScene { private: enum EControls { eControl_ViewBob, + // 4jcraft + eControl_ClassicPanorama, eControl_ShowHints, eControl_ShowTooltips, eControl_InGameGamertags, @@ -20,8 +22,8 @@ protected: static int m_iDifficultyTitleSettingA[4]; private: - UIControl_CheckBox m_checkboxViewBob, m_checkboxShowHints, - m_checkboxShowTooltips, m_checkboxInGameGamertags, + UIControl_CheckBox m_checkboxViewBob, m_checkboxClassicPanorama, + m_checkboxShowHints, m_checkboxShowTooltips, m_checkboxInGameGamertags, m_checkboxMashupWorlds; // Checkboxes UIControl_Slider m_sliderAutosave, m_sliderDifficulty; // Sliders UIControl_Label m_labelDifficultyText; // Text @@ -29,6 +31,8 @@ private: UI_BEGIN_MAP_ELEMENTS_AND_NAMES(UIScene) UI_MAP_ELEMENT(m_checkboxViewBob, "ViewBob") + // 4jcraft + UI_MAP_ELEMENT(m_checkboxClassicPanorama, "ClassicPanorama") UI_MAP_ELEMENT(m_checkboxShowHints, "ShowHints") UI_MAP_ELEMENT(m_checkboxShowTooltips, "ShowTooltips") UI_MAP_ELEMENT(m_checkboxInGameGamertags, "InGameGamertags") diff --git a/Minecraft.Client/Textures/Textures.cpp b/Minecraft.Client/Textures/Textures.cpp index 25a502dcb..2afdd477a 100644 --- a/Minecraft.Client/Textures/Textures.cpp +++ b/Minecraft.Client/Textures/Textures.cpp @@ -181,6 +181,12 @@ const wchar_t* Textures::preLoaded[TN_COUNT] = { L"gui/anvil", L"gui/trap", L"title/bg/panorama", + L"title/bg/panorama0", + L"title/bg/panorama1", + L"title/bg/panorama2", + L"title/bg/panorama3", + L"title/bg/panorama4", + L"title/bg/panorama5", #endif // L"item/christmas", // L"item/christmas_double", @@ -1494,4 +1500,4 @@ bool Textures::IsOriginalImage(TEXTURE_NAME texId, const std::wstring& name) { i++; } return false; -} +} \ No newline at end of file diff --git a/Minecraft.Client/Textures/Textures.h b/Minecraft.Client/Textures/Textures.h index 6c083cf70..c2ccaa936 100644 --- a/Minecraft.Client/Textures/Textures.h +++ b/Minecraft.Client/Textures/Textures.h @@ -163,6 +163,12 @@ typedef enum _TEXTURE_NAME { TN_GUI_ANVIL, TN_GUI_TRAP, TN_TITLE_BG_PANORAMA, + TN_TITLE_BG_PANORAMA0, + TN_TITLE_BG_PANORAMA1, + TN_TITLE_BG_PANORAMA2, + TN_TITLE_BG_PANORAMA3, + TN_TITLE_BG_PANORAMA4, + TN_TITLE_BG_PANORAMA5, #endif // TN_TILE_XMAS_CHEST, // TN_TILE_LARGE_XMAS_CHEST, @@ -360,4 +366,4 @@ public: // drive static bool IsTUImage(TEXTURE_NAME texId, const std::wstring& name); static bool IsOriginalImage(TEXTURE_NAME texId, const std::wstring& name); -}; +}; \ No newline at end of file diff --git a/Minecraft.Client/UI/Screens/TitleScreen.cpp b/Minecraft.Client/UI/Screens/TitleScreen.cpp index dcf055456..0f8212cb1 100644 --- a/Minecraft.Client/UI/Screens/TitleScreen.cpp +++ b/Minecraft.Client/UI/Screens/TitleScreen.cpp @@ -17,8 +17,7 @@ Random* TitleScreen::random = new Random(); TitleScreen::TitleScreen() { // 4J - added initialisers - // vo = 0; // 4jcraft removed - panoramaTimer = 0.0f; + vo = 0; multiplayerButton = NULL; splash = L"missingno"; @@ -67,18 +66,10 @@ TitleScreen::TitleScreen() { } splash = splashes.at(splashIndex); - - titlePanoramaPaths[0] = L"title/bg/panorama0.png"; - titlePanoramaPaths[1] = L"title/bg/panorama1.png"; - titlePanoramaPaths[2] = L"title/bg/panorama2.png"; - titlePanoramaPaths[3] = L"title/bg/panorama3.png"; - titlePanoramaPaths[4] = L"title/bg/panorama4.png"; - titlePanoramaPaths[5] = L"title/bg/panorama5.png"; } void TitleScreen::tick() { - panoramaTimer += 1.0f; - // vo += 1.0f; // 4jcraft removed + vo += 1.0f; // if( vo > 100.0f ) minecraft->setScreen(new SelectWorldScreen(this)); // // 4J - temp testing } @@ -173,139 +164,203 @@ void TitleScreen::buttonClicked(Button* button) { void TitleScreen::renderPanorama(float a) { #ifdef ENABLE_JAVA_GUIS Tesselator* t = Tesselator::getInstance(); - - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - glLoadIdentity(); - gluPerspective(120.0f, 1.0f, 0.05f, 10.0f); - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - glLoadIdentity(); - glColor4f(1.0f, 1.0f, 1.0f, 1.0f); - glRotatef(180.0f, 1.0f, 0.0f, 0.0f); - glEnable(GL_BLEND); - glDisable(GL_ALPHA_TEST); - glDisable(GL_CULL_FACE); - glDepthMask(false); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - char offsetPasses = 8; - - for (int i = 0; i < (offsetPasses * offsetPasses); i++) { + if (minecraft->options->classicPanorama) { + glMatrixMode(GL_PROJECTION); glPushMatrix(); - float x = - ((float)(i % offsetPasses) / (float)offsetPasses - 0.5f) / 64.0f; - float y = - ((float)(i / offsetPasses) / (float)offsetPasses - 0.5f) / 64.0f; - float z = 0.0f; - glTranslatef(x, y, z); - glRotatef(sin((panoramaTimer + a) / 400.0f) * 25.0f + 20.0f, 1.0f, 0.0f, - 0.0f); - glRotatef(-(panoramaTimer + a) * 0.1f, 0.0f, 1.0f, 0.0f); + glLoadIdentity(); + gluPerspective(120.0f, 1.0f, 0.05f, 10.0f); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + glColor4f(1.0f, 1.0f, 1.0f, 1.0f); + glRotatef(180.0f, 1.0f, 0.0f, 0.0f); + glEnable(GL_BLEND); + glDisable(GL_ALPHA_TEST); + glDisable(GL_CULL_FACE); + glDepthMask(false); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + char offsetPasses = 8; - for (int j = 0; j < 6; j++) { + for (int i = 0; i < (offsetPasses * offsetPasses); i++) { glPushMatrix(); + float x = ((float)(i % offsetPasses) / (float)offsetPasses - 0.5f) / + 64.0f; + float y = ((float)(i / offsetPasses) / (float)offsetPasses - 0.5f) / + 64.0f; + float z = 0.0f; + glTranslatef(x, y, z); + glRotatef(sin((vo + a) / 400.0f) * 25.0f + 20.0f, 1.0f, 0.0f, 0.0f); + glRotatef(-(vo + a) * 0.1f, 0.0f, 1.0f, 0.0f); - switch (j) { - case 1: - glRotatef(90.0f, 0.0f, 1.0f, 0.0f); - break; - case 2: - glRotatef(180.0f, 0.0f, 1.0f, 0.0f); - break; - case 3: - glRotatef(-90.0f, 0.0f, 1.0f, 0.0f); - break; - case 4: - glRotatef(90.0f, 1.0f, 0.0f, 0.0f); - break; - case 5: - glRotatef(-90.0f, 1.0f, 0.0f, 0.0f); - break; - default: - break; + for (int j = 0; j < 6; j++) { + glPushMatrix(); + + switch (j) { + case 1: + glRotatef(90.0f, 0.0f, 1.0f, 0.0f); + break; + case 2: + glRotatef(180.0f, 0.0f, 1.0f, 0.0f); + break; + case 3: + glRotatef(-90.0f, 0.0f, 1.0f, 0.0f); + break; + case 4: + glRotatef(90.0f, 1.0f, 0.0f, 0.0f); + break; + case 5: + glRotatef(-90.0f, 1.0f, 0.0f, 0.0f); + break; + default: + break; + } + + glBindTexture(GL_TEXTURE_2D, minecraft->textures->loadTexture( + TN_TITLE_BG_PANORAMA0 + j)); + t->begin(); + t->color(16777215, 255 / (i + 1)); + t->vertexUV(-1.0f, -1.0f, 1.0f, 0.0f, 0.0f); + t->vertexUV(1.0f, -1.0f, 1.0f, 1.0f, 0.0f); + t->vertexUV(1.0f, 1.0f, 1.0f, 1.0f, 1.0f); + t->vertexUV(-1.0f, 1.0f, 1.0f, 0.0f, 1.0f); + t->end(); + glPopMatrix(); } - - minecraft->textures->bindTexture(titlePanoramaPaths[j]); - t->begin(); - t->color(16777215, 255 / (i + 1)); - t->vertexUV(-1.0f, -1.0f, 1.0f, 0.0f, 0.0f); - t->vertexUV(1.0f, -1.0f, 1.0f, 1.0f, 0.0f); - t->vertexUV(1.0f, 1.0f, 1.0f, 1.0f, 1.0f); - t->vertexUV(-1.0f, 1.0f, 1.0f, 0.0f, 1.0f); - t->end(); glPopMatrix(); + glColorMask(true, true, true, false); } - glPopMatrix(); - glColorMask(true, true, true, false); - } - t->offset(0.0f, 0.0f, 0.0f); - glColorMask(true, true, true, true); - glMatrixMode(GL_PROJECTION); - glPopMatrix(); - glMatrixMode(GL_MODELVIEW); - glPopMatrix(); - glDepthMask(true); - glEnable(GL_CULL_FACE); - glEnable(GL_ALPHA_TEST); - glEnable(GL_DEPTH_TEST); + t->offset(0.0f, 0.0f, 0.0f); + glColorMask(true, true, true, true); + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + glDepthMask(true); + glEnable(GL_CULL_FACE); + glEnable(GL_ALPHA_TEST); + glEnable(GL_DEPTH_TEST); + } else { + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + glOrtho(0, width, height, 0, 1000, 3000); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + glTranslatef(0, 0, -2000); + + glDisable(GL_LIGHTING); + glDisable(GL_FOG); + glEnable(GL_TEXTURE_2D); + glDisable(GL_ALPHA_TEST); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glDepthMask(false); + + glBindTexture(GL_TEXTURE_2D, + minecraft->textures->loadTexture(TN_TITLE_BG_PANORAMA)); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + float off = vo * 0.0004f; + + float screenAspect = (float)width / (float)height; + float texAspect = 1748.0f / 144.0f; + float scale; + if (screenAspect > texAspect) { + scale = (float)width / 1748.0f; + } else { + scale = (float)height / 144.0f; + } + + float texWidth = 1748.0f * scale; + float texHeight = 144.0f * scale; + float yOff = (height - texHeight) / 2.0f; + + float uMax = off + (texWidth / 1748.0f); + + t->begin(GL_QUADS); + t->color(0xffffff, 255); + t->vertexUV(0, yOff + texHeight, 0, off, 1.0f); + t->vertexUV(texWidth, yOff + texHeight, 0, uMax, 1.0f); + t->vertexUV(texWidth, yOff, 0, uMax, 0.0f); + t->vertexUV(0, yOff, 0, off, 0.0f); + t->end(); + + glDepthMask(true); + glDisable(GL_BLEND); + glEnable(GL_ALPHA_TEST); + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + } #endif } // 4jcraft void TitleScreen::renderSkybox(float a) { - glViewport(0, 0, 256, 256); - renderPanorama(a); - glDisable(GL_TEXTURE_2D); - glEnable(GL_TEXTURE_2D); - - for (int i = 0; i < 8; i++) { - rotateAndBlur(a); +#ifdef ENABLE_JAVA_GUIS + if (minecraft->options->classicPanorama) { + glViewport(0, 0, 256, 256); } + renderPanorama(a); + if (minecraft->options->classicPanorama) { + glDisable(GL_TEXTURE_2D); + glEnable(GL_TEXTURE_2D); - glViewport(0, 0, minecraft->width, minecraft->height); + for (int i = 0; i < 8; i++) { + rotateAndBlur(a); + } - Tesselator* t = Tesselator::getInstance(); - t->begin(); - float aspect = - width > height ? 120.0f / (float)width : 120.0f / (float)height; - float sWidth = (float)height * aspect / 256.0f; - float sHeight = (float)width * aspect / 256.0f; - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - t->color(1.0f, 1.0f, 1.0f, 1.0f); - t->vertexUV(0.0f, height, 0.0f, (0.5f - sWidth), (0.5f + sHeight)); - t->vertexUV(width, height, 0.0f, (0.5f - sWidth), (0.5f - sHeight)); - t->vertexUV(width, 0.0f, 0.0f, (0.5f + sWidth), (0.5f - sHeight)); - t->vertexUV(0.0f, 0.0f, 0.0f, (0.5f + sWidth), (0.5f + sHeight)); - t->end(); - return; + glViewport(0, 0, minecraft->width, minecraft->height); + + Tesselator* t = Tesselator::getInstance(); + t->begin(); + float aspect = + width > height ? 120.0f / (float)width : 120.0f / (float)height; + float sWidth = (float)height * aspect / 256.0f; + float sHeight = (float)width * aspect / 256.0f; + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + t->color(1.0f, 1.0f, 1.0f, 1.0f); + t->vertexUV(0.0f, height, 0.0f, (0.5f - sWidth), (0.5f + sHeight)); + t->vertexUV(width, height, 0.0f, (0.5f - sWidth), (0.5f - sHeight)); + t->vertexUV(width, 0.0f, 0.0f, (0.5f + sWidth), (0.5f - sHeight)); + t->vertexUV(0.0f, 0.0f, 0.0f, (0.5f + sWidth), (0.5f + sHeight)); + t->end(); + } +#endif } // 4jcraft void TitleScreen::rotateAndBlur(float a) { #ifdef ENABLE_JAVA_GUIS - glBindTexture(GL_TEXTURE_2D, viewportTexture); - // this.mc.renderEngine.resetBoundTexture(); - glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 256, 256); - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glColorMask(true, true, true, false); - Tesselator* t = Tesselator::getInstance(); - t->begin(); - char blurPasses = 3; + if (minecraft->options->classicPanorama) { + glBindTexture(GL_TEXTURE_2D, viewportTexture); + glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 256, 256); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glColorMask(true, true, true, false); + Tesselator* t = Tesselator::getInstance(); + t->begin(); + char blurPasses = 3; - for (int i = 0; i < blurPasses; i++) { - t->color(1.0f, 1.0f, 1.0f, 1.0f / (float)(i + 1)); - float offset = (float)(i - blurPasses / 2) / 256.0f; - t->vertexUV(width, height, 0.0f, (0.0f + offset), 0.0f); - t->vertexUV(width, 0.0f, 0.0f, (1.0f + offset), 0.0f); - t->vertexUV(0.0f, 0.0f, 0.0f, (1.0f + offset), 1.0f); - t->vertexUV(0.0f, height, 0.0f, (0.0f + offset), 1.0f); + for (int i = 0; i < blurPasses; i++) { + t->color(1.0f, 1.0f, 1.0f, 1.0f / (float)(i + 1)); + float offset = (float)(i - blurPasses / 2) / 256.0f; + t->vertexUV(width, height, 0.0f, (0.0f + offset), 0.0f); + t->vertexUV(width, 0.0f, 0.0f, (1.0f + offset), 0.0f); + t->vertexUV(0.0f, 0.0f, 0.0f, (1.0f + offset), 1.0f); + t->vertexUV(0.0f, height, 0.0f, (0.0f + offset), 1.0f); + } + + t->end(); + glColorMask(true, true, true, true); } - - t->end(); - glColorMask(true, true, true, true); - // this.mc.renderEngine.resetBoundTexture(); #endif } @@ -321,9 +376,11 @@ void TitleScreen::render(int xm, int ym, float a) { int logoX = width / 2 - logoWidth / 2; int logoY = 30; - // 4jcraft: gradient - fillGradient(0, 0, width, height, -2130706433, 16777215); - fillGradient(0, 0, width, height, 0, INT_MIN); + // 4jcraft: gradient for classic panorama + if (minecraft->options->classicPanorama) { + fillGradient(0, 0, width, height, -2130706433, 16777215); + fillGradient(0, 0, width, height, 0, INT_MIN); + } glBindTexture(GL_TEXTURE_2D, minecraft->textures->loadTexture(TN_TITLE_MCLOGO)); diff --git a/Minecraft.Client/UI/Screens/TitleScreen.h b/Minecraft.Client/UI/Screens/TitleScreen.h index 9bb7ffdca..fa29afb52 100644 --- a/Minecraft.Client/UI/Screens/TitleScreen.h +++ b/Minecraft.Client/UI/Screens/TitleScreen.h @@ -17,8 +17,6 @@ private: void renderSkybox(float a); void rotateAndBlur(float a); int viewportTexture; - float panoramaTimer; - std::wstring titlePanoramaPaths[6]; // 4jcraft: taken from UIScene_MainMenu // 4J Added diff --git a/Minecraft.Client/UI/Screens/VideoSettingsScreen.cpp b/Minecraft.Client/UI/Screens/VideoSettingsScreen.cpp index 5daf8fdcc..4a2777494 100644 --- a/Minecraft.Client/UI/Screens/VideoSettingsScreen.cpp +++ b/Minecraft.Client/UI/Screens/VideoSettingsScreen.cpp @@ -6,6 +6,9 @@ #include "ControlsScreen.h" #include "../../../Minecraft.World/Headers/net.minecraft.locale.h" +// 4jcraft +#define ITEM_COUNT 11 + VideoSettingsScreen::VideoSettingsScreen(Screen* lastScreen, Options* options) { this->title = L"Video Settings"; // 4J - added this->lastScreen = lastScreen; @@ -16,18 +19,20 @@ void VideoSettingsScreen::init() { Language* language = Language::getInstance(); this->title = language->getElement(L"options.videoTitle"); - const Options::Option* items[10] = {Options::Option::GRAPHICS, - Options::Option::RENDER_DISTANCE, - Options::Option::AMBIENT_OCCLUSION, - Options::Option::FRAMERATE_LIMIT, - Options::Option::ANAGLYPH, - Options::Option::VIEW_BOBBING, - Options::Option::GUI_SCALE, - Options::Option::ADVANCED_OPENGL, - Options::Option::GAMMA, - Options::Option::FOV}; + const Options::Option* items[ITEM_COUNT] = { + Options::Option::GRAPHICS, + Options::Option::RENDER_DISTANCE, + Options::Option::AMBIENT_OCCLUSION, + Options::Option::FRAMERATE_LIMIT, + Options::Option::ANAGLYPH, + Options::Option::VIEW_BOBBING, + Options::Option::GUI_SCALE, + Options::Option::ADVANCED_OPENGL, + Options::Option::GAMMA, + Options::Option::FOV, + Options::Option::CLASSIC_PANORAMA}; - for (int i = 0; i < 10; i++) { + for (int i = 0; i < ITEM_COUNT; i++) { const Options::Option* item = items[i]; int xPos = width / 2 - 155 + (i % 2 * 160); int yPos = height / 6 + 24 * (i / 2); From 5ac7f23577e43bdf652e303f3a324c72a0e0e2bd Mon Sep 17 00:00:00 2001 From: Sally Knight Date: Thu, 26 Mar 2026 19:37:28 +0300 Subject: [PATCH 066/170] feat(jui): add hopper screen --- .../Common/res/1_2_2/gui/hopper.png | Bin 0 -> 1202 bytes Minecraft.Client/Player/LocalPlayer.cpp | 7 +++- Minecraft.Client/Textures/Textures.cpp | 1 + Minecraft.Client/Textures/Textures.h | 1 + .../UI/Screens/CreateWorldScreen.cpp | 4 +- Minecraft.Client/UI/Screens/HopperScreen.cpp | 37 ++++++++++++++++++ Minecraft.Client/UI/Screens/HopperScreen.h | 21 ++++++++++ 7 files changed, 69 insertions(+), 2 deletions(-) create mode 100644 Minecraft.Assets/Common/res/1_2_2/gui/hopper.png create mode 100644 Minecraft.Client/UI/Screens/HopperScreen.cpp create mode 100644 Minecraft.Client/UI/Screens/HopperScreen.h diff --git a/Minecraft.Assets/Common/res/1_2_2/gui/hopper.png b/Minecraft.Assets/Common/res/1_2_2/gui/hopper.png new file mode 100644 index 0000000000000000000000000000000000000000..3d0054790f574bb8ffcd90fe2069edc2375c0420 GIT binary patch literal 1202 zcmeAS@N?(olHy`uVBq!ia0y~yU<5K58911MRQ8&P5C#Tjh5(-sS0EP%%+1Y1Lqof} zyN?|^_W%EXh~OwW8Un*U1d^tF&INjsu_VYZn8D%MjWiG^$=lt9p@UV{1IXbl@Q5sC zVBk9l!i+m6X1@h0u=8|r45_&F_O>BkvjLAo;BJ*W|4-zGuhN^U>rt71reTV{Vk5KQ z#Md2sJJ&1c@B3ey=HIZhEBACCLofp)i+}?P@#9&c$*Qn0P6NJgt3)wm1s<$oJa$}M zI#k;&iHSp@fdN50XL(`$Yn_eLd!7s5*2P;IqnQihYB7J2tqqr3IGbZ9E4sZvd0|Ci z#qG#OLJdz)`jX7>pO;Ia!QS1s)s`LAUXY@d8&+ container) { } bool LocalPlayer::openHopper(std::shared_ptr container) { - // minecraft->setScreen(new HopperScreen(inventory, container)); +#ifdef ENABLE_JAVA_GUIS + minecraft->setScreen(new HopperScreen(inventory, container)); + bool success = true; +#else bool success = app.LoadHopperMenu(GetXboxPad(), inventory, container); if (success) ui.PlayUISFX(eSFX_Press); +#endif return success; } diff --git a/Minecraft.Client/Textures/Textures.cpp b/Minecraft.Client/Textures/Textures.cpp index 2afdd477a..50f92da4f 100644 --- a/Minecraft.Client/Textures/Textures.cpp +++ b/Minecraft.Client/Textures/Textures.cpp @@ -180,6 +180,7 @@ const wchar_t* Textures::preLoaded[TN_COUNT] = { L"gui/horse", L"gui/anvil", L"gui/trap", + L"gui/hopper", L"title/bg/panorama", L"title/bg/panorama0", L"title/bg/panorama1", diff --git a/Minecraft.Client/Textures/Textures.h b/Minecraft.Client/Textures/Textures.h index c2ccaa936..8b80be1ba 100644 --- a/Minecraft.Client/Textures/Textures.h +++ b/Minecraft.Client/Textures/Textures.h @@ -162,6 +162,7 @@ typedef enum _TEXTURE_NAME { TN_GUI_HORSE, TN_GUI_ANVIL, TN_GUI_TRAP, + TN_GUI_HOPPER, TN_TITLE_BG_PANORAMA, TN_TITLE_BG_PANORAMA0, TN_TITLE_BG_PANORAMA1, diff --git a/Minecraft.Client/UI/Screens/CreateWorldScreen.cpp b/Minecraft.Client/UI/Screens/CreateWorldScreen.cpp index 8ca1690e9..593f8416a 100644 --- a/Minecraft.Client/UI/Screens/CreateWorldScreen.cpp +++ b/Minecraft.Client/UI/Screens/CreateWorldScreen.cpp @@ -155,7 +155,9 @@ void CreateWorldScreen::buttonClicked(Button* button) { app.DebugPrintf("CreateWorldScreen::buttonClicked START\n"); if (!button->active) return; if (button->id == 1) { - app.DebugPrintf("CreateWorldScreen::buttonClicked 'Cancel' minecraft->setScreen(lastScreen)\n"); + app.DebugPrintf( + "CreateWorldScreen::buttonClicked 'Cancel' " + "minecraft->setScreen(lastScreen)\n"); minecraft->setScreen(lastScreen); } else if (button->id == 0) { minecraft->setScreen( diff --git a/Minecraft.Client/UI/Screens/HopperScreen.cpp b/Minecraft.Client/UI/Screens/HopperScreen.cpp new file mode 100644 index 000000000..2bab4945e --- /dev/null +++ b/Minecraft.Client/UI/Screens/HopperScreen.cpp @@ -0,0 +1,37 @@ +#include "../../Platform/stdafx.h" +#include "HopperScreen.h" +#include "../../Textures/Textures.h" +#include "../../Player/LocalPlayer.h" +#include "../Font.h" +#include "../../../Minecraft.World/Headers/net.minecraft.world.inventory.h" +#include "../../../Minecraft.World/Containers/HopperMenu.h" + +// 4jcraft: referenced from MCP 8.11 (JE 1.6.4) and the existing +// container classes +#ifdef ENABLE_JAVA_GUIS +ResourceLocation GUI_HOPPER_LOCATION = ResourceLocation(TN_GUI_HOPPER); +#endif + +HopperScreen::HopperScreen(std::shared_ptr inventory, + std::shared_ptr hopper) + : AbstractContainerScreen(new HopperMenu(inventory, hopper)) { + this->hopper = hopper; + this->inventory = inventory; + imageHeight = 133; +} + +void HopperScreen::renderLabels() { + font->draw(hopper->getName(), 8, 6, 0x404040); + font->draw(inventory->getName(), 8, imageHeight - 96 + 2, 0x404040); +} + +void HopperScreen::renderBg(float a) { + // 4J Unused +#ifdef ENABLE_JAVA_GUIS + glColor4f(1, 1, 1, 1); + minecraft->textures->bindTexture(&GUI_HOPPER_LOCATION); + int xo = (width - imageWidth) / 2; + int yo = (height - imageHeight) / 2; + this->blit(xo, yo, 0, 0, imageWidth, imageHeight); +#endif +} \ No newline at end of file diff --git a/Minecraft.Client/UI/Screens/HopperScreen.h b/Minecraft.Client/UI/Screens/HopperScreen.h new file mode 100644 index 000000000..eb1bb752f --- /dev/null +++ b/Minecraft.Client/UI/Screens/HopperScreen.h @@ -0,0 +1,21 @@ +#pragma once +#include +#include "AbstractContainerScreen.h" + +class HopperTileEntity; +class MinecartHopper; +class Inventory; + +class HopperScreen : public AbstractContainerScreen { +public: + HopperScreen(std::shared_ptr inventory, + std::shared_ptr hopper); + +protected: + virtual void renderLabels(); + virtual void renderBg(float a); + +private: + std::shared_ptr inventory; + std::shared_ptr hopper; +}; \ No newline at end of file From bdebc23e91542b768972a1b5a99a80ebfdb0f6fd Mon Sep 17 00:00:00 2001 From: Sally Knight Date: Thu, 26 Mar 2026 19:43:56 +0300 Subject: [PATCH 067/170] fix(jui): open hopper screen for minecart hopper as well --- Minecraft.Client/Player/LocalPlayer.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Minecraft.Client/Player/LocalPlayer.cpp b/Minecraft.Client/Player/LocalPlayer.cpp index c04a64230..c9cd930df 100644 --- a/Minecraft.Client/Player/LocalPlayer.cpp +++ b/Minecraft.Client/Player/LocalPlayer.cpp @@ -598,9 +598,13 @@ bool LocalPlayer::openHopper(std::shared_ptr container) { } bool LocalPlayer::openHopper(std::shared_ptr container) { - // minecraft->setScreen(new HopperScreen(inventory, container)); +#ifdef ENABLE_JAVA_GUIS + minecraft->setScreen(new HopperScreen(inventory, container)); + bool success = true; +#else bool success = app.LoadHopperMenu(GetXboxPad(), inventory, container); if (success) ui.PlayUISFX(eSFX_Press); +#endif return success; } From c512bcb19cb7edf7f548c3cc0aa115182131785c Mon Sep 17 00:00:00 2001 From: Sally Knight Date: Fri, 27 Mar 2026 19:32:10 +0300 Subject: [PATCH 068/170] feat(jui): add enchanting table screen --- Minecraft.Client/Textures/Textures.cpp | 1 + Minecraft.Client/Textures/Textures.h | 1 + .../UI/Screens/EnchantmentScreen.cpp | 322 ++++++++++++++++++ .../UI/Screens/EnchantmentScreen.h | 50 +++ 4 files changed, 374 insertions(+) create mode 100644 Minecraft.Client/UI/Screens/EnchantmentScreen.cpp create mode 100644 Minecraft.Client/UI/Screens/EnchantmentScreen.h diff --git a/Minecraft.Client/Textures/Textures.cpp b/Minecraft.Client/Textures/Textures.cpp index 50f92da4f..20b952c59 100644 --- a/Minecraft.Client/Textures/Textures.cpp +++ b/Minecraft.Client/Textures/Textures.cpp @@ -181,6 +181,7 @@ const wchar_t* Textures::preLoaded[TN_COUNT] = { L"gui/anvil", L"gui/trap", L"gui/hopper", + L"gui/enchant", L"title/bg/panorama", L"title/bg/panorama0", L"title/bg/panorama1", diff --git a/Minecraft.Client/Textures/Textures.h b/Minecraft.Client/Textures/Textures.h index 8b80be1ba..2a6ad074a 100644 --- a/Minecraft.Client/Textures/Textures.h +++ b/Minecraft.Client/Textures/Textures.h @@ -163,6 +163,7 @@ typedef enum _TEXTURE_NAME { TN_GUI_ANVIL, TN_GUI_TRAP, TN_GUI_HOPPER, + TN_GUI_ENCHANT, TN_TITLE_BG_PANORAMA, TN_TITLE_BG_PANORAMA0, TN_TITLE_BG_PANORAMA1, diff --git a/Minecraft.Client/UI/Screens/EnchantmentScreen.cpp b/Minecraft.Client/UI/Screens/EnchantmentScreen.cpp new file mode 100644 index 000000000..5b66569cc --- /dev/null +++ b/Minecraft.Client/UI/Screens/EnchantmentScreen.cpp @@ -0,0 +1,322 @@ +#include "../../Platform/stdafx.h" +#include "EnchantmentScreen.h" +#include +#include +#include +#include +#include "../../Player/MultiPlayerLocalPlayer.h" +#include "../../Rendering/Lighting.h" +#include "../../Textures/Textures.h" +#include "../../../Minecraft.World/Headers/net.minecraft.locale.h" +#include "../../../Minecraft.World/Containers/EnchantmentMenu.h" +#include "../../Rendering/Models/BookModel.h" +#include "../../../Minecraft.Client/Minecraft.h" + +// 4jcraft: referenced from MCP 8.11 (JE 1.6.4) and the existing +// container classes (and iggy too) +#ifdef ENABLE_JAVA_GUIS +ResourceLocation GUI_ENCHANT_LOCATION = ResourceLocation(TN_GUI_ENCHANT); +ResourceLocation ITEM_BOOK_LOCATION = ResourceLocation(TN_ITEM_BOOK); +#endif + +EnchantmentScreen::EnchantmentScreen(std::shared_ptr inventory, + Level* level, int x, int y, int z) + : AbstractContainerScreen(new EnchantmentMenu(inventory, level, x, y, z)) { + xMouse = yMouse = 0.0f; + + this->inventory = inventory; + this->enchantMenu = static_cast(menu); + bookTick = 0; + flip = oFlip = flipT = flipA = 0.0f; + open = oOpen = 0.0f; + last = nullptr; +} + +EnchantmentScreen::~EnchantmentScreen() = default; + +void EnchantmentScreen::init() { AbstractContainerScreen::init(); } + +void EnchantmentScreen::removed() { AbstractContainerScreen::removed(); } + +void EnchantmentScreen::renderLabels() { + font->draw(Language::getInstance()->getElement(L"container.enchant"), 12, 5, + 0x404040); + font->draw(inventory->getName(), 8, imageHeight - 96 + 2, 0x404040); + + int xo = (width - imageWidth) / 2; + int yo = (height - imageHeight) / 2; + + // 4jcraft: our own refactor, text rendering has been moved to the + // foreground here from renderBg() (which is where it was in the JE 1.6.4 + // code) + bool needsUpdate = false; + for (int i = 0; i < 3; ++i) { + if (enchantMenu->costs[i] != lastCosts[i]) { + needsUpdate = true; + lastCosts[i] = enchantMenu->costs[i]; + } + } + if (needsUpdate) { + for (int i = 0; i < 3; ++i) { + if (enchantMenu->costs[i] > 0) { + enchantNames[i] = EnchantmentNames::instance.getRandomName(); + } else { + enchantNames[i] = L""; + } + } + } + + for (int i = 0; i < 3; ++i) { + int cost = enchantMenu->costs[i]; + + int buttonX = 60; + int buttonY = 14 + 19 * i; + + bool isHovering = + (xMouse >= xo + buttonX && xMouse < xo + buttonX + 108 && + yMouse >= yo + buttonY && yMouse < yo + buttonY + 19); + + bool hasEnoughLevels = (minecraft->player->experienceLevel >= cost) || + minecraft->player->abilities.instabuild; + + if (cost > 0) { + std::wstring enchantName = enchantNames[i]; + + Font* weirdEnchantTableFont = minecraft->altFont; + if (weirdEnchantTableFont) { + int nameColor; + + if (!hasEnoughLevels) { + nameColor = 0x342F25; + } else if (isHovering) { + nameColor = 0xFFFF80; + } else { + nameColor = 0x685E4A; + } + + int textX = xo + buttonX + 2; + int textY = yo + buttonY + 2; + + weirdEnchantTableFont->drawWordWrap( + enchantName, buttonX + 2, buttonY + 2, 104, nameColor, 64); + } + + std::wstring costStr = std::to_wstring(cost); + int costX = buttonX + 108 - font->width(costStr) - 2; + int costY = buttonY + 8; + + int costColor; + if (!hasEnoughLevels) { + costColor = 0x407F10; + } else { + costColor = 0x80FF20; + } + + font->drawShadow(costStr, costX, costY, costColor); + } + } +} + +void EnchantmentScreen::render(int xm, int ym, float a) { + AbstractContainerScreen::render(xm, ym, a); + this->xMouse = (float)xm; + this->yMouse = (float)ym; +} + +void EnchantmentScreen::renderBg(float a) { + // 4J unused +#ifdef ENABLE_JAVA_GUIS + glColor4f(1.0f, 1.0f, 1.0f, 1.0f); + Minecraft::GetInstance()->textures->bindTexture(&GUI_ENCHANT_LOCATION); + int xo = (width - imageWidth) / 2; + int yo = (height - imageHeight) / 2; + blit(xo, yo, 0, 0, imageWidth, imageHeight); + + glPushMatrix(); + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + + ScreenSizeCalculator screenSize(minecraft->options, minecraft->width, + minecraft->height); + int scaledWidth = screenSize.getWidth(); + int scaledHeight = screenSize.getHeight(); + int scaleFactor = screenSize.scale; + + glViewport(((scaledWidth - 320) / 2) * scaleFactor, + ((scaledHeight - 240) / 2) * scaleFactor, 320 * scaleFactor, + 240 * scaleFactor); + + glTranslatef(-0.34f, 0.23f, 0.0f); + gluPerspective(90.0f, 1.3333334f, 9.0f, 80.0f); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + Lighting::turnOn(); + + glTranslatef(0.0f, 3.3f, -16.0f); + glScalef(5.0f, 5.0f, 5.0f); + glRotatef(180.0f, 0.0f, 0.0f, 1.0f); + + Minecraft::GetInstance()->textures->bindTexture(&ITEM_BOOK_LOCATION); + glRotatef(20.0f, 1.0f, 0.0f, 0.0f); + + // 4jcraft: brought over from UIControl_EnchantmentBook + float o = oOpen + (open - oOpen) * a; + glTranslatef((1 - o) * 0.2f, (1 - o) * 0.1f, (1 - o) * 0.25f); + glRotatef(-(1 - o) * 90 - 90, 0, 1, 0); + glRotatef(180, 1, 0, 0); + + float ff1 = oFlip + (flip - oFlip) * a + 0.25f; + float ff2 = oFlip + (flip - oFlip) * a + 0.75f; + ff1 = (ff1 - floor(ff1)) * 1.6f - 0.3f; + ff2 = (ff2 - floor(ff2)) * 1.6f - 0.3f; + + if (ff1 < 0.0f) ff1 = 0.0f; + if (ff2 < 0.0f) ff2 = 0.0f; + if (ff1 > 1.0f) ff1 = 1.0f; + if (ff2 > 1.0f) ff2 = 1.0f; + + glEnable(GL_RESCALE_NORMAL); + + static BookModel bookModel; + bookModel.render(nullptr, 0.0f, ff1, ff2, o, 0.0f, 0.0625f, true); + + glDisable(GL_RESCALE_NORMAL); + Lighting::turnOff(); + + glMatrixMode(GL_PROJECTION); + glViewport(0, 0, minecraft->width, minecraft->height); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + + Minecraft::GetInstance()->textures->bindTexture(&GUI_ENCHANT_LOCATION); + glColor4f(1.0f, 1.0f, 1.0f, 1.0f); + + for (int i = 0; i < 3; ++i) { + int cost = enchantMenu->costs[i]; + int buttonX = 60; + int buttonY = 14 + 19 * i; + + bool isHovering = + (xMouse >= xo + buttonX && xMouse < xo + buttonX + 108 && + yMouse >= yo + buttonY && yMouse < yo + buttonY + 19); + + if (cost == 0) { + blit(xo + buttonX, yo + buttonY, 0, 185, 108, 19); + } else { + bool hasEnoughLevels = + (minecraft->player->experienceLevel >= cost) || + minecraft->player->abilities.instabuild; + + int texV; + if (!hasEnoughLevels) { + texV = 185; + } else if (isHovering) { + texV = 204; + } else { + texV = 166; + } + + blit(xo + buttonX, yo + buttonY, 0, texV, 108, 19); + } + } +#endif +} + +void EnchantmentScreen::mouseClicked(int x, int y, int buttonNum) { + AbstractContainerScreen::mouseClicked(x, y, buttonNum); + int xo = (width - imageWidth) / 2; + int yo = (height - imageHeight) / 2; + + for (int i = 0; i < 3; ++i) { + int buttonX = xo + 60; + int buttonY = yo + 14 + 19 * i; + + if (x >= buttonX && x < buttonX + 108 && y >= buttonY && + y < buttonY + 19) { + if (enchantMenu->clickMenuButton(minecraft->player, i)) { + minecraft->gameMode->handleInventoryButtonClick( + enchantMenu->containerId, i); + } + break; + } + } +} + +void EnchantmentScreen::tick() { + AbstractContainerScreen::tick(); + + // 4jcraft: brought over from UIControl_EnchantmentBook + oFlip = flip; + oOpen = open; + + std::shared_ptr current = + enchantMenu->getSlot(EnchantmentMenu::INGREDIENT_SLOT)->getItem(); + if (!ItemInstance::matches(current, last)) { + last = current; + + if (current) { + do { + flipT += random.nextInt(4) - random.nextInt(4); + } while (flip <= flipT + 1 && flip >= flipT - 1); + } else { + flipT = 0.0f; + } + } + + bool shouldBeOpen = false; + for (int i = 0; i < 3; ++i) { + if (enchantMenu->costs[i] != 0) { + shouldBeOpen = true; + break; + } + } + + if (shouldBeOpen) + open += 0.2f; + else + open -= 0.2f; + + if (open < 0.0f) open = 0.0f; + if (open > 1.0f) open = 1.0f; + + float diff = (flipT - flip) * 0.4f; + float max = 0.2f; + if (diff < -max) diff = -max; + if (diff > max) diff = max; + flipA += (diff - flipA) * 0.9f; + flip = flip + flipA; +} + +// 4jcraft: brought over from UIControl_EnchantmentButton +EnchantmentScreen::EnchantmentNames + EnchantmentScreen::EnchantmentNames::instance; + +EnchantmentScreen::EnchantmentNames::EnchantmentNames() { + std::wstring allWords = + L"the elder scrolls klaatu berata niktu xyzzy bless curse light " + L"darkness fire air earth water hot dry cold wet ignite snuff embiggen " + L"twist shorten stretch fiddle destroy imbue galvanize enchant free " + L"limited range of towards inside sphere cube self other ball mental " + L"physical grow shrink demon elemental spirit animal creature beast " + L"humanoid undead fresh stale "; + std::wistringstream iss(allWords); + std::copy(std::istream_iterator >(iss), + std::istream_iterator >(), + std::back_inserter(words)); +} + +std::wstring EnchantmentScreen::EnchantmentNames::getRandomName() { + int wordCount = random.nextInt(2) + 3; + std::wstring word = L""; + for (int i = 0; i < wordCount; i++) { + if (i > 0) word += L" "; + word += words[random.nextInt(words.size())]; + } + return word; +} \ No newline at end of file diff --git a/Minecraft.Client/UI/Screens/EnchantmentScreen.h b/Minecraft.Client/UI/Screens/EnchantmentScreen.h new file mode 100644 index 000000000..79cf8786a --- /dev/null +++ b/Minecraft.Client/UI/Screens/EnchantmentScreen.h @@ -0,0 +1,50 @@ +#pragma once + +#include "AbstractContainerScreen.h" +#include "../../../Minecraft.World/Containers/EnchantmentMenu.h" + +class EnchantmentScreen : public AbstractContainerScreen { +public: + EnchantmentScreen(std::shared_ptr inventory, Level* level, int x, + int y, int z); + virtual ~EnchantmentScreen(); + + void init(); + void removed(); + void tick(); + void mouseClicked(int mouseX, int mouseY, int buttonNum); + void renderLabels(); + void renderBg(float a); + void render(int xm, int ym, float a); + +private: + std::shared_ptr inventory; + EnchantmentMenu* enchantMenu; + float xMouse, yMouse; + + Random random; + + // 4jcraft: brought over from UIControl_EnchantmentBook + int bookTick; + float flip, oFlip, flipT, flipA; + float open, oOpen; + std::shared_ptr last; + + // 4jcraft: brought over from UIControl_EnchantmentButton + class EnchantmentNames { + public: + static EnchantmentNames instance; + + private: + Random random; + std::vector words; + + EnchantmentNames(); + + public: + std::wstring getRandomName(); + }; + + std::wstring enchantNames[3]; + int lastCosts[3]; +}; \ No newline at end of file From 1a478c8a5b5feb85a97a45c4877a97b2e3221171 Mon Sep 17 00:00:00 2001 From: Sally Knight Date: Fri, 27 Mar 2026 20:33:41 +0300 Subject: [PATCH 069/170] refactor(jui): specify overrides, resourcelocations, and localization --- Minecraft.Client/UI/Button.cpp | 9 ++++-- .../UI/Screens/AbstractContainerScreen.h | 18 ++++++------ .../UI/Screens/AchievementScreen.h | 10 +++---- Minecraft.Client/UI/Screens/ChatScreen.h | 12 ++++---- Minecraft.Client/UI/Screens/ConfirmScreen.h | 6 ++-- Minecraft.Client/UI/Screens/ConnectScreen.h | 8 +++--- Minecraft.Client/UI/Screens/ContainerScreen.h | 4 +-- Minecraft.Client/UI/Screens/ControlsScreen.h | 8 +++--- .../UI/Screens/CraftingScreen.cpp | 16 +++++++---- Minecraft.Client/UI/Screens/CraftingScreen.h | 9 ++++-- .../UI/Screens/CreateWorldScreen.h | 16 +++++------ .../UI/Screens/CreativeInventoryScreen.h | 26 ++++++++--------- Minecraft.Client/UI/Screens/DeathScreen.h | 8 +++--- .../UI/Screens/DisconnectedScreen.h | 8 +++--- .../UI/Screens/EnchantmentScreen.h | 14 +++++----- Minecraft.Client/UI/Screens/ErrorScreen.h | 6 ++-- Minecraft.Client/UI/Screens/FurnaceScreen.cpp | 12 +++++--- Minecraft.Client/UI/Screens/FurnaceScreen.h | 5 ++-- Minecraft.Client/UI/Screens/HopperScreen.h | 4 +-- Minecraft.Client/UI/Screens/InBedChatScreen.h | 10 +++---- Minecraft.Client/UI/Screens/InventoryScreen.h | 10 +++---- .../UI/Screens/JoinMultiplayerScreen.h | 14 +++++----- Minecraft.Client/UI/Screens/MessageScreen.h | 6 ++-- Minecraft.Client/UI/Screens/NameEntryScreen.h | 10 +++---- Minecraft.Client/UI/Screens/OptionsScreen.h | 6 ++-- Minecraft.Client/UI/Screens/PauseScreen.h | 8 +++--- .../UI/Screens/ReceivingLevelScreen.h | 8 +++--- .../UI/Screens/RenameWorldScreen.h | 14 +++++----- .../UI/Screens/SelectWorldScreen.h | 8 +++--- Minecraft.Client/UI/Screens/StatsScreen.h | 6 ++-- Minecraft.Client/UI/Screens/TextEditScreen.h | 12 ++++---- Minecraft.Client/UI/Screens/TitleScreen.h | 10 +++---- .../UI/Screens/VideoSettingsScreen.h | 6 ++-- Minecraft.Client/UI/SlideButton.h | 8 +++--- Minecraft.World/Containers/RepairContainer.h | 4 +-- Minecraft.World/Containers/RepairResultSlot.h | 8 +++--- Minecraft.World/Containers/ResultContainer.h | 28 +++++++++---------- Minecraft.World/Containers/ResultSlot.h | 12 ++++---- Minecraft.World/Containers/SimpleContainer.h | 28 +++++++++---------- Minecraft.World/Containers/TrapMenu.h | 4 +-- 40 files changed, 218 insertions(+), 201 deletions(-) diff --git a/Minecraft.Client/UI/Button.cpp b/Minecraft.Client/UI/Button.cpp index 09630ed6b..b5759fa1f 100644 --- a/Minecraft.Client/UI/Button.cpp +++ b/Minecraft.Client/UI/Button.cpp @@ -2,6 +2,10 @@ #include "Button.h" #include "../Textures/Textures.h" +#ifdef ENABLE_JAVA_GUIS +ResourceLocation GUI_GUI_LOCATION = ResourceLocation(TN_GUI_GUI); +#endif + Button::Button(int id, int x, int y, const std::wstring& msg) { init(id, x, y, 200, 20, msg); } @@ -38,8 +42,9 @@ void Button::render(Minecraft* minecraft, int xm, int ym) { Font* font = minecraft->font; - glBindTexture(GL_TEXTURE_2D, minecraft->textures->loadTexture( - TN_GUI_GUI)); // 4J was L"/gui/gui.png" + // glBindTexture(GL_TEXTURE_2D, minecraft->textures->loadTexture( + // TN_GUI_GUI)); // 4J was L"/gui/gui.png" + minecraft->textures->bindTexture(&GUI_GUI_LOCATION); glColor4f(1, 1, 1, 1); bool hovered = xm >= x && ym >= y && xm < x + w && ym < y + h; diff --git a/Minecraft.Client/UI/Screens/AbstractContainerScreen.h b/Minecraft.Client/UI/Screens/AbstractContainerScreen.h index ace3ec4bf..eb7ddc0dd 100644 --- a/Minecraft.Client/UI/Screens/AbstractContainerScreen.h +++ b/Minecraft.Client/UI/Screens/AbstractContainerScreen.h @@ -17,8 +17,8 @@ public: AbstractContainerMenu* menu; AbstractContainerScreen(AbstractContainerMenu* menu); - virtual void init(); - virtual void render(int xm, int ym, float a); + virtual void init() override; + virtual void render(int xm, int ym, float a) override; protected: virtual void renderLabels(); @@ -33,13 +33,13 @@ private: virtual void renderSlot(Slot* slot); protected: - virtual void mouseClicked(int x, int y, int buttonNum); - virtual void mouseReleased(int x, int y, int buttonNum); - virtual void keyPressed(wchar_t eventCharacter, int eventKey); + virtual void mouseClicked(int x, int y, int buttonNum) override; + virtual void mouseReleased(int x, int y, int buttonNum) override; + virtual void keyPressed(wchar_t eventCharacter, int eventKey) override; public: - virtual void removed(); + virtual void removed() override; virtual void slotsChanged(std::shared_ptr container); - virtual bool isPauseScreen(); - virtual void tick(); -}; + virtual bool isPauseScreen() override; + virtual void tick() override; +}; \ No newline at end of file diff --git a/Minecraft.Client/UI/Screens/AchievementScreen.h b/Minecraft.Client/UI/Screens/AchievementScreen.h index 398ab950d..9c8a1223d 100644 --- a/Minecraft.Client/UI/Screens/AchievementScreen.h +++ b/Minecraft.Client/UI/Screens/AchievementScreen.h @@ -43,20 +43,20 @@ public: using Screen::keyPressed; AchievementScreen(StatsCounter* statsCounter); - virtual void init(); + virtual void init() override; protected: - virtual void buttonClicked(Button* button); + virtual void buttonClicked(Button* button) override; virtual void keyPressed(char eventCharacter, int eventKey); public: - virtual void render(int mouseX, int mouseY, float a); - virtual void tick(); + virtual void render(int mouseX, int mouseY, float a) override; + virtual void tick() override; protected: virtual void renderLabels(); virtual void renderBg(int xm, int ym, float a); public: - virtual bool isPauseScreen(); + virtual bool isPauseScreen() override; }; diff --git a/Minecraft.Client/UI/Screens/ChatScreen.h b/Minecraft.Client/UI/Screens/ChatScreen.h index a1d508fab..ce20f5a62 100644 --- a/Minecraft.Client/UI/Screens/ChatScreen.h +++ b/Minecraft.Client/UI/Screens/ChatScreen.h @@ -10,19 +10,19 @@ private: public: ChatScreen(); // 4J added - virtual void init(); - virtual void removed(); - virtual void tick(); + virtual void init() override; + virtual void removed() override; + virtual void tick() override; private: static const std::wstring allowedChars; protected: - void keyPressed(wchar_t ch, int eventKey); + void keyPressed(wchar_t ch, int eventKey) override; public: - void render(int xm, int ym, float a); + void render(int xm, int ym, float a) override; protected: - void mouseClicked(int x, int y, int buttonNum); + void mouseClicked(int x, int y, int buttonNum) override; }; \ No newline at end of file diff --git a/Minecraft.Client/UI/Screens/ConfirmScreen.h b/Minecraft.Client/UI/Screens/ConfirmScreen.h index d0e337129..d400c70cd 100644 --- a/Minecraft.Client/UI/Screens/ConfirmScreen.h +++ b/Minecraft.Client/UI/Screens/ConfirmScreen.h @@ -16,11 +16,11 @@ public: ConfirmScreen(Screen* parent, const std::wstring& title1, const std::wstring& title2, const std::wstring& yesButton, const std::wstring& noButton, int id); - virtual void init(); + virtual void init() override; protected: - virtual void buttonClicked(Button* button); + virtual void buttonClicked(Button* button) override; public: - virtual void render(int xm, int ym, float a); + virtual void render(int xm, int ym, float a) override; }; \ No newline at end of file diff --git a/Minecraft.Client/UI/Screens/ConnectScreen.h b/Minecraft.Client/UI/Screens/ConnectScreen.h index bb817198c..f99add276 100644 --- a/Minecraft.Client/UI/Screens/ConnectScreen.h +++ b/Minecraft.Client/UI/Screens/ConnectScreen.h @@ -10,17 +10,17 @@ private: public: ConnectScreen(Minecraft* minecraft, const std::wstring& ip, int port); - virtual void tick(); + virtual void tick() override; protected: virtual void keyPressed(char eventCharacter, int eventKey); public: - virtual void init(); + virtual void init() override; protected: - virtual void buttonClicked(Button* button); + virtual void buttonClicked(Button* button) override; public: - virtual void render(int xm, int ym, float a); + virtual void render(int xm, int ym, float a) override; }; \ No newline at end of file diff --git a/Minecraft.Client/UI/Screens/ContainerScreen.h b/Minecraft.Client/UI/Screens/ContainerScreen.h index 2e37eafa7..fca18c2f3 100644 --- a/Minecraft.Client/UI/Screens/ContainerScreen.h +++ b/Minecraft.Client/UI/Screens/ContainerScreen.h @@ -14,6 +14,6 @@ public: std::shared_ptr container); protected: - virtual void renderLabels(); - virtual void renderBg(float a); + virtual void renderLabels() override; + virtual void renderBg(float a) override; }; \ No newline at end of file diff --git a/Minecraft.Client/UI/Screens/ControlsScreen.h b/Minecraft.Client/UI/Screens/ControlsScreen.h index c5079aba1..3132fb451 100644 --- a/Minecraft.Client/UI/Screens/ControlsScreen.h +++ b/Minecraft.Client/UI/Screens/ControlsScreen.h @@ -25,12 +25,12 @@ private: int getLeftScreenPosition(); public: - void init(); + void init() override; protected: - void buttonClicked(Button* button); - void keyPressed(wchar_t eventCharacter, int eventKey); + void buttonClicked(Button* button) override; + void keyPressed(wchar_t eventCharacter, int eventKey) override; public: - void render(int xm, int ym, float a); + void render(int xm, int ym, float a) override; }; \ No newline at end of file diff --git a/Minecraft.Client/UI/Screens/CraftingScreen.cpp b/Minecraft.Client/UI/Screens/CraftingScreen.cpp index d9c3f4759..00b90e8c4 100644 --- a/Minecraft.Client/UI/Screens/CraftingScreen.cpp +++ b/Minecraft.Client/UI/Screens/CraftingScreen.cpp @@ -2,11 +2,18 @@ #include "CraftingScreen.h" #include "../../Textures/Textures.h" #include "../../Player/MultiPlayerLocalPlayer.h" +#include "../../../Minecraft.World/Headers/net.minecraft.locale.h" #include "../../../Minecraft.World/Headers/net.minecraft.world.inventory.h" +#ifdef ENABLE_JAVA_GUIS +ResourceLocation GUI_CRAFTING_LOCATION = ResourceLocation(TN_GUI_CRAFTING); +#endif + CraftingScreen::CraftingScreen(std::shared_ptr inventory, Level* level, int x, int y, int z) - : AbstractContainerScreen(new CraftingMenu(inventory, level, x, y, z)) {} + : AbstractContainerScreen(new CraftingMenu(inventory, level, x, y, z)) { + this->inventory = inventory; + } void CraftingScreen::removed() { AbstractContainerScreen::removed(); @@ -14,16 +21,15 @@ void CraftingScreen::removed() { } void CraftingScreen::renderLabels() { - font->draw(L"Crafting", 8 + 16 + 4, 2 + 2 + 2, 0x404040); - font->draw(L"Inventory", 8, imageHeight - 96 + 2, 0x404040); + font->draw(Language::getInstance()->getElement(L"container.crafting"), 8 + 16 + 4, 2 + 2 + 2, 0x404040); + font->draw(inventory->getName(), 8, imageHeight - 96 + 2, 0x404040); } void CraftingScreen::renderBg(float a) { // 4J Unused #ifdef ENABLE_JAVA_GUIS - int tex = minecraft->textures->loadTexture(TN_GUI_CRAFTING); glColor4f(1, 1, 1, 1); - minecraft->textures->bind(tex); + minecraft->textures->bindTexture(&GUI_CRAFTING_LOCATION); int xo = (width - imageWidth) / 2; int yo = (height - imageHeight) / 2; this->blit(xo, yo, 0, 0, imageWidth, imageHeight); diff --git a/Minecraft.Client/UI/Screens/CraftingScreen.h b/Minecraft.Client/UI/Screens/CraftingScreen.h index ba59f871d..77eb664c7 100644 --- a/Minecraft.Client/UI/Screens/CraftingScreen.h +++ b/Minecraft.Client/UI/Screens/CraftingScreen.h @@ -4,12 +4,15 @@ class Inventory; class Level; class CraftingScreen : public AbstractContainerScreen { +private: + std::shared_ptr inventory; + public: CraftingScreen(std::shared_ptr inventory, Level* level, int x, int y, int z); - virtual void removed(); + virtual void removed() override; protected: - virtual void renderLabels(); - virtual void renderBg(float a); + virtual void renderLabels() override; + virtual void renderBg(float a) override; }; \ No newline at end of file diff --git a/Minecraft.Client/UI/Screens/CreateWorldScreen.h b/Minecraft.Client/UI/Screens/CreateWorldScreen.h index 71a18e4d5..ba38b2ec3 100644 --- a/Minecraft.Client/UI/Screens/CreateWorldScreen.h +++ b/Minecraft.Client/UI/Screens/CreateWorldScreen.h @@ -31,8 +31,8 @@ private: public: CreateWorldScreen(Screen* lastScreen); - virtual void tick(); - virtual void init(); + virtual void tick() override; + virtual void init() override; private: void updateResultFolder(); @@ -41,16 +41,16 @@ private: public: static std::wstring findAvailableFolderName(LevelStorageSource* levelSource, const std::wstring& folder); - virtual void removed(); + virtual void removed() override; protected: - virtual void buttonClicked(Button* button); - virtual void keyPressed(wchar_t ch, int eventKey); - virtual void mouseClicked(int x, int y, int buttonNum); + virtual void buttonClicked(Button* button) override; + virtual void keyPressed(wchar_t ch, int eventKey) override; + virtual void mouseClicked(int x, int y, int buttonNum) override; public: - virtual void render(int xm, int ym, float a); - virtual void tabPressed(); + virtual void render(int xm, int ym, float a) override; + virtual void tabPressed() override; private: int m_iGameModeId; diff --git a/Minecraft.Client/UI/Screens/CreativeInventoryScreen.h b/Minecraft.Client/UI/Screens/CreativeInventoryScreen.h index 987ec9a88..6a4ba7847 100644 --- a/Minecraft.Client/UI/Screens/CreativeInventoryScreen.h +++ b/Minecraft.Client/UI/Screens/CreativeInventoryScreen.h @@ -60,21 +60,19 @@ public: }; public: - CreativeInventoryScreen(std::shared_ptr player); - virtual void removed(); - virtual void init(); - virtual void containerTick(); - virtual void tick(); - virtual void updateEvents(); - virtual void keyPressed(wchar_t eventCharacter, int eventKey); - virtual void mouseClicked(int x, int y, int buttonNum); - virtual void mouseReleased(int x, int y, int buttonNum); - virtual void render(int xm, int ym, float a); - + CreativeInventoryScreen(std::shared_ptr player); + virtual void removed() override; + virtual void init() override; + virtual void containerTick(); + virtual void tick() override; + virtual void updateEvents() override; + virtual void keyPressed(wchar_t eventCharacter, int eventKey) override; + virtual void mouseClicked(int x, int y, int buttonNum) override; + virtual void mouseReleased(int x, int y, int buttonNum) override; + virtual void render(int xm, int ym, float a) override; protected: - virtual void renderLabels(); - virtual void renderBg(float a); - + virtual void renderLabels() override; + virtual void renderBg(float a) override; private: void setCurrentCreativeTab(int tab); void selectTab(int tab); diff --git a/Minecraft.Client/UI/Screens/DeathScreen.h b/Minecraft.Client/UI/Screens/DeathScreen.h index 976832afb..382f0e5b6 100644 --- a/Minecraft.Client/UI/Screens/DeathScreen.h +++ b/Minecraft.Client/UI/Screens/DeathScreen.h @@ -3,13 +3,13 @@ class DeathScreen : public Screen { public: - virtual void init(); + virtual void init() override; protected: virtual void keyPressed(char eventCharacter, int eventKey); - virtual void buttonClicked(Button* button); + virtual void buttonClicked(Button* button) override; public: - virtual void render(int xm, int ym, float a); - virtual bool isPauseScreen(); + virtual void render(int xm, int ym, float a) override; + virtual bool isPauseScreen() override; }; \ No newline at end of file diff --git a/Minecraft.Client/UI/Screens/DisconnectedScreen.h b/Minecraft.Client/UI/Screens/DisconnectedScreen.h index 4e49685d7..1dcc1151d 100644 --- a/Minecraft.Client/UI/Screens/DisconnectedScreen.h +++ b/Minecraft.Client/UI/Screens/DisconnectedScreen.h @@ -8,7 +8,7 @@ private: public: DisconnectedScreen(const std::wstring& title, const std::wstring reason, void* reasonObjects, ...); - virtual void tick(); + virtual void tick() override; protected: using Screen::keyPressed; @@ -16,11 +16,11 @@ protected: virtual void keyPressed(char eventCharacter, int eventKey); public: - virtual void init(); + virtual void init() override; protected: - virtual void buttonClicked(Button* button); + virtual void buttonClicked(Button* button) override; public: - virtual void render(int xm, int ym, float a); + virtual void render(int xm, int ym, float a) override; }; diff --git a/Minecraft.Client/UI/Screens/EnchantmentScreen.h b/Minecraft.Client/UI/Screens/EnchantmentScreen.h index 79cf8786a..96a7a6af6 100644 --- a/Minecraft.Client/UI/Screens/EnchantmentScreen.h +++ b/Minecraft.Client/UI/Screens/EnchantmentScreen.h @@ -9,13 +9,13 @@ public: int y, int z); virtual ~EnchantmentScreen(); - void init(); - void removed(); - void tick(); - void mouseClicked(int mouseX, int mouseY, int buttonNum); - void renderLabels(); - void renderBg(float a); - void render(int xm, int ym, float a); + void init() override; + void removed() override; + void tick() override; + void mouseClicked(int mouseX, int mouseY, int buttonNum) override; + void renderLabels() override; + void renderBg(float a) override; + void render(int xm, int ym, float a) override; private: std::shared_ptr inventory; diff --git a/Minecraft.Client/UI/Screens/ErrorScreen.h b/Minecraft.Client/UI/Screens/ErrorScreen.h index b89b64e5d..4c46d36ff 100644 --- a/Minecraft.Client/UI/Screens/ErrorScreen.h +++ b/Minecraft.Client/UI/Screens/ErrorScreen.h @@ -7,9 +7,9 @@ private: public: ErrorScreen(const std::wstring& title, const std::wstring& message); - virtual void init(); - virtual void render(int xm, int ym, float a); + virtual void init() override; + virtual void render(int xm, int ym, float a) override; protected: - virtual void keyPressed(wchar_t eventCharacter, int eventKey); + virtual void keyPressed(wchar_t eventCharacter, int eventKey) override; }; \ No newline at end of file diff --git a/Minecraft.Client/UI/Screens/FurnaceScreen.cpp b/Minecraft.Client/UI/Screens/FurnaceScreen.cpp index c12ca82dc..04d0ca346 100644 --- a/Minecraft.Client/UI/Screens/FurnaceScreen.cpp +++ b/Minecraft.Client/UI/Screens/FurnaceScreen.cpp @@ -6,23 +6,27 @@ #include "../../../Minecraft.World/Headers/net.minecraft.world.inventory.h" #include "../../../Minecraft.World/Blocks/TileEntities/FurnaceTileEntity.h" +#ifdef ENABLE_JAVA_GUIS +ResourceLocation GUI_FURNACE_LOCATION = ResourceLocation(TN_GUI_FURNACE); +#endif + FurnaceScreen::FurnaceScreen(std::shared_ptr inventory, std::shared_ptr furnace) : AbstractContainerScreen(new FurnaceMenu(inventory, furnace)) { + this->inventory = inventory; this->furnace = furnace; } void FurnaceScreen::renderLabels() { - font->draw(L"Furnace", 16 + 4 + 40, 2 + 2 + 2, 0x404040); - font->draw(L"Inventory", 8, imageHeight - 96 + 2, 0x404040); + font->draw(furnace->getName(), 16 + 4 + 40, 2 + 2 + 2, 0x404040); + font->draw(inventory->getName(), 8, imageHeight - 96 + 2, 0x404040); } void FurnaceScreen::renderBg(float a) { // 4J Unused #ifdef ENABLE_JAVA_GUIS - int tex = minecraft->textures->loadTexture(TN_GUI_FURNACE); glColor4f(1, 1, 1, 1); - minecraft->textures->bind(tex); + minecraft->textures->bindTexture(&GUI_FURNACE_LOCATION); int xo = (width - imageWidth) / 2; int yo = (height - imageHeight) / 2; this->blit(xo, yo, 0, 0, imageWidth, imageHeight); diff --git a/Minecraft.Client/UI/Screens/FurnaceScreen.h b/Minecraft.Client/UI/Screens/FurnaceScreen.h index 6908524ec..cdaab078e 100644 --- a/Minecraft.Client/UI/Screens/FurnaceScreen.h +++ b/Minecraft.Client/UI/Screens/FurnaceScreen.h @@ -6,6 +6,7 @@ class Inventory; class FurnaceScreen : public AbstractContainerScreen { private: + std::shared_ptr inventory; std::shared_ptr furnace; public: @@ -13,6 +14,6 @@ public: std::shared_ptr furnace); protected: - virtual void renderLabels(); - virtual void renderBg(float a); + virtual void renderLabels() override; + virtual void renderBg(float a) override; }; \ No newline at end of file diff --git a/Minecraft.Client/UI/Screens/HopperScreen.h b/Minecraft.Client/UI/Screens/HopperScreen.h index eb1bb752f..e3e3d1eb4 100644 --- a/Minecraft.Client/UI/Screens/HopperScreen.h +++ b/Minecraft.Client/UI/Screens/HopperScreen.h @@ -12,8 +12,8 @@ public: std::shared_ptr hopper); protected: - virtual void renderLabels(); - virtual void renderBg(float a); + virtual void renderLabels() override; + virtual void renderBg(float a) override; private: std::shared_ptr inventory; diff --git a/Minecraft.Client/UI/Screens/InBedChatScreen.h b/Minecraft.Client/UI/Screens/InBedChatScreen.h index 3f8625eba..e068f5ce4 100644 --- a/Minecraft.Client/UI/Screens/InBedChatScreen.h +++ b/Minecraft.Client/UI/Screens/InBedChatScreen.h @@ -7,17 +7,17 @@ private: static const int WAKE_UP_BUTTON = 1; public: - virtual void init(); - virtual void removed(); + virtual void init() override; + virtual void removed() override; protected: - virtual void keyPressed(wchar_t ch, int eventKey); + virtual void keyPressed(wchar_t ch, int eventKey) override; public: - virtual void render(int xm, int ym, float a); + virtual void render(int xm, int ym, float a) override; protected: - virtual void buttonClicked(Button* button); + virtual void buttonClicked(Button* button) override; private: void sendWakeUp(); diff --git a/Minecraft.Client/UI/Screens/InventoryScreen.h b/Minecraft.Client/UI/Screens/InventoryScreen.h index 0c7080014..d2a5307c7 100644 --- a/Minecraft.Client/UI/Screens/InventoryScreen.h +++ b/Minecraft.Client/UI/Screens/InventoryScreen.h @@ -6,18 +6,18 @@ class Button; class InventoryScreen : public AbstractContainerScreen { public: InventoryScreen(std::shared_ptr player); - virtual void init(); + virtual void init() override; protected: - virtual void renderLabels(); + virtual void renderLabels() override; private: float xMouse, yMouse; public: - virtual void render(int xm, int ym, float a); + virtual void render(int xm, int ym, float a) override; protected: - virtual void renderBg(float a); - virtual void buttonClicked(Button* button); + virtual void renderBg(float a) override; + virtual void buttonClicked(Button* button) override; }; \ No newline at end of file diff --git a/Minecraft.Client/UI/Screens/JoinMultiplayerScreen.h b/Minecraft.Client/UI/Screens/JoinMultiplayerScreen.h index c04c0d41f..78bce6115 100644 --- a/Minecraft.Client/UI/Screens/JoinMultiplayerScreen.h +++ b/Minecraft.Client/UI/Screens/JoinMultiplayerScreen.h @@ -10,20 +10,20 @@ private: public: JoinMultiplayerScreen(Screen* lastScreen); - virtual void tick(); - virtual void init(); - virtual void removed(); + virtual void tick() override; + virtual void init() override; + virtual void removed() override; protected: - virtual void buttonClicked(Button* button); + virtual void buttonClicked(Button* button) override; private: virtual int parseInt(const std::wstring& str, int def); protected: - virtual void keyPressed(wchar_t ch, int eventKey); - virtual void mouseClicked(int x, int y, int buttonNum); + virtual void keyPressed(wchar_t ch, int eventKey) override; + virtual void mouseClicked(int x, int y, int buttonNum) override; public: - virtual void render(int xm, int ym, float a); + virtual void render(int xm, int ym, float a) override; }; \ No newline at end of file diff --git a/Minecraft.Client/UI/Screens/MessageScreen.h b/Minecraft.Client/UI/Screens/MessageScreen.h index 42a75aa78..62b4ee280 100644 --- a/Minecraft.Client/UI/Screens/MessageScreen.h +++ b/Minecraft.Client/UI/Screens/MessageScreen.h @@ -14,11 +14,11 @@ protected: virtual void keyPressed(char eventCharacter, int eventKey); public: - virtual void init(); + virtual void init() override; protected: - virtual void buttonClicked(Button* button); + virtual void buttonClicked(Button* button) override; public: - virtual void render(int xm, int ym, float a); + virtual void render(int xm, int ym, float a) override; }; \ No newline at end of file diff --git a/Minecraft.Client/UI/Screens/NameEntryScreen.h b/Minecraft.Client/UI/Screens/NameEntryScreen.h index e01c0b428..2f0babddd 100644 --- a/Minecraft.Client/UI/Screens/NameEntryScreen.h +++ b/Minecraft.Client/UI/Screens/NameEntryScreen.h @@ -15,9 +15,9 @@ private: public: NameEntryScreen(Screen* lastScreen, const std::wstring& oldName, int slot); - virtual void init(); - virtual void removed(); - virtual void tick(); + virtual void init() override; + virtual void removed() override; + virtual void tick() override; protected: virtual void buttonClicked(Button button); @@ -26,8 +26,8 @@ private: static const std::wstring allowedChars; protected: - virtual void keyPressed(wchar_t ch, int eventKey); + virtual void keyPressed(wchar_t ch, int eventKey) override; public: - virtual void render(int xm, int ym, float a); + virtual void render(int xm, int ym, float a) override; }; \ No newline at end of file diff --git a/Minecraft.Client/UI/Screens/OptionsScreen.h b/Minecraft.Client/UI/Screens/OptionsScreen.h index 9e33e3dfe..509162eff 100644 --- a/Minecraft.Client/UI/Screens/OptionsScreen.h +++ b/Minecraft.Client/UI/Screens/OptionsScreen.h @@ -16,11 +16,11 @@ private: public: OptionsScreen(Screen* lastScreen, Options* options); - virtual void init(); + virtual void init() override; protected: - virtual void buttonClicked(Button* button); + virtual void buttonClicked(Button* button) override; public: - virtual void render(int xm, int ym, float a); + virtual void render(int xm, int ym, float a) override; }; \ No newline at end of file diff --git a/Minecraft.Client/UI/Screens/PauseScreen.h b/Minecraft.Client/UI/Screens/PauseScreen.h index 375d03eb6..ef67c9f14 100644 --- a/Minecraft.Client/UI/Screens/PauseScreen.h +++ b/Minecraft.Client/UI/Screens/PauseScreen.h @@ -8,15 +8,15 @@ private: public: PauseScreen(); // 4J added - virtual void init(); + virtual void init() override; static void exitWorld(Minecraft* minecraft, bool save); protected: using Screen::buttonClicked; - virtual void buttonClicked(Button* button); + virtual void buttonClicked(Button* button) override; public: - virtual void tick(); - virtual void render(int xm, int ym, float a); + virtual void tick() override; + virtual void render(int xm, int ym, float a) override; }; diff --git a/Minecraft.Client/UI/Screens/ReceivingLevelScreen.h b/Minecraft.Client/UI/Screens/ReceivingLevelScreen.h index ede53e3a2..fb54bec4d 100644 --- a/Minecraft.Client/UI/Screens/ReceivingLevelScreen.h +++ b/Minecraft.Client/UI/Screens/ReceivingLevelScreen.h @@ -16,12 +16,12 @@ protected: virtual void keyPressed(char eventCharacter, int eventKey); public: - virtual void init(); - virtual void tick(); + virtual void init() override; + virtual void tick() override; protected: - virtual void buttonClicked(Button* button); + virtual void buttonClicked(Button* button) override; public: - virtual void render(int xm, int ym, float a); + virtual void render(int xm, int ym, float a) override; }; diff --git a/Minecraft.Client/UI/Screens/RenameWorldScreen.h b/Minecraft.Client/UI/Screens/RenameWorldScreen.h index 1bf433dd3..11f5ed41d 100644 --- a/Minecraft.Client/UI/Screens/RenameWorldScreen.h +++ b/Minecraft.Client/UI/Screens/RenameWorldScreen.h @@ -11,15 +11,15 @@ private: public: RenameWorldScreen(Screen* lastScreen, const std::wstring& levelId); - virtual void tick(); - virtual void init(); - virtual void removed(); + virtual void tick() override; + virtual void init() override; + virtual void removed() override; protected: - virtual void buttonClicked(Button* button); - virtual void keyPressed(wchar_t ch, int eventKey); - virtual void mouseClicked(int x, int y, int buttonNum); + virtual void buttonClicked(Button* button) override; + virtual void keyPressed(wchar_t ch, int eventKey) override; + virtual void mouseClicked(int x, int y, int buttonNum) override; public: - virtual void render(int xm, int ym, float a); + virtual void render(int xm, int ym, float a) override; }; \ No newline at end of file diff --git a/Minecraft.Client/UI/Screens/SelectWorldScreen.h b/Minecraft.Client/UI/Screens/SelectWorldScreen.h index 5531d08e7..77f8dd120 100644 --- a/Minecraft.Client/UI/Screens/SelectWorldScreen.h +++ b/Minecraft.Client/UI/Screens/SelectWorldScreen.h @@ -41,7 +41,7 @@ private: public: SelectWorldScreen(Screen* lastScreen); - virtual void init(); + virtual void init() override; private: void loadLevelList(); @@ -54,12 +54,12 @@ public: virtual void postInit(); protected: - virtual void buttonClicked(Button* button); + virtual void buttonClicked(Button* button) override; public: void worldSelected(int id); - void confirmResult(bool result, int id); - virtual void render(int xm, int ym, float a); + void confirmResult(bool result, int id) override; + virtual void render(int xm, int ym, float a) override; class WorldSelectionList : public ScrolledSelectionList { public: diff --git a/Minecraft.Client/UI/Screens/StatsScreen.h b/Minecraft.Client/UI/Screens/StatsScreen.h index 91b0f5c40..dc567006d 100644 --- a/Minecraft.Client/UI/Screens/StatsScreen.h +++ b/Minecraft.Client/UI/Screens/StatsScreen.h @@ -31,14 +31,14 @@ private: public: StatsScreen(Screen* lastScreen, StatsCounter* stats); - virtual void init(); + virtual void init() override; virtual void postInit(); protected: - virtual void buttonClicked(Button* button); + virtual void buttonClicked(Button* button) override; public: - virtual void render(int xm, int ym, float a); + virtual void render(int xm, int ym, float a) override; class GeneralStatisticsList : public ScrolledSelectionList { protected: diff --git a/Minecraft.Client/UI/Screens/TextEditScreen.h b/Minecraft.Client/UI/Screens/TextEditScreen.h index 4373bd9c9..0c0af219b 100644 --- a/Minecraft.Client/UI/Screens/TextEditScreen.h +++ b/Minecraft.Client/UI/Screens/TextEditScreen.h @@ -13,19 +13,19 @@ private: public: TextEditScreen(std::shared_ptr sign); - virtual void init(); - virtual void removed(); - virtual void tick(); + virtual void init() override; + virtual void removed() override; + virtual void tick() override; protected: - virtual void buttonClicked(Button* button); + virtual void buttonClicked(Button* button) override; private: static const std::wstring allowedChars; protected: - virtual void keyPressed(wchar_t ch, int eventKey); + virtual void keyPressed(wchar_t ch, int eventKey) override; public: - virtual void render(int xm, int ym, float a); + virtual void render(int xm, int ym, float a) override; }; \ No newline at end of file diff --git a/Minecraft.Client/UI/Screens/TitleScreen.h b/Minecraft.Client/UI/Screens/TitleScreen.h index fa29afb52..5df5d4984 100644 --- a/Minecraft.Client/UI/Screens/TitleScreen.h +++ b/Minecraft.Client/UI/Screens/TitleScreen.h @@ -33,17 +33,17 @@ private: public: TitleScreen(); - virtual void tick(); + virtual void tick() override; protected: - virtual void keyPressed(wchar_t eventCharacter, int eventKey); + virtual void keyPressed(wchar_t eventCharacter, int eventKey) override; public: - virtual void init(); + virtual void init() override; protected: - virtual void buttonClicked(Button* button); + virtual void buttonClicked(Button* button) override; public: - virtual void render(int xm, int ym, float a); + virtual void render(int xm, int ym, float a) override; }; \ No newline at end of file diff --git a/Minecraft.Client/UI/Screens/VideoSettingsScreen.h b/Minecraft.Client/UI/Screens/VideoSettingsScreen.h index 7075523b2..bbeb74698 100644 --- a/Minecraft.Client/UI/Screens/VideoSettingsScreen.h +++ b/Minecraft.Client/UI/Screens/VideoSettingsScreen.h @@ -14,11 +14,11 @@ private: public: VideoSettingsScreen(Screen* lastScreen, Options* options); - virtual void init(); + virtual void init() override; protected: - virtual void buttonClicked(Button* button); + virtual void buttonClicked(Button* button) override; public: - virtual void render(int xm, int ym, float a); + virtual void render(int xm, int ym, float a) override; }; \ No newline at end of file diff --git a/Minecraft.Client/UI/SlideButton.h b/Minecraft.Client/UI/SlideButton.h index 28e7726ef..f2db25366 100644 --- a/Minecraft.Client/UI/SlideButton.h +++ b/Minecraft.Client/UI/SlideButton.h @@ -16,10 +16,10 @@ public: const std::wstring& msg, float value); protected: - virtual int getYImage(bool hovered); - virtual void renderBg(Minecraft* minecraft, int xm, int ym); + virtual int getYImage(bool hovered) override; + virtual void renderBg(Minecraft* minecraft, int xm, int ym) override; public: - virtual bool clicked(Minecraft* minecraft, int mx, int my); - virtual void released(int mx, int my); + virtual bool clicked(Minecraft* minecraft, int mx, int my) override; + virtual void released(int mx, int my) override; }; \ No newline at end of file diff --git a/Minecraft.World/Containers/RepairContainer.h b/Minecraft.World/Containers/RepairContainer.h index edb7a6756..1494a1099 100644 --- a/Minecraft.World/Containers/RepairContainer.h +++ b/Minecraft.World/Containers/RepairContainer.h @@ -11,6 +11,6 @@ private: public: RepairContainer(AnvilMenu* menu, int name, bool customName, int size); - void setChanged(); - bool canPlaceItem(int slot, std::shared_ptr item); + void setChanged() override; + bool canPlaceItem(int slot, std::shared_ptr item) override; }; \ No newline at end of file diff --git a/Minecraft.World/Containers/RepairResultSlot.h b/Minecraft.World/Containers/RepairResultSlot.h index 1f8f0f4ea..bc646aa9a 100644 --- a/Minecraft.World/Containers/RepairResultSlot.h +++ b/Minecraft.World/Containers/RepairResultSlot.h @@ -14,9 +14,9 @@ public: std::shared_ptr container, int slot, int x, int y); - bool mayPlace(std::shared_ptr item); - bool mayPickup(std::shared_ptr player); + bool mayPlace(std::shared_ptr item) override; + bool mayPickup(std::shared_ptr player) override; void onTake(std::shared_ptr player, - std::shared_ptr carried); - virtual bool mayCombine(std::shared_ptr item); // 4J Added + std::shared_ptr carried) override; + virtual bool mayCombine(std::shared_ptr item) override; // 4J Added }; \ No newline at end of file diff --git a/Minecraft.World/Containers/ResultContainer.h b/Minecraft.World/Containers/ResultContainer.h index 69ed8ed1e..ea2446558 100644 --- a/Minecraft.World/Containers/ResultContainer.h +++ b/Minecraft.World/Containers/ResultContainer.h @@ -10,19 +10,19 @@ public: // 4J Stu Added a ctor to init items ResultContainer(); - virtual unsigned int getContainerSize(); - virtual std::shared_ptr getItem(unsigned int slot); - virtual std::wstring getName(); - virtual std::wstring getCustomName(); - virtual bool hasCustomName(); + virtual unsigned int getContainerSize() override; + virtual std::shared_ptr getItem(unsigned int slot) override; + virtual std::wstring getName() override; + virtual std::wstring getCustomName() override; + virtual bool hasCustomName() override; virtual std::shared_ptr removeItem(unsigned int slot, - int count); - virtual std::shared_ptr removeItemNoUpdate(int slot); - virtual void setItem(unsigned int slot, std::shared_ptr item); - virtual int getMaxStackSize(); - virtual void setChanged(); - virtual bool stillValid(std::shared_ptr player); - virtual void startOpen() {} // TODO Auto-generated method stub - virtual void stopOpen() {} // TODO Auto-generated method stub - virtual bool canPlaceItem(int slot, std::shared_ptr item); + int count) override; + virtual std::shared_ptr removeItemNoUpdate(int slot) override; + virtual void setItem(unsigned int slot, std::shared_ptr item) override; + virtual int getMaxStackSize() override; + virtual void setChanged() override; + virtual bool stillValid(std::shared_ptr player) override; + virtual void startOpen() override {} // TODO Auto-generated method stub + virtual void stopOpen() override {} // TODO Auto-generated method stub + virtual bool canPlaceItem(int slot, std::shared_ptr item) override; }; \ No newline at end of file diff --git a/Minecraft.World/Containers/ResultSlot.h b/Minecraft.World/Containers/ResultSlot.h index b2a0347f4..473cba387 100644 --- a/Minecraft.World/Containers/ResultSlot.h +++ b/Minecraft.World/Containers/ResultSlot.h @@ -14,15 +14,15 @@ public: std::shared_ptr container, int id, int x, int y); virtual ~ResultSlot() {} - virtual bool mayPlace(std::shared_ptr item); - virtual std::shared_ptr remove(int c); + virtual bool mayPlace(std::shared_ptr item) override; + virtual std::shared_ptr remove(int c) override; protected: - virtual void onQuickCraft(std::shared_ptr picked, int count); - virtual void checkTakeAchievements(std::shared_ptr carried); + virtual void onQuickCraft(std::shared_ptr picked, int count) override; + virtual void checkTakeAchievements(std::shared_ptr carried) override; public: virtual void onTake(std::shared_ptr player, - std::shared_ptr carried); - virtual bool mayCombine(std::shared_ptr item); // 4J Added + std::shared_ptr carried) override; + virtual bool mayCombine(std::shared_ptr item) override; // 4J Added }; \ No newline at end of file diff --git a/Minecraft.World/Containers/SimpleContainer.h b/Minecraft.World/Containers/SimpleContainer.h index 74392b3f3..9ca5e15f9 100644 --- a/Minecraft.World/Containers/SimpleContainer.h +++ b/Minecraft.World/Containers/SimpleContainer.h @@ -19,20 +19,20 @@ public: virtual void addListener(net_minecraft_world::ContainerListener* listener); virtual void removeListener( net_minecraft_world::ContainerListener* listener); - virtual std::shared_ptr getItem(unsigned int slot); + virtual std::shared_ptr getItem(unsigned int slot) override; virtual std::shared_ptr removeItem(unsigned int slot, - int count); - virtual std::shared_ptr removeItemNoUpdate(int slot); - virtual void setItem(unsigned int slot, std::shared_ptr item); - virtual unsigned int getContainerSize(); - virtual std::wstring getName(); - virtual std::wstring getCustomName(); - virtual bool hasCustomName(); + int count) override; + virtual std::shared_ptr removeItemNoUpdate(int slot) override; + virtual void setItem(unsigned int slot, std::shared_ptr item) override; + virtual unsigned int getContainerSize() override; + virtual std::wstring getName() override; + virtual std::wstring getCustomName() override; + virtual bool hasCustomName() override; virtual void setCustomName(const std::wstring& name); - virtual int getMaxStackSize(); - virtual void setChanged(); - virtual bool stillValid(std::shared_ptr player); - virtual void startOpen() {} // TODO Auto-generated method stub - virtual void stopOpen() {} // TODO Auto-generated method stub - virtual bool canPlaceItem(int slot, std::shared_ptr item); + virtual int getMaxStackSize() override; + virtual void setChanged() override; + virtual bool stillValid(std::shared_ptr player) override; + virtual void startOpen() override {} // TODO Auto-generated method stub + virtual void stopOpen() override {} // TODO Auto-generated method stub + virtual bool canPlaceItem(int slot, std::shared_ptr item) override; }; \ No newline at end of file diff --git a/Minecraft.World/Containers/TrapMenu.h b/Minecraft.World/Containers/TrapMenu.h index 03b818380..c4f38b626 100644 --- a/Minecraft.World/Containers/TrapMenu.h +++ b/Minecraft.World/Containers/TrapMenu.h @@ -18,7 +18,7 @@ public: TrapMenu(std::shared_ptr inventory, std::shared_ptr trap); - virtual bool stillValid(std::shared_ptr player); + virtual bool stillValid(std::shared_ptr player) override; virtual std::shared_ptr quickMoveStack( - std::shared_ptr player, int slotIndex); + std::shared_ptr player, int slotIndex) override; }; \ No newline at end of file From 02845d9a5f8dbaee930b466edbf94bdd45968d4f Mon Sep 17 00:00:00 2001 From: Sally Knight Date: Fri, 27 Mar 2026 20:37:52 +0300 Subject: [PATCH 070/170] chore: fmt --- Minecraft.Client/UI/Button.cpp | 2 +- .../UI/Screens/AchievementPopup.cpp | 26 ++++++++----------- .../UI/Screens/CraftingScreen.cpp | 7 ++--- .../UI/Screens/SelectWorldScreen.cpp | 14 ++++++---- .../UI/Screens/SelectWorldScreen.h | 2 +- 5 files changed, 26 insertions(+), 25 deletions(-) diff --git a/Minecraft.Client/UI/Button.cpp b/Minecraft.Client/UI/Button.cpp index b5759fa1f..4dd859f20 100644 --- a/Minecraft.Client/UI/Button.cpp +++ b/Minecraft.Client/UI/Button.cpp @@ -43,7 +43,7 @@ void Button::render(Minecraft* minecraft, int xm, int ym) { Font* font = minecraft->font; // glBindTexture(GL_TEXTURE_2D, minecraft->textures->loadTexture( - // TN_GUI_GUI)); // 4J was L"/gui/gui.png" + // TN_GUI_GUI)); // 4J was L"/gui/gui.png" minecraft->textures->bindTexture(&GUI_GUI_LOCATION); glColor4f(1, 1, 1, 1); diff --git a/Minecraft.Client/UI/Screens/AchievementPopup.cpp b/Minecraft.Client/UI/Screens/AchievementPopup.cpp index de59ec75b..f518da342 100644 --- a/Minecraft.Client/UI/Screens/AchievementPopup.cpp +++ b/Minecraft.Client/UI/Screens/AchievementPopup.cpp @@ -68,14 +68,14 @@ void AchievementPopup::prepareWindow() { void AchievementPopup::render() { // 4J Unused #if ENABLE_JAVA_GUIS - if (Minecraft::warezTime > 0) - { + if (Minecraft::warezTime > 0) { glDisable(GL_DEPTH_TEST); glDepthMask(false); Lighting::turnOff(); prepareWindow(); - std::wstring title = L"Minecraft " + SharedConstants::VERSION_STRING + L" Unlicensed Copy :("; + std::wstring title = L"Minecraft " + SharedConstants::VERSION_STRING + + L" Unlicensed Copy :("; std::wstring msg1 = L"(Or logged in from another location)"; std::wstring msg2 = L"Purchase at minecraft.net"; @@ -89,16 +89,12 @@ void AchievementPopup::render() { if (ach == NULL || startTime == 0) return; double time = (System::currentTimeMillis() - startTime) / 3000.0; - if (isHelper) - { - } - else if (!isHelper && (time < 0 || time > 1)) - { + if (isHelper) { + } else if (!isHelper && (time < 0 || time > 1)) { startTime = 0; return; } - prepareWindow(); glDisable(GL_DEPTH_TEST); glDepthMask(false); @@ -112,7 +108,7 @@ void AchievementPopup::render() { yo = yo * yo; int xx = width - 160; - int yy = 0 - (int) (yo * 36); + int yy = 0 - (int)(yo * 36); int tex = mc->textures->loadTexture(TN_ACHIEVEMENT_BG); glColor4f(1, 1, 1, 1); glEnable(GL_TEXTURE_2D); @@ -122,13 +118,13 @@ void AchievementPopup::render() { blit(xx, yy, 96, 202, 160, 32); // if (isHelper) - // { + // { // mc->font->drawWordWrap(desc, xx + 30, yy + 7, 120, 0xffffffff); // } - // else - // { - mc->font->draw(title, xx + 30, yy + 7, 0xffffff00); - mc->font->draw(desc, xx + 30, yy + 18, 0xffffffff); + // else + // { + mc->font->draw(title, xx + 30, yy + 7, 0xffffff00); + mc->font->draw(desc, xx + 30, yy + 18, 0xffffffff); // } glPushMatrix(); diff --git a/Minecraft.Client/UI/Screens/CraftingScreen.cpp b/Minecraft.Client/UI/Screens/CraftingScreen.cpp index 00b90e8c4..14b9aaae5 100644 --- a/Minecraft.Client/UI/Screens/CraftingScreen.cpp +++ b/Minecraft.Client/UI/Screens/CraftingScreen.cpp @@ -12,8 +12,8 @@ ResourceLocation GUI_CRAFTING_LOCATION = ResourceLocation(TN_GUI_CRAFTING); CraftingScreen::CraftingScreen(std::shared_ptr inventory, Level* level, int x, int y, int z) : AbstractContainerScreen(new CraftingMenu(inventory, level, x, y, z)) { - this->inventory = inventory; - } + this->inventory = inventory; +} void CraftingScreen::removed() { AbstractContainerScreen::removed(); @@ -21,7 +21,8 @@ void CraftingScreen::removed() { } void CraftingScreen::renderLabels() { - font->draw(Language::getInstance()->getElement(L"container.crafting"), 8 + 16 + 4, 2 + 2 + 2, 0x404040); + font->draw(Language::getInstance()->getElement(L"container.crafting"), + 8 + 16 + 4, 2 + 2 + 2, 0x404040); font->draw(inventory->getName(), 8, imageHeight - 96 + 2, 0x404040); } diff --git a/Minecraft.Client/UI/Screens/SelectWorldScreen.cpp b/Minecraft.Client/UI/Screens/SelectWorldScreen.cpp index aa410280b..8c181623d 100644 --- a/Minecraft.Client/UI/Screens/SelectWorldScreen.cpp +++ b/Minecraft.Client/UI/Screens/SelectWorldScreen.cpp @@ -127,7 +127,9 @@ void SelectWorldScreen::buttonClicked(Button* button) { minecraft->setScreen( new RenameWorldScreen(this, getWorldId(selectedWorld))); } else if (button->id == BUTTON_CANCEL_ID) { - app.DebugPrintf("SelectWorldScreen::buttonClicked 'Cancel' minecraft->setScreen(lastScreen)\n"); + app.DebugPrintf( + "SelectWorldScreen::buttonClicked 'Cancel' " + "minecraft->setScreen(lastScreen)\n"); minecraft->setScreen(lastScreen); } else { worldSelectionList->buttonClicked(button); @@ -181,9 +183,9 @@ void SelectWorldScreen::render(int xm, int ym, float a) { static bool forceCreateLevel = false; if (count++ >= 100) { if (!forceCreateLevel && levelList->size() > 0) { - // 4J Stu - For some obscures reason the "delete" button is called - // "renameButton" and vice versa. - // if( levelList->size() > 2 && deleteButton->active ) + // 4J Stu - For some obscures reason the "delete" button is + // called "renameButton" and vice versa. if( levelList->size() > + // 2 && deleteButton->active ) //{ // this->selectedWorld = 2; // count = 0; @@ -205,7 +207,9 @@ void SelectWorldScreen::render(int xm, int ym, float a) { count = 0; } } else { - app.DebugPrintf("SelectWorldScreen::render minecraft->setScreen(new CreateWorldScreen(this))\n"); + app.DebugPrintf( + "SelectWorldScreen::render minecraft->setScreen(new " + "CreateWorldScreen(this))\n"); minecraft->setScreen(new CreateWorldScreen(this)); } } diff --git a/Minecraft.Client/UI/Screens/SelectWorldScreen.h b/Minecraft.Client/UI/Screens/SelectWorldScreen.h index 77f8dd120..39b56c32f 100644 --- a/Minecraft.Client/UI/Screens/SelectWorldScreen.h +++ b/Minecraft.Client/UI/Screens/SelectWorldScreen.h @@ -20,7 +20,7 @@ protected: private: // final DateFormat DATE_FORMAT = new SimpleDateFormat(); // 4J - - //removed + // removed protected: Screen* lastScreen; From 0ce9597e2e44bf4a322630167397ba61672821a4 Mon Sep 17 00:00:00 2001 From: Sally Knight Date: Fri, 27 Mar 2026 20:40:28 +0300 Subject: [PATCH 071/170] chore: fmt (again) --- Minecraft.World/Containers/RepairResultSlot.h | 3 ++- Minecraft.World/Containers/ResultContainer.h | 6 ++++-- Minecraft.World/Containers/ResultSlot.h | 9 ++++++--- Minecraft.World/Containers/SimpleContainer.h | 6 ++++-- 4 files changed, 16 insertions(+), 8 deletions(-) diff --git a/Minecraft.World/Containers/RepairResultSlot.h b/Minecraft.World/Containers/RepairResultSlot.h index bc646aa9a..2dc6b5c17 100644 --- a/Minecraft.World/Containers/RepairResultSlot.h +++ b/Minecraft.World/Containers/RepairResultSlot.h @@ -18,5 +18,6 @@ public: bool mayPickup(std::shared_ptr player) override; void onTake(std::shared_ptr player, std::shared_ptr carried) override; - virtual bool mayCombine(std::shared_ptr item) override; // 4J Added + virtual bool mayCombine( + std::shared_ptr item) override; // 4J Added }; \ No newline at end of file diff --git a/Minecraft.World/Containers/ResultContainer.h b/Minecraft.World/Containers/ResultContainer.h index ea2446558..dc4ff7a9e 100644 --- a/Minecraft.World/Containers/ResultContainer.h +++ b/Minecraft.World/Containers/ResultContainer.h @@ -18,11 +18,13 @@ public: virtual std::shared_ptr removeItem(unsigned int slot, int count) override; virtual std::shared_ptr removeItemNoUpdate(int slot) override; - virtual void setItem(unsigned int slot, std::shared_ptr item) override; + virtual void setItem(unsigned int slot, + std::shared_ptr item) override; virtual int getMaxStackSize() override; virtual void setChanged() override; virtual bool stillValid(std::shared_ptr player) override; virtual void startOpen() override {} // TODO Auto-generated method stub virtual void stopOpen() override {} // TODO Auto-generated method stub - virtual bool canPlaceItem(int slot, std::shared_ptr item) override; + virtual bool canPlaceItem(int slot, + std::shared_ptr item) override; }; \ No newline at end of file diff --git a/Minecraft.World/Containers/ResultSlot.h b/Minecraft.World/Containers/ResultSlot.h index 473cba387..46fecd0b2 100644 --- a/Minecraft.World/Containers/ResultSlot.h +++ b/Minecraft.World/Containers/ResultSlot.h @@ -18,11 +18,14 @@ public: virtual std::shared_ptr remove(int c) override; protected: - virtual void onQuickCraft(std::shared_ptr picked, int count) override; - virtual void checkTakeAchievements(std::shared_ptr carried) override; + virtual void onQuickCraft(std::shared_ptr picked, + int count) override; + virtual void checkTakeAchievements( + std::shared_ptr carried) override; public: virtual void onTake(std::shared_ptr player, std::shared_ptr carried) override; - virtual bool mayCombine(std::shared_ptr item) override; // 4J Added + virtual bool mayCombine( + std::shared_ptr item) override; // 4J Added }; \ No newline at end of file diff --git a/Minecraft.World/Containers/SimpleContainer.h b/Minecraft.World/Containers/SimpleContainer.h index 9ca5e15f9..e9164c1eb 100644 --- a/Minecraft.World/Containers/SimpleContainer.h +++ b/Minecraft.World/Containers/SimpleContainer.h @@ -23,7 +23,8 @@ public: virtual std::shared_ptr removeItem(unsigned int slot, int count) override; virtual std::shared_ptr removeItemNoUpdate(int slot) override; - virtual void setItem(unsigned int slot, std::shared_ptr item) override; + virtual void setItem(unsigned int slot, + std::shared_ptr item) override; virtual unsigned int getContainerSize() override; virtual std::wstring getName() override; virtual std::wstring getCustomName() override; @@ -34,5 +35,6 @@ public: virtual bool stillValid(std::shared_ptr player) override; virtual void startOpen() override {} // TODO Auto-generated method stub virtual void stopOpen() override {} // TODO Auto-generated method stub - virtual bool canPlaceItem(int slot, std::shared_ptr item) override; + virtual bool canPlaceItem(int slot, + std::shared_ptr item) override; }; \ No newline at end of file From 678a186c46b5a3bb9e23806c79e8b5e595e44348 Mon Sep 17 00:00:00 2001 From: Sally Knight Date: Fri, 27 Mar 2026 21:28:41 +0300 Subject: [PATCH 072/170] fix(jui): put button render method behind ifdef Fixes build error if using iggy instead of jui --- Minecraft.Client/UI/Button.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Minecraft.Client/UI/Button.cpp b/Minecraft.Client/UI/Button.cpp index 4dd859f20..ced455e3b 100644 --- a/Minecraft.Client/UI/Button.cpp +++ b/Minecraft.Client/UI/Button.cpp @@ -38,6 +38,7 @@ int Button::getYImage(bool hovered) { } void Button::render(Minecraft* minecraft, int xm, int ym) { +#ifdef ENABLE_JAVA_GUIS if (!visible) return; Font* font = minecraft->font; @@ -64,6 +65,7 @@ void Button::render(Minecraft* minecraft, int xm, int ym) { drawCenteredString(font, msg, x + w / 2, y + (h - 8) / 2, 0xe0e0e0); } } +#endif } void Button::renderBg(Minecraft* minecraft, int xm, int ym) {} From 141678ed9673187252e016d82df223dc1d9bf1a5 Mon Sep 17 00:00:00 2001 From: Sally Knight Date: Fri, 27 Mar 2026 21:39:57 +0300 Subject: [PATCH 073/170] fix(jui): add Slot.h include Fixes clang builds --- Minecraft.Client/UI/Screens/EnchantmentScreen.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/Minecraft.Client/UI/Screens/EnchantmentScreen.cpp b/Minecraft.Client/UI/Screens/EnchantmentScreen.cpp index 5b66569cc..23685b1cc 100644 --- a/Minecraft.Client/UI/Screens/EnchantmentScreen.cpp +++ b/Minecraft.Client/UI/Screens/EnchantmentScreen.cpp @@ -9,6 +9,7 @@ #include "../../Textures/Textures.h" #include "../../../Minecraft.World/Headers/net.minecraft.locale.h" #include "../../../Minecraft.World/Containers/EnchantmentMenu.h" +#include "../../../Minecraft.World/Containers/Slot.h" #include "../../Rendering/Models/BookModel.h" #include "../../../Minecraft.Client/Minecraft.h" From ed83397c55db24bc58d6160b72537c2b50e5c0ed Mon Sep 17 00:00:00 2001 From: Sally Knight Date: Fri, 27 Mar 2026 22:57:39 +0300 Subject: [PATCH 074/170] chore(jui): remove inaccurate "unused" comments --- Minecraft.Client/UI/Screen.cpp | 1 - Minecraft.Client/UI/Screens/AbstractContainerScreen.cpp | 1 - Minecraft.Client/UI/Screens/AchievementPopup.cpp | 1 - Minecraft.Client/UI/Screens/AchievementScreen.cpp | 1 - Minecraft.Client/UI/Screens/ContainerScreen.cpp | 1 - Minecraft.Client/UI/Screens/CraftingScreen.cpp | 1 - Minecraft.Client/UI/Screens/EnchantmentScreen.cpp | 1 - Minecraft.Client/UI/Screens/FurnaceScreen.cpp | 1 - Minecraft.Client/UI/Screens/HopperScreen.cpp | 1 - Minecraft.Client/UI/Screens/HorseInventoryScreen.cpp | 1 - Minecraft.Client/UI/Screens/InventoryScreen.cpp | 1 - Minecraft.Client/UI/Screens/TitleScreen.cpp | 1 - Minecraft.Client/UI/Screens/TrapScreen.cpp | 1 - 13 files changed, 13 deletions(-) diff --git a/Minecraft.Client/UI/Screen.cpp b/Minecraft.Client/UI/Screen.cpp index c3260a893..d0d0a744c 100644 --- a/Minecraft.Client/UI/Screen.cpp +++ b/Minecraft.Client/UI/Screen.cpp @@ -174,7 +174,6 @@ void Screen::renderBackground(int vo) { } void Screen::renderDirtBackground(int vo) { - // 4J Unused - Iggy Flash UI renders the background on consoles #ifdef ENABLE_JAVA_GUIS glDisable(GL_LIGHTING); glDisable(GL_FOG); diff --git a/Minecraft.Client/UI/Screens/AbstractContainerScreen.cpp b/Minecraft.Client/UI/Screens/AbstractContainerScreen.cpp index bf608e7ee..a1723776e 100644 --- a/Minecraft.Client/UI/Screens/AbstractContainerScreen.cpp +++ b/Minecraft.Client/UI/Screens/AbstractContainerScreen.cpp @@ -240,7 +240,6 @@ void AbstractContainerScreen::render(int xm, int ym, float a) { void AbstractContainerScreen::renderLabels() {} void AbstractContainerScreen::renderSlot(Slot* slot) { - // 4J Unused #if ENABLE_JAVA_GUIS int x = slot->x; int y = slot->y; diff --git a/Minecraft.Client/UI/Screens/AchievementPopup.cpp b/Minecraft.Client/UI/Screens/AchievementPopup.cpp index f518da342..512533c81 100644 --- a/Minecraft.Client/UI/Screens/AchievementPopup.cpp +++ b/Minecraft.Client/UI/Screens/AchievementPopup.cpp @@ -66,7 +66,6 @@ void AchievementPopup::prepareWindow() { } void AchievementPopup::render() { -// 4J Unused #if ENABLE_JAVA_GUIS if (Minecraft::warezTime > 0) { glDisable(GL_DEPTH_TEST); diff --git a/Minecraft.Client/UI/Screens/AchievementScreen.cpp b/Minecraft.Client/UI/Screens/AchievementScreen.cpp index 1ef4a92bc..48ea264b4 100644 --- a/Minecraft.Client/UI/Screens/AchievementScreen.cpp +++ b/Minecraft.Client/UI/Screens/AchievementScreen.cpp @@ -136,7 +136,6 @@ void AchievementScreen::renderLabels() { } void AchievementScreen::renderBg(int xm, int ym, float a) { - // 4J Unused #if 0 int xScroll = Mth::floor(xScrollO + (xScrollP - xScrollO) * a); int yScroll = Mth::floor(yScrollO + (yScrollP - yScrollO) * a); diff --git a/Minecraft.Client/UI/Screens/ContainerScreen.cpp b/Minecraft.Client/UI/Screens/ContainerScreen.cpp index 4f34f524e..ad2513207 100644 --- a/Minecraft.Client/UI/Screens/ContainerScreen.cpp +++ b/Minecraft.Client/UI/Screens/ContainerScreen.cpp @@ -25,7 +25,6 @@ void ContainerScreen::renderLabels() { } void ContainerScreen::renderBg(float a) { - // 4J Unused #ifdef ENABLE_JAVA_GUIS int tex = minecraft->textures->loadTexture(TN_GUI_CONTAINER); glColor4f(1, 1, 1, 1); diff --git a/Minecraft.Client/UI/Screens/CraftingScreen.cpp b/Minecraft.Client/UI/Screens/CraftingScreen.cpp index 14b9aaae5..666c66878 100644 --- a/Minecraft.Client/UI/Screens/CraftingScreen.cpp +++ b/Minecraft.Client/UI/Screens/CraftingScreen.cpp @@ -27,7 +27,6 @@ void CraftingScreen::renderLabels() { } void CraftingScreen::renderBg(float a) { - // 4J Unused #ifdef ENABLE_JAVA_GUIS glColor4f(1, 1, 1, 1); minecraft->textures->bindTexture(&GUI_CRAFTING_LOCATION); diff --git a/Minecraft.Client/UI/Screens/EnchantmentScreen.cpp b/Minecraft.Client/UI/Screens/EnchantmentScreen.cpp index 23685b1cc..24d239382 100644 --- a/Minecraft.Client/UI/Screens/EnchantmentScreen.cpp +++ b/Minecraft.Client/UI/Screens/EnchantmentScreen.cpp @@ -125,7 +125,6 @@ void EnchantmentScreen::render(int xm, int ym, float a) { } void EnchantmentScreen::renderBg(float a) { - // 4J unused #ifdef ENABLE_JAVA_GUIS glColor4f(1.0f, 1.0f, 1.0f, 1.0f); Minecraft::GetInstance()->textures->bindTexture(&GUI_ENCHANT_LOCATION); diff --git a/Minecraft.Client/UI/Screens/FurnaceScreen.cpp b/Minecraft.Client/UI/Screens/FurnaceScreen.cpp index 04d0ca346..170aedb61 100644 --- a/Minecraft.Client/UI/Screens/FurnaceScreen.cpp +++ b/Minecraft.Client/UI/Screens/FurnaceScreen.cpp @@ -23,7 +23,6 @@ void FurnaceScreen::renderLabels() { } void FurnaceScreen::renderBg(float a) { - // 4J Unused #ifdef ENABLE_JAVA_GUIS glColor4f(1, 1, 1, 1); minecraft->textures->bindTexture(&GUI_FURNACE_LOCATION); diff --git a/Minecraft.Client/UI/Screens/HopperScreen.cpp b/Minecraft.Client/UI/Screens/HopperScreen.cpp index 2bab4945e..df3b3af9a 100644 --- a/Minecraft.Client/UI/Screens/HopperScreen.cpp +++ b/Minecraft.Client/UI/Screens/HopperScreen.cpp @@ -26,7 +26,6 @@ void HopperScreen::renderLabels() { } void HopperScreen::renderBg(float a) { - // 4J Unused #ifdef ENABLE_JAVA_GUIS glColor4f(1, 1, 1, 1); minecraft->textures->bindTexture(&GUI_HOPPER_LOCATION); diff --git a/Minecraft.Client/UI/Screens/HorseInventoryScreen.cpp b/Minecraft.Client/UI/Screens/HorseInventoryScreen.cpp index 1ce2e2fe1..f6de569c9 100644 --- a/Minecraft.Client/UI/Screens/HorseInventoryScreen.cpp +++ b/Minecraft.Client/UI/Screens/HorseInventoryScreen.cpp @@ -40,7 +40,6 @@ void HorseInventoryScreen::render(int xm, int ym, float a) { } void HorseInventoryScreen::renderBg(float a) { - // 4J Unused #ifdef ENABLE_JAVA_GUIS glColor4f(1, 1, 1, 1); minecraft->textures->bindTexture(&GUI_HORSE_LOCATION); diff --git a/Minecraft.Client/UI/Screens/InventoryScreen.cpp b/Minecraft.Client/UI/Screens/InventoryScreen.cpp index 67348db84..f4dccf4f6 100644 --- a/Minecraft.Client/UI/Screens/InventoryScreen.cpp +++ b/Minecraft.Client/UI/Screens/InventoryScreen.cpp @@ -32,7 +32,6 @@ void InventoryScreen::render(int xm, int ym, float a) { } void InventoryScreen::renderBg(float a) { - // 4J Unused #ifdef ENABLE_JAVA_GUIS int tex = minecraft->textures->loadTexture(TN_GUI_INVENTORY); glColor4f(1, 1, 1, 1); diff --git a/Minecraft.Client/UI/Screens/TitleScreen.cpp b/Minecraft.Client/UI/Screens/TitleScreen.cpp index 0f8212cb1..50b527600 100644 --- a/Minecraft.Client/UI/Screens/TitleScreen.cpp +++ b/Minecraft.Client/UI/Screens/TitleScreen.cpp @@ -365,7 +365,6 @@ void TitleScreen::rotateAndBlur(float a) { } void TitleScreen::render(int xm, int ym, float a) { - // 4J Unused - Iggy Flash UI renders the title screen on consoles #ifdef ENABLE_JAVA_GUIS // 4jcraft: panorama renderSkybox(a); diff --git a/Minecraft.Client/UI/Screens/TrapScreen.cpp b/Minecraft.Client/UI/Screens/TrapScreen.cpp index 7a1afb6bd..7936ec174 100644 --- a/Minecraft.Client/UI/Screens/TrapScreen.cpp +++ b/Minecraft.Client/UI/Screens/TrapScreen.cpp @@ -23,7 +23,6 @@ void TrapScreen::renderLabels() { } void TrapScreen::renderBg(float a) { - // 4J Unused #ifdef ENABLE_JAVA_GUIS glColor4f(1, 1, 1, 1); minecraft->textures->bindTexture(&GUI_TRAP_LOCATION); From 3dcc985cd4086c068639e2442bebc231f7336f59 Mon Sep 17 00:00:00 2001 From: Sally Knight Date: Fri, 27 Mar 2026 23:14:30 +0300 Subject: [PATCH 075/170] feat(jui): add brewing stand screen (+ fix enchantment screen not being used) --- .../Common/res/1_2_2/gui/brewing_stand.png | Bin 0 -> 1650 bytes Minecraft.Client/Player/LocalPlayer.cpp | 14 ++- Minecraft.Client/Textures/Textures.cpp | 1 + Minecraft.Client/Textures/Textures.h | 1 + .../UI/Screens/BrewingStandScreen.cpp | 99 ++++++++++++++++++ .../UI/Screens/BrewingStandScreen.h | 23 ++++ 6 files changed, 136 insertions(+), 2 deletions(-) create mode 100644 Minecraft.Assets/Common/res/1_2_2/gui/brewing_stand.png create mode 100644 Minecraft.Client/UI/Screens/BrewingStandScreen.cpp create mode 100644 Minecraft.Client/UI/Screens/BrewingStandScreen.h diff --git a/Minecraft.Assets/Common/res/1_2_2/gui/brewing_stand.png b/Minecraft.Assets/Common/res/1_2_2/gui/brewing_stand.png new file mode 100644 index 0000000000000000000000000000000000000000..e7dc2031ac1614c34be70770119ce2ccb1eb0918 GIT binary patch literal 1650 zcmcIkX;70_6n*(fFvw~|4NGD`bcigXphbuh0w@#k{6#xW$MF6xs9DJfng5e+^E%lR!a!P|VJgd}(EoPUP*pxQ77CNU37CHCNn;eff8W?4O5@P2guNl7L zBHqrWV1*O(5S`k7#^6iKxLRyop(R42eRHlzVxev~-c93Tm}jM8C-NK$yn(yH$WXKFiU>!%jFfNTFC$Yg&|?sEQqBoWc;b~4vMHuGbJr&IDyZlojV zK8z$ci`FXfWK-;G{E$()V3JP;nI!FxO;_GuFxOVO%VJeeP~P$lje6yf#R?)+h0qh^0UYxqMLKHn=iZM5Yx#)<^EqT zdTyG$u(}ya-;S83uy;3-coJ=z=68_7b|eT;Ffnyoft>wG=>XfYqmlb6Y6rkn4TbjL z-#zhK(X>J{Zt`^Thwx~I0WPP#nxEHsUw8!kUgT#U_S+VIpH0HY1zed(E3EQhxEi3V zznr1TBs^mqvsVIn-2``!fhWgmCu^+%$^Nb5`Fzbp;{hGuSDTl8=XOovt@)5iU#V%0 z4@*l>t0T>ip5gO(-E`_O+;ba!_F7C=tJ#3C4MTXYapYPE{5w1P3_I>xS?707@Oam= zwGdojr>W?6O$A}{g&21-raS811`}Z^-D|J1M~RI;>tY+MRaWPB$2#n7oI5*8W9T*g;`ObaqZdUxNngB${XSmVI$P*$R@XGteBIs zaY>n`(x^}9xgrg6yxix&b}iwsC5+DfTjW1=BN=Y6diyJXrPB&BETJas(58;B`og2D z6wY`B2r~lqa%-k4Bjl8zI)M_;2(3@6x_WSuiu2b{%ATFc$R~`RC;A z!=*fvQ3^VvH7M$}c)`h7&qB_-+|%Inug`md_K{iS?E=g$DRmq8zgF;=RdAsQx%KHK Qv-K7Zc22gHlz`+v074gx(*OVf literal 0 HcmV?d00001 diff --git a/Minecraft.Client/Player/LocalPlayer.cpp b/Minecraft.Client/Player/LocalPlayer.cpp index c9cd930df..a74161798 100644 --- a/Minecraft.Client/Player/LocalPlayer.cpp +++ b/Minecraft.Client/Player/LocalPlayer.cpp @@ -1,5 +1,7 @@ #include "../Platform/stdafx.h" #include "LocalPlayer.h" +#include "UI/Screens/BrewingStandScreen.h" +#include "UI/Screens/EnchantmentScreen.h" #include "UI/Screens/HopperScreen.h" #include "UI/Screens/HorseInventoryScreen.h" #include "UI/Screens/RepairScreen.h" @@ -645,10 +647,14 @@ bool LocalPlayer::openFireworks(int x, int y, int z) { bool LocalPlayer::startEnchanting(int x, int y, int z, const std::wstring& name) { +#ifdef ENABLE_JAVA_GUIS + minecraft->setScreen(new EnchantmentScreen(inventory, level, x, y, z)); + bool success = true; +#else bool success = app.LoadEnchantingMenu(GetXboxPad(), inventory, x, y, z, level, name); if (success) ui.PlayUISFX(eSFX_Press); - // minecraft.setScreen(new EnchantmentScreen(inventory, level, x, y, z)); +#endif return success; } @@ -677,10 +683,14 @@ bool LocalPlayer::openFurnace(std::shared_ptr furnace) { bool LocalPlayer::openBrewingStand( std::shared_ptr brewingStand) { +#ifdef ENABLE_JAVA_GUIS + minecraft->setScreen(new BrewingStandScreen(inventory, brewingStand)); + bool success = true; +#else bool success = app.LoadBrewingStandMenu(GetXboxPad(), inventory, brewingStand); if (success) ui.PlayUISFX(eSFX_Press); - // minecraft.setScreen(new BrewingStandScreen(inventory, brewingStand)); +#endif return success; } diff --git a/Minecraft.Client/Textures/Textures.cpp b/Minecraft.Client/Textures/Textures.cpp index 20b952c59..deef91211 100644 --- a/Minecraft.Client/Textures/Textures.cpp +++ b/Minecraft.Client/Textures/Textures.cpp @@ -182,6 +182,7 @@ const wchar_t* Textures::preLoaded[TN_COUNT] = { L"gui/trap", L"gui/hopper", L"gui/enchant", + L"gui/brewing_stand", L"title/bg/panorama", L"title/bg/panorama0", L"title/bg/panorama1", diff --git a/Minecraft.Client/Textures/Textures.h b/Minecraft.Client/Textures/Textures.h index 2a6ad074a..b073a77de 100644 --- a/Minecraft.Client/Textures/Textures.h +++ b/Minecraft.Client/Textures/Textures.h @@ -164,6 +164,7 @@ typedef enum _TEXTURE_NAME { TN_GUI_TRAP, TN_GUI_HOPPER, TN_GUI_ENCHANT, + TN_GUI_BREWING_STAND, TN_TITLE_BG_PANORAMA, TN_TITLE_BG_PANORAMA0, TN_TITLE_BG_PANORAMA1, diff --git a/Minecraft.Client/UI/Screens/BrewingStandScreen.cpp b/Minecraft.Client/UI/Screens/BrewingStandScreen.cpp new file mode 100644 index 000000000..1d1239c2a --- /dev/null +++ b/Minecraft.Client/UI/Screens/BrewingStandScreen.cpp @@ -0,0 +1,99 @@ +#include "../../Platform/stdafx.h" +#include "BrewingStandScreen.h" +#include +#include +#include +#include "../../Player/MultiPlayerLocalPlayer.h" +#include "../../Rendering/Lighting.h" +#include "../../Textures/Textures.h" +#include "../../../Minecraft.World/Headers/net.minecraft.locale.h" +#include "../../../Minecraft.World/Containers/BrewingStandMenu.h" +#include "../../../Minecraft.World/Containers/Slot.h" +#include "../../../Minecraft.Client/Minecraft.h" + +// 4jcraft: referenced from MCP 8.11 (JE 1.6.4) and the existing +// container classes +#ifdef ENABLE_JAVA_GUIS +ResourceLocation GUI_BREWING_STAND_LOCATION = + ResourceLocation(TN_GUI_BREWING_STAND); +#endif + +BrewingStandScreen::BrewingStandScreen( + std::shared_ptr inventory, + std::shared_ptr brewingStand) + : AbstractContainerScreen(new BrewingStandMenu(inventory, brewingStand)) { + this->inventory = inventory; + this->brewingStand = brewingStand; + this->brewMenu = static_cast(menu); +} + +BrewingStandScreen::~BrewingStandScreen() = default; + +void BrewingStandScreen::init() { AbstractContainerScreen::init(); } + +void BrewingStandScreen::removed() { AbstractContainerScreen::removed(); } + +void BrewingStandScreen::renderLabels() { + font->draw(brewingStand->getName(), + (imageWidth / 2) - (font->width(brewingStand->getName()) / 2), 6, + 0x404040); + font->draw(inventory->getName(), 8, imageHeight - 96 + 2, 0x404040); +} + +void BrewingStandScreen::renderBg(float a) { +#ifdef ENABLE_JAVA_GUIS + glColor4f(1.0f, 1.0f, 1.0f, 1.0f); + Minecraft::GetInstance()->textures->bindTexture( + &GUI_BREWING_STAND_LOCATION); + int xo = (width - imageWidth) / 2; + int yo = (height - imageHeight) / 2; + blit(xo, yo, 0, 0, imageWidth, imageHeight); + + int brewTime = brewingStand->getBrewTime(); + + if (brewTime > 0) { + int arrowHeight = (int)(28.0f * (1.0f - (float)brewTime / 400.0f)); + + if (arrowHeight > 0) { + blit(xo + 97, yo + 16 + (28 - arrowHeight), 176, 28 - arrowHeight, + 9, arrowHeight); + } + + int bubbleStep = (brewTime / 2) % 7; + int bubbleHeight = 0; + + switch (bubbleStep) { + case 0: + bubbleHeight = 29; + break; + case 1: + bubbleHeight = 24; + break; + case 2: + bubbleHeight = 20; + break; + case 3: + bubbleHeight = 16; + break; + case 4: + bubbleHeight = 11; + break; + case 5: + bubbleHeight = 6; + break; + case 6: + bubbleHeight = 0; + break; + } + + if (bubbleHeight > 0) { + blit(xo + 65, yo + 14 + (29 - bubbleHeight), 185, 29 - bubbleHeight, + 12, bubbleHeight); + } + } +#endif +} + +void BrewingStandScreen::render(int xm, int ym, float a) { + AbstractContainerScreen::render(xm, ym, a); +} \ No newline at end of file diff --git a/Minecraft.Client/UI/Screens/BrewingStandScreen.h b/Minecraft.Client/UI/Screens/BrewingStandScreen.h new file mode 100644 index 000000000..12f834ed7 --- /dev/null +++ b/Minecraft.Client/UI/Screens/BrewingStandScreen.h @@ -0,0 +1,23 @@ +#pragma once + +#include "AbstractContainerScreen.h" +#include "../../../Minecraft.World/Containers/BrewingStandMenu.h" +#include "../../../Minecraft.World/Headers/net.minecraft.world.level.tile.entity.h" + +class BrewingStandScreen : public AbstractContainerScreen { +public: + BrewingStandScreen(std::shared_ptr inventory, + std::shared_ptr brewingStand); + virtual ~BrewingStandScreen(); + + void init() override; + void removed() override; + void renderLabels() override; + void renderBg(float a) override; + void render(int xm, int ym, float a) override; + +private: + std::shared_ptr inventory; + std::shared_ptr brewingStand; + BrewingStandMenu* brewMenu; +}; \ No newline at end of file From affe60603c1169a8be8af867b0c467c48ae58e11 Mon Sep 17 00:00:00 2001 From: Sally Knight Date: Sat, 28 Mar 2026 22:07:17 +0300 Subject: [PATCH 076/170] make AbstractContainerScreen's itemRenderer protected --- Minecraft.Client/UI/Screens/AbstractContainerScreen.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Minecraft.Client/UI/Screens/AbstractContainerScreen.h b/Minecraft.Client/UI/Screens/AbstractContainerScreen.h index eb7ddc0dd..74f14cc5d 100644 --- a/Minecraft.Client/UI/Screens/AbstractContainerScreen.h +++ b/Minecraft.Client/UI/Screens/AbstractContainerScreen.h @@ -6,7 +6,8 @@ class Slot; class Container; class AbstractContainerScreen : public Screen { -private: +protected: + // 4jcraft: made protected to match JE 1.6.4 static ItemRenderer* itemRenderer; protected: From 80966a501c06575ead1324d4f3465531f74fbce8 Mon Sep 17 00:00:00 2001 From: Sally Knight Date: Sun, 29 Mar 2026 04:05:31 +0300 Subject: [PATCH 077/170] refactor(jui): extract tooltip rendering into standalone method so we can use tooltips elsewhere (the upcoming merchantscreen more specifically) --- .../UI/Screens/AbstractContainerScreen.cpp | 268 +++++++++--------- .../UI/Screens/AbstractContainerScreen.h | 4 + 2 files changed, 141 insertions(+), 131 deletions(-) diff --git a/Minecraft.Client/UI/Screens/AbstractContainerScreen.cpp b/Minecraft.Client/UI/Screens/AbstractContainerScreen.cpp index a1723776e..b437694a4 100644 --- a/Minecraft.Client/UI/Screens/AbstractContainerScreen.cpp +++ b/Minecraft.Client/UI/Screens/AbstractContainerScreen.cpp @@ -95,138 +95,11 @@ void AbstractContainerScreen::render(int xm, int ym, float a) { hoveredSlot->hasItem()) { std::shared_ptr item = hoveredSlot->getItem(); - // std::wstring elementName = - // trimString(Language::getInstance()->getElementName(hoveredSlot->getItem()->getDescriptionId())); - std::vector elementName; - std::vector* tooltipLines = - item->getHoverText(minecraft->player, false, elementName); + int xo = (width - imageWidth) / 2; + int yo = (height - imageHeight) / 2; - if (tooltipLines != NULL && tooltipLines->size() > 0) { - int tooltipWidth = 0; - std::vector cleanedLines; - std::vector lineColors; - - for (int lineIndex = 0; lineIndex < (int)tooltipLines->size(); - ++lineIndex) { - std::wstring rawLine = (*tooltipLines)[lineIndex]; - std::wstring clean = L""; - int lineColor = 0xffffffff; - - // 4jcraft: LCE is using HTML font elements for its tooltip - // colors, so make sure to parse them for parity w iggy UI - // - // examples would be enchantment books, potions and music - // discs - size_t fontPos = rawLine.find(L"') { - inTag = false; - } else if (!inTag) { - clean += currentChar; - } - } - - cleanedLines.push_back(clean); - lineColors.push_back(lineColor); - - int lineWidth = font->width(clean); - if (lineWidth > tooltipWidth) { - tooltipWidth = lineWidth; - } - } - - int tooltipX = xm - xo + 12; - int tooltipY = ym - yo - 12; - - int tooltipHeight = 8; - - if (tooltipLines->size() > 1) { - tooltipHeight += 2 + (tooltipLines->size() - 1) * 10; - } - - int bgColor = 0xf0100010; - fillGradient(tooltipX - 3, tooltipY - 4, - tooltipX + tooltipWidth + 3, tooltipY - 3, bgColor, - bgColor); - fillGradient(tooltipX - 3, tooltipY + tooltipHeight + 3, - tooltipX + tooltipWidth + 3, - tooltipY + tooltipHeight + 4, bgColor, bgColor); - fillGradient(tooltipX - 3, tooltipY - 3, - tooltipX + tooltipWidth + 3, - tooltipY + tooltipHeight + 3, bgColor, bgColor); - fillGradient(tooltipX - 4, tooltipY - 3, tooltipX - 3, - tooltipY + tooltipHeight + 3, bgColor, bgColor); - fillGradient(tooltipX + tooltipWidth + 3, tooltipY - 3, - tooltipX + tooltipWidth + 4, - tooltipY + tooltipHeight + 3, bgColor, bgColor); - - int borderStart = 0x505000ff; - int borderFinish = - (borderStart & 0xfefefe) >> 1 | borderStart & 0xff000000; - fillGradient(tooltipX - 3, (tooltipY - 3) + 1, (tooltipX - 3) + 1, - (tooltipY + tooltipHeight + 3) - 1, borderStart, - borderFinish); - fillGradient(tooltipX + tooltipWidth + 2, (tooltipY - 3) + 1, - tooltipX + tooltipWidth + 3, - (tooltipY + tooltipHeight + 3) - 1, borderStart, - borderFinish); - fillGradient(tooltipX - 3, tooltipY - 3, - tooltipX + tooltipWidth + 3, (tooltipY - 3) + 1, - borderStart, borderStart); - fillGradient(tooltipX - 3, tooltipY + tooltipHeight + 2, - tooltipX + tooltipWidth + 3, - tooltipY + tooltipHeight + 3, borderFinish, - borderFinish); - - int currentY = tooltipY; - for (int lineIndex = 0; lineIndex < (int)tooltipLines->size(); - ++lineIndex) { - std::wstring& currentLine = cleanedLines[lineIndex]; - int textColor; - - if (lineIndex == 0) { - textColor = app.GetHTMLColour(item->getRarity()->color); - } else { - textColor = (lineColors[lineIndex] != 0xffffffff) - ? lineColors[lineIndex] - : 0xffaaaaaa; - } - - font->drawShadow(currentLine, tooltipX, currentY, textColor); - - if (lineIndex == 0) { - currentY += 2; - } - - currentY += 10; - } - } + // 4jcraft: abstracted tooltip rendering into a new method + renderTooltip(item, xm - xo, ym - yo); } glPopMatrix(); @@ -237,6 +110,139 @@ void AbstractContainerScreen::render(int xm, int ym, float a) { #endif } +// 4jcraft: extracted from render() into a standalone method so this can be used +// in other derived classes +void AbstractContainerScreen::renderTooltip(std::shared_ptr item, + int x, int y) { + if (item == nullptr) return; + + std::vector elementName; + std::vector* tooltipLines = + item->getHoverText(minecraft->player, false, elementName); + + if (tooltipLines != NULL && tooltipLines->size() > 0) { + int tooltipWidth = 0; + std::vector cleanedLines; + std::vector lineColors; + + for (int lineIndex = 0; lineIndex < (int)tooltipLines->size(); + ++lineIndex) { + std::wstring rawLine = (*tooltipLines)[lineIndex]; + std::wstring clean = L""; + int lineColor = 0xffffffff; + + // 4jcraft: LCE is using HTML font elements for its tooltip + // colors, so make sure to parse them for parity w iggy UI + // + // examples would be enchantment books, potions and music + // discs + size_t fontPos = rawLine.find(L"') { + inTag = false; + } else if (!inTag) { + clean += currentChar; + } + } + + cleanedLines.push_back(clean); + lineColors.push_back(lineColor); + + int lineWidth = font->width(clean); + if (lineWidth > tooltipWidth) { + tooltipWidth = lineWidth; + } + } + + int tooltipX = x + 12; + int tooltipY = y - 12; + int tooltipHeight = 8; + + if (tooltipLines->size() > 1) { + tooltipHeight += 2 + (tooltipLines->size() - 1) * 10; + } + + int bgColor = 0xf0100010; + fillGradient(tooltipX - 3, tooltipY - 4, tooltipX + tooltipWidth + 3, + tooltipY - 3, bgColor, bgColor); + fillGradient(tooltipX - 3, tooltipY + tooltipHeight + 3, + tooltipX + tooltipWidth + 3, tooltipY + tooltipHeight + 4, + bgColor, bgColor); + fillGradient(tooltipX - 3, tooltipY - 3, tooltipX + tooltipWidth + 3, + tooltipY + tooltipHeight + 3, bgColor, bgColor); + fillGradient(tooltipX - 4, tooltipY - 3, tooltipX - 3, + tooltipY + tooltipHeight + 3, bgColor, bgColor); + fillGradient(tooltipX + tooltipWidth + 3, tooltipY - 3, + tooltipX + tooltipWidth + 4, tooltipY + tooltipHeight + 3, + bgColor, bgColor); + + int borderStart = 0x505000ff; + int borderFinish = + (borderStart & 0xfefefe) >> 1 | borderStart & 0xff000000; + fillGradient(tooltipX - 3, (tooltipY - 3) + 1, (tooltipX - 3) + 1, + (tooltipY + tooltipHeight + 3) - 1, borderStart, + borderFinish); + fillGradient(tooltipX + tooltipWidth + 2, (tooltipY - 3) + 1, + tooltipX + tooltipWidth + 3, + (tooltipY + tooltipHeight + 3) - 1, borderStart, + borderFinish); + fillGradient(tooltipX - 3, tooltipY - 3, tooltipX + tooltipWidth + 3, + (tooltipY - 3) + 1, borderStart, borderStart); + fillGradient(tooltipX - 3, tooltipY + tooltipHeight + 2, + tooltipX + tooltipWidth + 3, tooltipY + tooltipHeight + 3, + borderFinish, borderFinish); + + int currentY = tooltipY; + for (int lineIndex = 0; lineIndex < (int)tooltipLines->size(); + ++lineIndex) { + std::wstring& currentLine = cleanedLines[lineIndex]; + int textColor; + + if (lineIndex == 0) { + textColor = app.GetHTMLColour(item->getRarity()->color); + } else { + textColor = (lineColors[lineIndex] != 0xffffffff) + ? lineColors[lineIndex] + : 0xffaaaaaa; + } + + font->drawShadow(currentLine, tooltipX, currentY, textColor); + + if (lineIndex == 0) { + currentY += 2; + } + + currentY += 10; + } + } +} + void AbstractContainerScreen::renderLabels() {} void AbstractContainerScreen::renderSlot(Slot* slot) { diff --git a/Minecraft.Client/UI/Screens/AbstractContainerScreen.h b/Minecraft.Client/UI/Screens/AbstractContainerScreen.h index 74f14cc5d..af1654fbf 100644 --- a/Minecraft.Client/UI/Screens/AbstractContainerScreen.h +++ b/Minecraft.Client/UI/Screens/AbstractContainerScreen.h @@ -29,6 +29,10 @@ protected: // handling. virtual Slot* findSlot(int x, int y); virtual bool isHovering(Slot* slot, int xm, int ym); + // 4jcraft: extracted from render() into a standalone method so this can be + // used in other classes + virtual void renderTooltip(std::shared_ptr item, int x, + int y); private: virtual void renderSlot(Slot* slot); From 32149b7ec3d7b94797867e69705278f63d025909 Mon Sep 17 00:00:00 2001 From: Sally Knight Date: Sun, 29 Mar 2026 04:55:54 +0300 Subject: [PATCH 078/170] refactor(jui): backport hovering over helper from 1.6.x --- .../UI/Screens/AbstractContainerScreen.cpp | 12 +++++++++--- .../UI/Screens/AbstractContainerScreen.h | 3 +++ 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/Minecraft.Client/UI/Screens/AbstractContainerScreen.cpp b/Minecraft.Client/UI/Screens/AbstractContainerScreen.cpp index b437694a4..53a81d19d 100644 --- a/Minecraft.Client/UI/Screens/AbstractContainerScreen.cpp +++ b/Minecraft.Client/UI/Screens/AbstractContainerScreen.cpp @@ -283,14 +283,20 @@ Slot* AbstractContainerScreen::findSlot(int x, int y) { return NULL; } -bool AbstractContainerScreen::isHovering(Slot* slot, int xm, int ym) { +// 4jcraft: equivalent to MCP 8.11 (1.6.x)'s GuiContainer.isPointInRegion() for +// use in other derived classes +bool AbstractContainerScreen::isHoveringOver(int x, int y, int w, int h, int xm, + int ym) { int xo = (width - imageWidth) / 2; int yo = (height - imageHeight) / 2; xm -= xo; ym -= yo; - return xm >= slot->x - 1 && xm < slot->x + 16 + 1 && ym >= slot->y - 1 && - ym < slot->y + 16 + 1; + return xm >= x - 1 && xm < x + w + 1 && ym >= y - 1 && ym < y + h + 1; +} + +bool AbstractContainerScreen::isHovering(Slot* slot, int xm, int ym) { + return isHoveringOver(slot->x, slot->y, 16, 16, xm, ym); } void AbstractContainerScreen::mouseClicked(int x, int y, int buttonNum) { diff --git a/Minecraft.Client/UI/Screens/AbstractContainerScreen.h b/Minecraft.Client/UI/Screens/AbstractContainerScreen.h index af1654fbf..dcd2f4214 100644 --- a/Minecraft.Client/UI/Screens/AbstractContainerScreen.h +++ b/Minecraft.Client/UI/Screens/AbstractContainerScreen.h @@ -28,6 +28,9 @@ protected: // can call findSlot() and isHovering() directly for its custom click // handling. virtual Slot* findSlot(int x, int y); + // 4jcraft: equivalent to MCP 8.11 (1.6.x)'s GuiContainer.isPointInRegion() + // for use in other derived classes + virtual bool isHoveringOver(int x, int y, int w, int h, int xm, int ym); virtual bool isHovering(Slot* slot, int xm, int ym); // 4jcraft: extracted from render() into a standalone method so this can be // used in other classes From 97c6704d82cdb61e512fbcbf1534ab3425cc1c2e Mon Sep 17 00:00:00 2001 From: Sally Knight Date: Sun, 29 Mar 2026 05:15:30 +0300 Subject: [PATCH 079/170] feat(jui): add merchant screen --- .../Common/res/1_2_2/gui/villager.png | Bin 0 -> 3130 bytes Minecraft.Client/Network/ClientConnection.cpp | 14 +- Minecraft.Client/Player/LocalPlayer.cpp | 7 +- Minecraft.Client/Textures/Textures.cpp | 1 + Minecraft.Client/Textures/Textures.h | 1 + .../UI/Screens/MerchantScreen.cpp | 205 ++++++++++++++++++ Minecraft.Client/UI/Screens/MerchantScreen.h | 32 +++ Minecraft.Client/UI/TradeSwitchButton.cpp | 46 ++++ Minecraft.Client/UI/TradeSwitchButton.h | 14 ++ 9 files changed, 318 insertions(+), 2 deletions(-) create mode 100644 Minecraft.Assets/Common/res/1_2_2/gui/villager.png create mode 100644 Minecraft.Client/UI/Screens/MerchantScreen.cpp create mode 100644 Minecraft.Client/UI/Screens/MerchantScreen.h create mode 100644 Minecraft.Client/UI/TradeSwitchButton.cpp create mode 100644 Minecraft.Client/UI/TradeSwitchButton.h diff --git a/Minecraft.Assets/Common/res/1_2_2/gui/villager.png b/Minecraft.Assets/Common/res/1_2_2/gui/villager.png new file mode 100644 index 0000000000000000000000000000000000000000..3211a7a00b530648de14bd794a308a2a0f560156 GIT binary patch literal 3130 zcmd5;XH=8P8lHp*0YO-irXoRUHV8$@N()V-D@A${MPLEF^d=B+5d7YDFK2~r8jAY6mpY2yLJ?H+t-#2sSJI}n|Gw=JHXXeb^i&iE=0tW>E z079l0jBEgaa6Tab&dV8GgUhaS23{|76C-em``$YmIl)2r|8>DB1b}_7xg8>=WQGA? z?}(|9zFp+V@)x%hyIJXu?_)XYAA%J8AIs018{B1YE4Ksd3mJGb(E zB%?UL9W;hVstD+cK z-S><5q(r&S2GLBpo|E(Iifm^c2P*}ZUK+XBm6A1udVfuAU0bEU=f`x(VrWo|vW>pS zX#T(hZ1uor!fHD`TRw8c^Zv{moOkDj_GxA11?o+bebL2>HI9{0F}BRi%{6BeVM3Tj zuI0(F)ukiTQTc3dBA|pFlVI1acF!+RBA6oZjo!Ny)+Ban$r^YfqVk_be2p^6)KF6^ zKI1=F`J$=w+84&l9sDd4Nn2%)rd}+&PHhNZ8Y;3o@vVRrNX=kw81pBL=df2+40H4H zLiLDNxJ8nIev*M~Xx8WpmICaEdvoxNN2?}5IM~g>+}u2~G*2sn9*-S?81W}8 zObS~C!a*UwNyg#t&51@wFFm`eWFHEhS@Q4~7)NE0))Y-+wwHdJLIt}~Jm3L}um!RB zQQ7;`<%#-R3l)Tg&G~^7S!PAjn40BBSYP_>c#1TE*sFQ-Yh|5J&tOZeZ{Lb;X~mBj z`n^;=)K?k}B@KGtb;!h5s{4GrVDrVeZGoCBMw*AF<27&I5syC*5h1g#m2jRcXyVD+?WMzB{E-3e6w zP$F#}ATJ6eC0gZcmy^lHS!VLyYEn-I=866w-(fwCLx7vj+UzzcnmJk+Nacv3vK!pA zqyjx#L8Lu-pY+N(4}F+y&4)<{o_Z@3-&$byBy@4Gibz&5-PkCwe>wd~;AebH{%par zW!Fu2@qn2Yjr!EFG75jYJu?(YD%~|Q=)7jbX@ zPxNAC(cF-Z$2+&(^oMYspUEbe6Dkp|LoQHkJIdj+V62+|bBF>*t#R`>j#?xg$ClHta5&sFD#NDyq1^n^a9wR+^JMn&t^S6n z2Uc4J^*0QGpl{8fR+laFUYNf*QvC_iB{2u>>rgdGP^MjXVDN*FOv5v5O|oD0;9iDn z+d{EN_?KQ0q{FUQnz0kkK4goOH!0{|Hc%yk07|;-tMbE0ranlw-&ouXVP8_kca;O+7n0D+OJ0c!u;7U@G^a-A~k;1 z?n?NEBMkJyNC^4kP3J{P(N23Qx}RNcuB_6ei1?190K@AuEurAPxi@%1MncYXc@uCcTlqX01+Nr%TX>x83^t-A=piJlhS| z9UH#<65rt^fQ%eslj@WocI}eS;!l}Nh%3*J){L3kbo8`;(H4iG;f2GmUFkM>HLSxe zQUR8`=X@uYv@dl0A|V0Yii8&)FQO)d)ge?iI~%TX4gk!N;8k@{d0kJsY}i^*4KFMT zeg$`4(42VYN{YQL3+uN@UDTxr1W#pZLGxgb%vOvA1fEr-^MF^^lCn@js4n4|JI2{i zKI}H9-bqPVWPa#boU?%w>AXNs&HEnXfGi;O? zR`K-dQ{EZW0X;ZIp@8{i=vs+O2P7K`5CDh(;K+kM932%T3IkqmCl&sN;Q+t@fO7A0 zf-Sv^;M|t#h`PFZ`Ww_~>>DjPnTsIX1Fgkj)=*b}gGwJ*N4bu+AK->_?s91GC;2~E z{)VBLWbUkBQ7?8)?7+bkg5 zYT!W7je-4m!L0UF*NL9)?(gGJ!x4yMlWT?vPweeIZ6C|xK$o`M+`z0d_`i5~#@U%u VDd@O69>UywOpUFKstr67{{!+^XTJad literal 0 HcmV?d00001 diff --git a/Minecraft.Client/Network/ClientConnection.cpp b/Minecraft.Client/Network/ClientConnection.cpp index e41f43d77..78cc2c789 100644 --- a/Minecraft.Client/Network/ClientConnection.cpp +++ b/Minecraft.Client/Network/ClientConnection.cpp @@ -46,6 +46,7 @@ #include "../ClientConstants.h" #include "../../Minecraft.World/Util/SoundTypes.h" #include "../Textures/Packs/TexturePackRepository.h" +#include "UI/Screens/MerchantScreen.h" #ifdef _XBOX #include "../Platform/Common/XUI/XUI_Scene_Trading.h" #else @@ -3707,6 +3708,17 @@ void ClientConnection::handleCustomPayload( ByteArrayInputStream bais(customPayloadPacket->data); DataInputStream input(&bais); int containerId = input.readInt(); +#ifdef ENABLE_JAVA_GUIS + // 4jcraft: use the java gui getMerchant() to get trader as we don't + // have iggy's screen anymore + if (minecraft->screen && + dynamic_cast(minecraft->screen) && + containerId == minecraft->localplayers[m_userIndex] + ->containerMenu->containerId) { + std::shared_ptr trader = nullptr; + MerchantScreen* screen = (MerchantScreen*)minecraft->screen; + trader = screen->getMerchant(); +#else if (ui.IsSceneInStack(m_userIndex, eUIScene_TradingMenu) && containerId == minecraft->localplayers[m_userIndex] ->containerMenu->containerId) { @@ -3729,7 +3741,7 @@ void ClientConnection::handleCustomPayload( UIScene_TradingMenu* screen = (UIScene_TradingMenu*)scene; trader = screen->getMerchant(); #endif - +#endif MerchantRecipeList* recipeList = MerchantRecipeList::createFromStream(&input); trader->overrideOffers(recipeList); diff --git a/Minecraft.Client/Player/LocalPlayer.cpp b/Minecraft.Client/Player/LocalPlayer.cpp index a74161798..79003a286 100644 --- a/Minecraft.Client/Player/LocalPlayer.cpp +++ b/Minecraft.Client/Player/LocalPlayer.cpp @@ -4,6 +4,7 @@ #include "UI/Screens/EnchantmentScreen.h" #include "UI/Screens/HopperScreen.h" #include "UI/Screens/HorseInventoryScreen.h" +#include "UI/Screens/MerchantScreen.h" #include "UI/Screens/RepairScreen.h" #include "User.h" #include "../Input/Input.h" @@ -714,10 +715,14 @@ bool LocalPlayer::openTrap(std::shared_ptr trap) { bool LocalPlayer::openTrading(std::shared_ptr traderTarget, const std::wstring& name) { +#ifdef ENABLE_JAVA_GUIS + minecraft->setScreen(new MerchantScreen(inventory, traderTarget, level)); + bool success = true; +#else bool success = app.LoadTradingMenu(GetXboxPad(), inventory, traderTarget, level, name); if (success) ui.PlayUISFX(eSFX_Press); - // minecraft.setScreen(new MerchantScreen(inventory, traderTarget, level)); +#endif return success; } diff --git a/Minecraft.Client/Textures/Textures.cpp b/Minecraft.Client/Textures/Textures.cpp index deef91211..bbd96f14a 100644 --- a/Minecraft.Client/Textures/Textures.cpp +++ b/Minecraft.Client/Textures/Textures.cpp @@ -182,6 +182,7 @@ const wchar_t* Textures::preLoaded[TN_COUNT] = { L"gui/trap", L"gui/hopper", L"gui/enchant", + L"gui/villager", L"gui/brewing_stand", L"title/bg/panorama", L"title/bg/panorama0", diff --git a/Minecraft.Client/Textures/Textures.h b/Minecraft.Client/Textures/Textures.h index b073a77de..3edec4b5d 100644 --- a/Minecraft.Client/Textures/Textures.h +++ b/Minecraft.Client/Textures/Textures.h @@ -164,6 +164,7 @@ typedef enum _TEXTURE_NAME { TN_GUI_TRAP, TN_GUI_HOPPER, TN_GUI_ENCHANT, + TN_GUI_VILLAGER, TN_GUI_BREWING_STAND, TN_TITLE_BG_PANORAMA, TN_TITLE_BG_PANORAMA0, diff --git a/Minecraft.Client/UI/Screens/MerchantScreen.cpp b/Minecraft.Client/UI/Screens/MerchantScreen.cpp new file mode 100644 index 000000000..b069e89e8 --- /dev/null +++ b/Minecraft.Client/UI/Screens/MerchantScreen.cpp @@ -0,0 +1,205 @@ +#include "../../Platform/stdafx.h" +#include "MerchantScreen.h" +#include +#include +#include "../TradeSwitchButton.h" +#include "../../Player/MultiPlayerLocalPlayer.h" +#include "../../Rendering/Lighting.h" +#include "../../Textures/Textures.h" +#include "../../Rendering/EntityRenderers/ItemRenderer.h" +#include "../../../Minecraft.World/Headers/net.minecraft.locale.h" +#include "../../../Minecraft.World/Containers/MerchantMenu.h" +#include "../../../Minecraft.World/Containers/Slot.h" +#include "../../../Minecraft.World/Containers/MerchantContainer.h" +#include "../../../Minecraft.World/Headers/net.minecraft.world.item.trading.h" +#include "../../../Minecraft.Client/Minecraft.h" +#include "../../../Minecraft.Client/Network/ClientConnection.h" +#include "../../../Minecraft.World/IO/Streams/ByteArrayOutputStream.h" +#include "../../../Minecraft.World/IO/Streams/DataOutputStream.h" +#include "../../../Minecraft.World/Util/Rarity.h" + +// 4jcraft: referenced from MCP 8.11 (JE 1.6.4) and the existing +// container classes (and iggy too) +#ifdef ENABLE_JAVA_GUIS +ResourceLocation GUI_VILLAGER_LOCATION = ResourceLocation(TN_GUI_VILLAGER); +#endif + +MerchantScreen::MerchantScreen(std::shared_ptr inventory, + std::shared_ptr merchant, Level* level) + : AbstractContainerScreen(new MerchantMenu(inventory, merchant, level)) { + this->inventory = inventory; + this->merchantMenu = static_cast(menu); + this->merchant = merchant; + this->currentRecipeIndex = 0; + this->nextRecipeButton = nullptr; + this->prevRecipeButton = nullptr; +} + +MerchantScreen::~MerchantScreen() = default; + +void MerchantScreen::init() { + AbstractContainerScreen::init(); + + int xo = (width - imageWidth) / 2; + int yo = (height - imageHeight) / 2; + + nextRecipeButton = new TradeSwitchButton(1, xo + 120 + 27, yo + 24 - 1, true); + prevRecipeButton = new TradeSwitchButton(2, xo + 36 - 19, yo + 24 - 1, false); + + nextRecipeButton->active = false; + prevRecipeButton->active = false; + + buttons.push_back(nextRecipeButton); + buttons.push_back(prevRecipeButton); +} + +void MerchantScreen::removed() { AbstractContainerScreen::removed(); } + +void MerchantScreen::renderLabels() { + font->draw(merchant->getDisplayName(), + (imageWidth / 2) - (font->width(merchant->getDisplayName()) / 2), + 6, 0x404040); + + font->draw(inventory->getName(), 8, imageHeight - 96 + 2, 0x404040); +} + +void MerchantScreen::renderBg(float a) { +#ifdef ENABLE_JAVA_GUIS + glColor4f(1.0f, 1.0f, 1.0f, 1.0f); + minecraft->textures->bindTexture(&GUI_VILLAGER_LOCATION); + int xo = (width - imageWidth) / 2; + int yo = (height - imageHeight) / 2; + blit(xo, yo, 0, 0, imageWidth, imageHeight); + + MerchantRecipe* activeRecipe = + merchantMenu->getTradeContainer()->getActiveRecipe(); + if (activeRecipe != nullptr && !activeRecipe->isDeprecated()) { + blit(xo + 83, yo + 21, 212, 0, 28, 21); + blit(xo + 83, yo + 51, 212, 0, 28, 21); + } +#endif +} + +void MerchantScreen::render(int xm, int ym, float a) { + AbstractContainerScreen::render(xm, ym, a); + +#ifdef ENABLE_JAVA_GUIS + std::shared_ptr player = std::dynamic_pointer_cast( + inventory->player->shared_from_this()); + MerchantRecipeList* offers = merchant->getOffers(player); + + if (offers != nullptr && !offers->empty()) { + int xo = (width - imageWidth) / 2; + int yo = (height - imageHeight) / 2; + + MerchantRecipe* recipe = offers->at(currentRecipeIndex); + if (recipe != nullptr && !recipe->isDeprecated()) { + std::shared_ptr buyItem1 = recipe->getBuyAItem(); + std::shared_ptr buyItem2 = recipe->getBuyBItem(); + std::shared_ptr sellItem = recipe->getSellItem(); + + glPushMatrix(); + glTranslatef((float)xo, (float)yo, 0.0f); + + Lighting::turnOnGui(); + glEnable(GL_RESCALE_NORMAL); + glEnable(GL_LIGHTING); + + if (buyItem1 != nullptr) { + itemRenderer->renderGuiItem(font, minecraft->textures, buyItem1, + 36, 24); + itemRenderer->renderGuiItemDecorations( + font, minecraft->textures, buyItem1, 36, 24); + } + + if (buyItem2 != nullptr) { + itemRenderer->renderGuiItem(font, minecraft->textures, buyItem2, + 62, 24); + itemRenderer->renderGuiItemDecorations( + font, minecraft->textures, buyItem2, 62, 24); + } + + if (sellItem != nullptr) { + itemRenderer->renderGuiItem(font, minecraft->textures, sellItem, + 120, 24); + itemRenderer->renderGuiItemDecorations( + font, minecraft->textures, sellItem, 120, 24); + } + + glDisable(GL_LIGHTING); + glDisable(GL_RESCALE_NORMAL); + Lighting::turnOff(); + + glPopMatrix(); + + if (buyItem1 != nullptr && isHoveringOver(36, 24, 16, 16, xm, ym)) { + renderTooltip(buyItem1, xm, ym); + } else if (buyItem2 != nullptr && + isHoveringOver(62, 24, 16, 16, xm, ym)) { + renderTooltip(buyItem2, xm, ym); + } else if (sellItem != nullptr && + isHoveringOver(120, 24, 16, 16, xm, ym)) { + renderTooltip(sellItem, xm, ym); + } + } + } +#endif +} + +void MerchantScreen::tick() { + AbstractContainerScreen::tick(); + + std::shared_ptr player = std::dynamic_pointer_cast( + inventory->player->shared_from_this()); + + MerchantRecipeList* offers = merchant->getOffers(player); + + if (offers != nullptr) { + int offerCount = (int)offers->size(); + + nextRecipeButton->active = (currentRecipeIndex < offerCount - 1); + prevRecipeButton->active = (currentRecipeIndex > 0); + + if (currentRecipeIndex >= offerCount && offerCount > 0) { + currentRecipeIndex = offerCount - 1; + merchantMenu->setSelectionHint(currentRecipeIndex); + + // 4jcraft: taken from IUIScene_TradingMenu + ByteArrayOutputStream rawOutput; + DataOutputStream output(&rawOutput); + output.writeInt(currentRecipeIndex); + minecraft->player->connection->send( + std::shared_ptr(new CustomPayloadPacket( + CustomPayloadPacket::TRADER_SELECTION_PACKET, + rawOutput.toByteArray()))); + } + } else { + nextRecipeButton->active = false; + prevRecipeButton->active = false; + } +} + +void MerchantScreen::buttonClicked(Button* button) { + bool changed = false; + + if (button == nextRecipeButton) { + ++currentRecipeIndex; + changed = true; + } else if (button == prevRecipeButton) { + --currentRecipeIndex; + changed = true; + } + + if (changed) { + merchantMenu->setSelectionHint(currentRecipeIndex); + + // 4jcraft: taken from IUIScene_TradingMenu + ByteArrayOutputStream rawOutput; + DataOutputStream output(&rawOutput); + output.writeInt(currentRecipeIndex); + minecraft->player->connection->send( + std::shared_ptr(new CustomPayloadPacket( + CustomPayloadPacket::TRADER_SELECTION_PACKET, + rawOutput.toByteArray()))); + } +} \ No newline at end of file diff --git a/Minecraft.Client/UI/Screens/MerchantScreen.h b/Minecraft.Client/UI/Screens/MerchantScreen.h new file mode 100644 index 000000000..4a40bbb72 --- /dev/null +++ b/Minecraft.Client/UI/Screens/MerchantScreen.h @@ -0,0 +1,32 @@ +#pragma once + +#include "AbstractContainerScreen.h" +#include "../../../Minecraft.World/Containers/MerchantMenu.h" +#include "../../../Minecraft.World/Headers/net.minecraft.world.item.trading.h" + +class TradeSwitchButton; + +class MerchantScreen : public AbstractContainerScreen { +public: + MerchantScreen(std::shared_ptr inventory, + std::shared_ptr merchant, Level* level); + virtual ~MerchantScreen(); + + void init() override; + void removed() override; + void renderLabels() override; + void renderBg(float a) override; + void render(int xm, int ym, float a) override; + void tick() override; + void buttonClicked(Button* button) override; + + std::shared_ptr getMerchant() { return merchant; } + +private: + std::shared_ptr inventory; + std::shared_ptr merchant; + MerchantMenu* merchantMenu; + TradeSwitchButton* nextRecipeButton; + TradeSwitchButton* prevRecipeButton; + int currentRecipeIndex; +}; \ No newline at end of file diff --git a/Minecraft.Client/UI/TradeSwitchButton.cpp b/Minecraft.Client/UI/TradeSwitchButton.cpp new file mode 100644 index 000000000..860a2c43f --- /dev/null +++ b/Minecraft.Client/UI/TradeSwitchButton.cpp @@ -0,0 +1,46 @@ +#include "../../Platform/stdafx.h" +#include "TradeSwitchButton.h" +#include "../Textures/Textures.h" +#include "../Rendering/Tesselator.h" +#include "../../../Minecraft.Client/Minecraft.h" +#include "../../../Minecraft.World/Headers/net.minecraft.locale.h" +#include "../../../Minecraft.World/Containers/MerchantMenu.h" + +// 4jcraft: referenced from MCP 8.11 (JE 1.6.4) +#ifdef ENABLE_JAVA_GUIS +// ResourceLocation GUI_VILLAGER_LOCATION = ResourceLocation(TN_GUI_VILLAGER); +extern ResourceLocation GUI_VILLAGER_LOCATION; +#endif + +TradeSwitchButton::TradeSwitchButton(int id, int x, int y, bool mirrored) + : Button(id, x, y, 12, 19, L"") { + this->mirrored = mirrored; +} + +int TradeSwitchButton::getYImage(bool hovered) { return 0; } + +void TradeSwitchButton::renderBg(Minecraft* minecraft, int xm, int ym) { +#ifdef ENABLE_JAVA_GUIS + if (!visible) return; + + glColor4f(1.0f, 1.0f, 1.0f, 1.0f); + minecraft->textures->bindTexture(&GUI_VILLAGER_LOCATION); + + bool hovered = (xm >= x && ym >= y && xm < x + w && ym < y + h); + + int textureX = 176; + int textureY = 0; + + if (!active) { + textureX += w * 2; + } else if (hovered) { + textureX += w; + } + + if (!mirrored) { + textureY += h; + } + + blit(x, y, textureX, textureY, w, h); +#endif +} \ No newline at end of file diff --git a/Minecraft.Client/UI/TradeSwitchButton.h b/Minecraft.Client/UI/TradeSwitchButton.h new file mode 100644 index 000000000..f5e8e0f0b --- /dev/null +++ b/Minecraft.Client/UI/TradeSwitchButton.h @@ -0,0 +1,14 @@ +#pragma once +#include "Button.h" + +class TradeSwitchButton : public Button { +private: + bool mirrored; + +public: + TradeSwitchButton(int id, int x, int y, bool mirrored); + +protected: + int getYImage(bool hovered) override; + void renderBg(Minecraft* minecraft, int xm, int ym) override; +}; \ No newline at end of file From cfb54e65bd65c15b175e60467bd9bfe3a8fd1a20 Mon Sep 17 00:00:00 2001 From: Sally Knight Date: Sun, 29 Mar 2026 13:30:14 +0300 Subject: [PATCH 080/170] fix(jui): accidental ! in deprecated recipe check --- Minecraft.Client/UI/Screens/MerchantScreen.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/Minecraft.Client/UI/Screens/MerchantScreen.cpp b/Minecraft.Client/UI/Screens/MerchantScreen.cpp index b069e89e8..f7e5a51e5 100644 --- a/Minecraft.Client/UI/Screens/MerchantScreen.cpp +++ b/Minecraft.Client/UI/Screens/MerchantScreen.cpp @@ -43,8 +43,10 @@ void MerchantScreen::init() { int xo = (width - imageWidth) / 2; int yo = (height - imageHeight) / 2; - nextRecipeButton = new TradeSwitchButton(1, xo + 120 + 27, yo + 24 - 1, true); - prevRecipeButton = new TradeSwitchButton(2, xo + 36 - 19, yo + 24 - 1, false); + nextRecipeButton = + new TradeSwitchButton(1, xo + 120 + 27, yo + 24 - 1, true); + prevRecipeButton = + new TradeSwitchButton(2, xo + 36 - 19, yo + 24 - 1, false); nextRecipeButton->active = false; prevRecipeButton->active = false; @@ -73,7 +75,7 @@ void MerchantScreen::renderBg(float a) { MerchantRecipe* activeRecipe = merchantMenu->getTradeContainer()->getActiveRecipe(); - if (activeRecipe != nullptr && !activeRecipe->isDeprecated()) { + if (activeRecipe != nullptr && activeRecipe->isDeprecated()) { blit(xo + 83, yo + 21, 212, 0, 28, 21); blit(xo + 83, yo + 51, 212, 0, 28, 21); } From 03fac5b8e19894f09a80a5abca7487a9f1a0ca66 Mon Sep 17 00:00:00 2001 From: Sally Knight Date: Sun, 29 Mar 2026 16:34:23 +0300 Subject: [PATCH 081/170] refactor(jui): backport tooltip overloads from JE 1.6.4 --- .../UI/Screens/AbstractContainerScreen.cpp | 147 ++++++++++-------- .../UI/Screens/AbstractContainerScreen.h | 12 +- 2 files changed, 96 insertions(+), 63 deletions(-) diff --git a/Minecraft.Client/UI/Screens/AbstractContainerScreen.cpp b/Minecraft.Client/UI/Screens/AbstractContainerScreen.cpp index 53a81d19d..80e1ff815 100644 --- a/Minecraft.Client/UI/Screens/AbstractContainerScreen.cpp +++ b/Minecraft.Client/UI/Screens/AbstractContainerScreen.cpp @@ -112,8 +112,70 @@ void AbstractContainerScreen::render(int xm, int ym, float a) { // 4jcraft: extracted from render() into a standalone method so this can be used // in other derived classes +// update: also added 1.6.x era overloads (for the creative inventory and other +// places) +void AbstractContainerScreen::renderTooltipInternal( + const std::vector& cleanedLines, + const std::vector& lineColors, int mouseX, int mouseY) { + if (cleanedLines.empty()) return; + + int tooltipWidth = 0; + for (const auto& line : cleanedLines) { + int lineWidth = font->width(line); + if (lineWidth > tooltipWidth) tooltipWidth = lineWidth; + } + + int tooltipX = mouseX + 12; + int tooltipY = mouseY - 12; + int tooltipHeight = 8; + + if (cleanedLines.size() > 1) { + tooltipHeight += 2 + (cleanedLines.size() - 1) * 10; + } + + int bgColor = 0xf0100010; + fillGradient(tooltipX - 3, tooltipY - 4, tooltipX + tooltipWidth + 3, + tooltipY - 3, bgColor, bgColor); + fillGradient(tooltipX - 3, tooltipY + tooltipHeight + 3, + tooltipX + tooltipWidth + 3, tooltipY + tooltipHeight + 4, + bgColor, bgColor); + fillGradient(tooltipX - 3, tooltipY - 3, tooltipX + tooltipWidth + 3, + tooltipY + tooltipHeight + 3, bgColor, bgColor); + fillGradient(tooltipX - 4, tooltipY - 3, tooltipX - 3, + tooltipY + tooltipHeight + 3, bgColor, bgColor); + fillGradient(tooltipX + tooltipWidth + 3, tooltipY - 3, + tooltipX + tooltipWidth + 4, tooltipY + tooltipHeight + 3, + bgColor, bgColor); + + int borderStart = 0x505000ff; + int borderFinish = (borderStart & 0xfefefe) >> 1 | borderStart & 0xff000000; + fillGradient(tooltipX - 3, (tooltipY - 3) + 1, (tooltipX - 3) + 1, + (tooltipY + tooltipHeight + 3) - 1, borderStart, borderFinish); + fillGradient(tooltipX + tooltipWidth + 2, (tooltipY - 3) + 1, + tooltipX + tooltipWidth + 3, + (tooltipY + tooltipHeight + 3) - 1, borderStart, borderFinish); + fillGradient(tooltipX - 3, tooltipY - 3, tooltipX + tooltipWidth + 3, + (tooltipY - 3) + 1, borderStart, borderStart); + fillGradient(tooltipX - 3, tooltipY + tooltipHeight + 2, + tooltipX + tooltipWidth + 3, tooltipY + tooltipHeight + 3, + borderFinish, borderFinish); + + int currentY = tooltipY; + for (size_t lineIndex = 0; lineIndex < cleanedLines.size(); ++lineIndex) { + const std::wstring& currentLine = cleanedLines[lineIndex]; + int textColor = lineColors[lineIndex]; + + font->drawShadow(currentLine, tooltipX, currentY, textColor); + + if (lineIndex == 0) { + currentY += 2; + } + currentY += 10; + } +} + void AbstractContainerScreen::renderTooltip(std::shared_ptr item, - int x, int y) { + int mouseX, int mouseY) { if (item == nullptr) return; std::vector elementName; @@ -121,7 +183,6 @@ void AbstractContainerScreen::renderTooltip(std::shared_ptr item, item->getHoverText(minecraft->player, false, elementName); if (tooltipLines != NULL && tooltipLines->size() > 0) { - int tooltipWidth = 0; std::vector cleanedLines; std::vector lineColors; @@ -173,74 +234,38 @@ void AbstractContainerScreen::renderTooltip(std::shared_ptr item, cleanedLines.push_back(clean); lineColors.push_back(lineColor); - - int lineWidth = font->width(clean); - if (lineWidth > tooltipWidth) { - tooltipWidth = lineWidth; - } } - int tooltipX = x + 12; - int tooltipY = y - 12; - int tooltipHeight = 8; - - if (tooltipLines->size() > 1) { - tooltipHeight += 2 + (tooltipLines->size() - 1) * 10; + if (!cleanedLines.empty()) { + lineColors[0] = app.GetHTMLColour(item->getRarity()->color); } - int bgColor = 0xf0100010; - fillGradient(tooltipX - 3, tooltipY - 4, tooltipX + tooltipWidth + 3, - tooltipY - 3, bgColor, bgColor); - fillGradient(tooltipX - 3, tooltipY + tooltipHeight + 3, - tooltipX + tooltipWidth + 3, tooltipY + tooltipHeight + 4, - bgColor, bgColor); - fillGradient(tooltipX - 3, tooltipY - 3, tooltipX + tooltipWidth + 3, - tooltipY + tooltipHeight + 3, bgColor, bgColor); - fillGradient(tooltipX - 4, tooltipY - 3, tooltipX - 3, - tooltipY + tooltipHeight + 3, bgColor, bgColor); - fillGradient(tooltipX + tooltipWidth + 3, tooltipY - 3, - tooltipX + tooltipWidth + 4, tooltipY + tooltipHeight + 3, - bgColor, bgColor); + renderTooltipInternal(cleanedLines, lineColors, mouseX, mouseY); + } +} - int borderStart = 0x505000ff; - int borderFinish = - (borderStart & 0xfefefe) >> 1 | borderStart & 0xff000000; - fillGradient(tooltipX - 3, (tooltipY - 3) + 1, (tooltipX - 3) + 1, - (tooltipY + tooltipHeight + 3) - 1, borderStart, - borderFinish); - fillGradient(tooltipX + tooltipWidth + 2, (tooltipY - 3) + 1, - tooltipX + tooltipWidth + 3, - (tooltipY + tooltipHeight + 3) - 1, borderStart, - borderFinish); - fillGradient(tooltipX - 3, tooltipY - 3, tooltipX + tooltipWidth + 3, - (tooltipY - 3) + 1, borderStart, borderStart); - fillGradient(tooltipX - 3, tooltipY + tooltipHeight + 2, - tooltipX + tooltipWidth + 3, tooltipY + tooltipHeight + 3, - borderFinish, borderFinish); +void AbstractContainerScreen::renderTooltip( + const std::vector& lines, int mouseX, int mouseY) { + if (lines.empty()) return; - int currentY = tooltipY; - for (int lineIndex = 0; lineIndex < (int)tooltipLines->size(); - ++lineIndex) { - std::wstring& currentLine = cleanedLines[lineIndex]; - int textColor; + std::vector cleanedLines = lines; + std::vector lineColors; + lineColors.reserve(lines.size()); - if (lineIndex == 0) { - textColor = app.GetHTMLColour(item->getRarity()->color); - } else { - textColor = (lineColors[lineIndex] != 0xffffffff) - ? lineColors[lineIndex] - : 0xffaaaaaa; - } - - font->drawShadow(currentLine, tooltipX, currentY, textColor); - - if (lineIndex == 0) { - currentY += 2; - } - - currentY += 10; + for (size_t i = 0; i < lines.size(); ++i) { + if (i == 0) { + lineColors.push_back(0xffffffff); + } else { + lineColors.push_back(0xffaaaaaa); } } + + renderTooltipInternal(cleanedLines, lineColors, mouseX, mouseY); +} + +void AbstractContainerScreen::renderTooltip(const std::wstring& line, + int mouseX, int mouseY) { + renderTooltip(std::vector{line}, mouseX, mouseY); } void AbstractContainerScreen::renderLabels() {} diff --git a/Minecraft.Client/UI/Screens/AbstractContainerScreen.h b/Minecraft.Client/UI/Screens/AbstractContainerScreen.h index dcd2f4214..72f774ef6 100644 --- a/Minecraft.Client/UI/Screens/AbstractContainerScreen.h +++ b/Minecraft.Client/UI/Screens/AbstractContainerScreen.h @@ -33,7 +33,10 @@ protected: virtual bool isHoveringOver(int x, int y, int w, int h, int xm, int ym); virtual bool isHovering(Slot* slot, int xm, int ym); // 4jcraft: extracted from render() into a standalone method so this can be - // used in other classes + // used in other places + virtual void renderTooltipInternal( + const std::vector& cleanedLines, + const std::vector& lineColors, int mouseX, int mouseY); virtual void renderTooltip(std::shared_ptr item, int x, int y); @@ -50,4 +53,9 @@ public: virtual void slotsChanged(std::shared_ptr container); virtual bool isPauseScreen() override; virtual void tick() override; -}; \ No newline at end of file + + // 4jcraft: 1.6.x era overloads + virtual void renderTooltip(const std::vector& lines, int x, + int y); + virtual void renderTooltip(const std::wstring& line, int x, int y); +}; From 18dd2ed2ca451d2f61166a201568e5c9eed16e6d Mon Sep 17 00:00:00 2001 From: Sally Knight Date: Sun, 29 Mar 2026 20:07:00 +0300 Subject: [PATCH 082/170] update inventory.png to 1.6.4 version --- .../Common/res/1_2_2/gui/inventory.png | Bin 7211 -> 10737 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/Minecraft.Assets/Common/res/1_2_2/gui/inventory.png b/Minecraft.Assets/Common/res/1_2_2/gui/inventory.png index 4d9911690cccd6a72aab7cc3db4192d7f554aa29..d553c4f736c56a81fffa205c3bf2099e66c88a3e 100644 GIT binary patch literal 10737 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 MMNNeYIji9R0S$lESO5S3 literal 7211 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

Ss4Q5pP d(|qnB1;~h~(@uBbN#s9yfR+YEy<80&^dHSX Date: Sun, 29 Mar 2026 20:16:56 +0300 Subject: [PATCH 083/170] feat(jui): add beacon screen --- .../Common/res/1_2_2/gui/beacon.png | Bin 0 -> 2094 bytes Minecraft.Assets/Common/res/lang/en_US.lang | 3 + Minecraft.Client/Player/LocalPlayer.cpp | 7 +- Minecraft.Client/Textures/Textures.cpp | 1 + Minecraft.Client/Textures/Textures.h | 1 + Minecraft.Client/UI/AbstractBeaconButton.cpp | 46 ++++ Minecraft.Client/UI/AbstractBeaconButton.h | 24 ++ Minecraft.Client/UI/BeaconCancelButton.cpp | 25 ++ Minecraft.Client/UI/BeaconCancelButton.h | 13 + Minecraft.Client/UI/BeaconConfirmButton.cpp | 25 ++ Minecraft.Client/UI/BeaconConfirmButton.h | 13 + Minecraft.Client/UI/BeaconPowerButton.cpp | 39 +++ Minecraft.Client/UI/BeaconPowerButton.h | 18 ++ Minecraft.Client/UI/Screens/BeaconScreen.cpp | 229 ++++++++++++++++++ Minecraft.Client/UI/Screens/BeaconScreen.h | 32 +++ Minecraft.Client/UI/Screens/TitleScreen.cpp | 1 + Minecraft.World/Entities/MobEffect.cpp | 49 ++++ Minecraft.World/Entities/MobEffect.h | 2 + 18 files changed, 527 insertions(+), 1 deletion(-) create mode 100644 Minecraft.Assets/Common/res/1_2_2/gui/beacon.png create mode 100644 Minecraft.Client/UI/AbstractBeaconButton.cpp create mode 100644 Minecraft.Client/UI/AbstractBeaconButton.h create mode 100644 Minecraft.Client/UI/BeaconCancelButton.cpp create mode 100644 Minecraft.Client/UI/BeaconCancelButton.h create mode 100644 Minecraft.Client/UI/BeaconConfirmButton.cpp create mode 100644 Minecraft.Client/UI/BeaconConfirmButton.h create mode 100644 Minecraft.Client/UI/BeaconPowerButton.cpp create mode 100644 Minecraft.Client/UI/BeaconPowerButton.h create mode 100644 Minecraft.Client/UI/Screens/BeaconScreen.cpp create mode 100644 Minecraft.Client/UI/Screens/BeaconScreen.h diff --git a/Minecraft.Assets/Common/res/1_2_2/gui/beacon.png b/Minecraft.Assets/Common/res/1_2_2/gui/beacon.png new file mode 100644 index 0000000000000000000000000000000000000000..f51a2ef510b400fd868e2a53146fd032bbf89462 GIT binary patch literal 2094 zcmZux3pmv28vo|PxHIlyGRC%8om{gnF_X)>wS;KUSrd^6etPkJgh^a~=xV!;Pc3dFpCHt>~`pCNFQ=Sfsw|ySbJgTQJ_+!q*I_}Sa~LwB9Lw9*&{ zCe3il_%F)FB0q!)9!3Hhx$+N zp~FvL9c$~|ts4T?88+%)l0;c zecAGqckR59K71C@Mswj>bt8E`kb8^&*mA9P!KH9rUWJmp>UE^;kJt_}pO$fWk0Z35 znB<3a2wrOU_7_;ku{kI|xeV-!GSX;^=2olOEe$>@>RWR1&yjfrj^b zP|2eR<9niQmIWJ2t?e&!cth?XojI$Rlr|KDg5Nw`lJ(qZaybp}A5Reo9(3{T5H-;<^EnvAOT2c;f!zO^Heocsi06+)0Pl+6<8!v2W)`Ihmk5!4>}MH z!-!+5pyGsNSe7wyMvlS6=J|u?>PXWSa6$%NBu>rVk7a`f6N%kB$Hf2JEsW7|b!6P< z#(^G#sProV3-OdD=rWRVLIlx{gzg=igo%7h^gh7qp= z_2cfwfob;?Pm2%^AVe%;L@ZQuBN5QR|JA9}dD+>rrK$(8y&BdZ4G8`}c_}-MM()*_ zcGT^YE8E>4ZmwZxPZ6LUez|w@~#ue_{+FiA8Xvkx6aq$>_ zPYs8-$;1qf{d!n$XGK6Qlf${`rUW9aYV%`%>|im}Ms=2xL#Hr_BASj_$Z zQ$z^Z)KQoN)Co9aQQjI*B#`I)ROt8dZnS{x#LhZ5B(QohG0{|*zMTxDYP&Nk=@RC( zwYPpAycu)J?4zaCIlgtSqi;LD@En(PDC zIVve4f!&s>Z6QUH6PB&67vhJ6@Wq*pxF;p;R97OGX_=oB;)LC5%5565B{Wo|hzIi_ z(c2Kde~8nF%X0^(ppKd~V@kcc8F`gQIds$>&Y)VBb(@!8Td zEX+^LA}7W)%$MYn=9>ar6Up2-O?anS16|-&_4FV8vC%?F5* beacon) { - // minecraft->setScreen(new BeaconScreen(inventory, beacon)); +#ifdef ENABLE_JAVA_GUIS + minecraft->setScreen(new BeaconScreen(inventory, beacon)); + bool success = true; +#else bool success = app.LoadBeaconMenu(GetXboxPad(), inventory, beacon); if (success) ui.PlayUISFX(eSFX_Press); +#endif return success; } diff --git a/Minecraft.Client/Textures/Textures.cpp b/Minecraft.Client/Textures/Textures.cpp index bbd96f14a..907f51927 100644 --- a/Minecraft.Client/Textures/Textures.cpp +++ b/Minecraft.Client/Textures/Textures.cpp @@ -180,6 +180,7 @@ const wchar_t* Textures::preLoaded[TN_COUNT] = { L"gui/horse", L"gui/anvil", L"gui/trap", + L"gui/beacon", L"gui/hopper", L"gui/enchant", L"gui/villager", diff --git a/Minecraft.Client/Textures/Textures.h b/Minecraft.Client/Textures/Textures.h index 3edec4b5d..fd59fc66b 100644 --- a/Minecraft.Client/Textures/Textures.h +++ b/Minecraft.Client/Textures/Textures.h @@ -162,6 +162,7 @@ typedef enum _TEXTURE_NAME { TN_GUI_HORSE, TN_GUI_ANVIL, TN_GUI_TRAP, + TN_GUI_BEACON, TN_GUI_HOPPER, TN_GUI_ENCHANT, TN_GUI_VILLAGER, diff --git a/Minecraft.Client/UI/AbstractBeaconButton.cpp b/Minecraft.Client/UI/AbstractBeaconButton.cpp new file mode 100644 index 000000000..b2d874ddc --- /dev/null +++ b/Minecraft.Client/UI/AbstractBeaconButton.cpp @@ -0,0 +1,46 @@ +#include "../../Platform/stdafx.h" +#include "AbstractBeaconButton.h" +#include "../Textures/Textures.h" +#include "../../../Minecraft.Client/Minecraft.h" +#include + +// 4jcraft: referenced from MCP 8.11 (JE 1.6.4) +#ifdef ENABLE_JAVA_GUIS +extern ResourceLocation GUI_BEACON_LOCATION; +#endif + +AbstractBeaconButton::AbstractBeaconButton(int id, int x, int y) + : Button(id, x, y, 22, 22, L"") { + hovered = false; + selected = false; + iconRes = nullptr; + iconU = iconV = 0; +} + +void AbstractBeaconButton::renderBg(Minecraft* minecraft, int xm, int ym) { +#ifdef ENABLE_JAVA_GUIS + if (!visible) return; + + hovered = (xm >= x && ym >= y && xm < x + w && ym < y + h); + + glColor4f(1.0f, 1.0f, 1.0f, 1.0f); + minecraft->textures->bindTexture(&GUI_BEACON_LOCATION); + + int texU = 0; + if (!active) { + texU += w * 2; + } else if (selected) { + texU += w * 1; + } else if (hovered) { + texU += w * 3; + } + int texV = 219; + + blit(x, y, texU, texV, w, h); + + if (iconRes != nullptr && iconRes != &GUI_BEACON_LOCATION) { + minecraft->textures->bindTexture(iconRes); + } + blit(x + 2, y + 2, iconU, iconV, 18, 18); +#endif +} \ No newline at end of file diff --git a/Minecraft.Client/UI/AbstractBeaconButton.h b/Minecraft.Client/UI/AbstractBeaconButton.h new file mode 100644 index 000000000..3254f4912 --- /dev/null +++ b/Minecraft.Client/UI/AbstractBeaconButton.h @@ -0,0 +1,24 @@ +#pragma once +#include "Button.h" + +class ResourceLocation; + +class AbstractBeaconButton : public Button { +protected: + bool hovered; + bool selected; + ResourceLocation* iconRes; + int iconU, iconV; + +public: + AbstractBeaconButton(int id, int x, int y); + + void setSelected(bool sel) { selected = sel; } + bool isSelected() const { return selected; } + bool isHovered() const { return hovered; } + + virtual void renderTooltip(int xm, int ym) = 0; + +protected: + virtual void renderBg(Minecraft* minecraft, int xm, int ym) override; +}; \ No newline at end of file diff --git a/Minecraft.Client/UI/BeaconCancelButton.cpp b/Minecraft.Client/UI/BeaconCancelButton.cpp new file mode 100644 index 000000000..081029e4c --- /dev/null +++ b/Minecraft.Client/UI/BeaconCancelButton.cpp @@ -0,0 +1,25 @@ +#include "../../Platform/stdafx.h" +#include "BeaconCancelButton.h" +#include "Screens/BeaconScreen.h" +#include "../../../Minecraft.World/Headers/net.minecraft.locale.h" + +// 4jcraft: referenced from MCP 8.11 (JE 1.6.4) +#ifdef ENABLE_JAVA_GUIS +extern ResourceLocation GUI_BEACON_LOCATION; +#endif + +BeaconCancelButton::BeaconCancelButton(BeaconScreen* screen, int id, int x, + int y) + : AbstractBeaconButton(id, x, y) { + this->screen = screen; +#ifdef ENABLE_JAVA_GUIS + this->iconRes = &GUI_BEACON_LOCATION; +#endif + this->iconU = 112; + this->iconV = 220; +} + +void BeaconCancelButton::renderTooltip(int xm, int ym) { + screen->renderTooltip(Language::getInstance()->getElement(L"gui.cancel"), + xm, ym); +} \ No newline at end of file diff --git a/Minecraft.Client/UI/BeaconCancelButton.h b/Minecraft.Client/UI/BeaconCancelButton.h new file mode 100644 index 000000000..f9d62456e --- /dev/null +++ b/Minecraft.Client/UI/BeaconCancelButton.h @@ -0,0 +1,13 @@ +#pragma once +#include "AbstractBeaconButton.h" + +class BeaconScreen; + +class BeaconCancelButton : public AbstractBeaconButton { +public: + BeaconCancelButton(BeaconScreen* screen, int id, int x, int y); + void renderTooltip(int xm, int ym) override; + +private: + BeaconScreen* screen; +}; \ No newline at end of file diff --git a/Minecraft.Client/UI/BeaconConfirmButton.cpp b/Minecraft.Client/UI/BeaconConfirmButton.cpp new file mode 100644 index 000000000..00871f6e1 --- /dev/null +++ b/Minecraft.Client/UI/BeaconConfirmButton.cpp @@ -0,0 +1,25 @@ +#include "../../Platform/stdafx.h" +#include "BeaconConfirmButton.h" +#include "Screens/BeaconScreen.h" +#include "../../../Minecraft.World/Headers/net.minecraft.locale.h" + +// 4jcraft: referenced from MCP 8.11 (JE 1.6.4) +#ifdef ENABLE_JAVA_GUIS +extern ResourceLocation GUI_BEACON_LOCATION; +#endif + +BeaconConfirmButton::BeaconConfirmButton(BeaconScreen* screen, int id, int x, + int y) + : AbstractBeaconButton(id, x, y) { + this->screen = screen; +#ifdef ENABLE_JAVA_GUIS + this->iconRes = &GUI_BEACON_LOCATION; +#endif + this->iconU = 90; + this->iconV = 220; +} + +void BeaconConfirmButton::renderTooltip(int xm, int ym) { + screen->renderTooltip(Language::getInstance()->getElement(L"gui.done"), xm, + ym); +} \ No newline at end of file diff --git a/Minecraft.Client/UI/BeaconConfirmButton.h b/Minecraft.Client/UI/BeaconConfirmButton.h new file mode 100644 index 000000000..ab1d28177 --- /dev/null +++ b/Minecraft.Client/UI/BeaconConfirmButton.h @@ -0,0 +1,13 @@ +#pragma once +#include "AbstractBeaconButton.h" + +class BeaconScreen; + +class BeaconConfirmButton : public AbstractBeaconButton { +public: + BeaconConfirmButton(BeaconScreen* screen, int id, int x, int y); + void renderTooltip(int xm, int ym) override; + +private: + BeaconScreen* screen; +}; \ No newline at end of file diff --git a/Minecraft.Client/UI/BeaconPowerButton.cpp b/Minecraft.Client/UI/BeaconPowerButton.cpp new file mode 100644 index 000000000..958badfe7 --- /dev/null +++ b/Minecraft.Client/UI/BeaconPowerButton.cpp @@ -0,0 +1,39 @@ +#include "../../Platform/stdafx.h" +#include "BeaconPowerButton.h" +#include "Screens/BeaconScreen.h" +#include "../../../Minecraft.World/Entities/MobEffect.h" +#include "../../../Minecraft.World/Headers/net.minecraft.locale.h" +#include "../Textures/Textures.h" +#include "Textures/ResourceLocation.h" + +// 4jcraft: referenced from MCP 8.11 (JE 1.6.4) +#ifdef ENABLE_JAVA_GUIS +ResourceLocation GUI_INVENTORY_LOCATION = ResourceLocation(TN_GUI_INVENTORY); +#endif + +BeaconPowerButton::BeaconPowerButton(BeaconScreen* screen, int id, int x, int y, + int effectId, int tier) + : AbstractBeaconButton(id, x, y) { + this->screen = screen; + this->effectId = effectId; + this->tier = tier; + +#ifdef ENABLE_JAVA_GUIS + this->iconRes = &GUI_INVENTORY_LOCATION; +#endif + + int statusIconIndex = MobEffect::javaId(effectId); + this->iconU = (statusIconIndex % 8) * 18; + this->iconV = 198 + (statusIconIndex / 8) * 18; +} + +void BeaconPowerButton::renderTooltip(int xm, int ym) { + MobEffect* effect = MobEffect::effects[effectId]; + if (!effect) return; + + std::wstring name = app.GetString(effect->getDescriptionId()); + if (tier >= 3 && effect->id != MobEffect::regeneration->id) { + name += L" II"; + } + screen->renderTooltip(name, xm, ym); +} \ No newline at end of file diff --git a/Minecraft.Client/UI/BeaconPowerButton.h b/Minecraft.Client/UI/BeaconPowerButton.h new file mode 100644 index 000000000..fc6e40266 --- /dev/null +++ b/Minecraft.Client/UI/BeaconPowerButton.h @@ -0,0 +1,18 @@ +#pragma once +#include "AbstractBeaconButton.h" +#include "../../../Minecraft.World/Headers/net.minecraft.world.effect.h" + +class BeaconScreen; + +class BeaconPowerButton : public AbstractBeaconButton { +public: + BeaconPowerButton(BeaconScreen* screen, int id, int x, int y, int effectId, + int tier); + void renderTooltip(int xm, int ym) override; + bool isSelected() const { return selected; } + +private: + BeaconScreen* screen; + int effectId; + int tier; +}; \ No newline at end of file diff --git a/Minecraft.Client/UI/Screens/BeaconScreen.cpp b/Minecraft.Client/UI/Screens/BeaconScreen.cpp new file mode 100644 index 000000000..d44378d83 --- /dev/null +++ b/Minecraft.Client/UI/Screens/BeaconScreen.cpp @@ -0,0 +1,229 @@ +#include "../../Platform/stdafx.h" +#include "BeaconScreen.h" +#include "../BeaconConfirmButton.h" +#include "../BeaconCancelButton.h" +#include "../BeaconPowerButton.h" +#include +#include +#include "../../Player/MultiPlayerLocalPlayer.h" +#include "../../Rendering/Lighting.h" +#include "../../Textures/Textures.h" +#include "../../../Minecraft.World/Headers/net.minecraft.locale.h" +#include "../../../Minecraft.World/Containers/Slot.h" +#include "../../../Minecraft.World/Headers/net.minecraft.world.item.h" +#include "../../../Minecraft.Client/Minecraft.h" +#include "../../../Minecraft.Client/Network/ClientConnection.h" +#include "../../../Minecraft.World/IO/Streams/ByteArrayOutputStream.h" +#include "../../../Minecraft.World/IO/Streams/DataOutputStream.h" + +// 4jcraft: referenced from MCP 8.11 (JE 1.6.4) and the existing +// container classes (and iggy too) +#ifdef ENABLE_JAVA_GUIS +ResourceLocation GUI_BEACON_LOCATION = ResourceLocation(TN_GUI_BEACON); +#endif + +BeaconScreen::BeaconScreen(std::shared_ptr inventory, + std::shared_ptr beacon) + : AbstractContainerScreen(new BeaconMenu(inventory, beacon)) { + this->inventory = inventory; + this->beacon = beacon; + this->beaconMenu = static_cast(menu); + this->imageWidth = 230; + this->imageHeight = 219; + this->buttonsNotDrawn = true; + this->beaconConfirmButton = nullptr; +} + +BeaconScreen::~BeaconScreen() = default; + +void BeaconScreen::init() { + AbstractContainerScreen::init(); + + int xo = (width - imageWidth) / 2; + int yo = (height - imageHeight) / 2; + + beaconConfirmButton = new BeaconConfirmButton(this, -1, xo + 164, yo + 107); + buttons.push_back(beaconConfirmButton); + buttons.push_back(new BeaconCancelButton(this, -2, xo + 190, yo + 107)); + + buttonsNotDrawn = true; + beaconConfirmButton->active = false; +} + +void BeaconScreen::tick() { + if (buttonsNotDrawn && beacon->getLevels() >= 0) { + buttonsNotDrawn = false; + + int xo = (width - imageWidth) / 2; + int yo = (height - imageHeight) / 2; + + for (int tier = 0; tier <= 2; ++tier) { + int effectCount = BeaconTileEntity::BEACON_EFFECTS_EFFECTS; + int actualCount = 0; + for (int e = 0; e < effectCount; ++e) { + if (BeaconTileEntity::BEACON_EFFECTS[tier][e] != nullptr) { + actualCount++; + } else { + break; + } + } + + int totalWidth = actualCount * 22 + (actualCount - 1) * 2; + int startX = xo + 53 + (actualCount * 24 - totalWidth) / 2; + + for (int e = 0; e < actualCount; ++e) { + MobEffect* effect = BeaconTileEntity::BEACON_EFFECTS[tier][e]; + if (effect == nullptr) break; + + int buttonId = (tier << 8) | effect->id; + BeaconPowerButton* button = new BeaconPowerButton( + this, buttonId, startX + e * 24, yo + 22 + tier * 25, + effect->id, tier); + buttons.push_back(button); + + if (tier >= beacon->getLevels()) { + button->active = false; + } else if (effect->id == beacon->getPrimaryPower()) { + button->setSelected(true); + } + } + } + + int tier = 3; + int effectCount = BeaconTileEntity::BEACON_EFFECTS_EFFECTS; + int actualCount = 0; + for (int e = 0; e < effectCount; ++e) { + if (BeaconTileEntity::BEACON_EFFECTS[tier][e] != nullptr) { + actualCount++; + } else { + break; + } + } + + int totalWidth = (actualCount + 1) * 22 + actualCount * 2; + int startX = xo + 143 + ((actualCount + 1) * 24 - totalWidth) / 2; + + for (int e = 0; e < actualCount; ++e) { + MobEffect* effect = BeaconTileEntity::BEACON_EFFECTS[tier][e]; + if (effect == nullptr) break; + + int buttonId = (tier << 8) | effect->id; + BeaconPowerButton* button = new BeaconPowerButton( + this, buttonId, startX + e * 24, yo + 47, effect->id, tier); + buttons.push_back(button); + + if (tier >= beacon->getLevels()) { + button->active = false; + } else if (effect->id == beacon->getSecondaryPower()) { + button->setSelected(true); + } + } + + if (beacon->getPrimaryPower() > 0) { + int buttonId = (tier << 8) | beacon->getPrimaryPower(); + BeaconPowerButton* button = + new BeaconPowerButton(this, buttonId, startX + actualCount * 24, + yo + 47, beacon->getPrimaryPower(), tier); + buttons.push_back(button); + + if (tier >= beacon->getLevels()) { + button->active = false; + } else if (beacon->getPrimaryPower() == + beacon->getSecondaryPower()) { + button->setSelected(true); + } + } + } + + beaconConfirmButton->active = + (beacon->getItem(0) != nullptr && beacon->getPrimaryPower() > 0); +} + +void BeaconScreen::removed() { AbstractContainerScreen::removed(); } + +void BeaconScreen::renderLabels() { + std::wstring primaryLabel = + Language::getInstance()->getElement(L"tile.beacon.primary"); + font->drawShadow(primaryLabel, 25, 10, 0xE1E1E1); + + std::wstring secondaryLabel = + Language::getInstance()->getElement(L"tile.beacon.secondary"); + font->drawShadow(secondaryLabel, 125, 10, 0xE1E1E1); +} + +void BeaconScreen::renderBg(float a) { +#ifdef ENABLE_JAVA_GUIS + glColor4f(1.0f, 1.0f, 1.0f, 1.0f); + minecraft->textures->bindTexture(&GUI_BEACON_LOCATION); + int xo = (width - imageWidth) / 2; + int yo = (height - imageHeight) / 2; + blit(xo, yo, 0, 0, imageWidth, imageHeight); + + // Render payment item icons + itemRenderer->renderGuiItem( + font, minecraft->textures, + std::shared_ptr(new ItemInstance(Item::emerald_Id, 1, 0)), + xo + 42, yo + 109); + itemRenderer->renderGuiItem( + font, minecraft->textures, + std::shared_ptr(new ItemInstance(Item::diamond_Id, 1, 0)), + xo + 42 + 22, yo + 109); + itemRenderer->renderGuiItem(font, minecraft->textures, + std::shared_ptr( + new ItemInstance(Item::goldIngot_Id, 1, 0)), + xo + 42 + 44, yo + 109); + itemRenderer->renderGuiItem(font, minecraft->textures, + std::shared_ptr( + new ItemInstance(Item::ironIngot_Id, 1, 0)), + xo + 42 + 66, yo + 109); +#endif +} + +void BeaconScreen::render(int xm, int ym, float a) { + AbstractContainerScreen::render(xm, ym, a); + for (Button* button : buttons) { + AbstractBeaconButton* beaconButton = + dynamic_cast(button); + if (beaconButton && beaconButton->isHovered()) { + glDisable(GL_LIGHTING); + glDisable(GL_DEPTH_TEST); + beaconButton->renderTooltip(xm, ym); + glEnable(GL_LIGHTING); + glEnable(GL_DEPTH_TEST); + break; + } + } +} + +void BeaconScreen::buttonClicked(Button* button) { + if (button->id == -2) { + minecraft->player->closeContainer(); + } else if (button->id == -1) { + // 4jcraft: copied from IUIScene_BeaconMenu + ByteArrayOutputStream baos; + DataOutputStream dos(&baos); + dos.writeInt(beacon->getPrimaryPower()); + dos.writeInt(beacon->getSecondaryPower()); + + minecraft->player->connection->send( + std::shared_ptr(new CustomPayloadPacket( + CustomPayloadPacket::SET_BEACON_PACKET, baos.toByteArray()))); + minecraft->player->closeContainer(); + } else if (dynamic_cast(button)) { + int effectId = button->id & 255; + int tier = button->id >> 8; + + if (tier < 3) { + beacon->setPrimaryPower(effectId); + } else { + beacon->setSecondaryPower(effectId); + } + + for (Button* btn : buttons) { + delete btn; + } + buttons.clear(); + init(); + tick(); + } +} \ No newline at end of file diff --git a/Minecraft.Client/UI/Screens/BeaconScreen.h b/Minecraft.Client/UI/Screens/BeaconScreen.h new file mode 100644 index 000000000..03a9db927 --- /dev/null +++ b/Minecraft.Client/UI/Screens/BeaconScreen.h @@ -0,0 +1,32 @@ +#pragma once + +#include "AbstractContainerScreen.h" +#include "../../../Minecraft.World/Containers/BeaconMenu.h" +#include "../../../Minecraft.World/Headers/net.minecraft.world.level.tile.entity.h" + +class BeaconConfirmButton; +class BeaconCancelButton; + +class BeaconScreen : public AbstractContainerScreen { +public: + BeaconScreen(std::shared_ptr inventory, + std::shared_ptr beacon); + virtual ~BeaconScreen(); + + void init() override; + void removed() override; + void tick() override; + void renderLabels() override; + void renderBg(float a) override; + void render(int xm, int ym, float a) override; + void buttonClicked(Button* button) override; + + std::shared_ptr getBeacon() { return beacon; } + +private: + std::shared_ptr inventory; + std::shared_ptr beacon; + BeaconMenu* beaconMenu; + BeaconConfirmButton* beaconConfirmButton; + bool buttonsNotDrawn; +}; \ No newline at end of file diff --git a/Minecraft.Client/UI/Screens/TitleScreen.cpp b/Minecraft.Client/UI/Screens/TitleScreen.cpp index 50b527600..650d49af8 100644 --- a/Minecraft.Client/UI/Screens/TitleScreen.cpp +++ b/Minecraft.Client/UI/Screens/TitleScreen.cpp @@ -5,6 +5,7 @@ #include "JoinMultiplayerScreen.h" #include "../../Rendering/Tesselator.h" #include "../../Textures/Textures.h" +#include "../../GameState/Options.h" #include "../../../Minecraft.World/Util/StringHelpers.h" #include "../../../Minecraft.World/IO/Streams/InputOutputStream.h" #include "../../../Minecraft.World/Headers/net.minecraft.locale.h" diff --git a/Minecraft.World/Entities/MobEffect.cpp b/Minecraft.World/Entities/MobEffect.cpp index a0822934f..828b5a4e3 100644 --- a/Minecraft.World/Entities/MobEffect.cpp +++ b/Minecraft.World/Entities/MobEffect.cpp @@ -443,4 +443,53 @@ void MobEffect::addAttributeModifiers(std::shared_ptr entity, double MobEffect::getAttributeModifierValue(int amplifier, AttributeModifier* original) { return original->getAmount() * (amplifier + 1); +} + +// 4jcraft: helper for inventoryscreen and beaconscreen +int MobEffect::javaId(int id) { + // mapped to java based on the inventory texture (see gui/inventory.png) + switch (id) { + case 1: + return 0; + case 2: + return 1; + case 3: + return 2; + case 4: + return 3; + case 5: + return 4; + case 18: + return 5; + case 19: + return 6; + case 10: + return 7; + case 14: + return 8; + case 17: + return 9; + case 8: + return 10; + case 9: + return 11; + case 16: + return 12; + case 15: + return 13; + case 11: + return 14; + case 12: + return 15; + case 13: + return 16; + case 20: + return 17; + case 21: + return 18; + case 22: + return 18; + default: + return 0; + } } \ No newline at end of file diff --git a/Minecraft.World/Entities/MobEffect.h b/Minecraft.World/Entities/MobEffect.h index 8e7ccce17..5576a2b4b 100644 --- a/Minecraft.World/Entities/MobEffect.h +++ b/Minecraft.World/Entities/MobEffect.h @@ -134,4 +134,6 @@ public: int amplifier); virtual double getAttributeModifierValue(int amplifier, AttributeModifier* original); + static int javaId( + int id); // 4jcraft: helper for inventoryscreen and beaconscreen }; \ No newline at end of file From 7889fbb4d27864279a49c05d3cce9785b1c802aa Mon Sep 17 00:00:00 2001 From: StevenSYS <139715581+StevenSYS@users.noreply.github.com> Date: Sun, 29 Mar 2026 15:15:48 +0000 Subject: [PATCH 084/170] [Java Creative Inventory] Added tooltip when hovering over the tab icons. --- .../UI/Screens/CreativeInventoryScreen.cpp | 80 ++++++++++++++----- 1 file changed, 58 insertions(+), 22 deletions(-) diff --git a/Minecraft.Client/UI/Screens/CreativeInventoryScreen.cpp b/Minecraft.Client/UI/Screens/CreativeInventoryScreen.cpp index 98e2a3aec..30f0d068c 100644 --- a/Minecraft.Client/UI/Screens/CreativeInventoryScreen.cpp +++ b/Minecraft.Client/UI/Screens/CreativeInventoryScreen.cpp @@ -17,7 +17,7 @@ // Static member initialization int CreativeInventoryScreen::selectedTabIndex = IUIScene_CreativeMenu::eCreativeInventoryTab_BuildingBlocks; -int CreativeInventoryScreen::tabIconIds +const int CreativeInventoryScreen::tabIconIds [IUIScene_CreativeMenu::eCreativeInventoryTab_COUNT] = { // Building Blocks Tile::redBrick_Id, @@ -48,6 +48,7 @@ int CreativeInventoryScreen::tabIconIds // Materials Item::bucket_lava_Id}; + std::shared_ptr CreativeInventoryScreen::basicInventory = std::make_shared(0, L"", false, ITEMS_PER_PAGE); ItemRenderer* CreativeInventoryScreen::itemRenderer = new ItemRenderer(); @@ -378,6 +379,13 @@ void CreativeInventoryScreen::render(int xm, int ym, float a) { } AbstractContainerScreen::render(xm, ym, a); + + for (int i = 0; i < IUIScene_CreativeMenu::eCreativeInventoryTab_COUNT; + i++) { + if (renderIconTooltip(i, xm, ym)) { + break; + } + } } void CreativeInventoryScreen::renderLabels() { @@ -409,7 +417,7 @@ void CreativeInventoryScreen::renderBg(float a) { for (int tab = 0; tab < IUIScene_CreativeMenu::eCreativeInventoryTab_COUNT; tab++) { if (tab != selectedTabIndex) { - drawTab(tab); + renderTab(tab); } } @@ -433,10 +441,33 @@ void CreativeInventoryScreen::renderBg(float a) { } // Render selected tab last (on top) - drawTab(selectedTabIndex); + renderTab(selectedTabIndex); #endif } +bool CreativeInventoryScreen::isMouseOverInternal(int tab, int mouseX, + int mouseY, int xo, int yo, + int w, int h) { + int tabColumn = tab % 6; + int x = (tabColumn * 28) + xo; + int y = yo; + + if (tabColumn == 5) { + x = imageWidth - 28 + 2; + } else if (tabColumn > 0) { + x += tabColumn; + } + + if (tab < 6) { + y -= 32; + } else { + y = imageHeight; + } + + return ((mouseX >= x && mouseX <= x + w) && + (mouseY >= y && mouseY <= y + h)); +} + void CreativeInventoryScreen::setCurrentCreativeTab(int tab) { if (tab < 0 || tab >= IUIScene_CreativeMenu::eCreativeInventoryTab_COUNT) return; @@ -477,27 +508,14 @@ bool CreativeInventoryScreen::needsScrollBars() { } bool CreativeInventoryScreen::isMouseOverTab(int tab, int mouseX, int mouseY) { - int tabColumn = tab % 6; - int x = tabColumn * 28; - int y = 0; - - if (tabColumn == 5) { - x = imageWidth - 28 + 2; - } else if (tabColumn > 0) { - x += tabColumn; - } - - if (tab < 6) { - y -= 32; - } else { - y = imageHeight; - } - - return ((mouseX >= x && mouseX <= x + 28) && - (mouseY >= y && mouseY <= y + 32)); + return isMouseOverInternal(tab, mouseX, mouseY, 0, 0, 28, 32); } -void CreativeInventoryScreen::drawTab(int tab) { +bool CreativeInventoryScreen::isMouseOverIcon(int tab, int mouseX, int mouseY) { + return isMouseOverInternal(tab, mouseX, mouseY, 7, 12, 14, 16); +} + +void CreativeInventoryScreen::renderTab(int tab) { #ifdef ENABLE_JAVA_GUIS bool isSelected = (selectedTabIndex == tab); bool tabFirstRow = (tab < 6); @@ -544,4 +562,22 @@ void CreativeInventoryScreen::drawTab(int tab) { tabIcons[tab], x, y); glDisable(GL_LIGHTING); #endif +} + +bool CreativeInventoryScreen::renderIconTooltip(int tab, int mouseX, + int mouseY) { + int x = mouseX - (width - imageWidth) / 2; + int y = mouseY - (height - imageHeight) / 2; + + if (isMouseOverIcon(tab, x, y)) { + glDisable(GL_LIGHTING); + glDisable(GL_DEPTH_TEST); + renderTooltip( + app.GetString(IUIScene_CreativeMenu::specs[tab]->m_descriptionId), + mouseX, mouseY); + glEnable(GL_LIGHTING); + glEnable(GL_DEPTH_TEST); + return true; + } + return false; } \ No newline at end of file From cd6959b9897ed1ab79209204c673ed283f7c8ea9 Mon Sep 17 00:00:00 2001 From: Sally Knight Date: Sun, 29 Mar 2026 20:26:32 +0300 Subject: [PATCH 085/170] chore: fmt --- Minecraft.Client/UI/AbstractBeaconButton.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Minecraft.Client/UI/AbstractBeaconButton.cpp b/Minecraft.Client/UI/AbstractBeaconButton.cpp index b2d874ddc..92b49e881 100644 --- a/Minecraft.Client/UI/AbstractBeaconButton.cpp +++ b/Minecraft.Client/UI/AbstractBeaconButton.cpp @@ -28,13 +28,13 @@ void AbstractBeaconButton::renderBg(Minecraft* minecraft, int xm, int ym) { int texU = 0; if (!active) { - texU += w * 2; + texU += w * 2; } else if (selected) { - texU += w * 1; + texU += w * 1; } else if (hovered) { - texU += w * 3; + texU += w * 3; } - int texV = 219; + int texV = 219; blit(x, y, texU, texV, w, h); From ca276943f237f6bac148fe77ca07722436d70d14 Mon Sep 17 00:00:00 2001 From: Sally Knight Date: Sun, 29 Mar 2026 20:39:49 +0300 Subject: [PATCH 086/170] fix(jui): make creative screen correctly override menu clicked() (also made rendertooltip names in AbstractContainerScreen match so my editor stops complaining) --- .../UI/Screens/AbstractContainerScreen.cpp | 20 +++++++++---------- .../UI/Screens/AbstractContainerScreen.h | 12 +++++------ .../UI/Screens/CreativeInventoryScreen.cpp | 4 ++-- .../UI/Screens/CreativeInventoryScreen.h | 4 ++-- 4 files changed, 20 insertions(+), 20 deletions(-) diff --git a/Minecraft.Client/UI/Screens/AbstractContainerScreen.cpp b/Minecraft.Client/UI/Screens/AbstractContainerScreen.cpp index 80e1ff815..00a7e81f1 100644 --- a/Minecraft.Client/UI/Screens/AbstractContainerScreen.cpp +++ b/Minecraft.Client/UI/Screens/AbstractContainerScreen.cpp @@ -116,7 +116,7 @@ void AbstractContainerScreen::render(int xm, int ym, float a) { // places) void AbstractContainerScreen::renderTooltipInternal( const std::vector& cleanedLines, - const std::vector& lineColors, int mouseX, int mouseY) { + const std::vector& lineColors, int xm, int ym) { if (cleanedLines.empty()) return; int tooltipWidth = 0; @@ -125,8 +125,8 @@ void AbstractContainerScreen::renderTooltipInternal( if (lineWidth > tooltipWidth) tooltipWidth = lineWidth; } - int tooltipX = mouseX + 12; - int tooltipY = mouseY - 12; + int tooltipX = xm + 12; + int tooltipY = ym - 12; int tooltipHeight = 8; if (cleanedLines.size() > 1) { @@ -175,7 +175,7 @@ void AbstractContainerScreen::renderTooltipInternal( } void AbstractContainerScreen::renderTooltip(std::shared_ptr item, - int mouseX, int mouseY) { + int xm, int ym) { if (item == nullptr) return; std::vector elementName; @@ -240,12 +240,12 @@ void AbstractContainerScreen::renderTooltip(std::shared_ptr item, lineColors[0] = app.GetHTMLColour(item->getRarity()->color); } - renderTooltipInternal(cleanedLines, lineColors, mouseX, mouseY); + renderTooltipInternal(cleanedLines, lineColors, xm, ym); } } void AbstractContainerScreen::renderTooltip( - const std::vector& lines, int mouseX, int mouseY) { + const std::vector& lines, int xm, int ym) { if (lines.empty()) return; std::vector cleanedLines = lines; @@ -260,12 +260,12 @@ void AbstractContainerScreen::renderTooltip( } } - renderTooltipInternal(cleanedLines, lineColors, mouseX, mouseY); + renderTooltipInternal(cleanedLines, lineColors, xm, ym); } -void AbstractContainerScreen::renderTooltip(const std::wstring& line, - int mouseX, int mouseY) { - renderTooltip(std::vector{line}, mouseX, mouseY); +void AbstractContainerScreen::renderTooltip(const std::wstring& line, int xm, + int ym) { + renderTooltip(std::vector{line}, xm, ym); } void AbstractContainerScreen::renderLabels() {} diff --git a/Minecraft.Client/UI/Screens/AbstractContainerScreen.h b/Minecraft.Client/UI/Screens/AbstractContainerScreen.h index 72f774ef6..462e178d5 100644 --- a/Minecraft.Client/UI/Screens/AbstractContainerScreen.h +++ b/Minecraft.Client/UI/Screens/AbstractContainerScreen.h @@ -36,9 +36,9 @@ protected: // used in other places virtual void renderTooltipInternal( const std::vector& cleanedLines, - const std::vector& lineColors, int mouseX, int mouseY); - virtual void renderTooltip(std::shared_ptr item, int x, - int y); + const std::vector& lineColors, int xm, int ym); + virtual void renderTooltip(std::shared_ptr item, int xm, + int ym); private: virtual void renderSlot(Slot* slot); @@ -55,7 +55,7 @@ public: virtual void tick() override; // 4jcraft: 1.6.x era overloads - virtual void renderTooltip(const std::vector& lines, int x, - int y); - virtual void renderTooltip(const std::wstring& line, int x, int y); + virtual void renderTooltip(const std::vector& lines, int xm, + int ym); + virtual void renderTooltip(const std::wstring& line, int xm, int ym); }; diff --git a/Minecraft.Client/UI/Screens/CreativeInventoryScreen.cpp b/Minecraft.Client/UI/Screens/CreativeInventoryScreen.cpp index 30f0d068c..f2773df8f 100644 --- a/Minecraft.Client/UI/Screens/CreativeInventoryScreen.cpp +++ b/Minecraft.Client/UI/Screens/CreativeInventoryScreen.cpp @@ -90,8 +90,8 @@ bool CreativeInventoryScreen::ContainerCreative::stillValid( std::shared_ptr CreativeInventoryScreen::ContainerCreative::clicked( - int slotIndex, int buttonNum, int clickType, - std::shared_ptr player) { + int slotIndex, int buttonNum, int clickType, std::shared_ptr player, + bool looped) { std::shared_ptr inventory = player->inventory; std::shared_ptr carried = inventory->getCarried(); diff --git a/Minecraft.Client/UI/Screens/CreativeInventoryScreen.h b/Minecraft.Client/UI/Screens/CreativeInventoryScreen.h index 6a4ba7847..f4f6004fa 100644 --- a/Minecraft.Client/UI/Screens/CreativeInventoryScreen.h +++ b/Minecraft.Client/UI/Screens/CreativeInventoryScreen.h @@ -51,10 +51,10 @@ public: std::vector> itemList; ContainerCreative(std::shared_ptr player); - virtual bool stillValid(std::shared_ptr player); + virtual bool stillValid(std::shared_ptr player) override; virtual std::shared_ptr clicked( int slotIndex, int buttonNum, int clickType, - std::shared_ptr player); + std::shared_ptr player, bool looped = false) override; void scrollTo(float pos); bool canScroll(); }; From ad67f4be71255a77df93afffe07a1ea5271224b2 Mon Sep 17 00:00:00 2001 From: Tropical <42101043+tropicaaal@users.noreply.github.com> Date: Sun, 29 Mar 2026 15:41:46 -0500 Subject: [PATCH 087/170] refactor: configure classic panorama at compile-time --- Minecraft.Assets/Common/res/lang/en_US.lang | 1 - Minecraft.Client/GameState/Options.cpp | 18 +- Minecraft.Client/GameState/Options.h | 4 +- Minecraft.Client/UI/Screens/TitleScreen.cpp | 353 +++++++++--------- .../UI/Screens/VideoSettingsScreen.cpp | 3 +- Minecraft.Client/meson.build | 4 + meson.options | 5 + 7 files changed, 188 insertions(+), 200 deletions(-) diff --git a/Minecraft.Assets/Common/res/lang/en_US.lang b/Minecraft.Assets/Common/res/lang/en_US.lang index 890a2f576..44040b2b7 100644 --- a/Minecraft.Assets/Common/res/lang/en_US.lang +++ b/Minecraft.Assets/Common/res/lang/en_US.lang @@ -189,7 +189,6 @@ options.renderDistance.short=Short options.renderDistance.normal=Normal options.renderDistance.far=Far options.viewBobbing=View Bobbing -options.classicPanorama=Classic Panorama options.ao=Smooth Lighting options.anaglyph=3D Anaglyph options.framerateLimit=Performance diff --git a/Minecraft.Client/GameState/Options.cpp b/Minecraft.Client/GameState/Options.cpp index 3f6f4e4b1..07549b5c4 100644 --- a/Minecraft.Client/GameState/Options.cpp +++ b/Minecraft.Client/GameState/Options.cpp @@ -16,7 +16,7 @@ // 4J - the Option sub-class used to be an java enumerated type, trying to // emulate that functionality here -const Options::Option Options::Option::options[18] = { +const Options::Option Options::Option::options[17] = { Options::Option(L"options.music", true, false), Options::Option(L"options.sound", true, false), Options::Option(L"options.invertMouse", false, true), @@ -34,7 +34,6 @@ const Options::Option Options::Option::options[18] = { Options::Option(L"options.gamma", true, false), Options::Option(L"options.renderClouds", false, true), Options::Option(L"options.particles", false, false), - Options::Option(L"options.classicPanorama", false, true), }; const Options::Option* Options::Option::MUSIC = &Options::Option::options[0]; @@ -66,8 +65,6 @@ const Options::Option* Options::Option::RENDER_CLOUDS = &Options::Option::options[15]; const Options::Option* Options::Option::PARTICLES = &Options::Option::options[16]; -const Options::Option* Options::Option::CLASSIC_PANORAMA = - &(Options::Option::options[17]); const Options::Option* Options::Option::getItem(int id) { return &options[id]; } @@ -114,8 +111,6 @@ void Options::init() { invertYMouse = false; viewDistance = 0; bobView = true; - // 4jcraft - classicPanorama = false; anaglyph3d = false; advancedOpengl = false; @@ -245,10 +240,6 @@ void Options::toggle(const Options::Option* option, int dir) { // 4J-PB - changing // 4jcraft: uncommented this so that the view bobbing option works if (option == Option::VIEW_BOBBING) bobView = !bobView; - // 4jcraft - if (option == Option::CLASSIC_PANORAMA) { - classicPanorama = !classicPanorama; - } if (option == Option::RENDER_CLOUDS) renderClouds = !renderClouds; if (option == Option::ADVANCED_OPENGL) { advancedOpengl = !advancedOpengl; @@ -301,8 +292,6 @@ bool Options::getBooleanValue(const Options::Option* item) { // types if (item == Option::INVERT_MOUSE) return invertYMouse; if (item == Option::VIEW_BOBBING) return bobView; - // 4jcraft - if (item == Option::CLASSIC_PANORAMA) return classicPanorama; if (item == Option::ANAGLYPH) return anaglyph3d; if (item == Option::ADVANCED_OPENGL) return advancedOpengl; if (item == Option::AMBIENT_OCCLUSION) return ambientOcclusion; @@ -415,8 +404,6 @@ void Options::load() { if (cmds[0] == L"guiScale") guiScale = _fromString(cmds[1]); if (cmds[0] == L"particles") particles = _fromString(cmds[1]); if (cmds[0] == L"bobView") bobView = cmds[1] == L"true"; - // 4jcraft - if (cmds[0] == L"classicPanorama") classicPanorama = cmds[1] == L"true"; if (cmds[0] == L"anaglyph3d") anaglyph3d = cmds[1] == L"true"; if (cmds[0] == L"advancedOpengl") advancedOpengl = cmds[1] == L"true"; if (cmds[0] == L"fpsLimit") framerateLimit = _fromString(cmds[1]); @@ -471,9 +458,6 @@ void Options::save() { dos.writeChars(L"guiScale:" + _toString(guiScale)); dos.writeChars(L"particles:" + _toString(particles)); dos.writeChars(L"bobView:" + std::wstring(bobView ? L"true" : L"false")); - // 4jcraft - dos.writeChars(L"classicPanorama:" + - std::wstring(classicPanorama ? L"true" : L"false")); dos.writeChars(L"anaglyph3d:" + std::wstring(anaglyph3d ? L"true" : L"false")); dos.writeChars(L"advancedOpengl:" + diff --git a/Minecraft.Client/GameState/Options.h b/Minecraft.Client/GameState/Options.h index bb84fc759..b727da4a0 100644 --- a/Minecraft.Client/GameState/Options.h +++ b/Minecraft.Client/GameState/Options.h @@ -13,7 +13,7 @@ public: // 4J - this used to be an enum class Option { public: - static const Option options[18]; + static const Option options[17]; static const Option* MUSIC; static const Option* SOUND; static const Option* INVERT_MOUSE; @@ -31,7 +31,6 @@ public: static const Option* GAMMA; static const Option* RENDER_CLOUDS; static const Option* PARTICLES; - static const Option* CLASSIC_PANORAMA; private: const bool _isProgress; @@ -62,7 +61,6 @@ public: bool invertYMouse; int viewDistance; bool bobView; - bool classicPanorama; bool anaglyph3d; bool advancedOpengl; int framerateLimit; diff --git a/Minecraft.Client/UI/Screens/TitleScreen.cpp b/Minecraft.Client/UI/Screens/TitleScreen.cpp index 650d49af8..8aac613d5 100644 --- a/Minecraft.Client/UI/Screens/TitleScreen.cpp +++ b/Minecraft.Client/UI/Screens/TitleScreen.cpp @@ -164,204 +164,203 @@ void TitleScreen::buttonClicked(Button* button) { // method void TitleScreen::renderPanorama(float a) { #ifdef ENABLE_JAVA_GUIS + Tesselator* t = Tesselator::getInstance(); - if (minecraft->options->classicPanorama) { - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - glLoadIdentity(); - gluPerspective(120.0f, 1.0f, 0.05f, 10.0f); - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - glLoadIdentity(); - glColor4f(1.0f, 1.0f, 1.0f, 1.0f); - glRotatef(180.0f, 1.0f, 0.0f, 0.0f); - glEnable(GL_BLEND); - glDisable(GL_ALPHA_TEST); - glDisable(GL_CULL_FACE); - glDepthMask(false); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - char offsetPasses = 8; +#ifdef CLASSIC_PANORAMA + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + gluPerspective(120.0f, 1.0f, 0.05f, 10.0f); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + glColor4f(1.0f, 1.0f, 1.0f, 1.0f); + glRotatef(180.0f, 1.0f, 0.0f, 0.0f); + glEnable(GL_BLEND); + glDisable(GL_ALPHA_TEST); + glDisable(GL_CULL_FACE); + glDepthMask(false); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + char offsetPasses = 8; - for (int i = 0; i < (offsetPasses * offsetPasses); i++) { + for (int i = 0; i < (offsetPasses * offsetPasses); i++) { + glPushMatrix(); + float x = + ((float)(i % offsetPasses) / (float)offsetPasses - 0.5f) / 64.0f; + float y = + ((float)(i / offsetPasses) / (float)offsetPasses - 0.5f) / 64.0f; + float z = 0.0f; + glTranslatef(x, y, z); + glRotatef(sin((vo + a) / 400.0f) * 25.0f + 20.0f, 1.0f, 0.0f, 0.0f); + glRotatef(-(vo + a) * 0.1f, 0.0f, 1.0f, 0.0f); + + for (int j = 0; j < 6; j++) { glPushMatrix(); - float x = ((float)(i % offsetPasses) / (float)offsetPasses - 0.5f) / - 64.0f; - float y = ((float)(i / offsetPasses) / (float)offsetPasses - 0.5f) / - 64.0f; - float z = 0.0f; - glTranslatef(x, y, z); - glRotatef(sin((vo + a) / 400.0f) * 25.0f + 20.0f, 1.0f, 0.0f, 0.0f); - glRotatef(-(vo + a) * 0.1f, 0.0f, 1.0f, 0.0f); - for (int j = 0; j < 6; j++) { - glPushMatrix(); - - switch (j) { - case 1: - glRotatef(90.0f, 0.0f, 1.0f, 0.0f); - break; - case 2: - glRotatef(180.0f, 0.0f, 1.0f, 0.0f); - break; - case 3: - glRotatef(-90.0f, 0.0f, 1.0f, 0.0f); - break; - case 4: - glRotatef(90.0f, 1.0f, 0.0f, 0.0f); - break; - case 5: - glRotatef(-90.0f, 1.0f, 0.0f, 0.0f); - break; - default: - break; - } - - glBindTexture(GL_TEXTURE_2D, minecraft->textures->loadTexture( - TN_TITLE_BG_PANORAMA0 + j)); - t->begin(); - t->color(16777215, 255 / (i + 1)); - t->vertexUV(-1.0f, -1.0f, 1.0f, 0.0f, 0.0f); - t->vertexUV(1.0f, -1.0f, 1.0f, 1.0f, 0.0f); - t->vertexUV(1.0f, 1.0f, 1.0f, 1.0f, 1.0f); - t->vertexUV(-1.0f, 1.0f, 1.0f, 0.0f, 1.0f); - t->end(); - glPopMatrix(); + switch (j) { + case 1: + glRotatef(90.0f, 0.0f, 1.0f, 0.0f); + break; + case 2: + glRotatef(180.0f, 0.0f, 1.0f, 0.0f); + break; + case 3: + glRotatef(-90.0f, 0.0f, 1.0f, 0.0f); + break; + case 4: + glRotatef(90.0f, 1.0f, 0.0f, 0.0f); + break; + case 5: + glRotatef(-90.0f, 1.0f, 0.0f, 0.0f); + break; + default: + break; } + + glBindTexture(GL_TEXTURE_2D, minecraft->textures->loadTexture( + TN_TITLE_BG_PANORAMA0 + j)); + t->begin(); + t->color(16777215, 255 / (i + 1)); + t->vertexUV(-1.0f, -1.0f, 1.0f, 0.0f, 0.0f); + t->vertexUV(1.0f, -1.0f, 1.0f, 1.0f, 0.0f); + t->vertexUV(1.0f, 1.0f, 1.0f, 1.0f, 1.0f); + t->vertexUV(-1.0f, 1.0f, 1.0f, 0.0f, 1.0f); + t->end(); glPopMatrix(); - glColorMask(true, true, true, false); } - - t->offset(0.0f, 0.0f, 0.0f); - glColorMask(true, true, true, true); - glMatrixMode(GL_PROJECTION); - glPopMatrix(); - glMatrixMode(GL_MODELVIEW); - glPopMatrix(); - glDepthMask(true); - glEnable(GL_CULL_FACE); - glEnable(GL_ALPHA_TEST); - glEnable(GL_DEPTH_TEST); - } else { - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - glLoadIdentity(); - glOrtho(0, width, height, 0, 1000, 3000); - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - glLoadIdentity(); - glTranslatef(0, 0, -2000); - - glDisable(GL_LIGHTING); - glDisable(GL_FOG); - glEnable(GL_TEXTURE_2D); - glDisable(GL_ALPHA_TEST); - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glDepthMask(false); - - glBindTexture(GL_TEXTURE_2D, - minecraft->textures->loadTexture(TN_TITLE_BG_PANORAMA)); - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - - float off = vo * 0.0004f; - - float screenAspect = (float)width / (float)height; - float texAspect = 1748.0f / 144.0f; - float scale; - if (screenAspect > texAspect) { - scale = (float)width / 1748.0f; - } else { - scale = (float)height / 144.0f; - } - - float texWidth = 1748.0f * scale; - float texHeight = 144.0f * scale; - float yOff = (height - texHeight) / 2.0f; - - float uMax = off + (texWidth / 1748.0f); - - t->begin(GL_QUADS); - t->color(0xffffff, 255); - t->vertexUV(0, yOff + texHeight, 0, off, 1.0f); - t->vertexUV(texWidth, yOff + texHeight, 0, uMax, 1.0f); - t->vertexUV(texWidth, yOff, 0, uMax, 0.0f); - t->vertexUV(0, yOff, 0, off, 0.0f); - t->end(); - - glDepthMask(true); - glDisable(GL_BLEND); - glEnable(GL_ALPHA_TEST); - glMatrixMode(GL_PROJECTION); - glPopMatrix(); - glMatrixMode(GL_MODELVIEW); glPopMatrix(); + glColorMask(true, true, true, false); } + + t->offset(0.0f, 0.0f, 0.0f); + glColorMask(true, true, true, true); + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + glDepthMask(true); + glEnable(GL_CULL_FACE); + glEnable(GL_ALPHA_TEST); + glEnable(GL_DEPTH_TEST); +#else + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + glOrtho(0, width, height, 0, 1000, 3000); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + glTranslatef(0, 0, -2000); + + glDisable(GL_LIGHTING); + glDisable(GL_FOG); + glEnable(GL_TEXTURE_2D); + glDisable(GL_ALPHA_TEST); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glDepthMask(false); + + glBindTexture(GL_TEXTURE_2D, + minecraft->textures->loadTexture(TN_TITLE_BG_PANORAMA)); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + float off = vo * 0.0004f; + + float screenAspect = (float)width / (float)height; + float texAspect = 1748.0f / 144.0f; + float scale; + if (screenAspect > texAspect) { + scale = (float)width / 1748.0f; + } else { + scale = (float)height / 144.0f; + } + + float texWidth = 1748.0f * scale; + float texHeight = 144.0f * scale; + float yOff = (height - texHeight) / 2.0f; + + float uMax = off + (texWidth / 1748.0f); + + t->begin(GL_QUADS); + t->color(0xffffff, 255); + t->vertexUV(0, yOff + texHeight, 0, off, 1.0f); + t->vertexUV(texWidth, yOff + texHeight, 0, uMax, 1.0f); + t->vertexUV(texWidth, yOff, 0, uMax, 0.0f); + t->vertexUV(0, yOff, 0, off, 0.0f); + t->end(); + + glDepthMask(true); + glDisable(GL_BLEND); + glEnable(GL_ALPHA_TEST); + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); +#endif #endif } // 4jcraft void TitleScreen::renderSkybox(float a) { #ifdef ENABLE_JAVA_GUIS - if (minecraft->options->classicPanorama) { - glViewport(0, 0, 256, 256); - } +#ifdef CLASSIC_PANORAMA + glViewport(0, 0, 256, 256); +#endif renderPanorama(a); - if (minecraft->options->classicPanorama) { - glDisable(GL_TEXTURE_2D); - glEnable(GL_TEXTURE_2D); +#ifdef CLASSIC_PANORAMA + glDisable(GL_TEXTURE_2D); + glEnable(GL_TEXTURE_2D); - for (int i = 0; i < 8; i++) { - rotateAndBlur(a); - } - - glViewport(0, 0, minecraft->width, minecraft->height); - - Tesselator* t = Tesselator::getInstance(); - t->begin(); - float aspect = - width > height ? 120.0f / (float)width : 120.0f / (float)height; - float sWidth = (float)height * aspect / 256.0f; - float sHeight = (float)width * aspect / 256.0f; - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - t->color(1.0f, 1.0f, 1.0f, 1.0f); - t->vertexUV(0.0f, height, 0.0f, (0.5f - sWidth), (0.5f + sHeight)); - t->vertexUV(width, height, 0.0f, (0.5f - sWidth), (0.5f - sHeight)); - t->vertexUV(width, 0.0f, 0.0f, (0.5f + sWidth), (0.5f - sHeight)); - t->vertexUV(0.0f, 0.0f, 0.0f, (0.5f + sWidth), (0.5f + sHeight)); - t->end(); + for (int i = 0; i < 8; i++) { + rotateAndBlur(a); } + + glViewport(0, 0, minecraft->width, minecraft->height); + + Tesselator* t = Tesselator::getInstance(); + t->begin(); + float aspect = + width > height ? 120.0f / (float)width : 120.0f / (float)height; + float sWidth = (float)height * aspect / 256.0f; + float sHeight = (float)width * aspect / 256.0f; + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + t->color(1.0f, 1.0f, 1.0f, 1.0f); + t->vertexUV(0.0f, height, 0.0f, (0.5f - sWidth), (0.5f + sHeight)); + t->vertexUV(width, height, 0.0f, (0.5f - sWidth), (0.5f - sHeight)); + t->vertexUV(width, 0.0f, 0.0f, (0.5f + sWidth), (0.5f - sHeight)); + t->vertexUV(0.0f, 0.0f, 0.0f, (0.5f + sWidth), (0.5f + sHeight)); + t->end(); +#endif #endif } // 4jcraft void TitleScreen::rotateAndBlur(float a) { -#ifdef ENABLE_JAVA_GUIS - if (minecraft->options->classicPanorama) { - glBindTexture(GL_TEXTURE_2D, viewportTexture); - glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 256, 256); - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glColorMask(true, true, true, false); - Tesselator* t = Tesselator::getInstance(); - t->begin(); - char blurPasses = 3; +#if defined(ENABLE_JAVA_GUIS) && defined(CLASSIC_PANORAMA) + glBindTexture(GL_TEXTURE_2D, viewportTexture); + glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 256, 256); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glColorMask(true, true, true, false); + Tesselator* t = Tesselator::getInstance(); + t->begin(); + char blurPasses = 3; - for (int i = 0; i < blurPasses; i++) { - t->color(1.0f, 1.0f, 1.0f, 1.0f / (float)(i + 1)); - float offset = (float)(i - blurPasses / 2) / 256.0f; - t->vertexUV(width, height, 0.0f, (0.0f + offset), 0.0f); - t->vertexUV(width, 0.0f, 0.0f, (1.0f + offset), 0.0f); - t->vertexUV(0.0f, 0.0f, 0.0f, (1.0f + offset), 1.0f); - t->vertexUV(0.0f, height, 0.0f, (0.0f + offset), 1.0f); - } - - t->end(); - glColorMask(true, true, true, true); + for (int i = 0; i < blurPasses; i++) { + t->color(1.0f, 1.0f, 1.0f, 1.0f / (float)(i + 1)); + float offset = (float)(i - blurPasses / 2) / 256.0f; + t->vertexUV(width, height, 0.0f, (0.0f + offset), 0.0f); + t->vertexUV(width, 0.0f, 0.0f, (1.0f + offset), 0.0f); + t->vertexUV(0.0f, 0.0f, 0.0f, (1.0f + offset), 1.0f); + t->vertexUV(0.0f, height, 0.0f, (0.0f + offset), 1.0f); } + + t->end(); + glColorMask(true, true, true, true); #endif } @@ -377,10 +376,10 @@ void TitleScreen::render(int xm, int ym, float a) { int logoY = 30; // 4jcraft: gradient for classic panorama - if (minecraft->options->classicPanorama) { - fillGradient(0, 0, width, height, -2130706433, 16777215); - fillGradient(0, 0, width, height, 0, INT_MIN); - } +#ifdef CLASSIC_PANORAMA + fillGradient(0, 0, width, height, -2130706433, 16777215); + fillGradient(0, 0, width, height, 0, INT_MIN); +#endif glBindTexture(GL_TEXTURE_2D, minecraft->textures->loadTexture(TN_TITLE_MCLOGO)); diff --git a/Minecraft.Client/UI/Screens/VideoSettingsScreen.cpp b/Minecraft.Client/UI/Screens/VideoSettingsScreen.cpp index 4a2777494..d445f0052 100644 --- a/Minecraft.Client/UI/Screens/VideoSettingsScreen.cpp +++ b/Minecraft.Client/UI/Screens/VideoSettingsScreen.cpp @@ -29,8 +29,7 @@ void VideoSettingsScreen::init() { Options::Option::GUI_SCALE, Options::Option::ADVANCED_OPENGL, Options::Option::GAMMA, - Options::Option::FOV, - Options::Option::CLASSIC_PANORAMA}; + Options::Option::FOV}; for (int i = 0; i < ITEM_COUNT; i++) { const Options::Option* item = items[i]; diff --git a/Minecraft.Client/meson.build b/Minecraft.Client/meson.build index 8bcc874b1..9bb614fc4 100644 --- a/Minecraft.Client/meson.build +++ b/Minecraft.Client/meson.build @@ -75,6 +75,10 @@ if get_option('enable_vsync') global_cpp_defs += '-DENABLE_VSYNC' endif +if get_option('classic_panorama') + global_cpp_defs += '-DCLASSIC_PANORAMA' +endif + if get_option('ui_backend') == 'shiggy' shiggy_dep = dependency( 'shiggy', diff --git a/meson.options b/meson.options index 545d2a159..68eb92598 100644 --- a/meson.options +++ b/meson.options @@ -4,6 +4,11 @@ option('ui_backend', value : 'shiggy', description : 'Specifies a backend implementation for the game UI.') +option('classic_panorama', + type : 'boolean', + value : false, + description : 'Enable classic java edition panorama (ui_backend=java ONLY).') + option('enable_vsync', type : 'boolean', value : true, From 238b0019106ebebd74936d28a5e6fdb42ea5f298 Mon Sep 17 00:00:00 2001 From: Tropical <42101043+tropicaaal@users.noreply.github.com> Date: Sun, 29 Mar 2026 15:44:22 -0500 Subject: [PATCH 088/170] fix: remove remaining iggy checkmarks for pano --- .../Platform/Common/UI/UIScene_SettingsOptionsMenu.h | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/Minecraft.Client/Platform/Common/UI/UIScene_SettingsOptionsMenu.h b/Minecraft.Client/Platform/Common/UI/UIScene_SettingsOptionsMenu.h index 6bf721a2d..67c30660d 100644 --- a/Minecraft.Client/Platform/Common/UI/UIScene_SettingsOptionsMenu.h +++ b/Minecraft.Client/Platform/Common/UI/UIScene_SettingsOptionsMenu.h @@ -6,8 +6,6 @@ class UIScene_SettingsOptionsMenu : public UIScene { private: enum EControls { eControl_ViewBob, - // 4jcraft - eControl_ClassicPanorama, eControl_ShowHints, eControl_ShowTooltips, eControl_InGameGamertags, @@ -22,8 +20,8 @@ protected: static int m_iDifficultyTitleSettingA[4]; private: - UIControl_CheckBox m_checkboxViewBob, m_checkboxClassicPanorama, - m_checkboxShowHints, m_checkboxShowTooltips, m_checkboxInGameGamertags, + UIControl_CheckBox m_checkboxViewBob, m_checkboxShowHints, + m_checkboxShowTooltips, m_checkboxInGameGamertags, m_checkboxMashupWorlds; // Checkboxes UIControl_Slider m_sliderAutosave, m_sliderDifficulty; // Sliders UIControl_Label m_labelDifficultyText; // Text @@ -31,8 +29,6 @@ private: UI_BEGIN_MAP_ELEMENTS_AND_NAMES(UIScene) UI_MAP_ELEMENT(m_checkboxViewBob, "ViewBob") - // 4jcraft - UI_MAP_ELEMENT(m_checkboxClassicPanorama, "ClassicPanorama") UI_MAP_ELEMENT(m_checkboxShowHints, "ShowHints") UI_MAP_ELEMENT(m_checkboxShowTooltips, "ShowTooltips") UI_MAP_ELEMENT(m_checkboxInGameGamertags, "InGameGamertags") From 3653b7b465da2b3cff86f1c9ab764a9c6854886f Mon Sep 17 00:00:00 2001 From: Tropical <42101043+tropicaaal@users.noreply.github.com> Date: Sun, 29 Mar 2026 15:50:07 -0500 Subject: [PATCH 089/170] fix: readjust `VideoSettingsScreen` ITEM_COUNT --- Minecraft.Client/UI/Screens/VideoSettingsScreen.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Minecraft.Client/UI/Screens/VideoSettingsScreen.cpp b/Minecraft.Client/UI/Screens/VideoSettingsScreen.cpp index d445f0052..e97aa1f54 100644 --- a/Minecraft.Client/UI/Screens/VideoSettingsScreen.cpp +++ b/Minecraft.Client/UI/Screens/VideoSettingsScreen.cpp @@ -7,7 +7,7 @@ #include "../../../Minecraft.World/Headers/net.minecraft.locale.h" // 4jcraft -#define ITEM_COUNT 11 +#define ITEM_COUNT 10 VideoSettingsScreen::VideoSettingsScreen(Screen* lastScreen, Options* options) { this->title = L"Video Settings"; // 4J - added From a856a7e54e65049217fd326cc65b7f0e289ebcef Mon Sep 17 00:00:00 2001 From: Tropical <42101043+tropicaaal@users.noreply.github.com> Date: Sun, 29 Mar 2026 16:12:30 -0500 Subject: [PATCH 090/170] fix: rebase issue with CreativeInventoryScreen --- Minecraft.Client/UI/Gui.h | 2 +- .../UI/Screens/CreativeInventoryScreen.cpp | 8 ++-- .../UI/Screens/CreativeInventoryScreen.h | 37 +++++++++++-------- 3 files changed, 27 insertions(+), 20 deletions(-) diff --git a/Minecraft.Client/UI/Gui.h b/Minecraft.Client/UI/Gui.h index 2ced840c3..4077c9c40 100644 --- a/Minecraft.Client/UI/Gui.h +++ b/Minecraft.Client/UI/Gui.h @@ -2,9 +2,9 @@ #include #include "GuiComponent.h" #include "GuiMessage.h" +#include "../../../Minecraft.Client/Rendering/EntityRenderers/ItemRenderer.h" class Random; class Minecraft; -class ItemRenderer; class Gui : public GuiComponent { private: diff --git a/Minecraft.Client/UI/Screens/CreativeInventoryScreen.cpp b/Minecraft.Client/UI/Screens/CreativeInventoryScreen.cpp index f2773df8f..ac8481673 100644 --- a/Minecraft.Client/UI/Screens/CreativeInventoryScreen.cpp +++ b/Minecraft.Client/UI/Screens/CreativeInventoryScreen.cpp @@ -70,7 +70,7 @@ CreativeInventoryScreen::ContainerCreative::ContainerCreative( } // Add hotbar slots (9 slots at bottom) - for (int k = 0; k < 9; k++) { + for (int k = 0; k < 9; ++k) { addSlot(new Slot(inventoryplayer, k, 9 + k * 18, 112)); } @@ -181,8 +181,8 @@ void CreativeInventoryScreen::ContainerCreative::scrollTo(float pos) { j = 0; } - for (int k = 0; k < ROWS; k++) { - for (int l = 0; l < COLUMNS; l++) { + for (int k = 0; k < ROWS; ++k) { + for (int l = 0; l < COLUMNS; ++l) { int i1 = l + (k + j) * COLUMNS; if (i1 >= 0 && i1 < (int)itemList.size()) { @@ -484,7 +484,7 @@ void CreativeInventoryScreen::setCurrentCreativeTab(int tab) { IUIScene_CreativeMenu::specs[tab]; // Add items from static groups - for (int i = 0; i < spec->m_staticGroupsCount; i++) { + for (int i = 0; i < spec->m_staticGroupsCount; ++i) { int groupIdx = spec->m_staticGroupsA[i]; if (groupIdx >= 0 && groupIdx < diff --git a/Minecraft.Client/UI/Screens/CreativeInventoryScreen.h b/Minecraft.Client/UI/Screens/CreativeInventoryScreen.h index f4f6004fa..e8fd36877 100644 --- a/Minecraft.Client/UI/Screens/CreativeInventoryScreen.h +++ b/Minecraft.Client/UI/Screens/CreativeInventoryScreen.h @@ -20,7 +20,8 @@ private: static int selectedTabIndex; // Array of item ids for the tab icons - static int tabIconIds[IUIScene_CreativeMenu::eCreativeInventoryTab_COUNT]; + static const int + tabIconIds[IUIScene_CreativeMenu::eCreativeInventoryTab_COUNT]; // Temporary inventory for creative mode items static std::shared_ptr basicInventory; @@ -60,23 +61,29 @@ public: }; public: - CreativeInventoryScreen(std::shared_ptr player); - virtual void removed() override; - virtual void init() override; - virtual void containerTick(); - virtual void tick() override; - virtual void updateEvents() override; - virtual void keyPressed(wchar_t eventCharacter, int eventKey) override; - virtual void mouseClicked(int x, int y, int buttonNum) override; - virtual void mouseReleased(int x, int y, int buttonNum) override; - virtual void render(int xm, int ym, float a) override; + CreativeInventoryScreen(std::shared_ptr player); + virtual void removed() override; + virtual void init() override; + virtual void containerTick(); + virtual void tick() override; + virtual void updateEvents() override; + virtual void keyPressed(wchar_t eventCharacter, int eventKey) override; + virtual void mouseClicked(int x, int y, int buttonNum) override; + virtual void mouseReleased(int x, int y, int buttonNum) override; + virtual void render(int xm, int ym, float a) override; + protected: - virtual void renderLabels() override; - virtual void renderBg(float a) override; + virtual void renderLabels() override; + virtual void renderBg(float a) override; + virtual bool isMouseOverInternal(int tab, int mouseX, int mouseY, int xo, + int yo, int w, int h); + private: void setCurrentCreativeTab(int tab); void selectTab(int tab); bool needsScrollBars(); bool isMouseOverTab(int tab, int mouseX, int mouseY); - void drawTab(int tab); -}; + bool isMouseOverIcon(int tab, int mouseX, int mouseY); + void renderTab(int tab); + bool renderIconTooltip(int tab, int mouseX, int mouseY); +}; \ No newline at end of file From b630ec8800dbed70a9bec99a830ddd1d2c927f23 Mon Sep 17 00:00:00 2001 From: orng Date: Sun, 29 Mar 2026 18:34:00 -0500 Subject: [PATCH 091/170] fix: Vec3 construct wasn't constexpr --- Minecraft.World/Util/Vec3.cpp | 9 --------- Minecraft.World/Util/Vec3.h | 5 +++-- 2 files changed, 3 insertions(+), 11 deletions(-) diff --git a/Minecraft.World/Util/Vec3.cpp b/Minecraft.World/Util/Vec3.cpp index 00718fabe..8119ae772 100644 --- a/Minecraft.World/Util/Vec3.cpp +++ b/Minecraft.World/Util/Vec3.cpp @@ -5,15 +5,6 @@ #include "AABB.h" -Vec3::Vec3(double x, double y, double z) { - if (x == -0.0) x = 0.0; - if (y == -0.0) y = 0.0; - if (z == -0.0) z = 0.0; - this->x = x; - this->y = y; - this->z = z; -} - Vec3 Vec3::vectorTo(const Vec3& p) const { return {p.x - x, p.y - y, p.z - z}; } Vec3 Vec3::normalize() const { diff --git a/Minecraft.World/Util/Vec3.h b/Minecraft.World/Util/Vec3.h index bd470f663..a45cbebec 100644 --- a/Minecraft.World/Util/Vec3.h +++ b/Minecraft.World/Util/Vec3.h @@ -9,8 +9,9 @@ class Vec3 { public: double x, y, z; - Vec3() {} - Vec3(double x, double y, double z); + constexpr Vec3() = default; + constexpr Vec3(const double x, const double y, const double z) + : x(x), y(y), z(z) {} Vec3 vectorTo(const Vec3& p) const; Vec3 normalize() const; From 7062ef756474362793f7d267c9ef0944d726e411 Mon Sep 17 00:00:00 2001 From: orng Date: Sun, 29 Mar 2026 18:40:55 -0500 Subject: [PATCH 092/170] chore: fmt --- Minecraft.Client/Rendering/Cube.cpp | 13 ++++++------- Minecraft.Client/Rendering/Polygon.cpp | 7 +++---- Minecraft.Client/Rendering/Polygon.h | 3 ++- Minecraft.Client/Rendering/Vertex.h | 16 +++------------- 4 files changed, 14 insertions(+), 25 deletions(-) diff --git a/Minecraft.Client/Rendering/Cube.cpp b/Minecraft.Client/Rendering/Cube.cpp index 2291d0923..b091fa158 100644 --- a/Minecraft.Client/Rendering/Cube.cpp +++ b/Minecraft.Client/Rendering/Cube.cpp @@ -21,7 +21,7 @@ Cube::Cube(ModelPart* modelPart, int xTexOffs, int yTexOffs, float x0, float y0, Vertex{0, 0, 0, 0, 0}, Vertex{0, 0, 0, 0, 0}, Vertex{0, 0, 0, 0, 0}, Vertex{0, 0, 0, 0, 0}, Vertex{0, 0, 0, 0, 0}, Vertex{0, 0, 0, 0, 0}}), - polygons({}) { + polygons({}) { float x1 = x0 + w; float y1 = y0 + h; float z1 = z0 + d; @@ -89,10 +89,10 @@ Cube::Cube(ModelPart* modelPart, int xTexOffs, int yTexOffs, float x0, float y0, modelPart->xTexSize, modelPart->yTexSize); // Down } if (faceMask & 16) - polygons[faceCount++] = _Polygon( - std::array{u1, u0, u3, u2}, xTexOffs + d, - yTexOffs + d, xTexOffs + d + w, yTexOffs + d + h, - modelPart->xTexSize, modelPart->yTexSize); // Front + polygons[faceCount++] = + _Polygon(std::array{u1, u0, u3, u2}, xTexOffs + d, + yTexOffs + d, xTexOffs + d + w, yTexOffs + d + h, + modelPart->xTexSize, modelPart->yTexSize); // Front if (faceMask & 32) polygons[faceCount++] = _Polygon( std::array{l0, l1, l2, l3}, xTexOffs + d + w + d, @@ -101,8 +101,7 @@ Cube::Cube(ModelPart* modelPart, int xTexOffs, int yTexOffs, float x0, float y0, modelPart->yTexSize); // Back if (modelPart->bMirror) { - for (unsigned int i = 0; i < polygons.size(); i++) - polygons[i].mirror(); + for (unsigned int i = 0; i < polygons.size(); i++) polygons[i].mirror(); } } diff --git a/Minecraft.Client/Rendering/Polygon.cpp b/Minecraft.Client/Rendering/Polygon.cpp index bcfa26b37..d0de18504 100644 --- a/Minecraft.Client/Rendering/Polygon.cpp +++ b/Minecraft.Client/Rendering/Polygon.cpp @@ -5,7 +5,8 @@ #include _Polygon::_Polygon(const std::span vertices) - : vertexCount(vertices.size()), vertices(vertices.begin(), vertices.end()) {} + : vertexCount(vertices.size()), + vertices(vertices.begin(), vertices.end()) {} _Polygon::_Polygon(const std::span vertices, int u0, int v0, int u1, int v1, float xTexSize, float yTexSize) @@ -32,9 +33,7 @@ _Polygon::_Polygon(const std::span vertices, float u0, vertices[3].remap(u1, v1), }) {} -void _Polygon::mirror() { - std::reverse(vertices.begin(), vertices.end()); -} +void _Polygon::mirror() { std::reverse(vertices.begin(), vertices.end()); } void _Polygon::render(Tesselator* t, float scale) { Vec3 v0 = vertices[1].pos.vectorTo(vertices[0].pos); diff --git a/Minecraft.Client/Rendering/Polygon.h b/Minecraft.Client/Rendering/Polygon.h index a9ecf5638..c56306533 100644 --- a/Minecraft.Client/Rendering/Polygon.h +++ b/Minecraft.Client/Rendering/Polygon.h @@ -19,7 +19,8 @@ public: _Polygon(std::span vertices); _Polygon(std::span vertices, int u0, int v0, int u1, int v1, float xTexSize, float yTexSize); - _Polygon(std::span vertices, float u0, float v0, float u1, float v1); + _Polygon(std::span vertices, float u0, float v0, float u1, + float v1); void mirror(); void render(Tesselator* t, float scale); _Polygon* flipNormal(); diff --git a/Minecraft.Client/Rendering/Vertex.h b/Minecraft.Client/Rendering/Vertex.h index 7a175011f..b0437b9ba 100644 --- a/Minecraft.Client/Rendering/Vertex.h +++ b/Minecraft.Client/Rendering/Vertex.h @@ -8,22 +8,12 @@ public: public: constexpr Vertex(float x, float y, float z, float u, float v) - : pos({x, y, z}) - , u(u) - , v(v) - {} + : pos({x, y, z}), u(u), v(v) {} constexpr Vertex(Vertex* vertex, float u, float v) - : pos(vertex->pos) - , u(u) - , v(v) - {} + : pos(vertex->pos), u(u), v(v) {} - constexpr Vertex(Vec3* pos, float u, float v) - : pos(*pos) - , u(u) - , v(v) - {} + constexpr Vertex(Vec3* pos, float u, float v) : pos(*pos), u(u), v(v) {} Vertex remap(float u, float v) const; }; From ceea5c356c696f27c13070fbba053d029200ddad Mon Sep 17 00:00:00 2001 From: Tropical <42101043+tropicaaal@users.noreply.github.com> Date: Sun, 29 Mar 2026 19:09:50 -0500 Subject: [PATCH 093/170] guh 1 --- .github/workflows/build-linux.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-linux.yml b/.github/workflows/build-linux.yml index acec27a69..83a05bb33 100644 --- a/.github/workflows/build-linux.yml +++ b/.github/workflows/build-linux.yml @@ -1,11 +1,12 @@ -name: Build (Linux x86/64) +name: Build (Linux, x86-64) on: push: - "**.cpp" - "**.h" - "**.meson.build" - - ".github/workflows/*" + - '.github/workflows/build-linux.yml' + jobs: build-linux: From d669174ecdd22de1627844178d0bcbb1fefac98a Mon Sep 17 00:00:00 2001 From: Tropical <42101043+tropicaaal@users.noreply.github.com> Date: Sun, 29 Mar 2026 19:11:32 -0500 Subject: [PATCH 094/170] guh 2 --- .github/workflows/build-linux.yml | 11 ++++++----- .github/workflows/clang-format.yml | 11 ++++++----- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/.github/workflows/build-linux.yml b/.github/workflows/build-linux.yml index 83a05bb33..14697e934 100644 --- a/.github/workflows/build-linux.yml +++ b/.github/workflows/build-linux.yml @@ -2,10 +2,11 @@ name: Build (Linux, x86-64) on: push: - - "**.cpp" - - "**.h" - - "**.meson.build" - - '.github/workflows/build-linux.yml' + paths: + - "**.cpp" + - "**.h" + - "**.meson.build" + - '.github/workflows/*' jobs: @@ -13,7 +14,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout repository - uses: actions/checkout@v5 + uses: actions/checkout@v6 - name: Install Nix uses: cachix/install-nix-action@v31 diff --git a/.github/workflows/clang-format.yml b/.github/workflows/clang-format.yml index ed5f9a402..befc1e792 100644 --- a/.github/workflows/clang-format.yml +++ b/.github/workflows/clang-format.yml @@ -1,11 +1,12 @@ -name: Clang-Format (Linux x86/64) +name: Clang-Format (Linux, x86-64) on: push: - - "**.cpp" - - "**.h" - - "**.meson.build" - - ".github/workflows/*" + paths: + - "**.cpp" + - "**.h" + - "**.meson.build" + - ".github/workflows/*" jobs: formatting-check: From 80ca9142ef9081584a7a8a591c9cfc9da7131338 Mon Sep 17 00:00:00 2001 From: Tropical <42101043+tropicaaal@users.noreply.github.com> Date: Sun, 29 Mar 2026 19:14:35 -0500 Subject: [PATCH 095/170] guh 3 --- .github/workflows/build-linux.yml | 19 +++++++++++++------ .github/workflows/clang-format.yml | 18 +++++++++++++----- 2 files changed, 26 insertions(+), 11 deletions(-) diff --git a/.github/workflows/build-linux.yml b/.github/workflows/build-linux.yml index 14697e934..5729f6e2e 100644 --- a/.github/workflows/build-linux.yml +++ b/.github/workflows/build-linux.yml @@ -3,10 +3,17 @@ name: Build (Linux, x86-64) on: push: paths: - - "**.cpp" - - "**.h" + - '**.cpp' + - '**.h' + - '**.c' + - '**.cc' + - '**.cxx' + - '**.hh' + - '**.hpp' + - '**.hxx' + - '**.inl' - "**.meson.build" - - '.github/workflows/*' + - '.github/workflows/build-linux.yml*' jobs: @@ -21,8 +28,8 @@ jobs: with: nix_path: nixpkgs=channel:nixos-unstable - - name: Build - run: nix build - - name: Flake integrity run: nix flake check + + - name: Build + run: nix build diff --git a/.github/workflows/clang-format.yml b/.github/workflows/clang-format.yml index befc1e792..d51d1ee74 100644 --- a/.github/workflows/clang-format.yml +++ b/.github/workflows/clang-format.yml @@ -1,12 +1,20 @@ -name: Clang-Format (Linux, x86-64) +name: Check Format (Linux, x86-64) on: push: paths: - - "**.cpp" - - "**.h" - - "**.meson.build" - - ".github/workflows/*" + - '**.cpp' + - '**.h' + - '**.c' + - '**.cc' + - '**.cxx' + - '**.hh' + - '**.hpp' + - '**.hxx' + - '**.inl' + - '.clang-format' + - '.github/workflows/clang-format.yml' + - '.github/scripts/check-clang-format.sh' jobs: formatting-check: From 23452bf1292888dd72791949018bfe4e39497985 Mon Sep 17 00:00:00 2001 From: Tropical <42101043+tropicaaal@users.noreply.github.com> Date: Sun, 29 Mar 2026 19:15:53 -0500 Subject: [PATCH 096/170] guh 4 --- .github/workflows/build-linux.yml | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build-linux.yml b/.github/workflows/build-linux.yml index 5729f6e2e..2fb11be51 100644 --- a/.github/workflows/build-linux.yml +++ b/.github/workflows/build-linux.yml @@ -14,7 +14,19 @@ on: - '**.inl' - "**.meson.build" - '.github/workflows/build-linux.yml*' - + pull_request: + paths: + - '**.cpp' + - '**.h' + - '**.c' + - '**.cc' + - '**.cxx' + - '**.hh' + - '**.hpp' + - '**.hxx' + - '**.inl' + - "**.meson.build" + - '.github/workflows/build-linux.yml*' jobs: build-linux: From ec2a2b8d1362470e1a19132582ee605feaffa5cd Mon Sep 17 00:00:00 2001 From: Tropical <42101043+tropicaaal@users.noreply.github.com> Date: Sun, 29 Mar 2026 19:16:51 -0500 Subject: [PATCH 097/170] guhhhhhh --- .github/workflows/clang-format.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/clang-format.yml b/.github/workflows/clang-format.yml index d51d1ee74..01da33f84 100644 --- a/.github/workflows/clang-format.yml +++ b/.github/workflows/clang-format.yml @@ -21,7 +21,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout repository - uses: actions/checkout@v5 + uses: actions/checkout@v6 with: fetch-depth: 0 From a66a391225e0e209cb9ffa122a808c82cbc4460d Mon Sep 17 00:00:00 2001 From: orng Date: Sun, 29 Mar 2026 19:45:20 -0500 Subject: [PATCH 098/170] fix: `flake.nix` should include glm --- flake.nix | 1 + 1 file changed, 1 insertion(+) diff --git a/flake.nix b/flake.nix index fd8af4473..2db0000d7 100644 --- a/flake.nix +++ b/flake.nix @@ -100,6 +100,7 @@ openssl.dev libGL libGLU + glm SDL2 zlib ]; From 715f5e1dae3ba2df780c645fd870f280ec8d8b8e Mon Sep 17 00:00:00 2001 From: orng Date: Sun, 29 Mar 2026 19:50:20 -0500 Subject: [PATCH 099/170] fix: `clang-format` should have an `on: pull_request` --- .github/workflows/clang-format.yml | 37 ++++++++++++++++++++---------- 1 file changed, 25 insertions(+), 12 deletions(-) diff --git a/.github/workflows/clang-format.yml b/.github/workflows/clang-format.yml index 01da33f84..4908ef1f9 100644 --- a/.github/workflows/clang-format.yml +++ b/.github/workflows/clang-format.yml @@ -3,18 +3,31 @@ name: Check Format (Linux, x86-64) on: push: paths: - - '**.cpp' - - '**.h' - - '**.c' - - '**.cc' - - '**.cxx' - - '**.hh' - - '**.hpp' - - '**.hxx' - - '**.inl' - - '.clang-format' - - '.github/workflows/clang-format.yml' - - '.github/scripts/check-clang-format.sh' + - "**.cpp" + - "**.h" + - "**.c" + - "**.cc" + - "**.cxx" + - "**.hh" + - "**.hpp" + - "**.hxx" + - "**.inl" + - ".clang-format" + - ".github/workflows/clang-format.yml" + - ".github/scripts/check-clang-format.sh" + pull_request: + paths: + - "**.cpp" + - "**.h" + - "**.c" + - "**.cc" + - "**.cxx" + - "**.hh" + - "**.hpp" + - "**.hxx" + - "**.inl" + - "**.meson.build" + - ".github/workflows/clang-format.yml*" jobs: formatting-check: From aafc823c75cdc3bbaffa48b30417748dc28b293f Mon Sep 17 00:00:00 2001 From: Tropical <42101043+tropicaaal@users.noreply.github.com> Date: Sun, 29 Mar 2026 19:52:44 -0500 Subject: [PATCH 100/170] fix: --print-build-logs --- .github/workflows/build-linux.yml | 47 +++++++++++------------------- .github/workflows/clang-format.yml | 29 +++++++++--------- 2 files changed, 31 insertions(+), 45 deletions(-) diff --git a/.github/workflows/build-linux.yml b/.github/workflows/build-linux.yml index 2fb11be51..11e6eed3b 100644 --- a/.github/workflows/build-linux.yml +++ b/.github/workflows/build-linux.yml @@ -1,32 +1,19 @@ name: Build (Linux, x86-64) -on: - push: - paths: - - '**.cpp' - - '**.h' - - '**.c' - - '**.cc' - - '**.cxx' - - '**.hh' - - '**.hpp' - - '**.hxx' - - '**.inl' - - "**.meson.build" - - '.github/workflows/build-linux.yml*' - pull_request: - paths: - - '**.cpp' - - '**.h' - - '**.c' - - '**.cc' - - '**.cxx' - - '**.hh' - - '**.hpp' - - '**.hxx' - - '**.inl' - - "**.meson.build" - - '.github/workflows/build-linux.yml*' +on: [push, pull_request] + paths: + - '**.cpp' + - '**.h' + - '**.c' + - '**.cc' + - '**.cxx' + - '**.hh' + - '**.hpp' + - '**.hxx' + - '**.inl' + - "**meson.build" + - "flake.nix" + - '.github/workflows/build-linux.yml' jobs: build-linux: @@ -40,8 +27,8 @@ jobs: with: nix_path: nixpkgs=channel:nixos-unstable + - name: Build + run: nix build --print-build-logs + - name: Flake integrity run: nix flake check - - - name: Build - run: nix build diff --git a/.github/workflows/clang-format.yml b/.github/workflows/clang-format.yml index 01da33f84..6aab5fd76 100644 --- a/.github/workflows/clang-format.yml +++ b/.github/workflows/clang-format.yml @@ -1,20 +1,19 @@ name: Check Format (Linux, x86-64) -on: - push: - paths: - - '**.cpp' - - '**.h' - - '**.c' - - '**.cc' - - '**.cxx' - - '**.hh' - - '**.hpp' - - '**.hxx' - - '**.inl' - - '.clang-format' - - '.github/workflows/clang-format.yml' - - '.github/scripts/check-clang-format.sh' +on: [push, pull_request] + paths: + - '**.cpp' + - '**.h' + - '**.c' + - '**.cc' + - '**.cxx' + - '**.hh' + - '**.hpp' + - '**.hxx' + - '**.inl' + - "**meson.build" + - "flake.nix" + - '.github/workflows/build-linux.yml' jobs: formatting-check: From 43908b1de581668f52b289af9d7cf45a20b6451b Mon Sep 17 00:00:00 2001 From: Tropical <42101043+tropicaaal@users.noreply.github.com> Date: Sun, 29 Mar 2026 19:54:51 -0500 Subject: [PATCH 101/170] Update clang-format.yml --- .github/workflows/clang-format.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/clang-format.yml b/.github/workflows/clang-format.yml index 4a01c2676..c099cd110 100644 --- a/.github/workflows/clang-format.yml +++ b/.github/workflows/clang-format.yml @@ -1,4 +1,4 @@ -name: Check Format (Linux, x86-64) +name: Format Check (Linux, x86-64) on: [push, pull_request] paths: From 39ebddbafcac7182de58dedeebff8cc1727b2fac Mon Sep 17 00:00:00 2001 From: Tropical <42101043+tropicaaal@users.noreply.github.com> Date: Sun, 29 Mar 2026 20:04:19 -0500 Subject: [PATCH 102/170] update format workflow --- .github/workflows/clang-format.yml | 49 +++++++++++++++++++++--------- 1 file changed, 34 insertions(+), 15 deletions(-) diff --git a/.github/workflows/clang-format.yml b/.github/workflows/clang-format.yml index c099cd110..2bf8ec762 100644 --- a/.github/workflows/clang-format.yml +++ b/.github/workflows/clang-format.yml @@ -1,4 +1,4 @@ -name: Format Check (Linux, x86-64) +name: Format on: [push, pull_request] paths: @@ -11,23 +11,42 @@ on: [push, pull_request] - '**.hpp' - '**.hxx' - '**.inl' - - "**meson.build" - - "flake.nix" - - ".clang-format" - - '.github/workflows/build-linux.yml' - - ".github/scripts/check-clang-format.sh" + - '.clang-format' + - '.github/workflows/clang-format.yml' + - '.github/scripts/check-clang-format.sh' jobs: - formatting-check: + clang-format: runs-on: ubuntu-latest + concurrency: + group: clang-format-${{ github.ref }} + cancel-in-progress: true steps: - name: Checkout repository - uses: actions/checkout@v6 - with: - fetch-depth: 0 + uses: actions/checkout@v4 - - name: Run clang-format style check - uses: jidicula/clang-format-action@v4.18.0 - with: - # keep this in line with the flake - clang-format-version: "21" + - name: Install clang-format + run: | + sudo apt-get update + sudo apt-get install -y clang-format-21 + + - name: Check changed files + env: + CLANG_FORMAT_BIN: clang-format + EVENT_NAME: ${{ github.event_name }} + PR_BASE_REF: ${{ github.event.pull_request.base.ref }} + PR_BASE_SHA: ${{ github.event.pull_request.base.sha }} + BEFORE_SHA: ${{ github.event.before }} + CURRENT_SHA: ${{ github.sha }} + run: | + set -euo pipefail + + BASE_SHA="" + if [ "$EVENT_NAME" = "pull_request" ]; then + git fetch --no-tags origin "$PR_BASE_REF" + BASE_SHA="$(git merge-base "origin/$PR_BASE_REF" "$CURRENT_SHA")" + elif [ -n "$BEFORE_SHA" ] && [ "$BEFORE_SHA" != "0000000000000000000000000000000000000000" ]; then + BASE_SHA="$BEFORE_SHA" + fi + + bash ./.github/scripts/check-clang-format.sh "$BASE_SHA" "$CURRENT_SHA" From 327addddaefb3d928f62f1eab379bb04be9332b3 Mon Sep 17 00:00:00 2001 From: Tropical <42101043+tropicaaal@users.noreply.github.com> Date: Sun, 29 Mar 2026 20:06:38 -0500 Subject: [PATCH 103/170] yaml and its consequences for the human race --- .github/workflows/build-linux.yml | 32 +++++++++++++++++------------- .github/workflows/clang-format.yml | 32 +++++++++++++++++------------- 2 files changed, 36 insertions(+), 28 deletions(-) diff --git a/.github/workflows/build-linux.yml b/.github/workflows/build-linux.yml index 11e6eed3b..e1ff0b0fd 100644 --- a/.github/workflows/build-linux.yml +++ b/.github/workflows/build-linux.yml @@ -1,19 +1,23 @@ name: Build (Linux, x86-64) -on: [push, pull_request] - paths: - - '**.cpp' - - '**.h' - - '**.c' - - '**.cc' - - '**.cxx' - - '**.hh' - - '**.hpp' - - '**.hxx' - - '**.inl' - - "**meson.build" - - "flake.nix" - - '.github/workflows/build-linux.yml' +on: + push: + paths: &workflow_paths + - '**.cpp' + - '**.h' + - '**.c' + - '**.cc' + - '**.cxx' + - '**.hh' + - '**.hpp' + - '**.hxx' + - '**.inl' + - "**meson.build" + - "flake.nix" + - '.github/workflows/build-linux.yml' + + pull_request: + paths: *workflow_paths jobs: build-linux: diff --git a/.github/workflows/clang-format.yml b/.github/workflows/clang-format.yml index 2bf8ec762..9a4b43905 100644 --- a/.github/workflows/clang-format.yml +++ b/.github/workflows/clang-format.yml @@ -1,19 +1,23 @@ name: Format -on: [push, pull_request] - paths: - - '**.cpp' - - '**.h' - - '**.c' - - '**.cc' - - '**.cxx' - - '**.hh' - - '**.hpp' - - '**.hxx' - - '**.inl' - - '.clang-format' - - '.github/workflows/clang-format.yml' - - '.github/scripts/check-clang-format.sh' +on: + push: + paths: &workflow_paths + - '**.cpp' + - '**.h' + - '**.c' + - '**.cc' + - '**.cxx' + - '**.hh' + - '**.hpp' + - '**.hxx' + - '**.inl' + - '.clang-format' + - '.github/workflows/clang-format.yml' + - '.github/scripts/check-clang-format.sh' + + pull_request: + paths: *workflow_paths jobs: clang-format: From dcebd64557b96a9080432d882e36d7f5d1f2a374 Mon Sep 17 00:00:00 2001 From: Tropical <42101043+tropicaaal@users.noreply.github.com> Date: Sun, 29 Mar 2026 20:07:16 -0500 Subject: [PATCH 104/170] rename to format check --- .github/workflows/clang-format.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/clang-format.yml b/.github/workflows/clang-format.yml index 9a4b43905..7626686b9 100644 --- a/.github/workflows/clang-format.yml +++ b/.github/workflows/clang-format.yml @@ -1,4 +1,4 @@ -name: Format +name: Format Check on: push: From 6010fa184801118c4fa54816fdd27d651b274af2 Mon Sep 17 00:00:00 2001 From: Tropical <42101043+tropicaaal@users.noreply.github.com> Date: Sun, 29 Mar 2026 20:35:03 -0500 Subject: [PATCH 105/170] test --- flake.nix | 1 + 1 file changed, 1 insertion(+) diff --git a/flake.nix b/flake.nix index 2db0000d7..05ceb4fef 100644 --- a/flake.nix +++ b/flake.nix @@ -54,6 +54,7 @@ version = "0.1.0"; src = ./.; + dontFixup = true; dontUseCmakeConfigure = true; # 4jcraft - Meson expects this subprojects structure From 0e9c1403bff1530200b89a58734a643c2ed9ad54 Mon Sep 17 00:00:00 2001 From: Tropical <42101043+tropicaaal@users.noreply.github.com> Date: Sun, 29 Mar 2026 20:36:42 -0500 Subject: [PATCH 106/170] hate you ubuntu --- .github/workflows/clang-format.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/clang-format.yml b/.github/workflows/clang-format.yml index 7626686b9..e1bdc4b84 100644 --- a/.github/workflows/clang-format.yml +++ b/.github/workflows/clang-format.yml @@ -32,7 +32,7 @@ jobs: - name: Install clang-format run: | sudo apt-get update - sudo apt-get install -y clang-format-21 + sudo apt-get install -y clang-format - name: Check changed files env: From 7b5c2dfe257cd6dffc3a115fcbed0982c3826c09 Mon Sep 17 00:00:00 2001 From: Tropical <42101043+tropicaaal@users.noreply.github.com> Date: Sun, 29 Mar 2026 20:43:14 -0500 Subject: [PATCH 107/170] use fetch-depth 0 for format workflow --- .github/workflows/clang-format.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/clang-format.yml b/.github/workflows/clang-format.yml index e1bdc4b84..297144427 100644 --- a/.github/workflows/clang-format.yml +++ b/.github/workflows/clang-format.yml @@ -27,7 +27,9 @@ jobs: cancel-in-progress: true steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v6 + with: + fetch-depth: 0 - name: Install clang-format run: | From 1ead072c458ad4f7ab3f222f92b945525d08ac3b Mon Sep 17 00:00:00 2001 From: MatthewBeshay <92357869+MatthewBeshay@users.noreply.github.com> Date: Mon, 30 Mar 2026 12:46:50 +1100 Subject: [PATCH 108/170] Add text input support: safe uint16_t* to wstring conversion Replace unsafe (wchar_t*)pchText casts with uint16_to_wstring() in all keyboard callbacks. The direct cast is incorrect on platforms where wchar_t is 4 bytes (Linux/macOS). New helpers in StringHelpers route through u16string for proper UTF-16 to wchar_t conversion. - Add uint16_len, uint16_to_u16string, uint16_to_wstring to StringHelpers - Fix casts in AnvilMenu, CreateWorldMenu, DebugCreateSchematic, DebugSetCamera, LaunchMoreOptionsMenu, SignEntryMenu - Truncate sign text to 15 chars in SignEntryMenu - Move m_bIgnoreInput reset after if-block in LaunchMoreOptionsMenu --- .../Platform/Common/UI/UIScene_AnvilMenu.cpp | 5 +++-- .../Common/UI/UIScene_CreateWorldMenu.cpp | 16 ++++++++-------- .../Common/UI/UIScene_DebugCreateSchematic.cpp | 2 +- .../Common/UI/UIScene_DebugSetCamera.cpp | 2 +- .../Common/UI/UIScene_LaunchMoreOptionsMenu.cpp | 8 +++++--- .../Platform/Common/UI/UIScene_SignEntryMenu.cpp | 6 ++++-- Minecraft.World/Util/StringHelpers.cpp | 13 +++++++++++++ Minecraft.World/Util/StringHelpers.h | 4 ++++ 8 files changed, 39 insertions(+), 17 deletions(-) diff --git a/Minecraft.Client/Platform/Common/UI/UIScene_AnvilMenu.cpp b/Minecraft.Client/Platform/Common/UI/UIScene_AnvilMenu.cpp index 5b4692fe8..c00466165 100644 --- a/Minecraft.Client/Platform/Common/UI/UIScene_AnvilMenu.cpp +++ b/Minecraft.Client/Platform/Common/UI/UIScene_AnvilMenu.cpp @@ -4,6 +4,7 @@ #include "../../Minecraft.World/Headers/net.minecraft.world.level.tile.entity.h" #include "../../Minecraft.Client/Player/MultiPlayerLocalPlayer.h" #include "../../Minecraft.Client/Minecraft.h" +#include "../../Minecraft.World/Util/StringHelpers.h" #include "UIScene_AnvilMenu.h" UIScene_AnvilMenu::UIScene_AnvilMenu(int iPad, void* _initData, @@ -300,8 +301,8 @@ int UIScene_AnvilMenu::KeyboardCompleteCallback(void* lpParam, bool bRes) { uint16_t pchText[128]; ZeroMemory(pchText, 128 * sizeof(uint16_t)); InputManager.GetText(pchText); - pClass->setEditNameValue((wchar_t*)pchText); - pClass->m_itemName = (wchar_t*)pchText; + pClass->setEditNameValue(uint16_to_wstring(pchText)); + pClass->m_itemName = uint16_to_wstring(pchText); pClass->updateItemName(); } return 0; diff --git a/Minecraft.Client/Platform/Common/UI/UIScene_CreateWorldMenu.cpp b/Minecraft.Client/Platform/Common/UI/UIScene_CreateWorldMenu.cpp index 43dbade82..76beb132a 100644 --- a/Minecraft.Client/Platform/Common/UI/UIScene_CreateWorldMenu.cpp +++ b/Minecraft.Client/Platform/Common/UI/UIScene_CreateWorldMenu.cpp @@ -723,8 +723,8 @@ int UIScene_CreateWorldMenu::KeyboardCompleteWorldNameCallback(void* lpParam, InputManager.GetText(pchText); if (pchText[0] != 0) { - pClass->m_editWorldName.setLabel((wchar_t*)pchText); - pClass->m_worldName = (wchar_t*)pchText; + pClass->m_editWorldName.setLabel(uint16_to_wstring(pchText)); + pClass->m_worldName = uint16_to_wstring(pchText); } pClass->m_buttonCreateWorld.setEnable(!pClass->m_worldName.empty()); @@ -901,9 +901,9 @@ IDS_PRO_NOTONLINE_TEXT, uiIDA, 1, ProfileManager.GetPrimaryPad()); return; bool pccFriendsAllowed = true; bool bContentRestricted = false; - ProfileManager.AllowedPlayerCreatedContent( - ProfileManager.GetPrimaryPad(), false, &pccAllowed, - &pccFriendsAllowed); + GetAllowedPlayerCreatedContentFlags(ProfileManager.GetPrimaryPad(), + false, &pccAllowed, + &pccFriendsAllowed); #if defined(__PS3__) || defined(__PSVITA__) if (isOnlineGame && isSignedInLive) { ProfileManager.GetChatAndContentRestrictions( @@ -1346,9 +1346,9 @@ int UIScene_CreateWorldMenu::StartGame_SignInReturned(void* pParam, bool pccAllowed = true; bool pccFriendsAllowed = true; - ProfileManager.AllowedPlayerCreatedContent( - ProfileManager.GetPrimaryPad(), false, &pccAllowed, - &pccFriendsAllowed); + GetAllowedPlayerCreatedContentFlags(ProfileManager.GetPrimaryPad(), + false, &pccAllowed, + &pccFriendsAllowed); if (!pccAllowed && !pccFriendsAllowed) noUGC = true; if (isOnlineGame && (noPrivileges || noUGC)) { diff --git a/Minecraft.Client/Platform/Common/UI/UIScene_DebugCreateSchematic.cpp b/Minecraft.Client/Platform/Common/UI/UIScene_DebugCreateSchematic.cpp index 3e2d56504..00b175887 100644 --- a/Minecraft.Client/Platform/Common/UI/UIScene_DebugCreateSchematic.cpp +++ b/Minecraft.Client/Platform/Common/UI/UIScene_DebugCreateSchematic.cpp @@ -146,7 +146,7 @@ int UIScene_DebugCreateSchematic::KeyboardCompleteCallback(void* lpParam, InputManager.GetText(pchText); if (pchText[0] != 0) { - std::wstring value = (wchar_t*)pchText; + std::wstring value = uint16_to_wstring(pchText); int iVal = 0; if (!value.empty()) iVal = _fromString(value); switch (pClass->m_keyboardCallbackControl) { diff --git a/Minecraft.Client/Platform/Common/UI/UIScene_DebugSetCamera.cpp b/Minecraft.Client/Platform/Common/UI/UIScene_DebugSetCamera.cpp index af850cb67..1472864e3 100644 --- a/Minecraft.Client/Platform/Common/UI/UIScene_DebugSetCamera.cpp +++ b/Minecraft.Client/Platform/Common/UI/UIScene_DebugSetCamera.cpp @@ -124,7 +124,7 @@ int UIScene_DebugSetCamera::KeyboardCompleteCallback(void* lpParam, bool bRes) { InputManager.GetText(pchText); if (pchText[0] != 0) { - std::wstring value = (wchar_t*)pchText; + std::wstring value = uint16_to_wstring(pchText); double val = 0; if (!value.empty()) val = _fromString(value); switch (pClass->m_keyboardCallbackControl) { diff --git a/Minecraft.Client/Platform/Common/UI/UIScene_LaunchMoreOptionsMenu.cpp b/Minecraft.Client/Platform/Common/UI/UIScene_LaunchMoreOptionsMenu.cpp index 448acff95..8a7e7efda 100644 --- a/Minecraft.Client/Platform/Common/UI/UIScene_LaunchMoreOptionsMenu.cpp +++ b/Minecraft.Client/Platform/Common/UI/UIScene_LaunchMoreOptionsMenu.cpp @@ -1,5 +1,6 @@ #include "../../Minecraft.World/Platform/stdafx.h" #include "UI.h" +#include "../../Minecraft.World/Util/StringHelpers.h" #include "UIScene_LaunchMoreOptionsMenu.h" #define GAME_CREATE_ONLINE_TIMER_ID 0 @@ -589,7 +590,6 @@ int UIScene_LaunchMoreOptionsMenu::KeyboardCompleteSeedCallback(void* lpParam, bool bRes) { UIScene_LaunchMoreOptionsMenu* pClass = (UIScene_LaunchMoreOptionsMenu*)lpParam; - pClass->m_bIgnoreInput = false; // 4J HEG - No reason to set value if keyboard was cancelled if (bRes) { #ifdef __PSVITA__ @@ -601,9 +601,10 @@ int UIScene_LaunchMoreOptionsMenu::KeyboardCompleteSeedCallback(void* lpParam, ZeroMemory(pchText, 128 * sizeof(uint16_t)); #endif InputManager.GetText(pchText); - pClass->m_editSeed.setLabel((wchar_t*)pchText); - pClass->m_params->seed = (wchar_t*)pchText; + pClass->m_editSeed.setLabel(uint16_to_wstring(pchText)); + pClass->m_params->seed = uint16_to_wstring(pchText); } + pClass->m_bIgnoreInput = false; return 0; } @@ -643,6 +644,7 @@ void UIScene_LaunchMoreOptionsMenu::handlePress(F64 controlId, F64 childId) { 0, 60, &UIScene_LaunchMoreOptionsMenu::KeyboardCompleteSeedCallback, this, C_4JInput::EKeyboardMode_Default); + KeyboardCompleteSeedCallback(this, true); #endif } break; } diff --git a/Minecraft.Client/Platform/Common/UI/UIScene_SignEntryMenu.cpp b/Minecraft.Client/Platform/Common/UI/UIScene_SignEntryMenu.cpp index ad927a1dc..70288fb1f 100644 --- a/Minecraft.Client/Platform/Common/UI/UIScene_SignEntryMenu.cpp +++ b/Minecraft.Client/Platform/Common/UI/UIScene_SignEntryMenu.cpp @@ -1,5 +1,6 @@ #include "../../Minecraft.World/Platform/stdafx.h" #include "UI.h" +#include "../../Minecraft.World/Util/StringHelpers.h" #include "UIScene_SignEntryMenu.h" #include "../../Minecraft.Client/Minecraft.h" #include "../../Minecraft.Client/Player/MultiPlayerLocalPlayer.h" @@ -144,8 +145,9 @@ int UIScene_SignEntryMenu::KeyboardCompleteCallback(void* lpParam, bool bRes) { uint16_t pchText[128]; ZeroMemory(pchText, 128 * sizeof(uint16_t)); InputManager.GetText(pchText); - pClass->m_textInputLines[pClass->m_iEditingLine].setLabel( - (wchar_t*)pchText); + std::wstring str = uint16_to_wstring(pchText); + str.resize(15); + pClass->m_textInputLines[pClass->m_iEditingLine].setLabel(str); } return 0; } diff --git a/Minecraft.World/Util/StringHelpers.cpp b/Minecraft.World/Util/StringHelpers.cpp index 9f47f92b8..43cfb171a 100644 --- a/Minecraft.World/Util/StringHelpers.cpp +++ b/Minecraft.World/Util/StringHelpers.cpp @@ -36,6 +36,19 @@ bool equalsIgnoreCase(const std::wstring& a, const std::wstring& b) { return out; } +size_t uint16_len(const uint16_t* str) { + return std::char_traits::length( + reinterpret_cast(str)); +} + +std::u16string uint16_to_u16string(const uint16_t* str) { + return std::u16string(reinterpret_cast(str), uint16_len(str)); +} + +std::wstring uint16_to_wstring(const uint16_t* str) { + return u16string_to_wstring(uint16_to_u16string(str)); +} + std::wstring convStringToWstring(const std::string& converting) { std::wstring converted(converting.length(), L' '); copy(converting.begin(), converting.end(), converted.begin()); diff --git a/Minecraft.World/Util/StringHelpers.h b/Minecraft.World/Util/StringHelpers.h index 871e46d87..4f41be369 100644 --- a/Minecraft.World/Util/StringHelpers.h +++ b/Minecraft.World/Util/StringHelpers.h @@ -29,6 +29,10 @@ T _fromHEXString(const std::wstring& s) { return t; } +size_t uint16_len(const uint16_t* str); +std::u16string uint16_to_u16string(const uint16_t* str); +std::wstring uint16_to_wstring(const uint16_t* str); + std::wstring convStringToWstring(const std::string& converting); std::wstring u16string_to_wstring(const std::u16string& converting); std::u16string wstring_to_u16string(const std::wstring& converting); From 9d40fceecec0a736fab34fa7b06898f8b4d4d73e Mon Sep 17 00:00:00 2001 From: Tropical <42101043+tropicaaal@users.noreply.github.com> Date: Sun, 29 Mar 2026 20:51:08 -0500 Subject: [PATCH 109/170] cache clang-format installation --- .github/workflows/clang-format.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/clang-format.yml b/.github/workflows/clang-format.yml index 297144427..84820ad88 100644 --- a/.github/workflows/clang-format.yml +++ b/.github/workflows/clang-format.yml @@ -29,12 +29,12 @@ jobs: - name: Checkout repository uses: actions/checkout@v6 with: - fetch-depth: 0 + fetch-depth: 2 - name: Install clang-format - run: | - sudo apt-get update - sudo apt-get install -y clang-format + uses: daaku/gh-action-apt-install@v4 + with: + packages: clang-format - name: Check changed files env: From fbb7b304c8a86c4c171b618cbaaa5f0f0a42562a Mon Sep 17 00:00:00 2001 From: JuiceyDev Date: Thu, 26 Mar 2026 00:12:59 +0100 Subject: [PATCH 110/170] first batch & fix with new files (very hacky & uncleaned state); state: game runs but broken rendering every chunks is at 0,0,0 @n@ --- .../Platform/Linux/Iggy/gdraw/gdraw.c | 818 ++++++++++++++++++ .../Linux/Iggy/gdraw/{gdraw_sdl.h => gdraw.h} | 9 +- .../Platform/Linux/Iggy/gdraw/gdraw_sdl.c | 240 ----- Minecraft.Client/Platform/Linux/LinuxGL.cpp | 200 +++-- .../Platform/Linux/Linux_UIController.cpp | 52 +- Minecraft.Client/Platform/stdafx.h | 251 +++--- Minecraft.Client/Platform/stubs.h | 334 ++++--- 7 files changed, 1250 insertions(+), 654 deletions(-) create mode 100644 Minecraft.Client/Platform/Linux/Iggy/gdraw/gdraw.c rename Minecraft.Client/Platform/Linux/Iggy/gdraw/{gdraw_sdl.h => gdraw.h} (94%) delete mode 100644 Minecraft.Client/Platform/Linux/Iggy/gdraw/gdraw_sdl.c diff --git a/Minecraft.Client/Platform/Linux/Iggy/gdraw/gdraw.c b/Minecraft.Client/Platform/Linux/Iggy/gdraw/gdraw.c new file mode 100644 index 000000000..0c2cea4d5 --- /dev/null +++ b/Minecraft.Client/Platform/Linux/Iggy/gdraw/gdraw.c @@ -0,0 +1,818 @@ +#define GDRAW_ASSERTS + +#include "../../../Windows64/Iggy/include/iggy.h" +#include "../../../Windows64/Iggy/include/gdraw.h" +#include "gdraw.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define true 1 +#define false 0 + + +#ifndef _ENABLEIGGY +void* IggyGDrawMallocAnnotated(SINTa size, const char* file, int line) { + (void)file; + (void)line; + return malloc((size_t)size); +} + +void IggyGDrawFree(void* ptr) { free(ptr); } + +void IggyGDrawSendWarning(Iggy* f, char const* message, ...) { + (void)f; + va_list args; + va_start(args, message); + fprintf(stderr, "[Iggy GDraw Warning] "); + vfprintf(stderr, message, args); + fprintf(stderr, "\n"); + va_end(args); +} + +void IggyDiscardVertexBufferCallback(void* owner, void* buf) { + (void)owner; + (void)buf; +} +#endif + +// We track all the extensions we use. +#define GDRAW_GL_EXTENSION_LIST \ + /* identifier import procname */ \ + /* GL_ARB_vertex_buffer_object */ \ + GLE(GenBuffers, "GenBuffersARB", GENBUFFERSARB) \ + GLE(DeleteBuffers, "DeleteBuffersARB", DELETEBUFFERSARB) \ + GLE(BindBuffer, "BindBufferARB", BINDBUFFERARB) \ + GLE(BufferData, "BufferDataARB", BUFFERDATAARB) \ + GLE(MapBuffer, "MapBufferARB", MAPBUFFERARB) \ + GLE(UnmapBuffer, "UnmapBufferARB", UNMAPBUFFERARB) \ + GLE(VertexAttribPointer, "VertexAttribPointerARB", VERTEXATTRIBPOINTERARB) \ + GLE(EnableVertexAttribArray, "EnableVertexAttribArrayARB", \ + ENABLEVERTEXATTRIBARRAYARB) \ + GLE(DisableVertexAttribArray, "DisableVertexAttribArrayARB", \ + DISABLEVERTEXATTRIBARRAYARB) \ + /* GL_ARB_shader_objects */ \ + GLE(CreateShader, "CreateShaderObjectARB", CREATESHADEROBJECTARB) \ + GLE(DeleteShader, "DeleteObjectARB", DELETEOBJECTARB) \ + GLE(ShaderSource, "ShaderSourceARB", SHADERSOURCEARB) \ + GLE(CompileShader, "CompileShaderARB", COMPILESHADERARB) \ + GLE(GetShaderiv, "GetObjectParameterivARB", GETOBJECTPARAMETERIVARB) \ + GLE(GetShaderInfoLog, "GetInfoLogARB", GETINFOLOGARB) \ + GLE(CreateProgram, "CreateProgramObjectARB", CREATEPROGRAMOBJECTARB) \ + GLE(DeleteProgram, "DeleteObjectARB", DELETEOBJECTARB) \ + GLE(AttachShader, "AttachObjectARB", ATTACHOBJECTARB) \ + GLE(LinkProgram, "LinkProgramARB", LINKPROGRAMARB) \ + GLE(GetUniformLocation, "GetUniformLocationARB", GETUNIFORMLOCATIONARB) \ + GLE(UseProgram, "UseProgramObjectARB", USEPROGRAMOBJECTARB) \ + GLE(GetProgramiv, "GetObjectParameterivARB", GETOBJECTPARAMETERIVARB) \ + GLE(GetProgramInfoLog, "GetInfoLogARB", GETINFOLOGARB) \ + GLE(Uniform1i, "Uniform1iARB", UNIFORM1IARB) \ + GLE(Uniform4f, "Uniform4fARB", UNIFORM4FARB) \ + GLE(Uniform4fv, "Uniform4fvARB", UNIFORM4FVARB) \ + /* GL_ARB_vertex_shader */ \ + GLE(BindAttribLocation, "BindAttribLocationARB", BINDATTRIBLOCATIONARB) \ + /* Missing from WGL but needed by shared code */ \ + GLE(Uniform1f, "Uniform1fARB", UNIFORM1FARB) \ + /* GL_EXT_framebuffer_object */ \ + GLE(GenRenderbuffers, "GenRenderbuffersEXT", GENRENDERBUFFERSEXT) \ + GLE(DeleteRenderbuffers, "DeleteRenderbuffersEXT", DELETERENDERBUFFERSEXT) \ + GLE(BindRenderbuffer, "BindRenderbufferEXT", BINDRENDERBUFFEREXT) \ + GLE(RenderbufferStorage, "RenderbufferStorageEXT", RENDERBUFFERSTORAGEEXT) \ + GLE(GenFramebuffers, "GenFramebuffersEXT", GENFRAMEBUFFERSEXT) \ + GLE(DeleteFramebuffers, "DeleteFramebuffersEXT", DELETEFRAMEBUFFERSEXT) \ + GLE(BindFramebuffer, "BindFramebufferEXT", BINDFRAMEBUFFEREXT) \ + GLE(CheckFramebufferStatus, "CheckFramebufferStatusEXT", \ + CHECKFRAMEBUFFERSTATUSEXT) \ + GLE(FramebufferRenderbuffer, "FramebufferRenderbufferEXT", \ + FRAMEBUFFERRENDERBUFFEREXT) \ + GLE(FramebufferTexture2D, "FramebufferTexture2DEXT", \ + FRAMEBUFFERTEXTURE2DEXT) \ + GLE(GenerateMipmap, "GenerateMipmapEXT", GENERATEMIPMAPEXT) \ + /* GL_EXT_framebuffer_blit */ \ + GLE(BlitFramebuffer, "BlitFramebufferEXT", BLITFRAMEBUFFEREXT) \ + /* GL_EXT_framebuffer_multisample */ \ + GLE(RenderbufferStorageMultisample, "RenderbufferStorageMultisampleEXT", \ + RENDERBUFFERSTORAGEMULTISAMPLEEXT) \ + /* */ + + +// Shared .inl +#define gdraw_GLx_(id) gdraw_GL_##id +#define GDRAW_GLx_(id) GDRAW_GL_##id +#define GDRAW_SHADERS "gdraw_gl_shaders.inl" + +// GLhandleARB is void* but shader functions use GLuint values. +// homework stolen from gdraw_gl_shared.inl. +#define GDrawGLProgram GLuint +typedef GLuint GLhandle; +typedef gdraw_gl_resourcetype gdraw_resourcetype; + +#define GLE(id, import, procname) static PFNGL##procname##PROC gl##id; +GDRAW_GL_EXTENSION_LIST +#undef GLE + + +typedef const GLubyte*(APIENTRYP PFNGLGETSTRINGIPROC_)(GLenum name, + GLuint index); +static PFNGLGETSTRINGIPROC_ gdraw_glGetStringi = NULL; + +typedef void(APIENTRYP PFNGLGENVERTEXARRAYSPROC_)(GLsizei n, GLuint* arrays); +typedef void(APIENTRYP PFNGLBINDVERTEXARRAYPROC_)(GLuint array); +static PFNGLGENVERTEXARRAYSPROC_ gdraw_glGenVertexArrays = NULL; +static PFNGLBINDVERTEXARRAYPROC_ gdraw_glBindVertexArray = NULL; +static GLuint gdraw_vao = 0; + +typedef void(APIENTRYP gdraw_vtxattrib_fn)(GLuint, GLint, GLenum, GLboolean, + GLsizei, const void*); +static gdraw_vtxattrib_fn gdraw_real_vtxattrib = NULL; +static GLuint gdraw_screenvbo = 0; +static const void* gdraw_screenvbo_base = NULL; +static size_t gdraw_expected_vbo_size = 0; + + +typedef void(APIENTRYP gdraw_drawelements_fn)(GLenum mode, GLsizei count, + GLenum type, const void* indices); +static gdraw_drawelements_fn gdraw_real_drawelements = NULL; +static GLuint gdraw_screenibo = 0; + + +typedef GLuint(APIENTRYP gdraw_createshader_fn)(GLenum); +typedef void(APIENTRYP gdraw_shadersource_fn)(GLuint, GLsizei, const GLchar**, + const GLint*); +typedef void(APIENTRYP gdraw_compileshader_fn)(GLuint); +typedef void(APIENTRYP gdraw_linkprogram_fn)(GLuint); +static gdraw_createshader_fn gdraw_real_createshader = NULL; +static gdraw_shadersource_fn gdraw_real_shadersource = NULL; +static gdraw_compileshader_fn gdraw_real_compileshader = NULL; +static gdraw_linkprogram_fn gdraw_real_linkprogram = NULL; + +// some core reject p0 + +typedef void(APIENTRYP gdraw_useprogram_fn)(GLuint); +static gdraw_useprogram_fn gdraw_real_useprogram = NULL; +static GLuint gdraw_null_program = 0; + + +typedef void(APIENTRYP gdraw_teximage2d_fn)(GLenum, GLint, GLint, GLsizei, + GLsizei, GLint, GLenum, GLenum, + const void*); +typedef void(APIENTRYP gdraw_texsubimage2d_fn)(GLenum, GLint, GLint, GLint, + GLsizei, GLsizei, GLenum, GLenum, + const void*); +static gdraw_teximage2d_fn gdraw_real_teximage2d = NULL; +static gdraw_texsubimage2d_fn gdraw_real_texsubimage2d = NULL; + +#define TRY(ptr, arb, core) \ + do { \ + void* _p = SDL_GL_GetProcAddress(core); \ + if (!_p) _p = SDL_GL_GetProcAddress(arb); \ + *(void**)&(ptr) = _p; \ + } while (0) + +static void load_extensions(void) { +// gl_shared requires ts shit ugh +#define GLE(id, import, procname) \ + gl##id = (PFNGL##procname##PROC)SDL_GL_GetProcAddress("gl" import); + GDRAW_GL_EXTENSION_LIST +#undef GLE + + TRY(glCreateShader, "glCreateShaderObjectARB", "glCreateShader"); + TRY(glDeleteShader, "glDeleteObjectARB", "glDeleteShader"); + TRY(glShaderSource, "glShaderSourceARB", "glShaderSource"); + TRY(glCompileShader, "glCompileShaderARB", "glCompileShader"); + TRY(glGetShaderiv, "glGetObjectParameterivARB", "glGetShaderiv"); + TRY(glGetShaderInfoLog, "glGetInfoLogARB", "glGetShaderInfoLog"); + TRY(glCreateProgram, "glCreateProgramObjectARB", "glCreateProgram"); + TRY(glDeleteProgram, "glDeleteObjectARB", "glDeleteProgram"); + TRY(glAttachShader, "glAttachObjectARB", "glAttachShader"); + TRY(glLinkProgram, "glLinkProgramARB", "glLinkProgram"); + TRY(glGetUniformLocation, "glGetUniformLocationARB", + "glGetUniformLocation"); + TRY(glUseProgram, "glUseProgramObjectARB", "glUseProgram"); + TRY(glGetProgramiv, "glGetObjectParameterivARB", "glGetProgramiv"); + TRY(glGetProgramInfoLog, "glGetInfoLogARB", "glGetProgramInfoLog"); + TRY(glUniform1i, "glUniform1iARB", "glUniform1i"); + TRY(glUniform4f, "glUniform4fARB", "glUniform4f"); + TRY(glUniform4fv, "glUniform4fvARB", "glUniform4fv"); + TRY(glUniform1f, "glUniform1fARB", "glUniform1f"); + TRY(glBindAttribLocation, "glBindAttribLocationARB", + "glBindAttribLocation"); + + TRY(glGenBuffers, "glGenBuffersARB", "glGenBuffers"); + TRY(glDeleteBuffers, "glDeleteBuffersARB", "glDeleteBuffers"); + TRY(glBindBuffer, "glBindBufferARB", "glBindBuffer"); + TRY(glBufferData, "glBufferDataARB", "glBufferData"); + TRY(glMapBuffer, "glMapBufferARB", "glMapBuffer"); + TRY(glUnmapBuffer, "glUnmapBufferARB", "glUnmapBuffer"); + TRY(glVertexAttribPointer, "glVertexAttribPointerARB", + "glVertexAttribPointer"); + TRY(glEnableVertexAttribArray, "glEnableVertexAttribArrayARB", + "glEnableVertexAttribArray"); + TRY(glDisableVertexAttribArray, "glDisableVertexAttribArrayARB", + "glDisableVertexAttribArray"); + + TRY(glGenRenderbuffers, "glGenRenderbuffersEXT", "glGenRenderbuffers"); + TRY(glDeleteRenderbuffers, "glDeleteRenderbuffersEXT", + "glDeleteRenderbuffers"); + TRY(glBindRenderbuffer, "glBindRenderbufferEXT", "glBindRenderbuffer"); + TRY(glRenderbufferStorage, "glRenderbufferStorageEXT", + "glRenderbufferStorage"); + TRY(glGenFramebuffers, "glGenFramebuffersEXT", "glGenFramebuffers"); + TRY(glDeleteFramebuffers, "glDeleteFramebuffersEXT", + "glDeleteFramebuffers"); + TRY(glBindFramebuffer, "glBindFramebufferEXT", "glBindFramebuffer"); + TRY(glCheckFramebufferStatus, "glCheckFramebufferStatusEXT", + "glCheckFramebufferStatus"); + TRY(glFramebufferRenderbuffer, "glFramebufferRenderbufferEXT", + "glFramebufferRenderbuffer"); + TRY(glFramebufferTexture2D, "glFramebufferTexture2DEXT", + "glFramebufferTexture2D"); + TRY(glGenerateMipmap, "glGenerateMipmapEXT", "glGenerateMipmap"); + TRY(glBlitFramebuffer, "glBlitFramebufferEXT", "glBlitFramebuffer"); + TRY(glRenderbufferStorageMultisample, "glRenderbufferStorageMultisampleEXT", + "glRenderbufferStorageMultisample"); + + // Save raw pointers before we #define over the names below + gdraw_real_vtxattrib = (gdraw_vtxattrib_fn)(void*)glVertexAttribPointer; + gdraw_real_createshader = (gdraw_createshader_fn)(void*)glCreateShader; + gdraw_real_shadersource = (gdraw_shadersource_fn)(void*)glShaderSource; + gdraw_real_compileshader = (gdraw_compileshader_fn)(void*)glCompileShader; + gdraw_real_linkprogram = (gdraw_linkprogram_fn)(void*)glLinkProgram; + gdraw_real_teximage2d = (gdraw_teximage2d_fn)(void*)glTexImage2D; + gdraw_real_texsubimage2d = (gdraw_texsubimage2d_fn)(void*)glTexSubImage2D; + gdraw_real_useprogram = (gdraw_useprogram_fn)(void*)glUseProgram; + gdraw_real_drawelements = + (gdraw_drawelements_fn)SDL_GL_GetProcAddress("glDrawElements"); + + gdraw_glGetStringi = + (PFNGLGETSTRINGIPROC_)SDL_GL_GetProcAddress("glGetStringi"); + // VAO + gdraw_glGenVertexArrays = + (PFNGLGENVERTEXARRAYSPROC_)SDL_GL_GetProcAddress("glGenVertexArrays"); + gdraw_glBindVertexArray = + (PFNGLBINDVERTEXARRAYPROC_)SDL_GL_GetProcAddress("glBindVertexArray"); + + if (gdraw_glGenVertexArrays && gdraw_glBindVertexArray && gdraw_vao == 0) { + gdraw_glGenVertexArrays(1, &gdraw_vao); + gdraw_glBindVertexArray(gdraw_vao); + } +} + +#undef TRY + +// rebind vbo + +static void clear_renderstate_platform_specific(void) { + if (gdraw_glBindVertexArray && gdraw_vao) + gdraw_glBindVertexArray(gdraw_vao); +} + +static void error_msg_platform_specific(const char* msg) { + fprintf(stderr, "[GDraw] %s\n", msg); +} + +#define GDRAW_MULTISAMPLING + +// i wish i could improve this function +#ifdef RR_BREAK +#undef RR_BREAK +#endif +#define RR_BREAK() \ + do { \ + fprintf(stderr, "[GDraw] GL error at %s:%d\n", __FILE__, __LINE__); \ + } while (0) + + +// the magic number that tropical told me +#define GDRAW_MAX_SHADERS 64 +static struct { + GLuint handle; + GLenum type; +} gdraw_shader_types[GDRAW_MAX_SHADERS]; +static int gdraw_shader_type_count = 0; + +static GLenum gdraw_get_shader_type(GLuint shader) { + int i; + for (i = 0; i < gdraw_shader_type_count; i++) + if (gdraw_shader_types[i].handle == shader) + return gdraw_shader_types[i].type; + return GL_FRAGMENT_SHADER; +} + +static GLuint gdraw_CreateShaderTracked(GLenum type) { + GLuint h = gdraw_real_createshader(type); + if (h && gdraw_shader_type_count < GDRAW_MAX_SHADERS) { + gdraw_shader_types[gdraw_shader_type_count].handle = h; + gdraw_shader_types[gdraw_shader_type_count].type = type; + gdraw_shader_type_count++; + } + return h; +} + + + +static void gdraw_CompileShaderAndLog(GLuint shader) { + GLint status = 0; + gdraw_real_compileshader(shader); + glGetShaderiv(shader, GL_COMPILE_STATUS, &status); + if (!status) { + char log[2048]; + GLint len = 0; + glGetShaderInfoLog(shader, (GLsizei)sizeof(log) - 1, &len, log); + log[len] = '\0'; + fprintf(stderr, "[GDraw GLSL] compile FAILED shader=%u:\n%s\n", shader, + log); + fflush(stderr); + } +} + +static void gdraw_LinkProgramAndLog(GLuint program) { + GLint status = 0; + gdraw_real_linkprogram(program); + glGetProgramiv(program, GL_LINK_STATUS, &status); + if (!status) { + char log[2048]; + GLint len = 0; + glGetProgramInfoLog(program, (GLsizei)sizeof(log) - 1, &len, log); + log[len] = '\0'; + fprintf(stderr, "[GDraw GLSL] link FAILED program=%u:\n%s\n", program, + log); + fflush(stderr); + } +} + +#undef glCreateShader +#define glCreateShader gdraw_CreateShaderTracked + +// This is the part that turns the old ugly shaders to 330 +static char* gdraw_strreplace(char* src, const char* find, const char* rep) { + char* result; + char* pos; + char* base = src; + size_t find_len = strlen(find); + size_t rep_len = strlen(rep); + size_t count = 0; + char* tmp = src; + + while ((tmp = strstr(tmp, find))) { + count++; + tmp += find_len; + } + if (!count) return src; + + result = (char*)malloc(strlen(src) + count * (rep_len + 1) + 1); + if (!result) return src; + + tmp = result; + while ((pos = strstr(src, find))) { + size_t before = (size_t)(pos - src); + memcpy(tmp, src, before); + tmp += before; + memcpy(tmp, rep, rep_len); + tmp += rep_len; + src = pos + find_len; + } + strcpy(tmp, src); + free(base); + return result; +} + +static void gdraw_ShaderSourceUpgraded(GLuint shader, GLsizei count, + const GLchar** strings, + const GLint* lengths) { + int i; + size_t total = 0; + char* src; + char* patched; + int is_vert; + const GLchar* patched_ptr; + + for (i = 0; i < count; i++) + total += lengths ? (lengths[i] >= 0 ? (size_t)lengths[i] + : strlen(strings[i])) + : strlen(strings[i]); + + src = (char*)malloc(total + 1); + if (!src) { + gdraw_real_shadersource(shader, count, strings, lengths); + return; + } + + src[0] = '\0'; + for (i = 0; i < count; i++) { + size_t len = lengths ? (lengths[i] >= 0 ? (size_t)lengths[i] + : strlen(strings[i])) + : strlen(strings[i]); + strncat(src, strings[i], len); + } + + is_vert = (gdraw_get_shader_type(shader) == GL_VERTEX_SHADER); + + // Strip any existing #version directive as i'll add our own + { + char* vp = strstr(src, "#version"); + if (vp) { + char* nl = strchr(vp, '\n'); + if (nl) + memmove(vp, nl + 1, strlen(nl + 1) + 1); + else + *vp = '\0'; + } + } + + // Texture built-ins + src = gdraw_strreplace(src, "texture2DRect", "texture"); + src = gdraw_strreplace(src, "texture2D", "texture"); + + // Attribute -> in + src = gdraw_strreplace(src, "attribute ", "in "); + src = gdraw_strreplace(src, "attribute\t", "in\t"); + src = gdraw_strreplace(src, "attribute\n", "in\n"); + + // Varying -> out (vert) / in (frag) + if (is_vert) { + src = gdraw_strreplace(src, "varying ", "out "); + src = gdraw_strreplace(src, "varying\t", "out\t"); + src = gdraw_strreplace(src, "varying\n", "out\n"); + } else { + src = gdraw_strreplace(src, "varying ", "in "); + src = gdraw_strreplace(src, "varying\t", "in\t"); + src = gdraw_strreplace(src, "varying\n", "in\n"); + } + if (!is_vert) { + src = gdraw_strreplace(src, "gl_FragData[0]", "_gdraw_frag_out"); + src = gdraw_strreplace(src, "gl_FragColor", "_gdraw_frag_out"); + } + + // finally turn it 330 + { + const char* vert_header = "#version 330 core\n"; + const char* frag_header = + "#version 330 core\nout vec4 _gdraw_frag_out;\n"; + const char* header = is_vert ? vert_header : frag_header; + patched = (char*)malloc(strlen(header) + strlen(src) + 2); + if (!patched) { + free(src); + gdraw_real_shadersource(shader, count, strings, lengths); + return; + } + strcpy(patched, header); + strcat(patched, src); + free(src); + } + + patched_ptr = (const GLchar*)patched; + gdraw_real_shadersource(shader, 1, &patched_ptr, NULL); + free(patched); +} + +#undef glShaderSource +#define glShaderSource gdraw_ShaderSourceUpgraded + + +// Remap all the deprecated internal formats to their modern equivalents +// (idk why but just the word "swizzle" is cracking me up) +static void gdraw_apply_swizzle(GLenum internal_fmt) { + if (internal_fmt == 0x1906 /* GL_ALPHA */ || internal_fmt == GL_RED) { + GLint sw[4] = {GL_ZERO, GL_ZERO, GL_ZERO, GL_RED}; + glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, sw); + } else if (internal_fmt == 0x1909 /* GL_LUMINANCE */) { + GLint sw[4] = {GL_RED, GL_RED, GL_RED, GL_ONE}; + glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, sw); + } else if (internal_fmt == 0x190A /* GL_LUMINANCE_ALPHA */) { + GLint sw[4] = {GL_RED, GL_RED, GL_RED, GL_GREEN}; + glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, sw); + } +} + +static GLenum gdraw_remap_fmt(GLenum fmt) { + switch (fmt) { + case 0x1906: + return GL_RED; // GL_ALPHA + case 0x1909: + return GL_RED; // GL_LUMINANCE + case 0x190A: + return GL_RG; // GL_LUMINANCE_ALPHA + case 0x8033: + return GL_RG; // GL_LUMINANCE4_ALPHA4 + case 0x8045: + return GL_R8; // GL_LUMINANCE8 + case 0x8048: + return GL_RG8; // GL_LUMINANCE8_ALPHA8 + case 0x804F: + return GL_R8; // GL_INTENSITY4 + case 0x8050: + return GL_R8; // GL_INTENSITY8 + default: + return fmt; + } +} + +static void gdraw_TexImage2D(GLenum target, GLint level, GLint ifmt, GLsizei w, + GLsizei h, GLint border, GLenum fmt, GLenum type, + const void* data) { + GLenum new_ifmt = gdraw_remap_fmt((GLenum)ifmt); + GLenum new_fmt = gdraw_remap_fmt(fmt); + gdraw_real_teximage2d(target, level, (GLint)new_ifmt, w, h, border, new_fmt, + type, data); + if (new_ifmt != (GLenum)ifmt) gdraw_apply_swizzle((GLenum)ifmt); +} + +static void gdraw_TexSubImage2D(GLenum target, GLint level, GLint xoff, + GLint yoff, GLsizei w, GLsizei h, GLenum fmt, + GLenum type, const void* data) { + GLenum new_fmt = gdraw_remap_fmt(fmt); + gdraw_real_texsubimage2d(target, level, xoff, yoff, w, h, new_fmt, type, + data); +} + +#undef glTexImage2D +#define glTexImage2D gdraw_TexImage2D +#undef glTexSubImage2D +#define glTexSubImage2D gdraw_TexSubImage2D + +// vbo emu +static void gdraw_ClientVertexAttribPointer(GLuint index, GLint size, + GLenum type, GLboolean normalized, + GLsizei stride, + const void* pointer) { + if (gdraw_glBindVertexArray && gdraw_vao) { + GLint current_vao = 0; + glGetIntegerv(GL_VERTEX_ARRAY_BINDING, ¤t_vao); + if ((GLuint)current_vao != gdraw_vao) + gdraw_glBindVertexArray(gdraw_vao); + } + + { + GLint current_vbo = 0; + glGetIntegerv(GL_ARRAY_BUFFER_BINDING, ¤t_vbo); + + if (current_vbo != 0 && current_vbo != (GLint)gdraw_screenvbo) { + gdraw_real_vtxattrib(index, size, type, normalized, stride, + pointer); + return; + } + } + + if (pointer == NULL) { + gdraw_real_vtxattrib(index, size, type, normalized, stride, pointer); + return; + } + + if (gdraw_screenvbo_base == NULL) { + if (!gdraw_screenvbo) glGenBuffers(1, &gdraw_screenvbo); + glBindBuffer(GL_ARRAY_BUFFER, gdraw_screenvbo); + + size_t upload_size = + gdraw_expected_vbo_size > 0 ? gdraw_expected_vbo_size : 256; + glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)upload_size, pointer, + GL_STREAM_DRAW); + + gdraw_screenvbo_base = pointer; + gdraw_real_vtxattrib(index, size, type, normalized, stride, + (const void*)0); + } else { + glBindBuffer(GL_ARRAY_BUFFER, gdraw_screenvbo); + ptrdiff_t offset = + (const char*)pointer - (const char*)gdraw_screenvbo_base; + gdraw_real_vtxattrib(index, size, type, normalized, stride, + (const void*)offset); + } +} + +#undef glVertexAttribPointer +#define glVertexAttribPointer gdraw_ClientVertexAttribPointer + +// fake ibo +static void hooked_glDrawElements(GLenum mode, GLsizei count, GLenum type, + const void* indices) { + GLint current_ibo = 0; + glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, ¤t_ibo); + + if (current_ibo == 0 && indices != NULL) { + if (!gdraw_screenibo) glGenBuffers(1, &gdraw_screenibo); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, gdraw_screenibo); + + size_t index_size = (type == GL_UNSIGNED_SHORT) ? 2 + : (type == GL_UNSIGNED_BYTE) ? 1 + : 4; + glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)(count * index_size), + indices, GL_STREAM_DRAW); + + gdraw_real_drawelements(mode, count, type, (const void*)0); + } else { + gdraw_real_drawelements(mode, count, type, indices); + } +} + +#define glDrawElements hooked_glDrawElements + +// dummy shader for glUseProgram(0) safety +static void gdraw_UseProgramSafe(GLuint program) { + if (!program) { + if (!gdraw_null_program && gdraw_real_useprogram) { + const char* vs = + "#version 330 core\nvoid main(){gl_Position=vec4(0);}"; + const char* fs = + "#version 330 core\nout vec4 c;\nvoid main(){c=vec4(0);}"; + GLuint v = gdraw_real_createshader(GL_VERTEX_SHADER); + GLuint f = gdraw_real_createshader(GL_FRAGMENT_SHADER); + gdraw_real_shadersource(v, 1, &vs, NULL); + gdraw_real_shadersource(f, 1, &fs, NULL); + gdraw_real_compileshader(v); + gdraw_real_compileshader(f); + gdraw_null_program = glCreateProgram(); + glAttachShader(gdraw_null_program, v); + glAttachShader(gdraw_null_program, f); + gdraw_real_linkprogram(gdraw_null_program); + glDeleteShader(v); + glDeleteShader(f); + } + gdraw_real_useprogram(0); + return; + } + gdraw_real_useprogram(program); +} + +#undef glUseProgram +#define glUseProgram gdraw_UseProgramSafe + +#undef glCompileShader +#define glCompileShader gdraw_CompileShaderAndLog + +#undef glLinkProgram +#define glLinkProgram gdraw_LinkProgramAndLog + +// v ugh fuck you windows +#include "../../../Windows64/Iggy/gdraw/gdraw_gl_shared.inl" +#undef glVertexAttribPointer +#define glVertexAttribPointer gdraw_real_vtxattrib + +// 3.3 c extension +static int hasext_core(const char* name) { + GLint n = 0; + GLint i; + if (!gdraw_glGetStringi) return 0; + glGetIntegerv(GL_NUM_EXTENSIONS, &n); + for (i = 0; i < n; i++) { + const char* e = + (const char*)gdraw_glGetStringi(GL_EXTENSIONS, (GLuint)i); + if (e && strcmp(e, name) == 0) return 1; + } + return 0; +} + +static gdraw_draw_indexed_triangles* real_DrawIndexedTriangles = NULL; + +static void RADLINK hooked_DrawIndexedTriangles(GDrawRenderState* r, + GDrawPrimitive* prim, + GDrawVertexBuffer* buf, + GDrawStats* stats) { + if (buf == NULL && prim != NULL && prim->vertices != NULL) { + size_t stride = 8; + if (prim->vertex_format == GDRAW_vformat_v2aa) + stride = 16; + else if (prim->vertex_format == GDRAW_vformat_v2tc2) + stride = 16; + else if (prim->vertex_format == GDRAW_vformat_ihud1) + stride = 20; + gdraw_expected_vbo_size = prim->num_vertices * stride; + } else { + gdraw_expected_vbo_size = 0; + } + gdraw_screenvbo_base = NULL; // Force VBO re-upload for each primitive + real_DrawIndexedTriangles(r, prim, buf, stats); +} + +static gdraw_filter_quad* real_FilterQuad = NULL; + +static void RADLINK hooked_FilterQuad(GDrawRenderState* r, S32 x0, S32 y0, + S32 x1, S32 y1, GDrawStats* stats) { + gdraw_expected_vbo_size = 4 * 20; // 4 vertices, max stride + gdraw_screenvbo_base = NULL; + real_FilterQuad(r, x0, y0, x1, y1, stats); +} + +static gdraw_rendering_begin* real_RenderingBegin = NULL; + +// stupid hack +static void RADLINK hooked_RenderingBegin(void) { + if (real_RenderingBegin) real_RenderingBegin(); + glDisable(GL_DEPTH_TEST); + glDisable(GL_CULL_FACE); +} + +// Creating the context +GDrawFunctions* gdraw_GL_CreateContext(S32 w, S32 h, S32 msaa_samples) { + static const TextureFormatDesc tex_formats[] = { + {IFT_FORMAT_rgba_8888, 1, 1, 4, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE}, + {IFT_FORMAT_rgba_4444_LE, 1, 1, 2, GL_RGBA4, GL_RGBA, + GL_UNSIGNED_SHORT_4_4_4_4}, + {IFT_FORMAT_rgba_5551_LE, 1, 1, 2, GL_RGB5_A1, GL_RGBA, + GL_UNSIGNED_SHORT_5_5_5_1}, + {IFT_FORMAT_la_88, 1, 1, 2, GL_LUMINANCE8_ALPHA8, GL_LUMINANCE_ALPHA, + GL_UNSIGNED_BYTE}, + {IFT_FORMAT_la_44, 1, 1, 1, GL_LUMINANCE4_ALPHA4, GL_LUMINANCE_ALPHA, + GL_UNSIGNED_BYTE}, + {IFT_FORMAT_i_8, 1, 1, 1, GL_INTENSITY8, GL_ALPHA, GL_UNSIGNED_BYTE}, + {IFT_FORMAT_i_4, 1, 1, 1, GL_INTENSITY4, GL_ALPHA, GL_UNSIGNED_BYTE}, + {IFT_FORMAT_l_8, 1, 1, 1, GL_LUMINANCE8, GL_LUMINANCE, + GL_UNSIGNED_BYTE}, + {IFT_FORMAT_l_4, 1, 1, 1, GL_LUMINANCE4, GL_LUMINANCE, + GL_UNSIGNED_BYTE}, + {IFT_FORMAT_DXT1, 4, 4, 8, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, 0, + GL_UNSIGNED_BYTE}, + {IFT_FORMAT_DXT3, 4, 4, 16, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, 0, + GL_UNSIGNED_BYTE}, + {IFT_FORMAT_DXT5, 4, 4, 16, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, 0, + GL_UNSIGNED_BYTE}, + {0, 0, 0, 0, 0, 0, 0}, + }; + + GDrawFunctions* funcs; + GLint n; + GLint major = 0, minor = 0; + + // incase everything goes wrong and it goes like 1.1 or smh + glGetIntegerv(GL_MAJOR_VERSION, &major); + glGetIntegerv(GL_MINOR_VERSION, &minor); + if (major < 3 || (major == 3 && minor < 3)) { + fprintf(stderr, "[GDraw] GL 3.3 or higher required (got %d.%d)\n", + major, minor); + return NULL; + } + + // FBO is core since 3.0 + if (!hasext_core("GL_EXT_framebuffer_object")) { + fprintf(stderr, + "[GDraw] GL_EXT_framebuffer_object not listed, " + "fuck it, let's continue.\n"); + } + + if (!hasext_core("GL_EXT_framebuffer_multisample") && msaa_samples > 1) + return NULL; + + load_extensions(); + + if (gdraw_glBindVertexArray && gdraw_vao) + gdraw_glBindVertexArray(gdraw_vao); + + funcs = create_context(w, h); + if (!funcs) return NULL; + + // hook the vtable entries for VBO reset and render state + real_DrawIndexedTriangles = funcs->DrawIndexedTriangles; + funcs->DrawIndexedTriangles = hooked_DrawIndexedTriangles; + + real_FilterQuad = funcs->FilterQuad; + funcs->FilterQuad = hooked_FilterQuad; + + real_RenderingBegin = funcs->RenderingBegin; + funcs->RenderingBegin = hooked_RenderingBegin; + + gdraw->tex_formats = tex_formats; + gdraw->has_mapbuffer = true; + gdraw->has_depth24 = true; + gdraw->has_texture_max_level = true; + + if (hasext_core("GL_EXT_packed_depth_stencil")) + gdraw->has_packed_depth_stencil = true; + + glGetIntegerv(GL_MAX_TEXTURE_SIZE, &n); + gdraw->has_conditional_non_power_of_two = (n < 8192); + + if (msaa_samples > 1) { + glGetIntegerv(GL_MAX_SAMPLES, &n); + gdraw->multisampling = RR_MIN(msaa_samples, n); + } + + opengl_check(); + + fprintf(stderr, + "[GDraw] Context created successfully (%dx%d, msaa=%d)\n", w, h, + msaa_samples); + return funcs; +} + +// Custom draw callbacks +void gdraw_GL_BeginCustomDraw_4J(IggyCustomDrawCallbackRegion* region, + F32* matrix) { + // rebind vbo + if (gdraw_glBindVertexArray && gdraw_vao) + gdraw_glBindVertexArray(gdraw_vao); + clear_renderstate(); + gdraw_GetObjectSpaceMatrix(matrix, region->o2w, gdraw->projection, + depth_from_id(0), 0); +} + +void gdraw_GL_CalculateCustomDraw_4J(IggyCustomDrawCallbackRegion* region, + F32* matrix) { + gdraw_GetObjectSpaceMatrix(matrix, region->o2w, gdraw->projection, 0.0f, 0); +} \ No newline at end of file diff --git a/Minecraft.Client/Platform/Linux/Iggy/gdraw/gdraw_sdl.h b/Minecraft.Client/Platform/Linux/Iggy/gdraw/gdraw.h similarity index 94% rename from Minecraft.Client/Platform/Linux/Iggy/gdraw/gdraw_sdl.h rename to Minecraft.Client/Platform/Linux/Iggy/gdraw/gdraw.h index 063660297..326d5c5a5 100644 --- a/Minecraft.Client/Platform/Linux/Iggy/gdraw/gdraw_sdl.h +++ b/Minecraft.Client/Platform/Linux/Iggy/gdraw/gdraw.h @@ -1,7 +1,9 @@ -#ifndef __RAD_INCLUDE_GDRAW_SDL_H__ -#define __RAD_INCLUDE_GDRAW_SDL_H__ +#ifndef __LINUX_IGGY_GDRAW_H__ +#define __LINUX_IGGY_GDRAW_H__ + #include "../../../Windows64/Iggy/include/gdraw.h" #include "../../../Windows64/Iggy/include/iggy.h" + #ifdef __cplusplus extern "C" { #endif @@ -34,4 +36,5 @@ extern void gdraw_GL_DestroyTextureFromResource(GDrawTexture *tex); #ifdef __cplusplus } #endif -#endif // __RAD_INCLUDE_GDRAW_SDL_H__ \ No newline at end of file + +#endif // __LINUX_IGGY_GDRAW_H__ \ No newline at end of file diff --git a/Minecraft.Client/Platform/Linux/Iggy/gdraw/gdraw_sdl.c b/Minecraft.Client/Platform/Linux/Iggy/gdraw/gdraw_sdl.c deleted file mode 100644 index 7e3506367..000000000 --- a/Minecraft.Client/Platform/Linux/Iggy/gdraw/gdraw_sdl.c +++ /dev/null @@ -1,240 +0,0 @@ -// Rewrite of gdraw_GLFW to gdraw_SDL -// I hope iggy gets fully implemented rrlllly quickly <3 -#define GDRAW_ASSERTS - -#include "../../../Windows64/Iggy/include/iggy.h" -#include "../../../Windows64/Iggy/include/gdraw.h" -#include "gdraw_sdl.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define true 1 -#define false 0 - -// Say hi to sdl - -#ifndef _ENABLEIGGY -void *IggyGDrawMallocAnnotated(SINTa size, const char *file, int line) -{ - (void)file; (void)line; - return malloc((size_t)size); -} - -void IggyGDrawFree(void *ptr) -{ - free(ptr); -} - -void IggyGDrawSendWarning(Iggy *f, char const *message, ...) -{ - (void)f; - va_list args; - va_start(args, message); - fprintf(stderr, "[Iggy GDraw Warning] "); - vfprintf(stderr, message, args); - fprintf(stderr, "\n"); - va_end(args); -} - -void IggyDiscardVertexBufferCallback(void *owner, void *buf) -{ - (void)owner; (void)buf; -} -#endif - -// glActiveTexture and glCompressedTexImage2D are core GL 1.3+ on Linux and -// are declared directly in , so they are omitted from this list. -#define GDRAW_GL_EXTENSION_LIST \ -/* identifier import procname */ \ -/* GL_ARB_vertex_buffer_object */ \ -GLE(GenBuffers, "GenBuffersARB", GENBUFFERSARB) \ -GLE(DeleteBuffers, "DeleteBuffersARB", DELETEBUFFERSARB) \ -GLE(BindBuffer, "BindBufferARB", BINDBUFFERARB) \ -GLE(BufferData, "BufferDataARB", BUFFERDATAARB) \ -GLE(MapBuffer, "MapBufferARB", MAPBUFFERARB) \ -GLE(UnmapBuffer, "UnmapBufferARB", UNMAPBUFFERARB) \ -GLE(VertexAttribPointer, "VertexAttribPointerARB", VERTEXATTRIBPOINTERARB) \ -GLE(EnableVertexAttribArray, "EnableVertexAttribArrayARB", ENABLEVERTEXATTRIBARRAYARB) \ -GLE(DisableVertexAttribArray, "DisableVertexAttribArrayARB", DISABLEVERTEXATTRIBARRAYARB) \ -/* GL_ARB_shader_objects */ \ -GLE(CreateShader, "CreateShaderObjectARB", CREATESHADEROBJECTARB) \ -GLE(DeleteShader, "DeleteObjectARB", DELETEOBJECTARB) \ -GLE(ShaderSource, "ShaderSourceARB", SHADERSOURCEARB) \ -GLE(CompileShader, "CompileShaderARB", COMPILESHADERARB) \ -GLE(GetShaderiv, "GetObjectParameterivARB", GETOBJECTPARAMETERIVARB) \ -GLE(GetShaderInfoLog, "GetInfoLogARB", GETINFOLOGARB) \ -GLE(CreateProgram, "CreateProgramObjectARB", CREATEPROGRAMOBJECTARB) \ -GLE(DeleteProgram, "DeleteObjectARB", DELETEOBJECTARB) \ -GLE(AttachShader, "AttachObjectARB", ATTACHOBJECTARB) \ -GLE(LinkProgram, "LinkProgramARB", LINKPROGRAMARB) \ -GLE(GetUniformLocation, "GetUniformLocationARB", GETUNIFORMLOCATIONARB) \ -GLE(UseProgram, "UseProgramObjectARB", USEPROGRAMOBJECTARB) \ -GLE(GetProgramiv, "GetObjectParameterivARB", GETOBJECTPARAMETERIVARB) \ -GLE(GetProgramInfoLog, "GetInfoLogARB", GETINFOLOGARB) \ -GLE(Uniform1i, "Uniform1iARB", UNIFORM1IARB) \ -GLE(Uniform4f, "Uniform4fARB", UNIFORM4FARB) \ -GLE(Uniform4fv, "Uniform4fvARB", UNIFORM4FVARB) \ -/* GL_ARB_vertex_shader */ \ -GLE(BindAttribLocation, "BindAttribLocationARB", BINDATTRIBLOCATIONARB) \ -/* Missing from WGL but needed by shared code */ \ -GLE(Uniform1f, "Uniform1fARB", UNIFORM1FARB) \ -/* GL_EXT_framebuffer_object */ \ -GLE(GenRenderbuffers, "GenRenderbuffersEXT", GENRENDERBUFFERSEXT) \ -GLE(DeleteRenderbuffers, "DeleteRenderbuffersEXT", DELETERENDERBUFFERSEXT) \ -GLE(BindRenderbuffer, "BindRenderbufferEXT", BINDRENDERBUFFEREXT) \ -GLE(RenderbufferStorage, "RenderbufferStorageEXT", RENDERBUFFERSTORAGEEXT) \ -GLE(GenFramebuffers, "GenFramebuffersEXT", GENFRAMEBUFFERSEXT) \ -GLE(DeleteFramebuffers, "DeleteFramebuffersEXT", DELETEFRAMEBUFFERSEXT) \ -GLE(BindFramebuffer, "BindFramebufferEXT", BINDFRAMEBUFFEREXT) \ -GLE(CheckFramebufferStatus, "CheckFramebufferStatusEXT", CHECKFRAMEBUFFERSTATUSEXT) \ -GLE(FramebufferRenderbuffer, "FramebufferRenderbufferEXT", FRAMEBUFFERRENDERBUFFEREXT) \ -GLE(FramebufferTexture2D, "FramebufferTexture2DEXT", FRAMEBUFFERTEXTURE2DEXT) \ -GLE(GenerateMipmap, "GenerateMipmapEXT", GENERATEMIPMAPEXT) \ -/* GL_EXT_framebuffer_blit */ \ -GLE(BlitFramebuffer, "BlitFramebufferEXT", BLITFRAMEBUFFEREXT) \ -/* GL_EXT_framebuffer_multisample */ \ -GLE(RenderbufferStorageMultisample, "RenderbufferStorageMultisampleEXT",RENDERBUFFERSTORAGEMULTISAMPLEEXT) \ -/* */ - -#define gdraw_GLx_(id) gdraw_GL_##id -#define GDRAW_GLx_(id) GDRAW_GL_##id -#define GDRAW_SHADERS "gdraw_gl_shaders.inl" - -// On Linux, GLhandleARB is void* but shader functions use GLuint values. -// Use GLuint as our handle type, matching the Mac pattern from gdraw_gl_shared.inl. -#define GDrawGLProgram GLuint -typedef GLuint GLhandle; -typedef gdraw_gl_resourcetype gdraw_resourcetype; - -// Declare extension function pointers -#define GLE(id, import, procname) static PFNGL##procname##PROC gl##id; -GDRAW_GL_EXTENSION_LIST -#undef GLE - -static void load_extensions(void) -{ - #define GLE(id, import, procname) \ - gl##id = (PFNGL##procname##PROC) SDL_GL_GetProcAddress("gl" import); - GDRAW_GL_EXTENSION_LIST - #undef GLE -} - -static void clear_renderstate_platform_specific(void) -{ - glDisable(GL_ALPHA_TEST); -} - -static void error_msg_platform_specific(const char *msg) -{ - fprintf(stderr, "[GDraw SDL] %s\n", msg); -} - -#define GDRAW_MULTISAMPLING - -// Suppress SIGTRAP from GL debug assertions on Linux -#ifdef RR_BREAK -#undef RR_BREAK -#endif -#define RR_BREAK() \ - do { fprintf(stderr, "[GDraw] RR_BREAK suppressed (GL error)\n"); } while(0) - -#include "../../../Windows64/Iggy/gdraw/gdraw_gl_shared.inl" - -// Context creation and management - -GDrawFunctions *gdraw_GL_CreateContext(S32 w, S32 h, S32 msaa_samples) -{ - static const TextureFormatDesc tex_formats[] = { - { IFT_FORMAT_rgba_8888, 1, 1, 4, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE }, - { IFT_FORMAT_rgba_4444_LE, 1, 1, 2, GL_RGBA4, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4 }, - { IFT_FORMAT_rgba_5551_LE, 1, 1, 2, GL_RGB5_A1, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1 }, - { IFT_FORMAT_la_88, 1, 1, 2, GL_LUMINANCE8_ALPHA8, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE }, - { IFT_FORMAT_la_44, 1, 1, 1, GL_LUMINANCE4_ALPHA4, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE }, - { IFT_FORMAT_i_8, 1, 1, 1, GL_INTENSITY8, GL_ALPHA, GL_UNSIGNED_BYTE }, - { IFT_FORMAT_i_4, 1, 1, 1, GL_INTENSITY4, GL_ALPHA, GL_UNSIGNED_BYTE }, - { IFT_FORMAT_l_8, 1, 1, 1, GL_LUMINANCE8, GL_LUMINANCE, GL_UNSIGNED_BYTE }, - { IFT_FORMAT_l_4, 1, 1, 1, GL_LUMINANCE4, GL_LUMINANCE, GL_UNSIGNED_BYTE }, - { IFT_FORMAT_DXT1, 4, 4, 8, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, 0, GL_UNSIGNED_BYTE }, - { IFT_FORMAT_DXT3, 4, 4, 16, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, 0, GL_UNSIGNED_BYTE }, - { IFT_FORMAT_DXT5, 4, 4, 16, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, 0, GL_UNSIGNED_BYTE }, - { 0, 0, 0, 0, 0, 0, 0 }, - }; - - GDrawFunctions *funcs; - const char *s; - GLint n; - - // A current SDL2 GL context must be active before calling this, if it doesn't exist, just throw an warning- - s = (const char *) glGetString(GL_EXTENSIONS); - if (!s) { - fprintf(stderr, "[GDraw SDL] glGetString(GL_EXTENSIONS) returned NULL - " - "SDL GL context not current?\n"); - assert(s != NULL); - return NULL; - } - - // Verify required extensions - if (!hasext(s, "GL_ARB_multitexture") || - !hasext(s, "GL_ARB_texture_compression") || - !hasext(s, "GL_ARB_texture_mirrored_repeat") || - !hasext(s, "GL_ARB_texture_non_power_of_two") || - !hasext(s, "GL_ARB_vertex_buffer_object") || - !hasext(s, "GL_EXT_framebuffer_object") || - !hasext(s, "GL_ARB_shader_objects") || - !hasext(s, "GL_ARB_vertex_shader") || - !hasext(s, "GL_ARB_fragment_shader")) - { - fprintf(stderr, "[GDraw SDL] Required GL extensions not available\n"); - return NULL; - } - - if (!hasext(s, "GL_EXT_framebuffer_multisample") && msaa_samples > 1) - return NULL; - - load_extensions(); - funcs = create_context(w, h); - if (!funcs) - return NULL; - - gdraw->tex_formats = tex_formats; - - gdraw->has_mapbuffer = true; // core in ARB_vertex_buffer_object - gdraw->has_depth24 = true; - gdraw->has_texture_max_level = true; // core GL - - if (hasext(s, "GL_EXT_packed_depth_stencil")) - gdraw->has_packed_depth_stencil = true; - - glGetIntegerv(GL_MAX_TEXTURE_SIZE, &n); - gdraw->has_conditional_non_power_of_two = (n < 8192); - - if (msaa_samples > 1) { - glGetIntegerv(GL_MAX_SAMPLES, &n); - gdraw->multisampling = RR_MIN(msaa_samples, n); - } - - opengl_check(); - - fprintf(stderr, "[GDraw SDL] Context created successfully (%dx%d, msaa=%d)\n", - w, h, msaa_samples); - return funcs; -} - -void gdraw_GL_BeginCustomDraw_4J(IggyCustomDrawCallbackRegion *region, F32 *matrix) -{ - clear_renderstate(); - gdraw_GetObjectSpaceMatrix(matrix, region->o2w, gdraw->projection, depth_from_id(0), 0); -} - -void gdraw_GL_CalculateCustomDraw_4J(IggyCustomDrawCallbackRegion *region, F32 *matrix) -{ - gdraw_GetObjectSpaceMatrix(matrix, region->o2w, gdraw->projection, 0.0f, 0); -} diff --git a/Minecraft.Client/Platform/Linux/LinuxGL.cpp b/Minecraft.Client/Platform/Linux/LinuxGL.cpp index 351bb5d24..1333b5114 100644 --- a/Minecraft.Client/Platform/Linux/LinuxGL.cpp +++ b/Minecraft.Client/Platform/Linux/LinuxGL.cpp @@ -1,7 +1,6 @@ #ifdef __linux__ #include "../stdafx.h" - #include #include #include @@ -11,125 +10,138 @@ #include "../../Minecraft.World/IO/Streams/FloatBuffer.h" #include "../../Minecraft.World/IO/Streams/ByteBuffer.h" -void LinuxGLLogLightmapState(const char* stage, int textureId, bool scaleLight) { - static int logCount = 0; - if (logCount >= 16) return; +#undef glGenTextures +#undef glDeleteTextures +#undef glLight +#undef glLightModel +#undef glGetFloat +#undef glTexGen +#undef glFog +#undef glTexCoordPointer +#undef glNormalPointer +#undef glColorPointer +#undef glVertexPointer +#undef glEndList +#undef glTexImage2D +#undef glCallLists +#undef glReadPixels +#undef glActiveTexture - ++logCount; - - static bool loggedSymbols = false; - if (!loggedSymbols) { - loggedSymbols = true; - app.DebugPrintf( - "[linux-lightmap] linuxgl symbols glActiveTexture=%p " - "glClientActiveTexture=%p glMultiTexCoord2f=%p\n", - reinterpret_cast(::glActiveTexture), - reinterpret_cast(::glClientActiveTexture), - reinterpret_cast(::glMultiTexCoord2f)); - } - - GLint activeTexture = 0; - GLint matrixMode = 0; - ::glGetIntegerv(GL_ACTIVE_TEXTURE, &activeTexture); - ::glGetIntegerv(GL_MATRIX_MODE, &matrixMode); - - const GLint restoreTexture = activeTexture; - ::glActiveTexture(GL_TEXTURE1); - - GLint unit1Binding = 0; - ::glGetIntegerv(GL_TEXTURE_BINDING_2D, &unit1Binding); - const bool unit1Enabled = (::glIsEnabled(GL_TEXTURE_2D) == GL_TRUE); - - GLfloat textureMatrix[16]; - ::glGetFloatv(GL_TEXTURE_MATRIX, textureMatrix); - - ::glActiveTexture(restoreTexture); - - app.DebugPrintf( - "[linux-lightmap] %s tex=%d scale=%d active=%#x matrixMode=%#x " - "unit1Bound=%d unit1Enabled=%d texMatrix=[%.4f %.4f %.4f %.4f]\n", - stage, textureId, scaleLight ? 1 : 0, activeTexture, matrixMode, - unit1Binding, unit1Enabled ? 1 : 0, textureMatrix[0], textureMatrix[5], - textureMatrix[12], textureMatrix[13]); -} - -int glGenTextures() { - GLuint id = 0; - ::glGenTextures(1, &id); - return (int)id; -} - -void glGenTextures(IntBuffer* buf) { +// _4j suffix shit (todo: make ts better) +void glGenTextures_4J(IntBuffer* buf) { GLuint id = 0; ::glGenTextures(1, &id); buf->put((int)id); buf->flip(); } -void glDeleteTextures(int id) { - GLuint uid = (GLuint)id; - ::glDeleteTextures(1, &uid); +void glDeleteTextures_4J(IntBuffer* buf) { + if (buf && buf->limit() > 0) { + int id = buf->get(0); + GLuint uid = (GLuint)id; + ::glDeleteTextures(1, &uid); + } } -void glDeleteTextures(IntBuffer* buf) { - int id = buf->get(0); - GLuint uid = (GLuint)id; - ::glDeleteTextures(1, &uid); -} - -void glLight(int light, int pname, FloatBuffer* params) { +void glLight_4J(int light, int pname, FloatBuffer* params) { ::glLightfv((GLenum)light, (GLenum)pname, params->_getDataPointer()); } -void glLightModel(int pname, FloatBuffer* params) { +void glLightModel_4J(int pname, FloatBuffer* params) { ::glLightModelfv((GLenum)pname, params->_getDataPointer()); } -void glGetFloat(int pname, FloatBuffer* params) { +void glGetFloat_4J(int pname, FloatBuffer* params) { ::glGetFloatv((GLenum)pname, params->_getDataPointer()); } -void glTexGen(int coord, int pname, FloatBuffer* params) { +void glTexGen_4J(int coord, int pname, FloatBuffer* params) { ::glTexGenfv((GLenum)coord, (GLenum)pname, params->_getDataPointer()); } -void glFog(int pname, FloatBuffer* params) { +void glFog_4J(int pname, FloatBuffer* params) { ::glFogfv((GLenum)pname, params->_getDataPointer()); } -void glTexCoordPointer(int size, int type, FloatBuffer* pointer) { +void glTexCoordPointer_4J(int size, int type, FloatBuffer* pointer) { ::glTexCoordPointer(size, (GLenum)type, 0, pointer->_getDataPointer()); } -void glNormalPointer(int type, ByteBuffer* pointer) { +void glNormalPointer_4J(int type, ByteBuffer* pointer) { ::glNormalPointer((GLenum)type, 0, pointer->getBuffer()); } -void glColorPointer(int size, bool normalized, int stride, - ByteBuffer* pointer) { +void glColorPointer_4J(int size, bool normalized, int stride, + ByteBuffer* pointer) { (void)normalized; ::glColorPointer(size, GL_UNSIGNED_BYTE, stride, pointer->getBuffer()); } -void glVertexPointer(int size, int type, FloatBuffer* pointer) { +void glVertexPointer_4J(int size, int type, FloatBuffer* pointer) { ::glVertexPointer(size, (GLenum)type, 0, pointer->_getDataPointer()); } -void glEndList(int) { ::glEndList(); } +void glEndList_4J(int dummy) { + (void)dummy; + ::glEndList(); +} -void glTexImage2D(int target, int level, int internalformat, int width, - int height, int border, int format, int type, - ByteBuffer* pixels) { +void glTexImage2D_4J(int target, int level, int internalformat, int width, + int height, int border, int format, int type, + ByteBuffer* pixels) { void* data = pixels ? pixels->getBuffer() : nullptr; ::glTexImage2D((GLenum)target, level, internalformat, width, height, border, (GLenum)format, (GLenum)type, data); } -void glCallLists(IntBuffer* lists) { +void glCallLists_4J(IntBuffer* lists) { int count = lists->limit() - lists->position(); ::glCallLists(count, GL_INT, lists->getBuffer()); } +void glReadPixels_4J(int x, int y, int width, int height, int format, int type, + ByteBuffer* pixels) { + ::glReadPixels(x, y, width, height, (GLenum)format, (GLenum)type, + pixels->getBuffer()); +} + +void glGetFloat(int pname, FloatBuffer* params) { + glGetFloat_4J(pname, params); +} +void glGenTextures(IntBuffer* buf) { glGenTextures_4J(buf); } +void glDeleteTextures(IntBuffer* buf) { glDeleteTextures_4J(buf); } +void glLight(int light, int pname, FloatBuffer* params) { + glLight_4J(light, pname, params); +} +void glLightModel(int pname, FloatBuffer* params) { + glLightModel_4J(pname, params); +} +void glTexGen(int coord, int pname, FloatBuffer* params) { + glTexGen_4J(coord, pname, params); +} +void glFog(int pname, FloatBuffer* params) { glFog_4J(pname, params); } +void glTexCoordPointer(int size, int type, FloatBuffer* pointer) { + glTexCoordPointer_4J(size, type, pointer); +} +void glNormalPointer(int type, ByteBuffer* pointer) { + glNormalPointer_4J(type, pointer); +} +void glColorPointer(int size, bool normalized, int stride, + ByteBuffer* pointer) { + glColorPointer_4J(size, normalized, stride, pointer); +} +void glVertexPointer(int size, int type, FloatBuffer* pointer) { + glVertexPointer_4J(size, type, pointer); +} +void glTexImage2D(int t, int l, int i, int w, int h, int b, int f, int ty, + ByteBuffer* p) { + glTexImage2D_4J(t, l, i, w, h, b, f, ty, p); +} +void glCallLists(IntBuffer* lists) { glCallLists_4J(lists); } +void glReadPixels(int x, int y, int w, int h, int f, int t, ByteBuffer* p) { + glReadPixels_4J(x, y, w, h, f, t, p); +} + static PFNGLGENQUERIESARBPROC _glGenQueriesARB = nullptr; static PFNGLBEGINQUERYARBPROC _glBeginQueryARB = nullptr; static PFNGLENDQUERYARBPROC _glEndQueryARB = nullptr; @@ -148,7 +160,7 @@ static void initQueryFuncs() { RTLD_DEFAULT, "glGetQueryObjectuivARB"); } -void glGenQueriesARB(IntBuffer* buf) { +void glGenQueriesARB_4J(IntBuffer* buf) { initQueryFuncs(); if (_glGenQueriesARB) { GLuint id = 0; @@ -157,18 +169,21 @@ void glGenQueriesARB(IntBuffer* buf) { buf->flip(); } } +void glGenQueriesARB(IntBuffer* buf) { glGenQueriesARB_4J(buf); } -void glBeginQueryARB(int target, int id) { +void glBeginQueryARB_4J(int target, int id) { initQueryFuncs(); if (_glBeginQueryARB) _glBeginQueryARB((GLenum)target, (GLuint)id); } +void glBeginQueryARB(int target, int id) { glBeginQueryARB_4J(target, id); } -void glEndQueryARB(int target) { +void glEndQueryARB_4J(int target) { initQueryFuncs(); if (_glEndQueryARB) _glEndQueryARB((GLenum)target); } +void glEndQueryARB(int target) { glEndQueryARB_4J(target); } -void glGetQueryObjectuARB(int id, int pname, IntBuffer* params) { +void glGetQueryObjectuARB_4J(int id, int pname, IntBuffer* params) { initQueryFuncs(); if (_glGetQueryObjectuivARB) { GLuint val = 0; @@ -177,11 +192,30 @@ void glGetQueryObjectuARB(int id, int pname, IntBuffer* params) { params->flip(); } } - -void glReadPixels(int x, int y, int width, int height, int format, int type, - ByteBuffer* pixels) { - ::glReadPixels(x, y, width, height, (GLenum)format, (GLenum)type, - pixels->getBuffer()); +void glGetQueryObjectuARB(int id, int pname, IntBuffer* params) { + glGetQueryObjectuARB_4J(id, pname, params); } -#endif +void LinuxGLLogLightmapState(const char* stage, int textureId, + bool scaleLight) { + static int logCount = 0; + if (logCount >= 16) return; + ++logCount; + + GLint activeTexture = 0; + ::glGetIntegerv(GL_ACTIVE_TEXTURE, &activeTexture); + const GLint restoreTexture = activeTexture; + ::glActiveTexture(GL_TEXTURE1); + GLint unit1Binding = 0; + ::glGetIntegerv(GL_TEXTURE_BINDING_2D, &unit1Binding); + const bool unit1Enabled = (::glIsEnabled(GL_TEXTURE_2D) == GL_TRUE); + ::glActiveTexture(restoreTexture); + + app.DebugPrintf( + "[linux-lightmap] %s tex=%d scale=%d active=%#x unit1Bound=%d " + "unit1Enabled=%d\n", + stage, textureId, scaleLight ? 1 : 0, activeTexture, unit1Binding, + unit1Enabled ? 1 : 0); +} + +#endif \ No newline at end of file diff --git a/Minecraft.Client/Platform/Linux/Linux_UIController.cpp b/Minecraft.Client/Platform/Linux/Linux_UIController.cpp index 4a39e85ef..445fd5d9d 100644 --- a/Minecraft.Client/Platform/Linux/Linux_UIController.cpp +++ b/Minecraft.Client/Platform/Linux/Linux_UIController.cpp @@ -1,3 +1,4 @@ +// Linux_UIController.cpp #include "../../../Minecraft.World/Platform/stdafx.h" #include "Linux_UIController.h" @@ -6,34 +7,34 @@ #include "../../Textures/Textures.h" // GDraw GL backend for Linux -#include "Iggy/gdraw/gdraw_sdl.h" +#include "Iggy/gdraw/gdraw.h" +#include "4J_Render.h" ConsoleUIController ui; static void restoreFixedFunctionStateAfterIggy() { - glColor4f(1.0f, 1.0f, 1.0f, 1.0f); - glEnable(GL_ALPHA_TEST); - glAlphaFunc(GL_GREATER, 0.1f); - glEnable(GL_DEPTH_TEST); - glDepthFunc(GL_LEQUAL); - glEnable(GL_CULL_FACE); - glCullFace(GL_BACK); + RenderManager.StateSetColour(1.0f, 1.0f, 1.0f, 1.0f); + RenderManager.StateSetAlphaTestEnable(true); + RenderManager.StateSetAlphaFunc(GL_GREATER, 0.1f); - glClientActiveTexture(GL_TEXTURE1); - glActiveTexture(GL_TEXTURE1); - glDisable(GL_TEXTURE_2D); - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - glMatrixMode(GL_TEXTURE); - glLoadIdentity(); + RenderManager.StateSetDepthTestEnable(true); + RenderManager.StateSetDepthFunc(GL_LEQUAL); + RenderManager.StateSetDepthMask(true); - glClientActiveTexture(GL_TEXTURE0); - glActiveTexture(GL_TEXTURE0); - glEnable(GL_TEXTURE_2D); - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - glMatrixMode(GL_TEXTURE); - glLoadIdentity(); + RenderManager.StateSetFaceCull(true); + RenderManager.StateSetActiveTexture(GL_TEXTURE1); + RenderManager.StateSetTextureEnable(false); + RenderManager.MatrixMode(GL_TEXTURE); + RenderManager.MatrixSetIdentity(); - glMatrixMode(GL_MODELVIEW); + RenderManager.StateSetActiveTexture(GL_TEXTURE0); + RenderManager.StateSetTextureEnable(true); + RenderManager.MatrixMode(GL_TEXTURE); + + RenderManager.MatrixSetIdentity(); + RenderManager.MatrixMode(GL_MODELVIEW); + + RenderManager.Set_matrixDirty(); } void ConsoleUIController::init(S32 w, S32 h) { @@ -66,8 +67,11 @@ void ConsoleUIController::render() { if (!gdraw_funcs) return; gdraw_GL_SetTileOrigin(0, 0, 0); - if (!app.GetGameStarted() && gdraw_funcs->ClearID) { - gdraw_funcs->ClearID(); + if (!app.GetGameStarted()) { + glDisable(GL_SCISSOR_TEST); + glClearDepth(1.0); + glDepthMask(GL_TRUE); + glClear(GL_DEPTH_BUFFER_BIT); } // render @@ -138,4 +142,4 @@ void ConsoleUIController::shutdown() { gdraw_funcs = nullptr; } #endif -} +} \ No newline at end of file diff --git a/Minecraft.Client/Platform/stdafx.h b/Minecraft.Client/Platform/stdafx.h index aa113c2c0..e305669a7 100644 --- a/Minecraft.Client/Platform/stdafx.h +++ b/Minecraft.Client/Platform/stdafx.h @@ -5,8 +5,8 @@ #pragma once -//#include -//#include +// #include +// #include #define __STR2__(x) #x #define __STR1__(x) __STR2__(x) @@ -34,7 +34,7 @@ #include #include #include -#include +#include #include #include #include @@ -49,7 +49,7 @@ #include #include #include -#include +#include #include #include "../Platform/PSVita/PSVitaExtras/PSVitaTypes.h" #include "../Platform/PSVita/PSVitaExtras/PSVitaStubs.h" @@ -71,8 +71,8 @@ typedef unsigned __int64 __uint64; #endif -#ifdef _WINDOWS64 -#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers +#ifdef _WINDOWS64 +#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers // Windows Header Files: #include #include @@ -80,14 +80,12 @@ typedef unsigned __int64 __uint64; // TODO: reference additional headers your program requires here #include #include -using namespace DirectX; +using namespace DirectX; #define HRESULT_SUCCEEDED(hr) (((HRESULT)(hr)) >= 0) #endif - - #ifdef _DURANGO #include #include @@ -95,14 +93,12 @@ using namespace DirectX; #include #include #include -using namespace DirectX; +using namespace DirectX; #include #include "../Platform/Durango/DurangoExtras/DurangoStubs.h" #define HRESULT_SUCCEEDED(hr) (((HRESULT)(hr)) >= 0) #endif - - #ifdef _XBOX #include #include @@ -166,42 +162,42 @@ typedef XUID GameSessionUID; #include "../../Minecraft.World/Util/PerformanceTimer.h" #ifdef _XBOX - #include "xbox/4JLibs/inc/4J_Input.h" - #include "xbox/4JLibs/inc/4J_Profile.h" - #include "xbox/4JLibs/inc/4J_Render.h" - #include "xbox/4JLibs/inc/4J_XTMS.h" - #include "xbox/4JLibs/inc/4J_Storage.h" -#elif defined (__PS3__) +#include "xbox/4JLibs/inc/4J_Input.h" +#include "xbox/4JLibs/inc/4J_Profile.h" +#include "xbox/4JLibs/inc/4J_Render.h" +#include "xbox/4JLibs/inc/4J_XTMS.h" +#include "xbox/4JLibs/inc/4J_Storage.h" +#elif defined(__PS3__) - #include "../Platform/PS3/4JLibs/inc/4J_Input.h" - #include "../Platform/PS3/4JLibs/inc/4J_Profile.h" - #include "../Platform/PS3/4JLibs/inc/4J_Render.h" - #include "../Platform/PS3/4JLibs/inc/4J_Storage.h" +#include "../Platform/PS3/4JLibs/inc/4J_Input.h" +#include "../Platform/PS3/4JLibs/inc/4J_Profile.h" +#include "../Platform/PS3/4JLibs/inc/4J_Render.h" +#include "../Platform/PS3/4JLibs/inc/4J_Storage.h" #elif defined _DURANGO - #include "../Platform/Durango/4JLibs/inc/4J_Input.h" - #include "../Platform/Durango/4JLibs/inc/4J_Profile.h" - #include "../Platform/Durango/4JLibs/inc/4J_Render.h" - #include "../Platform/Durango/4JLibs/inc/4J_Storage.h" +#include "../Platform/Durango/4JLibs/inc/4J_Input.h" +#include "../Platform/Durango/4JLibs/inc/4J_Profile.h" +#include "../Platform/Durango/4JLibs/inc/4J_Render.h" +#include "../Platform/Durango/4JLibs/inc/4J_Storage.h" #elif defined _WINDOWS64 - #include "../Platform/Windows64/4JLibs/inc/4J_Input.h" - #include "../Platform/Windows64/4JLibs/inc/4J_Profile.h" - #include "../Platform/Windows64/4JLibs/inc/4J_Render.h" - #include "../Platform/Windows64/4JLibs/inc/4J_Storage.h" +#include "../Platform/Windows64/4JLibs/inc/4J_Input.h" +#include "../Platform/Windows64/4JLibs/inc/4J_Profile.h" +#include "../Platform/Windows64/4JLibs/inc/4J_Render.h" +#include "../Platform/Windows64/4JLibs/inc/4J_Storage.h" #elif defined __linux__ - #include "4J_Input.h" - #include "4J_Profile.h" - #include "4J_Render.h" - #include "4J_Storage.h" +#include "4J_Input.h" +#include "4J_Profile.h" +#include "4J_Render.h" +#include "4J_Storage.h" #elif defined __PSVITA__ - #include "../Platform/PSVita/4JLibs/inc/4J_Input.h" - #include "../Platform/PSVita/4JLibs/inc/4J_Profile.h" - #include "../Platform/PSVita/4JLibs/inc/4J_Render.h" - #include "../Platform/PSVita/4JLibs/inc/4J_Storage.h" +#include "../Platform/PSVita/4JLibs/inc/4J_Input.h" +#include "../Platform/PSVita/4JLibs/inc/4J_Profile.h" +#include "../Platform/PSVita/4JLibs/inc/4J_Render.h" +#include "../Platform/PSVita/4JLibs/inc/4J_Storage.h" #else - #include "../Platform/Orbis/4JLibs/inc/4J_Input.h" - #include "../Platform/Orbis/4JLibs/inc/4J_Profile.h" - #include "../Platform/Orbis/4JLibs/inc/4J_Render.h" - #include "../Platform/Orbis/4JLibs/inc/4J_Storage.h" +#include "../Platform/Orbis/4JLibs/inc/4J_Input.h" +#include "../Platform/Orbis/4JLibs/inc/4J_Profile.h" +#include "../Platform/Orbis/4JLibs/inc/4J_Render.h" +#include "../Platform/Orbis/4JLibs/inc/4J_Storage.h" #endif #include "../Textures/Textures.h" @@ -229,7 +225,7 @@ typedef XUID GameSessionUID; #include "../Platform/Common/App_enums.h" #include "../Platform/Common/Tutorial/TutorialEnum.h" #include "../Platform/Common/App_structs.h" -//#endif +// #endif #include "../Platform/Common/Consoles_App.h" #include "../Platform/Common/Minecraft_Macros.h" @@ -242,95 +238,94 @@ typedef XUID GameSessionUID; #include "strings.h" #ifdef _XBOX - #include "../Platform/Xbox/Xbox_App.h" - #include "../Platform/Xbox/Sentient/MinecraftTelemetry.h" - #include "../Platform/Xbox/Sentient/DynamicConfigurations.h" - #include "../Platform/Xbox/Sentient/SentientTelemetryCommon.h" - #include "../Platform/Xbox/Sentient/Include/SenClientStats.h" - #include "../Platform/Xbox/GameConfig/Minecraft.spa.h" - #include "../../Minecraft.Assets/XboxMedia/4J_strings.h" - #include "../Platform/Xbox/XML/ATGXmlParser.h" - #include "../Platform/Xbox/Leaderboards/XboxLeaderboardManager.h" - #include "../Platform/Xbox/Social/SocialManager.h" - #include "../Platform/Xbox/Audio/SoundEngine.h" - #include "../Platform/Xbox/Xbox_UIController.h" +#include "../Platform/Xbox/Xbox_App.h" +#include "../Platform/Xbox/Sentient/MinecraftTelemetry.h" +#include "../Platform/Xbox/Sentient/DynamicConfigurations.h" +#include "../Platform/Xbox/Sentient/SentientTelemetryCommon.h" +#include "../Platform/Xbox/Sentient/Include/SenClientStats.h" +#include "../Platform/Xbox/GameConfig/Minecraft.spa.h" +#include "../../Minecraft.Assets/XboxMedia/4J_strings.h" +#include "../Platform/Xbox/XML/ATGXmlParser.h" +#include "../Platform/Xbox/Leaderboards/XboxLeaderboardManager.h" +#include "../Platform/Xbox/Social/SocialManager.h" +#include "../Platform/Xbox/Audio/SoundEngine.h" +#include "../Platform/Xbox/Xbox_UIController.h" -#elif defined (__PS3__) - #include "extraX64client.h" - #include "../Platform/PS3/Sentient/MinecraftTelemetry.h" - #include "../Platform/PS3/Sentient/DynamicConfigurations.h" - #include "../Platform/PS3/Sentient/SentientTelemetryCommon.h" - #include "../Platform/PS3/PS3_App.h" - #include "../Platform/PS3/GameConfig/Minecraft.spa.h" - #include "../../Minecraft.Assets/PS3Media/4J_strings.h" - #include "../Platform/PS3/XML/ATGXmlParser.h" - #include "../Platform/PS3/Social/SocialManager.h" - #include "../Platform/Common/Audio/SoundEngine.h" - #include "../Platform/PS3/Iggy/include/iggy.h" - #include "../Platform/PS3/Iggy/gdraw/gdraw_ps3gcm.h" - #include "../Platform/PS3/PS3_UIController.h" +#elif defined(__PS3__) +#include "extraX64client.h" +#include "../Platform/PS3/Sentient/MinecraftTelemetry.h" +#include "../Platform/PS3/Sentient/DynamicConfigurations.h" +#include "../Platform/PS3/Sentient/SentientTelemetryCommon.h" +#include "../Platform/PS3/PS3_App.h" +#include "../Platform/PS3/GameConfig/Minecraft.spa.h" +#include "../../Minecraft.Assets/PS3Media/4J_strings.h" +#include "../Platform/PS3/XML/ATGXmlParser.h" +#include "../Platform/PS3/Social/SocialManager.h" +#include "../Platform/Common/Audio/SoundEngine.h" +#include "../Platform/PS3/Iggy/include/iggy.h" +#include "../Platform/PS3/Iggy/gdraw/gdraw_ps3gcm.h" +#include "../Platform/PS3/PS3_UIController.h" #elif defined _DURANGO - #include "../Platform/Durango/Sentient/MinecraftTelemetry.h" - #include "../Platform/Durango/Durango_App.h" - #include "../Platform/Durango/Sentient/DynamicConfigurations.h" - #include "../Platform/Durango/Sentient/TelemetryEnum.h" - #include "../Platform/Durango/Sentient/SentientTelemetryCommon.h" - #include "../Platform/Durango/PresenceIds.h" - #include "../../Minecraft.Assets/DurangoMedia/4J_strings.h" - #include "../Platform/Durango/XML/ATGXmlParser.h" - #include "../Platform/Durango/Social/SocialManager.h" - #include "../Platform/Common/Audio/SoundEngine.h" - #include "../Platform/Durango/Iggy/include/iggy.h" - #include "../Platform/Durango/Iggy/gdraw/gdraw_d3d11.h" - #include "../Platform/Durango/Durango_UIController.h" +#include "../Platform/Durango/Sentient/MinecraftTelemetry.h" +#include "../Platform/Durango/Durango_App.h" +#include "../Platform/Durango/Sentient/DynamicConfigurations.h" +#include "../Platform/Durango/Sentient/TelemetryEnum.h" +#include "../Platform/Durango/Sentient/SentientTelemetryCommon.h" +#include "../Platform/Durango/PresenceIds.h" +#include "../../Minecraft.Assets/DurangoMedia/4J_strings.h" +#include "../Platform/Durango/XML/ATGXmlParser.h" +#include "../Platform/Durango/Social/SocialManager.h" +#include "../Platform/Common/Audio/SoundEngine.h" +#include "../Platform/Durango/Iggy/include/iggy.h" +#include "../Platform/Durango/Iggy/gdraw/gdraw_d3d11.h" +#include "../Platform/Durango/Durango_UIController.h" #elif defined _WINDOWS64 - #include "../Platform/Windows64/Sentient/MinecraftTelemetry.h" - #include "../Platform/Windows64/Windows64_App.h" - #include "../Platform/Windows64/Sentient/DynamicConfigurations.h" - #include "../Platform/Windows64/Sentient/SentientTelemetryCommon.h" - #include "../Platform/Windows64/GameConfig/Minecraft.spa.h" - #include "../Platform/Windows64/XML/ATGXmlParser.h" - #include "../Platform/Windows64/Social/SocialManager.h" - #include "../Platform/Common/Audio/SoundEngine.h" - #include "../Platform/Windows64/Iggy/include/iggy.h" - #include "../Platform/Windows64/Iggy/gdraw/gdraw_d3d11.h" - #include "../Platform/Windows64/Windows64_UIController.h" +#include "../Platform/Windows64/Sentient/MinecraftTelemetry.h" +#include "../Platform/Windows64/Windows64_App.h" +#include "../Platform/Windows64/Sentient/DynamicConfigurations.h" +#include "../Platform/Windows64/Sentient/SentientTelemetryCommon.h" +#include "../Platform/Windows64/GameConfig/Minecraft.spa.h" +#include "../Platform/Windows64/XML/ATGXmlParser.h" +#include "../Platform/Windows64/Social/SocialManager.h" +#include "../Platform/Common/Audio/SoundEngine.h" +#include "../Platform/Windows64/Iggy/include/iggy.h" +#include "../Platform/Windows64/Iggy/gdraw/gdraw_d3d11.h" +#include "../Platform/Windows64/Windows64_UIController.h" #elif defined __linux__ - // Linux build: avoid pulling in Windows64 platform headers (they cause - // symbol/class redefinitions). Use Orbis-compatible stubs and Linux controller. - #include "../Platform/Linux/Linux_App.h" - #include "../Platform/Linux/Iggy/include/iggy.h" - #include "../Platform/Linux/Sentient/SentientTelemetryCommon.h" - #include "../Platform/Linux/Sentient/DynamicConfigurations.h" - #include "../Platform/Orbis/GameConfig/Minecraft.spa.h" - #include "../Platform/Common/Audio/SoundEngine.h" - #include "../Platform/Linux/Linux_UIController.h" - #include "../Platform/Linux/Social/SocialManager.h" +// todo: cleanup ts +#include "../Platform/Linux/Linux_App.h" +#include "../Platform/Linux/Iggy/include/iggy.h" +#include "../Platform/Linux/Sentient/SentientTelemetryCommon.h" +#include "../Platform/Linux/Sentient/DynamicConfigurations.h" +#include "../Platform/Orbis/GameConfig/Minecraft.spa.h" +#include "../Platform/Common/Audio/SoundEngine.h" +#include "../Platform/Linux/Linux_UIController.h" +#include "../Platform/Linux/Social/SocialManager.h" #elif defined __PSVITA__ - #include "../Platform/PSVita/PSVita_App.h" - #include "../Platform/PSVita/Sentient/SentientManager.h" - #include "../Platform/PSVita/Sentient/MinecraftTelemetry.h" - #include "../Platform/PSVita/Sentient/DynamicConfigurations.h" - #include "../Platform/PSVita/GameConfig/Minecraft.spa.h" - #include "../Platform/PSVita/XML/ATGXmlParser.h" - #include "../Platform/PSVita/Social/SocialManager.h" - #include "../Platform/Common/Audio/SoundEngine.h" - #include "../Platform/PSVita/Iggy/include/iggy.h" - #include "../Platform/PSVita/Iggy/gdraw/gdraw_psp2.h" - #include "../Platform/PSVita/PSVita_UIController.h" +#include "../Platform/PSVita/PSVita_App.h" +#include "../Platform/PSVita/Sentient/SentientManager.h" +#include "../Platform/PSVita/Sentient/MinecraftTelemetry.h" +#include "../Platform/PSVita/Sentient/DynamicConfigurations.h" +#include "../Platform/PSVita/GameConfig/Minecraft.spa.h" +#include "../Platform/PSVita/XML/ATGXmlParser.h" +#include "../Platform/PSVita/Social/SocialManager.h" +#include "../Platform/Common/Audio/SoundEngine.h" +#include "../Platform/PSVita/Iggy/include/iggy.h" +#include "../Platform/PSVita/Iggy/gdraw/gdraw_psp2.h" +#include "../Platform/PSVita/PSVita_UIController.h" #else - #include "../Platform/Orbis/Sentient/MinecraftTelemetry.h" - #include "../Platform/Orbis/Orbis_App.h" - #include "../Platform/Orbis/Sentient/SentientTelemetryCommon.h" - #include "../Platform/Orbis/Sentient/DynamicConfigurations.h" - #include "../Platform/Orbis/GameConfig/Minecraft.spa.h" - #include "../../Minecraft.Assets/OrbisMedia/4J_strings.h" - #include "../Platform/Orbis/XML/ATGXmlParser.h" - #include "../Platform/Windows64/Social/SocialManager.h" - #include "../Platform/Common/Audio/SoundEngine.h" - #include "../Platform/Orbis/Iggy/include/iggy.h" - #include "../Platform/Orbis/Iggy/gdraw/gdraw_orbis.h" - #include "../Platform/Orbis/Orbis_UIController.h" +#include "../Platform/Orbis/Sentient/MinecraftTelemetry.h" +#include "../Platform/Orbis/Orbis_App.h" +#include "../Platform/Orbis/Sentient/SentientTelemetryCommon.h" +#include "../Platform/Orbis/Sentient/DynamicConfigurations.h" +#include "../Platform/Orbis/GameConfig/Minecraft.spa.h" +#include "../../Minecraft.Assets/OrbisMedia/4J_strings.h" +#include "../Platform/Orbis/XML/ATGXmlParser.h" +#include "../Platform/Windows64/Social/SocialManager.h" +#include "../Platform/Common/Audio/SoundEngine.h" +#include "../Platform/Orbis/Iggy/include/iggy.h" +#include "../Platform/Orbis/Iggy/gdraw/gdraw_orbis.h" +#include "../Platform/Orbis/Orbis_UIController.h" #endif #ifdef _XBOX @@ -358,13 +353,11 @@ typedef XUID GameSessionUID; #include "../Platform/Common/Telemetry/TelemetryManager.h" #ifdef _XBOX -//#include "../Platform/Xbox/Xbox_App.h" +// #include "../Platform/Xbox/Xbox_App.h" #elif !defined(__PS3__) #include "extraX64client.h" #endif - - #ifdef _FINAL_BUILD #define printf BREAKTHECOMPILE #define wprintf BREAKTHECOMPILE diff --git a/Minecraft.Client/Platform/stubs.h b/Minecraft.Client/Platform/stubs.h index 91464c6a8..9841637ca 100644 --- a/Minecraft.Client/Platform/stubs.h +++ b/Minecraft.Client/Platform/stubs.h @@ -13,30 +13,32 @@ class FloatBuffer; class IntBuffer; class ByteBuffer; -void glGenTextures(IntBuffer *); +void glGenTextures(IntBuffer*); int glGenTextures(); -void glDeleteTextures(IntBuffer *); +void glDeleteTextures(IntBuffer*); void glDeleteTextures(int); -void glLight(int, int, FloatBuffer *); -void glLightModel(int, FloatBuffer *); -void glGetFloat(int, FloatBuffer *); -void glTexGen(int, int, FloatBuffer *); -void glFog(int, FloatBuffer *); -void glTexCoordPointer(int, int, FloatBuffer *); -void glNormalPointer(int, ByteBuffer *); -void glColorPointer(int, bool, int, ByteBuffer *); -void glVertexPointer(int, int, FloatBuffer *); -void glEndList(int); -void glTexImage2D(int, int, int, int, int, int, int, int, ByteBuffer *); -void glCallLists(IntBuffer *); -void glGenQueriesARB(IntBuffer *); +void glLight(int, int, FloatBuffer*); +void glLightModel(int, FloatBuffer*); +void glGetFloat(int, FloatBuffer*); +void glTexGen(int, int, FloatBuffer*); +void glFog(int, FloatBuffer*); +void glTexCoordPointer(int, int, FloatBuffer*); +void glNormalPointer(int, ByteBuffer*); +void glColorPointer(int, bool, int, ByteBuffer*); +void glVertexPointer(int, int, FloatBuffer*); + +void glEndList_4J(int vertexCount = 0); + +void glTexImage2D(int, int, int, int, int, int, int, int, ByteBuffer*); +void glCallLists(IntBuffer*); +void glGenQueriesARB(IntBuffer*); void glBeginQueryARB(int, int); void glEndQueryARB(int); -void glGetQueryObjectuARB(int, int, IntBuffer *); -void glReadPixels(int, int, int, int, int, int, ByteBuffer *); +void glGetQueryObjectuARB(int, int, IntBuffer*); +void glReadPixels(int, int, int, int, int, int, ByteBuffer*); + void LinuxGLLogLightmapState(const char* stage, int textureId, bool scaleLight); void LinuxLogStubLightmapProbe(); - #else const int GL_BYTE = 0; @@ -54,13 +56,9 @@ const int GL_NORMALIZE = 0; const int GL_RESCALE_NORMAL = 0; - - const int GL_SMOOTH = 0; const int GL_FLAT = 0; - - const int GL_RGBA = 0; const int GL_BGRA = 1; const int GL_BGR = 0; @@ -83,73 +81,73 @@ const int GL_TEXTURE1 = 0; const int GL_TEXTURE0 = 1; void glFlush(); -void glTexGeni(int,int,int); -void glTexGen(int,int,FloatBuffer *); -void glReadPixels(int,int, int, int, int, int, ByteBuffer *); +void glTexGeni(int, int, int); +void glTexGen(int, int, FloatBuffer*); +void glReadPixels(int, int, int, int, int, int, ByteBuffer*); void glClearDepth(double); void glCullFace(int); -void glDeleteLists(int,int); -void glGenTextures(IntBuffer *); +void glDeleteLists(int, int); +void glGenTextures(IntBuffer*); int glGenTextures(); int glGenLists(int); -void glLight(int, int,FloatBuffer *); -void glLightModel(int, FloatBuffer *); -void glGetFloat(int a, FloatBuffer *b); +void glLight(int, int, FloatBuffer*); +void glLightModel(int, FloatBuffer*); +void glGetFloat(int a, FloatBuffer* b); void glTexCoordPointer(int, int, int, int); -void glTexCoordPointer(int, int, FloatBuffer *); +void glTexCoordPointer(int, int, FloatBuffer*); void glNormalPointer(int, int, int); -void glNormalPointer(int, ByteBuffer *); +void glNormalPointer(int, ByteBuffer*); void glEnableClientState(int); void glDisableClientState(int); -void glColorPointer(int, bool, int, ByteBuffer *); +void glColorPointer(int, bool, int, ByteBuffer*); void glColorPointer(int, int, int, int); void glVertexPointer(int, int, int, int); -void glVertexPointer(int, int, FloatBuffer *); -void glDrawArrays(int,int,int); -void glTranslatef(float,float,float); -void glRotatef(float,float,float,float); -void glNewList(int,int); +void glVertexPointer(int, int, FloatBuffer*); +void glDrawArrays(int, int, int); +void glTranslatef(float, float, float); +void glRotatef(float, float, float, float); +void glNewList(int, int); void glEndList(int vertexCount = 0); void glCallList(int); void glPopMatrix(); void glPushMatrix(); -void glColor3f(float,float,float); -void glScalef(float,float,float); -void glMultMatrixf(float *); -void glColor4f(float,float,float,float); +void glColor3f(float, float, float); +void glScalef(float, float, float); +void glMultMatrixf(float*); +void glColor4f(float, float, float, float); void glDisable(int); void glEnable(int); -void glBlendFunc(int,int); +void glBlendFunc(int, int); void glDepthMask(bool); -void glNormal3f(float,float,float); +void glNormal3f(float, float, float); void glDepthFunc(int); void glMatrixMode(int); void glLoadIdentity(); -void glBindTexture(int,int); -void glTexParameteri(int,int,int); -void glTexImage2D(int,int,int,int,int,int,int,int,ByteBuffer *); -void glDeleteTextures(IntBuffer *); +void glBindTexture(int, int); +void glTexParameteri(int, int, int); +void glTexImage2D(int, int, int, int, int, int, int, int, ByteBuffer*); +void glDeleteTextures(IntBuffer*); void glDeleteTextures(int); -void glCallLists(IntBuffer *); -void glGenQueriesARB(IntBuffer *); -void glColorMask(bool,bool,bool,bool); -void glBeginQueryARB(int,int); +void glCallLists(IntBuffer*); +void glGenQueriesARB(IntBuffer*); +void glColorMask(bool, bool, bool, bool); +void glBeginQueryARB(int, int); void glEndQueryARB(int); -void glGetQueryObjectuARB(int,int,IntBuffer *); +void glGetQueryObjectuARB(int, int, IntBuffer*); void glShadeModel(int); -void glPolygonOffset(float,float); +void glPolygonOffset(float, float); void glLineWidth(float); -void glScaled(double,double,double); -void gluPerspective(float,float,float,float); +void glScaled(double, double, double); +void gluPerspective(float, float, float, float); void glClear(int); -void glViewport(int,int,int,int); -void glAlphaFunc(int,float); -void glOrtho(float,float,float,float,float,float); -void glClearColor(float,float,float,float); -void glFogi(int,int); -void glFogf(int,float); -void glFog(int,FloatBuffer *); -void glColorMaterial(int,int); +void glViewport(int, int, int, int); +void glAlphaFunc(int, float); +void glOrtho(float, float, float, float, float, float); +void glClearColor(float, float, float, float); +void glFogi(int, int); +void glFogf(int, float); +void glFog(int, FloatBuffer*); +void glColorMaterial(int, int); void glMultiTexCoord2f(int, float, float); void glClientActiveTexture(int); @@ -158,164 +156,150 @@ void glActiveTexture(int); #endif #ifdef __linux__ -class GL11 -{ -public: - static const int GL_SMOOTH = 0x1D01; - static const int GL_FLAT = 0x1D00; - static void glShadeModel(int mode) { ::glShadeModel(mode); } -}; +class GL11 { +public: + static const int GL_SMOOTH = 0x1D01; + static const int GL_FLAT = 0x1D00; +#undef glShadeModel +#define GL_SHADEMODEL_IS_FUNCTION + static void glShadeModel(int mode) { ::glShadeModel(mode); } +}; #undef GL_ARRAY_BUFFER_ARB #undef GL_STREAM_DRAW_ARB -class ARBVertexBufferObject -{ +class ARBVertexBufferObject { public: - static const int GL_ARRAY_BUFFER_ARB = 0x8892; - static const int GL_STREAM_DRAW_ARB = 0x88E0; - static void glBindBufferARB(int, int) {} - static void glBufferDataARB(int, ByteBuffer *, int) {} - static void glGenBuffersARB(IntBuffer *) {} + static const int GL_ARRAY_BUFFER_ARB = 0x8892; + static const int GL_STREAM_DRAW_ARB = 0x88E0; + static void glBindBufferARB(int, int) {} + static void glBufferDataARB(int, ByteBuffer*, int) {} + static void glGenBuffersARB(IntBuffer*) {} }; #else -class GL11 -{ +class GL11 { public: - static const int GL_SMOOTH = 0; - static const int GL_FLAT = 0; - static void glShadeModel(int) {}; + static const int GL_SMOOTH = 0; + static const int GL_FLAT = 0; + static void glShadeModel(int) {}; }; -class ARBVertexBufferObject -{ +class ARBVertexBufferObject { public: - static const int GL_ARRAY_BUFFER_ARB = 0; - static const int GL_STREAM_DRAW_ARB = 0; - static void glBindBufferARB(int, int) {} - static void glBufferDataARB(int, ByteBuffer *, int) {} - static void glGenBuffersARB(IntBuffer *) {} + static const int GL_ARRAY_BUFFER_ARB = 0; + static const int GL_STREAM_DRAW_ARB = 0; + static void glBindBufferARB(int, int) {} + static void glBufferDataARB(int, ByteBuffer*, int) {} + static void glGenBuffersARB(IntBuffer*) {} }; #endif - class Level; class Player; class Textures; class Font; class MapItemSavedData; class Mob; -class Particles -{ +class Particles { public: - void render(float) {} - void tick() {} + void render(float) {} + void tick() {} }; class BufferedImage; -class Graphics -{ +class Graphics { public: - void drawImage(BufferedImage *, int, int, void *) {} - void dispose() {} + void drawImage(BufferedImage*, int, int, void*) {} + void dispose() {} }; -class ZipEntry -{ -}; +class ZipEntry {}; class InputStream; class File; -class ZipFile -{ +class ZipFile { public: - ZipFile(File *file) {} - InputStream *getInputStream(ZipEntry *entry) { return NULL; } - ZipEntry *getEntry(const std::wstring& name) {return NULL;} - void close() {} + ZipFile(File* file) {} + InputStream* getInputStream(ZipEntry* entry) { return NULL; } + ZipEntry* getEntry(const std::wstring& name) { return NULL; } + void close() {} }; -class ImageIO -{ +class ImageIO { public: - static BufferedImage *read(InputStream *in) { return NULL; } + static BufferedImage* read(InputStream* in) { return NULL; } }; -class Keyboard -{ +class Keyboard { public: - static void create() {} - static void destroy() {} - static bool isKeyDown(int) {return false;} - static std::wstring getKeyName(int) { return L"KEYNAME"; } - static void enableRepeatEvents(bool) {} - static const int KEY_A = 0; - static const int KEY_B = 1; - static const int KEY_C = 2; - static const int KEY_D = 3; - static const int KEY_E = 4; - static const int KEY_F = 5; - static const int KEY_G = 6; - static const int KEY_H = 7; - static const int KEY_I = 8; - static const int KEY_J = 9; - static const int KEY_K = 10; - static const int KEY_L = 11; - static const int KEY_M = 12; - static const int KEY_N = 13; - static const int KEY_O = 14; - static const int KEY_P = 15; - static const int KEY_Q = 16; - static const int KEY_R = 17; - static const int KEY_S = 18; - static const int KEY_T = 19; - static const int KEY_U = 20; - static const int KEY_V = 21; - static const int KEY_W = 22; - static const int KEY_X = 23; - static const int KEY_Y = 24; - static const int KEY_Z = 25; - static const int KEY_SPACE = 26; - static const int KEY_LSHIFT = 27; - static const int KEY_ESCAPE = 28; - static const int KEY_BACK = 29; - static const int KEY_RETURN = 30; - static const int KEY_RSHIFT = 31; - static const int KEY_UP = 32; - static const int KEY_DOWN = 33; - static const int KEY_TAB = 34; + static void create() {} + static void destroy() {} + static bool isKeyDown(int) { return false; } + static std::wstring getKeyName(int) { return L"KEYNAME"; } + static void enableRepeatEvents(bool) {} + static const int KEY_A = 0; + static const int KEY_B = 1; + static const int KEY_C = 2; + static const int KEY_D = 3; + static const int KEY_E = 4; + static const int KEY_F = 5; + static const int KEY_G = 6; + static const int KEY_H = 7; + static const int KEY_I = 8; + static const int KEY_J = 9; + static const int KEY_K = 10; + static const int KEY_L = 11; + static const int KEY_M = 12; + static const int KEY_N = 13; + static const int KEY_O = 14; + static const int KEY_P = 15; + static const int KEY_Q = 16; + static const int KEY_R = 17; + static const int KEY_S = 18; + static const int KEY_T = 19; + static const int KEY_U = 20; + static const int KEY_V = 21; + static const int KEY_W = 22; + static const int KEY_X = 23; + static const int KEY_Y = 24; + static const int KEY_Z = 25; + static const int KEY_SPACE = 26; + static const int KEY_LSHIFT = 27; + static const int KEY_ESCAPE = 28; + static const int KEY_BACK = 29; + static const int KEY_RETURN = 30; + static const int KEY_RSHIFT = 31; + static const int KEY_UP = 32; + static const int KEY_DOWN = 33; + static const int KEY_TAB = 34; }; -class Mouse -{ +class Mouse { public: - static void create() {} - static void destroy() {} - static int getX() { return 0; } - static int getY() { return 0; } - static bool isButtonDown(int) { return false; } + static void create() {} + static void destroy() {} + static int getX() { return 0; } + static int getY() { return 0; } + static bool isButtonDown(int) { return false; } }; -class Display -{ +class Display { public: - static bool isActive() {return true;} - static void update(); - static void swapBuffers(); - static void destroy() {} + static bool isActive() { return true; } + static void update(); + static void swapBuffers(); + static void destroy() {} }; -class BackgroundDownloader -{ +class BackgroundDownloader { public: - BackgroundDownloader(File workDir, Minecraft* minecraft) {} - void start() {} - void halt() {} - void forceReload() {} + BackgroundDownloader(File workDir, Minecraft* minecraft) {} + void start() {} + void halt() {} + void forceReload() {} }; -class Color -{ +class Color { public: - static int HSBtoRGB(float,float,float) {return 0;} + static int HSBtoRGB(float, float, float) { return 0; } }; From 09e8a8f9819475291a2e755a277337e7d6b21b0e Mon Sep 17 00:00:00 2001 From: JuiceyDev Date: Fri, 27 Mar 2026 00:36:18 +0100 Subject: [PATCH 111/170] batch 2: fixing chunk rendering & frustum culling; rewrote most of it, but now it works. next step is to fix the "highlight" effect & add the optimizations i wrote on optifromhell.txt --- .../Platform/Linux/Linux_UIController.cpp | 2 +- Minecraft.Client/Rendering/Camera.cpp | 6 +- Minecraft.Client/Rendering/Frustum.cpp | 81 +++++++------------ Minecraft.Client/Rendering/FrustumData.cpp | 15 ++-- Minecraft.Client/Rendering/LevelRenderer.cpp | 21 ++++- Minecraft.Client/Rendering/Tesselator.cpp | 13 ++- 6 files changed, 69 insertions(+), 69 deletions(-) diff --git a/Minecraft.Client/Platform/Linux/Linux_UIController.cpp b/Minecraft.Client/Platform/Linux/Linux_UIController.cpp index 445fd5d9d..f4a1c033a 100644 --- a/Minecraft.Client/Platform/Linux/Linux_UIController.cpp +++ b/Minecraft.Client/Platform/Linux/Linux_UIController.cpp @@ -1,4 +1,4 @@ -// Linux_UIController.cpp +// should we keep Linux_UIController.cpp?* #include "../../../Minecraft.World/Platform/stdafx.h" #include "Linux_UIController.h" diff --git a/Minecraft.Client/Rendering/Camera.cpp b/Minecraft.Client/Rendering/Camera.cpp index f728f3f09..137108089 100644 --- a/Minecraft.Client/Rendering/Camera.cpp +++ b/Minecraft.Client/Rendering/Camera.cpp @@ -22,8 +22,10 @@ float Camera::xa2 = 0.0f; float Camera::za2 = 0.0f; void Camera::prepare(std::shared_ptr player, bool mirror) { - glGetFloat(GL_MODELVIEW_MATRIX, modelview); - glGetFloat(GL_PROJECTION_MATRIX, projection); + memcpy(modelview->_getDataPointer(), + RenderManager.MatrixGet(GL_MODELVIEW_MATRIX), 16 * sizeof(float)); + memcpy(projection->_getDataPointer(), + RenderManager.MatrixGet(GL_PROJECTION_MATRIX), 16 * sizeof(float)); /* Original java code for reference glGetInteger(GL_VIEWPORT, viewport); diff --git a/Minecraft.Client/Rendering/Frustum.cpp b/Minecraft.Client/Rendering/Frustum.cpp index 1144a7d5f..3d2e562ea 100644 --- a/Minecraft.Client/Rendering/Frustum.cpp +++ b/Minecraft.Client/Rendering/Frustum.cpp @@ -1,9 +1,11 @@ #include "../Platform/stdafx.h" #include "../../Minecraft.World/IO/Streams/FloatBuffer.h" #include "Frustum.h" +#include "Camera.h" Frustum* Frustum::frustum = new Frustum(); +// those are now unused but i still gotta do testing. Frustum::Frustum() { _proj = MemoryTracker::createFloatBuffer(16); _modl = MemoryTracker::createFloatBuffer(16); @@ -43,63 +45,38 @@ void Frustum::normalizePlane(float** frustum, int side) { } void Frustum::calculateFrustum() { - _proj->clear(); - _modl->clear(); - _clip->clear(); + // 4jcraft: GL 3.3 core removed GL_MODELVIEW_MATRIX / GL_PROJECTION_MATRIX + // queries. + // Camera::prepare() already captures both matrices every frame :) + // i spent an ungodly amount of time on this simple fix. + memcpy(proj.data, RenderManager.MatrixGet(GL_PROJECTION_MATRIX), + 16 * sizeof(float)); + memcpy(modl.data, RenderManager.MatrixGet(GL_MODELVIEW_MATRIX), + 16 * sizeof(float)); - // glGetFloatv() is used to extract information about our OpenGL world. - // Below, we pass in GL_PROJECTION_MATRIX to abstract our projection matrix. - // It then stores the matrix into an array of [16]. - glGetFloat(GL_PROJECTION_MATRIX, _proj); + float* p = proj.data; + float* m = modl.data; + float* c = clip.data; - // By passing in GL_MODELVIEW_MATRIX, we can abstract our model view matrix. - // This also stores it in an array of [16]. - glGetFloat(GL_MODELVIEW_MATRIX, _modl); + c[0] = m[0] * p[0] + m[1] * p[4] + m[2] * p[8] + m[3] * p[12]; + c[1] = m[0] * p[1] + m[1] * p[5] + m[2] * p[9] + m[3] * p[13]; + c[2] = m[0] * p[2] + m[1] * p[6] + m[2] * p[10] + m[3] * p[14]; + c[3] = m[0] * p[3] + m[1] * p[7] + m[2] * p[11] + m[3] * p[15]; - _proj->flip()->limit(16); - _proj->get(&proj); - _modl->flip()->limit(16); - _modl->get(&modl); + c[4] = m[4] * p[0] + m[5] * p[4] + m[6] * p[8] + m[7] * p[12]; + c[5] = m[4] * p[1] + m[5] * p[5] + m[6] * p[9] + m[7] * p[13]; + c[6] = m[4] * p[2] + m[5] * p[6] + m[6] * p[10] + m[7] * p[14]; + c[7] = m[4] * p[3] + m[5] * p[7] + m[6] * p[11] + m[7] * p[15]; - // Now that we have our modelview and projection matrix, if we combine these - // 2 matrices, it will give us our clipping planes. To combine 2 matrices, - // we multiply them. + c[8] = m[8] * p[0] + m[9] * p[4] + m[10] * p[8] + m[11] * p[12]; + c[9] = m[8] * p[1] + m[9] * p[5] + m[10] * p[9] + m[11] * p[13]; + c[10] = m[8] * p[2] + m[9] * p[6] + m[10] * p[10] + m[11] * p[14]; + c[11] = m[8] * p[3] + m[9] * p[7] + m[10] * p[11] + m[11] * p[15]; - clip[0] = modl[0] * proj[0] + modl[1] * proj[4] + modl[2] * proj[8] + - modl[3] * proj[12]; - clip[1] = modl[0] * proj[1] + modl[1] * proj[5] + modl[2] * proj[9] + - modl[3] * proj[13]; - clip[2] = modl[0] * proj[2] + modl[1] * proj[6] + modl[2] * proj[10] + - modl[3] * proj[14]; - clip[3] = modl[0] * proj[3] + modl[1] * proj[7] + modl[2] * proj[11] + - modl[3] * proj[15]; - - clip[4] = modl[4] * proj[0] + modl[5] * proj[4] + modl[6] * proj[8] + - modl[7] * proj[12]; - clip[5] = modl[4] * proj[1] + modl[5] * proj[5] + modl[6] * proj[9] + - modl[7] * proj[13]; - clip[6] = modl[4] * proj[2] + modl[5] * proj[6] + modl[6] * proj[10] + - modl[7] * proj[14]; - clip[7] = modl[4] * proj[3] + modl[5] * proj[7] + modl[6] * proj[11] + - modl[7] * proj[15]; - - clip[8] = modl[8] * proj[0] + modl[9] * proj[4] + modl[10] * proj[8] + - modl[11] * proj[12]; - clip[9] = modl[8] * proj[1] + modl[9] * proj[5] + modl[10] * proj[9] + - modl[11] * proj[13]; - clip[10] = modl[8] * proj[2] + modl[9] * proj[6] + modl[10] * proj[10] + - modl[11] * proj[14]; - clip[11] = modl[8] * proj[3] + modl[9] * proj[7] + modl[10] * proj[11] + - modl[11] * proj[15]; - - clip[12] = modl[12] * proj[0] + modl[13] * proj[4] + modl[14] * proj[8] + - modl[15] * proj[12]; - clip[13] = modl[12] * proj[1] + modl[13] * proj[5] + modl[14] * proj[9] + - modl[15] * proj[13]; - clip[14] = modl[12] * proj[2] + modl[13] * proj[6] + modl[14] * proj[10] + - modl[15] * proj[14]; - clip[15] = modl[12] * proj[3] + modl[13] * proj[7] + modl[14] * proj[11] + - modl[15] * proj[15]; + c[12] = m[12] * p[0] + m[13] * p[4] + m[14] * p[8] + m[15] * p[12]; + c[13] = m[12] * p[1] + m[13] * p[5] + m[14] * p[9] + m[15] * p[13]; + c[14] = m[12] * p[2] + m[13] * p[6] + m[14] * p[10] + m[15] * p[14]; + c[15] = m[12] * p[3] + m[13] * p[7] + m[14] * p[11] + m[15] * p[15]; // Now we actually want to get the sides of the frustum. To do this we take // the clipping planes we received above and extract the sides from them. diff --git a/Minecraft.Client/Rendering/FrustumData.cpp b/Minecraft.Client/Rendering/FrustumData.cpp index a5f11b768..eb46045e3 100644 --- a/Minecraft.Client/Rendering/FrustumData.cpp +++ b/Minecraft.Client/Rendering/FrustumData.cpp @@ -1,21 +1,22 @@ #include "../Platform/stdafx.h" #include "FrustumData.h" -float** m_Frustum; +// float** m_Frustum; FrustumData::FrustumData() { - m_Frustum = new float*[16]; - for (int i = 0; i < 16; i++) m_Frustum[i] = new float[16]; + this->m_Frustum = new float*[6]; + for (int i = 0; i < 6; i++) { + this->m_Frustum[i] = new float[4]; + } proj = floatArray(16); modl = floatArray(16); clip = floatArray(16); } FrustumData::~FrustumData() { - delete[] proj.data; - delete[] modl.data; - delete[] clip.data; - for (int i = 0; i < 16; i++) delete[] m_Frustum[i]; + for (int i = 0; i < 6; i++) { + delete[] m_Frustum[i]; + } delete[] m_Frustum; } diff --git a/Minecraft.Client/Rendering/LevelRenderer.cpp b/Minecraft.Client/Rendering/LevelRenderer.cpp index 0d5e9afa7..f64a9b284 100644 --- a/Minecraft.Client/Rendering/LevelRenderer.cpp +++ b/Minecraft.Client/Rendering/LevelRenderer.cpp @@ -856,6 +856,10 @@ int LevelRenderer::renderChunks(int from, int to, int layer, double alpha) { if ((globalChunkFlags[pClipChunk->globalIdx] & emptyFlag) == emptyFlag) continue; // Check that this particular layer isn't empty + glPushMatrix(); + + glTranslatef((float)pClipChunk->chunk->x, (float)pClipChunk->chunk->y, + (float)pClipChunk->chunk->z); // List can be calculated directly from the chunk's global idex int list = pClipChunk->globalIdx * 2 + layer; list += chunkLists; @@ -863,6 +867,8 @@ int LevelRenderer::renderChunks(int from, int to, int layer, double alpha) { if (RenderManager.CBuffCall(list, first)) { first = false; } + + glPopMatrix(); count++; } @@ -2248,9 +2254,13 @@ bool LevelRenderer::updateDirtyChunks() { // int64_t startTime = System::currentTimeMillis(); // app.DebugPrintf("Rebuilding permaChunk %d\n", index); - + Tesselator::getInstance()->offset(-permaChunk[index].x, + -permaChunk[index].y, + -permaChunk[index].z); permaChunk[index].rebuild(); + Tesselator::getInstance()->offset(0, 0, 0); + if (index != 0) s_rebuildCompleteEvents->Set( index - 1); // MGH - this rebuild happening on the main @@ -2303,7 +2313,10 @@ bool LevelRenderer::updateDirtyChunks() { // static int64_t totalTime = 0; // static int64_t countTime = 0; // int64_t startTime = System::currentTimeMillis(); + Tesselator::getInstance()->offset( + -permaChunk[index].x, -permaChunk[index].y, -permaChunk[index].z); permaChunk.rebuild(); + Tesselator::getInstance()->offset(0, 0, 0); // int64_t endTime = System::currentTimeMillis(); // totalTime += (endTime - startTime); // countTime++; @@ -4039,10 +4052,12 @@ int LevelRenderer::rebuildChunkThreadProc(void* lpParam) { while (true) { s_activationEventA[index]->WaitForSignal(INFINITE); - + Tesselator* t = Tesselator::getInstance(); + Tesselator::getInstance()->offset( + -permaChunk[index].x, -permaChunk[index].y, -permaChunk[index].z); // app.DebugPrintf("Rebuilding permaChunk %d\n", index + 1); permaChunk[index + 1].rebuild(); - + Tesselator::getInstance()->offset(0, 0, 0); // Inform the producer thread that we are done with this chunk s_rebuildCompleteEvents->Set(index); } diff --git a/Minecraft.Client/Rendering/Tesselator.cpp b/Minecraft.Client/Rendering/Tesselator.cpp index 49e6f5669..76e13d996 100644 --- a/Minecraft.Client/Rendering/Tesselator.cpp +++ b/Minecraft.Client/Rendering/Tesselator.cpp @@ -215,10 +215,15 @@ void Tesselator::end() { } #endif } - glDisableClientState(GL_VERTEX_ARRAY); - if (hasTexture) glDisableClientState(GL_TEXTURE_COORD_ARRAY); - if (hasColor) glDisableClientState(GL_COLOR_ARRAY); - if (hasNormal) glDisableClientState(GL_NORMAL_ARRAY); + // 4jcraft: gldisableclientstate breaks gl compat, commenting those lead + // to some weird glitches with input but.. somehow stopped one day so.. + // just keep an eye on these incase mouse locking stops working outta + // nowhere (i blame opengl not me) + // + // glDisableClientState(GL_VERTEX_ARRAY); if (hasTexture) + // glDisableClientState(GL_TEXTURE_COORD_ARRAY); if (hasColor) + // glDisableClientState(GL_COLOR_ARRAY); if (hasNormal) + // glDisableClientState(GL_NORMAL_ARRAY); } clear(); From e71ff8699a78b6f3908d3a4fd42590f8f2341fe4 Mon Sep 17 00:00:00 2001 From: JuiceyDev Date: Fri, 27 Mar 2026 09:12:07 +0100 Subject: [PATCH 112/170] batch 2.1; entity lightfix --- .../EntityRenderers/ItemRenderer.cpp | 30 ++++++++++++------- Minecraft.Client/Rendering/Lighting.cpp | 28 +++++++++++++---- 2 files changed, 43 insertions(+), 15 deletions(-) diff --git a/Minecraft.Client/Rendering/EntityRenderers/ItemRenderer.cpp b/Minecraft.Client/Rendering/EntityRenderers/ItemRenderer.cpp index bf94c18ab..35cfa3e3f 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/ItemRenderer.cpp +++ b/Minecraft.Client/Rendering/EntityRenderers/ItemRenderer.cpp @@ -358,16 +358,22 @@ void ItemRenderer::renderGuiItem(Font* font, Textures* textures, Tile* tile = Tile::tiles[itemId]; glPushMatrix(); + // 4J - original code left here for reference // 4jcraft: original code reused for proper lighting + // force normalize + glEnable(GL_NORMALIZE); + glDisable(GL_RESCALE_NORMAL); + #if 1 - glTranslatef((float)(x), (float)(y), 0.0f); - glScalef(fScaleX, fScaleY, 1.0f); - glTranslatef(-2.0f,3.0f, -3.0f + blitOffset); - glScalef(10.0f, 10.0f, 10.0f); + // does it work? too lazy to find out + glTranslatef((float)(x), (float)(y), 0.0f); + glScalef(fScaleX, fScaleY, 1.0f); + glTranslatef(-2.0f, 3.0f, -3.0f + blitOffset); + glScalef(10.0f, 10.0f, 10.0f); glTranslatef(1.0f, 0.5f, 8.0f); - glScalef(1.0f, 1.0f, -1.0f); - glRotatef(180.0f + 30.0f, 1.0f, 0.0f, 0.0f); + glScalef(1.0f, -1.0f, 1.0f); + glRotatef(30.0f, 1.0f, 0.0f, 0.0f); glRotatef(45.0f, 0.0f, 1.0f, 0.0f); #else glTranslatef(x, y, 0.0f); // Translate to screen coords @@ -385,12 +391,16 @@ void ItemRenderer::renderGuiItem(Font* font, Textures* textures, glRotatef(45.0f, 0.0f, 1.0f, 0.0f); // Rotate round y axis (centre at origin) #endif - // 4J-PB - pass the alpha value in - the grass block - // render has the top surface coloured differently to - // the rest of the block - glRotatef(-90.0f, 0.0f, 1.0f, 0.0f); + // 4J-PB - pass the alpha value in - the grass block + // render has the top surface coloured differently to + // the rest of the block + glRotatef(-90.0f, 0.0f, 1.0f, 0.0f); + // glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE); + tileRenderer->renderTile(tile, itemAuxValue, 1, fAlpha, useCompiled); + // glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE); + glDisable(GL_NORMALIZE); glPopMatrix(); PIXEndNamedEvent(); } else if (Item::items[itemId]->hasMultipleSpriteLayers()) { diff --git a/Minecraft.Client/Rendering/Lighting.cpp b/Minecraft.Client/Rendering/Lighting.cpp index 4182a9fe3..ada92606a 100644 --- a/Minecraft.Client/Rendering/Lighting.cpp +++ b/Minecraft.Client/Rendering/Lighting.cpp @@ -52,9 +52,27 @@ FloatBuffer* Lighting::getBuffer(float a, float b, float c, float d) { } void Lighting::turnOnGui() { - glPushMatrix(); - glRotatef(-30, 0, 1, 0); - glRotatef(165, 1, 0, 0); - turnOn(); - glPopMatrix(); + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); + glEnable(GL_LIGHT1); + glEnable(GL_COLOR_MATERIAL); + glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE); + + float a = 0.4f; + float d = 0.6f; + float s = 0.0f; + // big john machine + // (copied from turnon) + RenderManager.StateSetLightDirection(0, 0.129f, 0.965f, 0.224f); + glLight(GL_LIGHT0, GL_DIFFUSE, getBuffer(d, d, d, 1)); + glLight(GL_LIGHT0, GL_AMBIENT, getBuffer(0.0f, 0.0f, 0.0f, 1.0f)); + glLight(GL_LIGHT0, GL_SPECULAR, getBuffer(s, s, s, 1.0f)); + + RenderManager.StateSetLightDirection(1, -0.129f, 0.965f, -0.224f); + glLight(GL_LIGHT1, GL_DIFFUSE, getBuffer(d, d, d, 1)); + glLight(GL_LIGHT1, GL_AMBIENT, getBuffer(0.0f, 0.0f, 0.0f, 1.0f)); + glLight(GL_LIGHT1, GL_SPECULAR, getBuffer(s, s, s, 1.0f)); + + glShadeModel(GL_FLAT); + glLightModel(GL_LIGHT_MODEL_AMBIENT, getBuffer(a, a, a, 1)); } From 97b068260a399751e9be4de4cf828f382284c34e Mon Sep 17 00:00:00 2001 From: JuiceyDev Date: Fri, 27 Mar 2026 09:33:32 +0100 Subject: [PATCH 113/170] batch 2.2, clamp be gone --- Minecraft.Client/Textures/Textures.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Minecraft.Client/Textures/Textures.cpp b/Minecraft.Client/Textures/Textures.cpp index 907f51927..37f99f1ca 100644 --- a/Minecraft.Client/Textures/Textures.cpp +++ b/Minecraft.Client/Textures/Textures.cpp @@ -696,8 +696,8 @@ void Textures::loadTexture(BufferedImage* img, int id, bool blur, bool clamp) { } if (clamp) { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); } else { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); From b7ac84ca79cf3965bc471f25e65b62e7f1d53cf1 Mon Sep 17 00:00:00 2001 From: Tropical <42101043+tropicaaal@users.noreply.github.com> Date: Fri, 27 Mar 2026 04:21:18 -0500 Subject: [PATCH 114/170] fix: revert changes to lighting direction --- Minecraft.Client/Platform/Common/UI/UIScene.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Minecraft.Client/Platform/Common/UI/UIScene.cpp b/Minecraft.Client/Platform/Common/UI/UIScene.cpp index c50a82230..863e0f951 100644 --- a/Minecraft.Client/Platform/Common/UI/UIScene.cpp +++ b/Minecraft.Client/Platform/Common/UI/UIScene.cpp @@ -712,7 +712,7 @@ void UIScene::_customDrawSlotControl(CustomDrawData* region, int iPad, } glEnable(GL_RESCALE_NORMAL); glPushMatrix(); - Lighting::turnOnGui(); + Lighting::turnOn(); glRotatef(120, 1, 0, 0); glPopMatrix(); From 08ed9861b9bac78751b8ff761a38d8a7f671e546 Mon Sep 17 00:00:00 2001 From: JuiceyDev Date: Fri, 27 Mar 2026 11:00:36 +0100 Subject: [PATCH 115/170] batch 2.3 enabling back optimizations --- Minecraft.Client/Platform/Linux/Linux_UIController.cpp | 2 ++ Minecraft.Client/Rendering/GameRenderer.cpp | 2 +- Minecraft.Client/Textures/Textures.cpp | 4 ++-- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/Minecraft.Client/Platform/Linux/Linux_UIController.cpp b/Minecraft.Client/Platform/Linux/Linux_UIController.cpp index f4a1c033a..a8da75b1d 100644 --- a/Minecraft.Client/Platform/Linux/Linux_UIController.cpp +++ b/Minecraft.Client/Platform/Linux/Linux_UIController.cpp @@ -35,6 +35,8 @@ static void restoreFixedFunctionStateAfterIggy() { RenderManager.MatrixMode(GL_MODELVIEW); RenderManager.Set_matrixDirty(); + Minecraft::GetInstance()->textures->clearLastBoundId(); + // 4jcraft: clears the last bound id, dumb fix but fine } void ConsoleUIController::init(S32 w, S32 h) { diff --git a/Minecraft.Client/Rendering/GameRenderer.cpp b/Minecraft.Client/Rendering/GameRenderer.cpp index 3e5763087..9b9759704 100644 --- a/Minecraft.Client/Rendering/GameRenderer.cpp +++ b/Minecraft.Client/Rendering/GameRenderer.cpp @@ -1778,7 +1778,7 @@ void GameRenderer::renderSnowAndRain(float a) { yy1 * s / 4.0f + ra * s); #endif t->offset(0, 0, 0); - t->end(); + } else { if (mode != 1) { if (mode >= 0) t->end(); diff --git a/Minecraft.Client/Textures/Textures.cpp b/Minecraft.Client/Textures/Textures.cpp index 37f99f1ca..cad870918 100644 --- a/Minecraft.Client/Textures/Textures.cpp +++ b/Minecraft.Client/Textures/Textures.cpp @@ -541,11 +541,11 @@ void Textures::bindTextureLayers(ResourceLocation* resource) { } void Textures::bind(int id) { - // if (id != lastBoundId) + if (id != lastBoundId) { if (id < 0) return; glBindTexture(GL_TEXTURE_2D, id); - // lastBoundId = id; + lastBoundId = id; } } From e0aa739aacfb5943dd7e92e5eb4e3626f32e829d Mon Sep 17 00:00:00 2001 From: JuiceyDev Date: Fri, 27 Mar 2026 11:22:23 +0100 Subject: [PATCH 116/170] batch 2.4 | highlight fix --- .../Platform/Linux/Linux_UIController.cpp | 2 +- Minecraft.Client/Rendering/LevelRenderer.cpp | 83 +++++++++++-------- 2 files changed, 49 insertions(+), 36 deletions(-) diff --git a/Minecraft.Client/Platform/Linux/Linux_UIController.cpp b/Minecraft.Client/Platform/Linux/Linux_UIController.cpp index a8da75b1d..5b6524c9f 100644 --- a/Minecraft.Client/Platform/Linux/Linux_UIController.cpp +++ b/Minecraft.Client/Platform/Linux/Linux_UIController.cpp @@ -33,7 +33,7 @@ static void restoreFixedFunctionStateAfterIggy() { RenderManager.MatrixSetIdentity(); RenderManager.MatrixMode(GL_MODELVIEW); - + glDisable(GL_SCISSOR_TEST); // iggy is mean RenderManager.Set_matrixDirty(); Minecraft::GetInstance()->textures->clearLastBoundId(); // 4jcraft: clears the last bound id, dumb fix but fine diff --git a/Minecraft.Client/Rendering/LevelRenderer.cpp b/Minecraft.Client/Rendering/LevelRenderer.cpp index f64a9b284..f2ed64ceb 100644 --- a/Minecraft.Client/Rendering/LevelRenderer.cpp +++ b/Minecraft.Client/Rendering/LevelRenderer.cpp @@ -2469,7 +2469,6 @@ void LevelRenderer::renderDestroyAnimation(Tesselator* t, glPopMatrix(); } } - void LevelRenderer::renderHitOutline(std::shared_ptr player, HitResult* h, int mode, float a) { if (mode == 0 && h->type == HitResult::TILE) { @@ -2477,14 +2476,18 @@ void LevelRenderer::renderHitOutline(std::shared_ptr player, // 4J-PB - If Display HUD is false, don't render the hit outline if (app.GetGameSettings(iPad, eGameSetting_DisplayHUD) == 0) return; + RenderManager.StateSetLightingEnable(false); + RenderManager.StateSetTextureEnable(false); + + // draw hit outline + RenderManager.StateSetColour(0.0f, 0.0f, 0.0f, 0.4f); + RenderManager.StateSetLineWidth(2.0f); + + // hack + glDepthFunc(GL_LEQUAL); + glEnable(GL_POLYGON_OFFSET_LINE); + glPolygonOffset(-2.0f, -2.0f); - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glColor4f(0, 0, 0, 0.4f); - glLineWidth(2.0f); - glDisable(GL_TEXTURE_2D); - glDepthMask(false); - float ss = 0.002f; int tileId = level[iPad]->getTile(h->x, h->y, h->z); if (tileId > 0) { @@ -2495,46 +2498,56 @@ void LevelRenderer::renderHitOutline(std::shared_ptr player, AABB bb = Tile::tiles[tileId] ->getTileAABB(level[iPad], h->x, h->y, h->z) - .grow(ss, ss, ss) + .grow(0.002f, 0.002f, 0.002f) .move(-xo, -yo, -zo); render(&bb); } - glDepthMask(true); - glEnable(GL_TEXTURE_2D); - glDisable(GL_BLEND); + + // restore + glDisable(GL_POLYGON_OFFSET_LINE); + RenderManager.StateSetColour(1.0f, 1.0f, 1.0f, 1.0f); + RenderManager.StateSetTextureEnable(true); + RenderManager.StateSetLightingEnable(true); } } void LevelRenderer::render(AABB* b) { Tesselator* t = Tesselator::getInstance(); + RenderManager.StateSetLightingEnable(false); + RenderManager.StateSetTextureEnable(false); + RenderManager.StateSetColour(0.0f, 0.0f, 0.0f, 0.4f); - t->begin(GL_LINE_STRIP); - t->vertex((float)(b->x0), (float)(b->y0), (float)(b->z0)); - t->vertex((float)(b->x1), (float)(b->y0), (float)(b->z0)); - t->vertex((float)(b->x1), (float)(b->y0), (float)(b->z1)); - t->vertex((float)(b->x0), (float)(b->y0), (float)(b->z1)); - t->vertex((float)(b->x0), (float)(b->y0), (float)(b->z0)); - t->end(); + // prevent zfight + glEnable(GL_POLYGON_OFFSET_LINE); + glPolygonOffset(-2.0f, -2.0f); - t->begin(GL_LINE_STRIP); - t->vertex((float)(b->x0), (float)(b->y1), (float)(b->z0)); - t->vertex((float)(b->x1), (float)(b->y1), (float)(b->z0)); - t->vertex((float)(b->x1), (float)(b->y1), (float)(b->z1)); - t->vertex((float)(b->x0), (float)(b->y1), (float)(b->z1)); - t->vertex((float)(b->x0), (float)(b->y1), (float)(b->z0)); - t->end(); + // One call please! + t->begin(GL_LINES); + + // Bottom + t->vertex(b->x0, b->y0, b->z0); t->vertex(b->x1, b->y0, b->z0); + t->vertex(b->x1, b->y0, b->z0); t->vertex(b->x1, b->y0, b->z1); + t->vertex(b->x1, b->y0, b->z1); t->vertex(b->x0, b->y0, b->z1); + t->vertex(b->x0, b->y0, b->z1); t->vertex(b->x0, b->y0, b->z0); + + // Top + t->vertex(b->x0, b->y1, b->z0); t->vertex(b->x1, b->y1, b->z0); + t->vertex(b->x1, b->y1, b->z0); t->vertex(b->x1, b->y1, b->z1); + t->vertex(b->x1, b->y1, b->z1); t->vertex(b->x0, b->y1, b->z1); + t->vertex(b->x0, b->y1, b->z1); t->vertex(b->x0, b->y1, b->z0); + + // Vertical + t->vertex(b->x0, b->y0, b->z0); t->vertex(b->x0, b->y1, b->z0); + t->vertex(b->x1, b->y0, b->z0); t->vertex(b->x1, b->y1, b->z0); + t->vertex(b->x1, b->y0, b->z1); t->vertex(b->x1, b->y1, b->z1); + t->vertex(b->x0, b->y0, b->z1); t->vertex(b->x0, b->y1, b->z1); - t->begin(GL_LINES); - t->vertex((float)(b->x0), (float)(b->y0), (float)(b->z0)); - t->vertex((float)(b->x0), (float)(b->y1), (float)(b->z0)); - t->vertex((float)(b->x1), (float)(b->y0), (float)(b->z0)); - t->vertex((float)(b->x1), (float)(b->y1), (float)(b->z0)); - t->vertex((float)(b->x1), (float)(b->y0), (float)(b->z1)); - t->vertex((float)(b->x1), (float)(b->y1), (float)(b->z1)); - t->vertex((float)(b->x0), (float)(b->y0), (float)(b->z1)); - t->vertex((float)(b->x0), (float)(b->y1), (float)(b->z1)); t->end(); + glDisable(GL_POLYGON_OFFSET_LINE); + RenderManager.StateSetLightingEnable(true); + RenderManager.StateSetTextureEnable(true); + RenderManager.StateSetColour(1.0f, 1.0f, 1.0f, 1.0f); } void LevelRenderer::setDirty(int x0, int y0, int z0, int x1, int y1, int z1, From 98c8d49eaff20c9394578390b3c88587650f55ab Mon Sep 17 00:00:00 2001 From: Tropical <42101043+tropicaaal@users.noreply.github.com> Date: Fri, 27 Mar 2026 10:24:44 -0500 Subject: [PATCH 117/170] fix: make hit outline width 1 pixel --- Minecraft.Client/Rendering/LevelRenderer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Minecraft.Client/Rendering/LevelRenderer.cpp b/Minecraft.Client/Rendering/LevelRenderer.cpp index f2ed64ceb..9471f43cc 100644 --- a/Minecraft.Client/Rendering/LevelRenderer.cpp +++ b/Minecraft.Client/Rendering/LevelRenderer.cpp @@ -2481,7 +2481,7 @@ void LevelRenderer::renderHitOutline(std::shared_ptr player, // draw hit outline RenderManager.StateSetColour(0.0f, 0.0f, 0.0f, 0.4f); - RenderManager.StateSetLineWidth(2.0f); + RenderManager.StateSetLineWidth(1.0f); // hack glDepthFunc(GL_LEQUAL); From ca601c8205b297cc4efc03b371f58c5e742a72ed Mon Sep 17 00:00:00 2001 From: Tropical <42101043+tropicaaal@users.noreply.github.com> Date: Fri, 27 Mar 2026 11:37:37 -0500 Subject: [PATCH 118/170] restore original code for renderGuiItem --- Minecraft.Client/Rendering/EntityRenderers/ItemRenderer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Minecraft.Client/Rendering/EntityRenderers/ItemRenderer.cpp b/Minecraft.Client/Rendering/EntityRenderers/ItemRenderer.cpp index 35cfa3e3f..769ece8e8 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/ItemRenderer.cpp +++ b/Minecraft.Client/Rendering/EntityRenderers/ItemRenderer.cpp @@ -365,7 +365,7 @@ void ItemRenderer::renderGuiItem(Font* font, Textures* textures, glEnable(GL_NORMALIZE); glDisable(GL_RESCALE_NORMAL); -#if 1 +#if 0 // does it work? too lazy to find out glTranslatef((float)(x), (float)(y), 0.0f); glScalef(fScaleX, fScaleY, 1.0f); From dbd7ce40cd68ff165583a1416eaca0089e816c13 Mon Sep 17 00:00:00 2001 From: Tropical <42101043+tropicaaal@users.noreply.github.com> Date: Fri, 27 Mar 2026 11:52:28 -0500 Subject: [PATCH 119/170] fix: don't GL_NORMALIZE/GL_RESCALE_NORMAL when rendering items --- .../Rendering/EntityRenderers/ItemRenderer.cpp | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/Minecraft.Client/Rendering/EntityRenderers/ItemRenderer.cpp b/Minecraft.Client/Rendering/EntityRenderers/ItemRenderer.cpp index 769ece8e8..e5eba0d25 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/ItemRenderer.cpp +++ b/Minecraft.Client/Rendering/EntityRenderers/ItemRenderer.cpp @@ -360,12 +360,7 @@ void ItemRenderer::renderGuiItem(Font* font, Textures* textures, glPushMatrix(); // 4J - original code left here for reference - // 4jcraft: original code reused for proper lighting - // force normalize - glEnable(GL_NORMALIZE); - glDisable(GL_RESCALE_NORMAL); - -#if 0 +#if 1 // does it work? too lazy to find out glTranslatef((float)(x), (float)(y), 0.0f); glScalef(fScaleX, fScaleY, 1.0f); @@ -400,7 +395,6 @@ void ItemRenderer::renderGuiItem(Font* font, Textures* textures, tileRenderer->renderTile(tile, itemAuxValue, 1, fAlpha, useCompiled); // glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE); - glDisable(GL_NORMALIZE); glPopMatrix(); PIXEndNamedEvent(); } else if (Item::items[itemId]->hasMultipleSpriteLayers()) { From a4db31ee64a1d484ef133a88f68ac6ec181031a1 Mon Sep 17 00:00:00 2001 From: Tropical <42101043+tropicaaal@users.noreply.github.com> Date: Fri, 27 Mar 2026 11:56:36 -0500 Subject: [PATCH 120/170] add back ItemRenderer comment --- Minecraft.Client/Rendering/EntityRenderers/ItemRenderer.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Minecraft.Client/Rendering/EntityRenderers/ItemRenderer.cpp b/Minecraft.Client/Rendering/EntityRenderers/ItemRenderer.cpp index e5eba0d25..069de61af 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/ItemRenderer.cpp +++ b/Minecraft.Client/Rendering/EntityRenderers/ItemRenderer.cpp @@ -360,6 +360,8 @@ void ItemRenderer::renderGuiItem(Font* font, Textures* textures, glPushMatrix(); // 4J - original code left here for reference + // 4jcraft: original code reused for proper lighting + // force normalize #if 1 // does it work? too lazy to find out glTranslatef((float)(x), (float)(y), 0.0f); From 23af1b0a727e1766eb408c98809c58c7de0fd972 Mon Sep 17 00:00:00 2001 From: Tropical <42101043+tropicaaal@users.noreply.github.com> Date: Fri, 27 Mar 2026 19:08:14 -0500 Subject: [PATCH 121/170] revert unintentional turnOnGui --- Minecraft.Client/Rendering/Lighting.cpp | 28 +++++-------------------- 1 file changed, 5 insertions(+), 23 deletions(-) diff --git a/Minecraft.Client/Rendering/Lighting.cpp b/Minecraft.Client/Rendering/Lighting.cpp index ada92606a..4182a9fe3 100644 --- a/Minecraft.Client/Rendering/Lighting.cpp +++ b/Minecraft.Client/Rendering/Lighting.cpp @@ -52,27 +52,9 @@ FloatBuffer* Lighting::getBuffer(float a, float b, float c, float d) { } void Lighting::turnOnGui() { - glEnable(GL_LIGHTING); - glEnable(GL_LIGHT0); - glEnable(GL_LIGHT1); - glEnable(GL_COLOR_MATERIAL); - glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE); - - float a = 0.4f; - float d = 0.6f; - float s = 0.0f; - // big john machine - // (copied from turnon) - RenderManager.StateSetLightDirection(0, 0.129f, 0.965f, 0.224f); - glLight(GL_LIGHT0, GL_DIFFUSE, getBuffer(d, d, d, 1)); - glLight(GL_LIGHT0, GL_AMBIENT, getBuffer(0.0f, 0.0f, 0.0f, 1.0f)); - glLight(GL_LIGHT0, GL_SPECULAR, getBuffer(s, s, s, 1.0f)); - - RenderManager.StateSetLightDirection(1, -0.129f, 0.965f, -0.224f); - glLight(GL_LIGHT1, GL_DIFFUSE, getBuffer(d, d, d, 1)); - glLight(GL_LIGHT1, GL_AMBIENT, getBuffer(0.0f, 0.0f, 0.0f, 1.0f)); - glLight(GL_LIGHT1, GL_SPECULAR, getBuffer(s, s, s, 1.0f)); - - glShadeModel(GL_FLAT); - glLightModel(GL_LIGHT_MODEL_AMBIENT, getBuffer(a, a, a, 1)); + glPushMatrix(); + glRotatef(-30, 0, 1, 0); + glRotatef(165, 1, 0, 0); + turnOn(); + glPopMatrix(); } From fa248125824a877c9f418416970641002a1cdb39 Mon Sep 17 00:00:00 2001 From: Tropical <42101043+tropicaaal@users.noreply.github.com> Date: Sat, 28 Mar 2026 00:29:37 -0500 Subject: [PATCH 122/170] revert some seemingly unneeded changes --- Minecraft.Client/Rendering/FrustumData.cpp | 7 ++++--- Minecraft.Client/Rendering/GameRenderer.cpp | 2 +- Minecraft.Client/Rendering/LevelRenderer.cpp | 9 --------- 3 files changed, 5 insertions(+), 13 deletions(-) diff --git a/Minecraft.Client/Rendering/FrustumData.cpp b/Minecraft.Client/Rendering/FrustumData.cpp index eb46045e3..098243a75 100644 --- a/Minecraft.Client/Rendering/FrustumData.cpp +++ b/Minecraft.Client/Rendering/FrustumData.cpp @@ -14,9 +14,10 @@ FrustumData::FrustumData() { } FrustumData::~FrustumData() { - for (int i = 0; i < 6; i++) { - delete[] m_Frustum[i]; - } + delete[] proj.data; + delete[] modl.data; + delete[] clip.data; + for (int i = 0; i < 6; i++) delete[] m_Frustum[i]; delete[] m_Frustum; } diff --git a/Minecraft.Client/Rendering/GameRenderer.cpp b/Minecraft.Client/Rendering/GameRenderer.cpp index 9b9759704..3e5763087 100644 --- a/Minecraft.Client/Rendering/GameRenderer.cpp +++ b/Minecraft.Client/Rendering/GameRenderer.cpp @@ -1778,7 +1778,7 @@ void GameRenderer::renderSnowAndRain(float a) { yy1 * s / 4.0f + ra * s); #endif t->offset(0, 0, 0); - + t->end(); } else { if (mode != 1) { if (mode >= 0) t->end(); diff --git a/Minecraft.Client/Rendering/LevelRenderer.cpp b/Minecraft.Client/Rendering/LevelRenderer.cpp index 9471f43cc..9cf3dfdd3 100644 --- a/Minecraft.Client/Rendering/LevelRenderer.cpp +++ b/Minecraft.Client/Rendering/LevelRenderer.cpp @@ -2254,13 +2254,8 @@ bool LevelRenderer::updateDirtyChunks() { // int64_t startTime = System::currentTimeMillis(); // app.DebugPrintf("Rebuilding permaChunk %d\n", index); - Tesselator::getInstance()->offset(-permaChunk[index].x, - -permaChunk[index].y, - -permaChunk[index].z); permaChunk[index].rebuild(); - Tesselator::getInstance()->offset(0, 0, 0); - if (index != 0) s_rebuildCompleteEvents->Set( index - 1); // MGH - this rebuild happening on the main @@ -4065,12 +4060,8 @@ int LevelRenderer::rebuildChunkThreadProc(void* lpParam) { while (true) { s_activationEventA[index]->WaitForSignal(INFINITE); - Tesselator* t = Tesselator::getInstance(); - Tesselator::getInstance()->offset( - -permaChunk[index].x, -permaChunk[index].y, -permaChunk[index].z); // app.DebugPrintf("Rebuilding permaChunk %d\n", index + 1); permaChunk[index + 1].rebuild(); - Tesselator::getInstance()->offset(0, 0, 0); // Inform the producer thread that we are done with this chunk s_rebuildCompleteEvents->Set(index); } From 9680753f5e5d81476447c454e49bf899a6f786e2 Mon Sep 17 00:00:00 2001 From: MatthewBeshay <92357869+MatthewBeshay@users.noreply.github.com> Date: Sat, 28 Mar 2026 18:00:47 +1100 Subject: [PATCH 123/170] fix(linux): restore UI GL state handoff for core renderer --- .../Common/UI/UIScene_EnchantingMenu.cpp | 2 - .../Platform/Linux/Iggy/gdraw/gdraw.c | 3 +- Minecraft.Client/Platform/Linux/LinuxGL.cpp | 13 ++++- .../Platform/Linux/Linux_UIController.cpp | 56 ++++++++----------- Minecraft.Client/Rendering/FrustumData.cpp | 2 +- Minecraft.Client/Rendering/GameRenderer.cpp | 1 + Minecraft.Client/Rendering/LevelRenderer.cpp | 8 +-- 7 files changed, 43 insertions(+), 42 deletions(-) diff --git a/Minecraft.Client/Platform/Common/UI/UIScene_EnchantingMenu.cpp b/Minecraft.Client/Platform/Common/UI/UIScene_EnchantingMenu.cpp index 78fca71e5..0affa127f 100644 --- a/Minecraft.Client/Platform/Common/UI/UIScene_EnchantingMenu.cpp +++ b/Minecraft.Client/Platform/Common/UI/UIScene_EnchantingMenu.cpp @@ -5,8 +5,6 @@ #include "../../Minecraft.Client/Minecraft.h" #include "UIScene_EnchantingMenu.h" -#include - UIScene_EnchantingMenu::UIScene_EnchantingMenu(int iPad, void* _initData, UILayer* parentLayer) : UIScene_AbstractContainerMenu(iPad, parentLayer) { diff --git a/Minecraft.Client/Platform/Linux/Iggy/gdraw/gdraw.c b/Minecraft.Client/Platform/Linux/Iggy/gdraw/gdraw.c index 0c2cea4d5..fc037dcbf 100644 --- a/Minecraft.Client/Platform/Linux/Iggy/gdraw/gdraw.c +++ b/Minecraft.Client/Platform/Linux/Iggy/gdraw/gdraw.c @@ -776,6 +776,7 @@ GDrawFunctions* gdraw_GL_CreateContext(S32 w, S32 h, S32 msaa_samples) { real_RenderingBegin = funcs->RenderingBegin; funcs->RenderingBegin = hooked_RenderingBegin; + funcs->ClearID = gdraw_ClearID; gdraw->tex_formats = tex_formats; gdraw->has_mapbuffer = true; @@ -815,4 +816,4 @@ void gdraw_GL_BeginCustomDraw_4J(IggyCustomDrawCallbackRegion* region, void gdraw_GL_CalculateCustomDraw_4J(IggyCustomDrawCallbackRegion* region, F32* matrix) { gdraw_GetObjectSpaceMatrix(matrix, region->o2w, gdraw->projection, 0.0f, 0); -} \ No newline at end of file +} diff --git a/Minecraft.Client/Platform/Linux/LinuxGL.cpp b/Minecraft.Client/Platform/Linux/LinuxGL.cpp index 1333b5114..a1d992ee3 100644 --- a/Minecraft.Client/Platform/Linux/LinuxGL.cpp +++ b/Minecraft.Client/Platform/Linux/LinuxGL.cpp @@ -28,6 +28,12 @@ #undef glActiveTexture // _4j suffix shit (todo: make ts better) +int glGenTextures() { + GLuint id = 0; + ::glGenTextures(1, &id); + return (int)id; +} + void glGenTextures_4J(IntBuffer* buf) { GLuint id = 0; ::glGenTextures(1, &id); @@ -35,6 +41,11 @@ void glGenTextures_4J(IntBuffer* buf) { buf->flip(); } +void glDeleteTextures(int id) { + GLuint uid = (GLuint)id; + ::glDeleteTextures(1, &uid); +} + void glDeleteTextures_4J(IntBuffer* buf) { if (buf && buf->limit() > 0) { int id = buf->get(0); @@ -218,4 +229,4 @@ void LinuxGLLogLightmapState(const char* stage, int textureId, unit1Enabled ? 1 : 0); } -#endif \ No newline at end of file +#endif diff --git a/Minecraft.Client/Platform/Linux/Linux_UIController.cpp b/Minecraft.Client/Platform/Linux/Linux_UIController.cpp index 5b6524c9f..e2c1c17c7 100644 --- a/Minecraft.Client/Platform/Linux/Linux_UIController.cpp +++ b/Minecraft.Client/Platform/Linux/Linux_UIController.cpp @@ -1,42 +1,35 @@ -// should we keep Linux_UIController.cpp?* #include "../../../Minecraft.World/Platform/stdafx.h" #include "Linux_UIController.h" -// Temp -#include "../../Minecraft.h" -#include "../../Textures/Textures.h" - // GDraw GL backend for Linux #include "Iggy/gdraw/gdraw.h" -#include "4J_Render.h" ConsoleUIController ui; static void restoreFixedFunctionStateAfterIggy() { - RenderManager.StateSetColour(1.0f, 1.0f, 1.0f, 1.0f); - RenderManager.StateSetAlphaTestEnable(true); - RenderManager.StateSetAlphaFunc(GL_GREATER, 0.1f); + glColor4f(1.0f, 1.0f, 1.0f, 1.0f); + glEnable(GL_ALPHA_TEST); + glAlphaFunc(GL_GREATER, 0.1f); + glEnable(GL_DEPTH_TEST); + glDepthFunc(GL_LEQUAL); + glEnable(GL_CULL_FACE); + glCullFace(GL_BACK); - RenderManager.StateSetDepthTestEnable(true); - RenderManager.StateSetDepthFunc(GL_LEQUAL); - RenderManager.StateSetDepthMask(true); + glClientActiveTexture(GL_TEXTURE1); + glActiveTexture(GL_TEXTURE1); + glDisable(GL_TEXTURE_2D); + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + glMatrixMode(GL_TEXTURE); + glLoadIdentity(); - RenderManager.StateSetFaceCull(true); - RenderManager.StateSetActiveTexture(GL_TEXTURE1); - RenderManager.StateSetTextureEnable(false); - RenderManager.MatrixMode(GL_TEXTURE); - RenderManager.MatrixSetIdentity(); + glClientActiveTexture(GL_TEXTURE0); + glActiveTexture(GL_TEXTURE0); + glEnable(GL_TEXTURE_2D); + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + glMatrixMode(GL_TEXTURE); + glLoadIdentity(); - RenderManager.StateSetActiveTexture(GL_TEXTURE0); - RenderManager.StateSetTextureEnable(true); - RenderManager.MatrixMode(GL_TEXTURE); - - RenderManager.MatrixSetIdentity(); - RenderManager.MatrixMode(GL_MODELVIEW); - glDisable(GL_SCISSOR_TEST); // iggy is mean - RenderManager.Set_matrixDirty(); - Minecraft::GetInstance()->textures->clearLastBoundId(); - // 4jcraft: clears the last bound id, dumb fix but fine + glMatrixMode(GL_MODELVIEW); } void ConsoleUIController::init(S32 w, S32 h) { @@ -69,11 +62,8 @@ void ConsoleUIController::render() { if (!gdraw_funcs) return; gdraw_GL_SetTileOrigin(0, 0, 0); - if (!app.GetGameStarted()) { - glDisable(GL_SCISSOR_TEST); - glClearDepth(1.0); - glDepthMask(GL_TRUE); - glClear(GL_DEPTH_BUFFER_BIT); + if (!app.GetGameStarted() && gdraw_funcs->ClearID) { + gdraw_funcs->ClearID(); } // render @@ -144,4 +134,4 @@ void ConsoleUIController::shutdown() { gdraw_funcs = nullptr; } #endif -} \ No newline at end of file +} diff --git a/Minecraft.Client/Rendering/FrustumData.cpp b/Minecraft.Client/Rendering/FrustumData.cpp index 098243a75..140fa4772 100644 --- a/Minecraft.Client/Rendering/FrustumData.cpp +++ b/Minecraft.Client/Rendering/FrustumData.cpp @@ -130,4 +130,4 @@ bool FrustumData::cubeInFrustum(double x1, double y1, double z1, double x2, bool FrustumData::isVisible(AABB* aabb) { return cubeInFrustum(aabb->x0, aabb->y0, aabb->z0, aabb->x1, aabb->y1, aabb->z1); -} \ No newline at end of file +} diff --git a/Minecraft.Client/Rendering/GameRenderer.cpp b/Minecraft.Client/Rendering/GameRenderer.cpp index 3e5763087..61171598e 100644 --- a/Minecraft.Client/Rendering/GameRenderer.cpp +++ b/Minecraft.Client/Rendering/GameRenderer.cpp @@ -1779,6 +1779,7 @@ void GameRenderer::renderSnowAndRain(float a) { #endif t->offset(0, 0, 0); t->end(); + } else { if (mode != 1) { if (mode >= 0) t->end(); diff --git a/Minecraft.Client/Rendering/LevelRenderer.cpp b/Minecraft.Client/Rendering/LevelRenderer.cpp index 9cf3dfdd3..627a46f47 100644 --- a/Minecraft.Client/Rendering/LevelRenderer.cpp +++ b/Minecraft.Client/Rendering/LevelRenderer.cpp @@ -2472,7 +2472,7 @@ void LevelRenderer::renderHitOutline(std::shared_ptr player, // 4J-PB - If Display HUD is false, don't render the hit outline if (app.GetGameSettings(iPad, eGameSetting_DisplayHUD) == 0) return; RenderManager.StateSetLightingEnable(false); - RenderManager.StateSetTextureEnable(false); + glDisable(GL_TEXTURE_2D); // draw hit outline RenderManager.StateSetColour(0.0f, 0.0f, 0.0f, 0.4f); @@ -2502,7 +2502,7 @@ void LevelRenderer::renderHitOutline(std::shared_ptr player, // restore glDisable(GL_POLYGON_OFFSET_LINE); RenderManager.StateSetColour(1.0f, 1.0f, 1.0f, 1.0f); - RenderManager.StateSetTextureEnable(true); + glEnable(GL_TEXTURE_2D); RenderManager.StateSetLightingEnable(true); } } @@ -2510,7 +2510,7 @@ void LevelRenderer::renderHitOutline(std::shared_ptr player, void LevelRenderer::render(AABB* b) { Tesselator* t = Tesselator::getInstance(); RenderManager.StateSetLightingEnable(false); - RenderManager.StateSetTextureEnable(false); + glDisable(GL_TEXTURE_2D); RenderManager.StateSetColour(0.0f, 0.0f, 0.0f, 0.4f); // prevent zfight @@ -2541,7 +2541,7 @@ void LevelRenderer::render(AABB* b) { t->end(); glDisable(GL_POLYGON_OFFSET_LINE); RenderManager.StateSetLightingEnable(true); - RenderManager.StateSetTextureEnable(true); + glEnable(GL_TEXTURE_2D); RenderManager.StateSetColour(1.0f, 1.0f, 1.0f, 1.0f); } From c60a71581d327995595365ae446b27354f70fa01 Mon Sep 17 00:00:00 2001 From: Tropical <42101043+tropicaaal@users.noreply.github.com> Date: Sat, 28 Mar 2026 02:48:12 -0500 Subject: [PATCH 124/170] revert ItemRenderer changes --- Minecraft.Client/Rendering/EntityRenderers/ItemRenderer.cpp | 4 ++-- subprojects/4jlibs.wrap | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Minecraft.Client/Rendering/EntityRenderers/ItemRenderer.cpp b/Minecraft.Client/Rendering/EntityRenderers/ItemRenderer.cpp index 069de61af..6b36e130e 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/ItemRenderer.cpp +++ b/Minecraft.Client/Rendering/EntityRenderers/ItemRenderer.cpp @@ -369,8 +369,8 @@ void ItemRenderer::renderGuiItem(Font* font, Textures* textures, glTranslatef(-2.0f, 3.0f, -3.0f + blitOffset); glScalef(10.0f, 10.0f, 10.0f); glTranslatef(1.0f, 0.5f, 8.0f); - glScalef(1.0f, -1.0f, 1.0f); - glRotatef(30.0f, 1.0f, 0.0f, 0.0f); + glScalef(1.0f, 1.0f, -1.0f); + glRotatef(180.0f + 30.0f, 1.0f, 0.0f, 0.0f); glRotatef(45.0f, 0.0f, 1.0f, 0.0f); #else glTranslatef(x, y, 0.0f); // Translate to screen coords diff --git a/subprojects/4jlibs.wrap b/subprojects/4jlibs.wrap index e9e21334c..ab584a950 100644 --- a/subprojects/4jlibs.wrap +++ b/subprojects/4jlibs.wrap @@ -1,6 +1,6 @@ [wrap-git] url = https://github.com/4jcraft/4jlibs.git -revision = main +revision = immediategone-v2 [provide] dependency_names = 4j-render, 4j-input, 4j-profile, 4j-storage From 8dfd9e50448c4fdf56e571e0525734ee20213927 Mon Sep 17 00:00:00 2001 From: MatthewBeshay <92357869+MatthewBeshay@users.noreply.github.com> Date: Sat, 28 Mar 2026 18:57:19 +1100 Subject: [PATCH 125/170] fix(gui): always rebind textures for java font rendering --- Minecraft.Client/Textures/Textures.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Minecraft.Client/Textures/Textures.cpp b/Minecraft.Client/Textures/Textures.cpp index cad870918..7fc2dabcf 100644 --- a/Minecraft.Client/Textures/Textures.cpp +++ b/Minecraft.Client/Textures/Textures.cpp @@ -541,11 +541,11 @@ void Textures::bindTextureLayers(ResourceLocation* resource) { } void Textures::bind(int id) { - if (id != lastBoundId) + // Classic GUI code still performs some raw glBindTexture calls, so this + // path must always rebind rather than trusting lastBoundId to be in sync. { if (id < 0) return; glBindTexture(GL_TEXTURE_2D, id); - lastBoundId = id; } } From 69e9db9edc25689b891d2dbc341aad1b6af70f4e Mon Sep 17 00:00:00 2001 From: Tropical <42101043+tropicaaal@users.noreply.github.com> Date: Sat, 28 Mar 2026 03:06:32 -0500 Subject: [PATCH 126/170] chore: undo some comments --- Minecraft.Client/Rendering/EntityRenderers/ItemRenderer.cpp | 4 ---- Minecraft.Client/Rendering/GameRenderer.cpp | 1 - 2 files changed, 5 deletions(-) diff --git a/Minecraft.Client/Rendering/EntityRenderers/ItemRenderer.cpp b/Minecraft.Client/Rendering/EntityRenderers/ItemRenderer.cpp index 6b36e130e..d5925a3ec 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/ItemRenderer.cpp +++ b/Minecraft.Client/Rendering/EntityRenderers/ItemRenderer.cpp @@ -358,12 +358,9 @@ void ItemRenderer::renderGuiItem(Font* font, Textures* textures, Tile* tile = Tile::tiles[itemId]; glPushMatrix(); - // 4J - original code left here for reference // 4jcraft: original code reused for proper lighting - // force normalize #if 1 - // does it work? too lazy to find out glTranslatef((float)(x), (float)(y), 0.0f); glScalef(fScaleX, fScaleY, 1.0f); glTranslatef(-2.0f, 3.0f, -3.0f + blitOffset); @@ -396,7 +393,6 @@ void ItemRenderer::renderGuiItem(Font* font, Textures* textures, tileRenderer->renderTile(tile, itemAuxValue, 1, fAlpha, useCompiled); - // glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE); glPopMatrix(); PIXEndNamedEvent(); } else if (Item::items[itemId]->hasMultipleSpriteLayers()) { diff --git a/Minecraft.Client/Rendering/GameRenderer.cpp b/Minecraft.Client/Rendering/GameRenderer.cpp index 61171598e..3e5763087 100644 --- a/Minecraft.Client/Rendering/GameRenderer.cpp +++ b/Minecraft.Client/Rendering/GameRenderer.cpp @@ -1779,7 +1779,6 @@ void GameRenderer::renderSnowAndRain(float a) { #endif t->offset(0, 0, 0); t->end(); - } else { if (mode != 1) { if (mode >= 0) t->end(); From fb745767f26579bb35659d8803694658d1030c92 Mon Sep 17 00:00:00 2001 From: Tropical <42101043+tropicaaal@users.noreply.github.com> Date: Sat, 28 Mar 2026 03:10:19 -0500 Subject: [PATCH 127/170] undo changes to Camera.cpp --- Minecraft.Client/Rendering/Camera.cpp | 8 +++----- Minecraft.Client/Textures/Textures.cpp | 6 ++++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Minecraft.Client/Rendering/Camera.cpp b/Minecraft.Client/Rendering/Camera.cpp index 137108089..aac62892a 100644 --- a/Minecraft.Client/Rendering/Camera.cpp +++ b/Minecraft.Client/Rendering/Camera.cpp @@ -22,11 +22,9 @@ float Camera::xa2 = 0.0f; float Camera::za2 = 0.0f; void Camera::prepare(std::shared_ptr player, bool mirror) { - memcpy(modelview->_getDataPointer(), - RenderManager.MatrixGet(GL_MODELVIEW_MATRIX), 16 * sizeof(float)); - memcpy(projection->_getDataPointer(), - RenderManager.MatrixGet(GL_PROJECTION_MATRIX), 16 * sizeof(float)); - + glGetFloat(GL_MODELVIEW_MATRIX, modelview); + glGetFloat(GL_PROJECTION_MATRIX, projection); + /* Original java code for reference glGetInteger(GL_VIEWPORT, viewport); diff --git a/Minecraft.Client/Textures/Textures.cpp b/Minecraft.Client/Textures/Textures.cpp index 7fc2dabcf..13c76e46c 100644 --- a/Minecraft.Client/Textures/Textures.cpp +++ b/Minecraft.Client/Textures/Textures.cpp @@ -541,11 +541,13 @@ void Textures::bindTextureLayers(ResourceLocation* resource) { } void Textures::bind(int id) { - // Classic GUI code still performs some raw glBindTexture calls, so this - // path must always rebind rather than trusting lastBoundId to be in sync. + // 4jcraft: Classic GUI code still performs some raw glBindTexture calls, so + // this path must always rebind rather than trusting lastBoundId to be in sync. + // if (id != lastBoundId) { if (id < 0) return; glBindTexture(GL_TEXTURE_2D, id); + // lastBoundId = id; } } From fc6e4e32b14eab4913458d1e21357fb69a7f11f7 Mon Sep 17 00:00:00 2001 From: Tropical <42101043+tropicaaal@users.noreply.github.com> Date: Sat, 28 Mar 2026 03:17:41 -0500 Subject: [PATCH 128/170] undo further LevelRenderer changes --- Minecraft.Client/Rendering/LevelRenderer.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Minecraft.Client/Rendering/LevelRenderer.cpp b/Minecraft.Client/Rendering/LevelRenderer.cpp index 627a46f47..47702a12a 100644 --- a/Minecraft.Client/Rendering/LevelRenderer.cpp +++ b/Minecraft.Client/Rendering/LevelRenderer.cpp @@ -2308,10 +2308,7 @@ bool LevelRenderer::updateDirtyChunks() { // static int64_t totalTime = 0; // static int64_t countTime = 0; // int64_t startTime = System::currentTimeMillis(); - Tesselator::getInstance()->offset( - -permaChunk[index].x, -permaChunk[index].y, -permaChunk[index].z); permaChunk.rebuild(); - Tesselator::getInstance()->offset(0, 0, 0); // int64_t endTime = System::currentTimeMillis(); // totalTime += (endTime - startTime); // countTime++; @@ -4060,8 +4057,10 @@ int LevelRenderer::rebuildChunkThreadProc(void* lpParam) { while (true) { s_activationEventA[index]->WaitForSignal(INFINITE); + // app.DebugPrintf("Rebuilding permaChunk %d\n", index + 1); permaChunk[index + 1].rebuild(); + // Inform the producer thread that we are done with this chunk s_rebuildCompleteEvents->Set(index); } From 485edf06798b8783a7bcd97f4fc82cd061338fc6 Mon Sep 17 00:00:00 2001 From: Tropical <42101043+tropicaaal@users.noreply.github.com> Date: Sat, 28 Mar 2026 03:22:37 -0500 Subject: [PATCH 129/170] clean up the diff further --- Minecraft.Client/Rendering/Camera.cpp | 2 +- Minecraft.Client/Rendering/EntityRenderers/ItemRenderer.cpp | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/Minecraft.Client/Rendering/Camera.cpp b/Minecraft.Client/Rendering/Camera.cpp index aac62892a..f728f3f09 100644 --- a/Minecraft.Client/Rendering/Camera.cpp +++ b/Minecraft.Client/Rendering/Camera.cpp @@ -24,7 +24,7 @@ float Camera::za2 = 0.0f; void Camera::prepare(std::shared_ptr player, bool mirror) { glGetFloat(GL_MODELVIEW_MATRIX, modelview); glGetFloat(GL_PROJECTION_MATRIX, projection); - + /* Original java code for reference glGetInteger(GL_VIEWPORT, viewport); diff --git a/Minecraft.Client/Rendering/EntityRenderers/ItemRenderer.cpp b/Minecraft.Client/Rendering/EntityRenderers/ItemRenderer.cpp index d5925a3ec..2b3faece9 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/ItemRenderer.cpp +++ b/Minecraft.Client/Rendering/EntityRenderers/ItemRenderer.cpp @@ -389,7 +389,6 @@ void ItemRenderer::renderGuiItem(Font* font, Textures* textures, // render has the top surface coloured differently to // the rest of the block glRotatef(-90.0f, 0.0f, 1.0f, 0.0f); - // glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE); tileRenderer->renderTile(tile, itemAuxValue, 1, fAlpha, useCompiled); From d53831186e3fda37f7d4c2c5e756b7512fa0b682 Mon Sep 17 00:00:00 2001 From: MatthewBeshay <92357869+MatthewBeshay@users.noreply.github.com> Date: Sat, 28 Mar 2026 20:22:26 +1100 Subject: [PATCH 130/170] fix(linux): stop core-profile GL state leakage in iggy title rendering --- .../Platform/Linux/Iggy/gdraw/gdraw.c | 7 +++ .../Platform/Linux/Linux_UIController.cpp | 2 - .../Windows64/Iggy/gdraw/gdraw_gl_shared.inl | 46 +++++++++++++------ Minecraft.Client/Rendering/GameRenderer.cpp | 28 +++++++++++ 4 files changed, 67 insertions(+), 16 deletions(-) diff --git a/Minecraft.Client/Platform/Linux/Iggy/gdraw/gdraw.c b/Minecraft.Client/Platform/Linux/Iggy/gdraw/gdraw.c index fc037dcbf..c56cf237b 100644 --- a/Minecraft.Client/Platform/Linux/Iggy/gdraw/gdraw.c +++ b/Minecraft.Client/Platform/Linux/Iggy/gdraw/gdraw.c @@ -278,6 +278,12 @@ static void error_msg_platform_specific(const char* msg) { fprintf(stderr, "[GDraw] %s\n", msg); } +#define GDRAW_PLATFORM_REPORT_GL_SITE(site) \ + do { \ + if ((site) != NULL) \ + fprintf(stderr, "[GDraw] GL error site: %s\n", (site)); \ + } while (0) + #define GDRAW_MULTISAMPLING // i wish i could improve this function @@ -707,6 +713,7 @@ static void RADLINK hooked_RenderingBegin(void) { if (real_RenderingBegin) real_RenderingBegin(); glDisable(GL_DEPTH_TEST); glDisable(GL_CULL_FACE); + OPENGL_CHECK_SITE("hooked_RenderingBegin:post_state"); } // Creating the context diff --git a/Minecraft.Client/Platform/Linux/Linux_UIController.cpp b/Minecraft.Client/Platform/Linux/Linux_UIController.cpp index e2c1c17c7..4d99f518f 100644 --- a/Minecraft.Client/Platform/Linux/Linux_UIController.cpp +++ b/Minecraft.Client/Platform/Linux/Linux_UIController.cpp @@ -18,14 +18,12 @@ static void restoreFixedFunctionStateAfterIggy() { glClientActiveTexture(GL_TEXTURE1); glActiveTexture(GL_TEXTURE1); glDisable(GL_TEXTURE_2D); - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glMatrixMode(GL_TEXTURE); glLoadIdentity(); glClientActiveTexture(GL_TEXTURE0); glActiveTexture(GL_TEXTURE0); glEnable(GL_TEXTURE_2D); - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glMatrixMode(GL_TEXTURE); glLoadIdentity(); diff --git a/Minecraft.Client/Platform/Windows64/Iggy/gdraw/gdraw_gl_shared.inl b/Minecraft.Client/Platform/Windows64/Iggy/gdraw/gdraw_gl_shared.inl index c22517041..a7a965d19 100644 --- a/Minecraft.Client/Platform/Windows64/Iggy/gdraw/gdraw_gl_shared.inl +++ b/Minecraft.Client/Platform/Windows64/Iggy/gdraw/gdraw_gl_shared.inl @@ -57,6 +57,10 @@ static RADINLINE void break_on_err(GLint e) #endif } +#ifndef GDRAW_PLATFORM_REPORT_GL_SITE +#define GDRAW_PLATFORM_REPORT_GL_SITE(site) ((void)0) +#endif + static void report_err(GLint e) { break_on_err(e); @@ -74,17 +78,31 @@ static void eat_gl_err(void) while (glGetError() != GL_NO_ERROR); } +static void opengl_check_site(const char *site); + static void opengl_check(void) +{ + opengl_check_site(NULL); +} + +static void opengl_check_site(const char *site) { #ifdef _DEBUG GLint e = glGetError(); if (e != GL_NO_ERROR) { + GDRAW_PLATFORM_REPORT_GL_SITE(site); report_err(e); eat_gl_err(); } +#else + (void) site; #endif } +#ifndef OPENGL_CHECK_SITE +#define OPENGL_CHECK_SITE(site) opengl_check_site(site) +#endif + static U32 is_pow2(S32 n) { return ((U32) n & (U32) (n-1)) == 0; @@ -1355,18 +1373,18 @@ static int set_render_state(GDrawRenderState *r, S32 vformat, const int **ovvars } use_lazy_shader(prg); - opengl_check(); + OPENGL_CHECK_SITE("set_render_state:use_lazy_shader"); fvars = prg->vars[0]; vvars = prg->vars[1]; if (vformat == GDRAW_vformat_ihud1) { F32 wv[2][4] = { 1.0f/960,0,0,-1.0, 0,-1.0f/540,0,+1.0 }; glUniform4fv(vvars[VAR_ihudv_worldview], 2, wv[0]); - opengl_check(); + OPENGL_CHECK_SITE("set_render_state:ihud_worldview"); glUniform4fv(vvars[VAR_ihudv_material], p->uniform_count, p->uniforms); - opengl_check(); + OPENGL_CHECK_SITE("set_render_state:ihud_material"); glUniform1f(vvars[VAR_ihudv_textmode], p->drawprim_mode ? 0.0f : 1.0f); - opengl_check(); + OPENGL_CHECK_SITE("set_render_state:ihud_textmode"); } else { // set vertex shader constants @@ -1393,7 +1411,7 @@ static int set_render_state(GDrawRenderState *r, S32 vformat, const int **ovvars // texture stuff set_texture(0, r->tex[0]); - opengl_check(); + OPENGL_CHECK_SITE("set_render_state:set_texture0"); if (r->tex[0] && gdraw->has_conditional_non_power_of_two && ((GDrawHandle*) r->tex[0])->handle.tex.nonpow2) { // only wrap mode allowed in conditional nonpow2 is clamp; this should @@ -1490,7 +1508,7 @@ static int set_render_state(GDrawRenderState *r, S32 vformat, const int **ovvars else glDepthMask(GL_FALSE); - opengl_check(); + OPENGL_CHECK_SITE("set_render_state:final"); if (ovvars) *ovvars = vvars; @@ -1611,7 +1629,7 @@ static void RADLINK gdraw_DrawIndexedTriangles(GDrawRenderState *r, GDrawPrimiti glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); } - opengl_check(); + OPENGL_CHECK_SITE("gdraw_DrawIndexedTriangles:final"); tag_resources(vb, r->tex[0], r->tex[1]); } @@ -1628,33 +1646,33 @@ static void do_screen_quad(gswf_recti *s, F32 *tc, const int *vvars, GDrawStats F32 vert[4][4]; F32 world[2*4]; - opengl_check(); + OPENGL_CHECK_SITE("do_screen_quad:begin"); vert[0][0] = px0; vert[0][1] = py0; vert[0][2] = s0; vert[0][3] = t0; vert[1][0] = px1; vert[1][1] = py0; vert[1][2] = s1; vert[1][3] = t0; vert[2][0] = px1; vert[2][1] = py1; vert[2][2] = s1; vert[2][3] = t1; vert[3][0] = px0; vert[3][1] = py1; vert[3][2] = s0; vert[3][3] = t1; - opengl_check(); + OPENGL_CHECK_SITE("do_screen_quad:after_vertices"); gdraw_PixelSpace(world); world[2] = depth; set_world_projection(vvars, world); - opengl_check(); + OPENGL_CHECK_SITE("do_screen_quad:after_projection"); set_vertex_format(GDRAW_vformat_v2tc2, vert[0]); glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - opengl_check(); + OPENGL_CHECK_SITE("do_screen_quad:before_draw"); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); reset_vertex_format(GDRAW_vformat_v2tc2); - opengl_check(); + OPENGL_CHECK_SITE("do_screen_quad:after_draw"); gstats->nonzero_flags |= GDRAW_STATS_batches; gstats->num_batches += 1; gstats->drawn_vertices += 4; gstats->drawn_indices += 6; - opengl_check(); + OPENGL_CHECK_SITE("do_screen_quad:final"); } #ifdef GDRAW_FEWER_CLEARS @@ -1805,7 +1823,7 @@ static void RADLINK gdraw_FilterQuad(GDrawRenderState *r, S32 x0, S32 y0, S32 x1 glColorMask(1,1,1,1); glDisable(GL_BLEND); glDisable(GL_DEPTH_TEST); - opengl_check(); + OPENGL_CHECK_SITE("gdraw_FilterQuad:pre_filter"); if (r->blend_mode == GDRAW_BLEND_filter) { switch (r->filter) { diff --git a/Minecraft.Client/Rendering/GameRenderer.cpp b/Minecraft.Client/Rendering/GameRenderer.cpp index 3e5763087..6a1bbc614 100644 --- a/Minecraft.Client/Rendering/GameRenderer.cpp +++ b/Minecraft.Client/Rendering/GameRenderer.cpp @@ -1845,6 +1845,34 @@ void GameRenderer::setupGuiScreen(int forceScale /*=-1*/) { // 4jcraft: use actual framebuffer dimensions instead of mc->width/height // to ensure GUI scales correctly after a window resize. ScreenSizeCalculator ssc(mc->options, fbw, fbh, forceScale); + + // 4jcraft: Java GUI screens still assume a clean 2D fixed-function style state. + RenderManager.StateSetFaceCull(false); + glDisable(GL_LIGHTING); + glDisable(GL_FOG); + glColor4f(1, 1, 1, 1); + glEnable(GL_ALPHA_TEST); + glAlphaFunc(GL_GREATER, 0.1f); + glEnable(GL_DEPTH_TEST); + glDepthFunc(GL_LEQUAL); + glDepthMask(true); + + RenderManager.TextureBindVertex(-1); + + glClientActiveTexture(GL_TEXTURE1); + glActiveTexture(GL_TEXTURE1); + glDisable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, 0); + glMatrixMode(GL_TEXTURE); + glLoadIdentity(); + + glClientActiveTexture(GL_TEXTURE0); + glActiveTexture(GL_TEXTURE0); + glEnable(GL_TEXTURE_2D); + glMatrixMode(GL_TEXTURE); + glLoadIdentity(); + glMatrixMode(GL_MODELVIEW); + glClear(GL_DEPTH_BUFFER_BIT); glMatrixMode(GL_PROJECTION); glLoadIdentity(); From 35d92fe504b15ce4ffbeb06e6e8bfc34f6efae2e Mon Sep 17 00:00:00 2001 From: Tropical <42101043+tropicaaal@users.noreply.github.com> Date: Sat, 28 Mar 2026 04:25:24 -0500 Subject: [PATCH 131/170] docs: add FIXME for clipChunk translation --- Minecraft.Client/Rendering/LevelRenderer.cpp | 47 +++++++++++++------- 1 file changed, 31 insertions(+), 16 deletions(-) diff --git a/Minecraft.Client/Rendering/LevelRenderer.cpp b/Minecraft.Client/Rendering/LevelRenderer.cpp index 47702a12a..ad1c0642e 100644 --- a/Minecraft.Client/Rendering/LevelRenderer.cpp +++ b/Minecraft.Client/Rendering/LevelRenderer.cpp @@ -858,6 +858,9 @@ int LevelRenderer::renderChunks(int from, int to, int layer, double alpha) { glPushMatrix(); + // 4jcraft: added this. On OpenGL 2.1 this breaks, but the 3.3 renderer + // requires it. + // FIXME: find a way to get rid of this. glTranslatef((float)pClipChunk->chunk->x, (float)pClipChunk->chunk->y, (float)pClipChunk->chunk->z); // List can be calculated directly from the chunk's global idex @@ -2470,11 +2473,11 @@ void LevelRenderer::renderHitOutline(std::shared_ptr player, if (app.GetGameSettings(iPad, eGameSetting_DisplayHUD) == 0) return; RenderManager.StateSetLightingEnable(false); glDisable(GL_TEXTURE_2D); - + // draw hit outline RenderManager.StateSetColour(0.0f, 0.0f, 0.0f, 0.4f); RenderManager.StateSetLineWidth(1.0f); - + // hack glDepthFunc(GL_LEQUAL); glEnable(GL_POLYGON_OFFSET_LINE); @@ -2515,25 +2518,37 @@ void LevelRenderer::render(AABB* b) { glPolygonOffset(-2.0f, -2.0f); // One call please! - t->begin(GL_LINES); + t->begin(GL_LINES); // Bottom - t->vertex(b->x0, b->y0, b->z0); t->vertex(b->x1, b->y0, b->z0); - t->vertex(b->x1, b->y0, b->z0); t->vertex(b->x1, b->y0, b->z1); - t->vertex(b->x1, b->y0, b->z1); t->vertex(b->x0, b->y0, b->z1); - t->vertex(b->x0, b->y0, b->z1); t->vertex(b->x0, b->y0, b->z0); + t->vertex(b->x0, b->y0, b->z0); + t->vertex(b->x1, b->y0, b->z0); + t->vertex(b->x1, b->y0, b->z0); + t->vertex(b->x1, b->y0, b->z1); + t->vertex(b->x1, b->y0, b->z1); + t->vertex(b->x0, b->y0, b->z1); + t->vertex(b->x0, b->y0, b->z1); + t->vertex(b->x0, b->y0, b->z0); // Top - t->vertex(b->x0, b->y1, b->z0); t->vertex(b->x1, b->y1, b->z0); - t->vertex(b->x1, b->y1, b->z0); t->vertex(b->x1, b->y1, b->z1); - t->vertex(b->x1, b->y1, b->z1); t->vertex(b->x0, b->y1, b->z1); - t->vertex(b->x0, b->y1, b->z1); t->vertex(b->x0, b->y1, b->z0); + t->vertex(b->x0, b->y1, b->z0); + t->vertex(b->x1, b->y1, b->z0); + t->vertex(b->x1, b->y1, b->z0); + t->vertex(b->x1, b->y1, b->z1); + t->vertex(b->x1, b->y1, b->z1); + t->vertex(b->x0, b->y1, b->z1); + t->vertex(b->x0, b->y1, b->z1); + t->vertex(b->x0, b->y1, b->z0); // Vertical - t->vertex(b->x0, b->y0, b->z0); t->vertex(b->x0, b->y1, b->z0); - t->vertex(b->x1, b->y0, b->z0); t->vertex(b->x1, b->y1, b->z0); - t->vertex(b->x1, b->y0, b->z1); t->vertex(b->x1, b->y1, b->z1); - t->vertex(b->x0, b->y0, b->z1); t->vertex(b->x0, b->y1, b->z1); + t->vertex(b->x0, b->y0, b->z0); + t->vertex(b->x0, b->y1, b->z0); + t->vertex(b->x1, b->y0, b->z0); + t->vertex(b->x1, b->y1, b->z0); + t->vertex(b->x1, b->y0, b->z1); + t->vertex(b->x1, b->y1, b->z1); + t->vertex(b->x0, b->y0, b->z1); + t->vertex(b->x0, b->y1, b->z1); t->end(); glDisable(GL_POLYGON_OFFSET_LINE); @@ -4060,7 +4075,7 @@ int LevelRenderer::rebuildChunkThreadProc(void* lpParam) { // app.DebugPrintf("Rebuilding permaChunk %d\n", index + 1); permaChunk[index + 1].rebuild(); - + // Inform the producer thread that we are done with this chunk s_rebuildCompleteEvents->Set(index); } From dc8c0b04c038a67110f087ace42e136e4b30f0dd Mon Sep 17 00:00:00 2001 From: JuiceyDev Date: Sat, 28 Mar 2026 11:25:58 +0100 Subject: [PATCH 132/170] apply setchuckoffset to direct shader matrix --- Minecraft.Client/Rendering/LevelRenderer.cpp | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/Minecraft.Client/Rendering/LevelRenderer.cpp b/Minecraft.Client/Rendering/LevelRenderer.cpp index ad1c0642e..7990e1737 100644 --- a/Minecraft.Client/Rendering/LevelRenderer.cpp +++ b/Minecraft.Client/Rendering/LevelRenderer.cpp @@ -856,24 +856,22 @@ int LevelRenderer::renderChunks(int from, int to, int layer, double alpha) { if ((globalChunkFlags[pClipChunk->globalIdx] & emptyFlag) == emptyFlag) continue; // Check that this particular layer isn't empty - glPushMatrix(); - - // 4jcraft: added this. On OpenGL 2.1 this breaks, but the 3.3 renderer - // requires it. - // FIXME: find a way to get rid of this. - glTranslatef((float)pClipChunk->chunk->x, (float)pClipChunk->chunk->y, - (float)pClipChunk->chunk->z); // List can be calculated directly from the chunk's global idex int list = pClipChunk->globalIdx * 2 + layer; list += chunkLists; + // 4jcraft: replaced glPushMatrix/glTranslatef/glPopMatrix per chunk + // no more full MVP upload per chunk, can also be bkwards compat + RenderManager.SetChunkOffset((float)pClipChunk->chunk->x, + (float)pClipChunk->chunk->y, + (float)pClipChunk->chunk->z); + if (RenderManager.CBuffCall(list, first)) { first = false; } - - glPopMatrix(); count++; } + RenderManager.SetChunkOffset(0.f, 0.f, 0.f); #ifdef __PSVITA__ // AP - alpha cut out is expensive on vita. Now we render all the alpha cut From 31acc463089db730d2160e585dc4d715d4bb24c1 Mon Sep 17 00:00:00 2001 From: MatthewBeshay <92357869+MatthewBeshay@users.noreply.github.com> Date: Sat, 28 Mar 2026 21:09:35 +1100 Subject: [PATCH 133/170] fix(linux): localise chunk transforms and guard optional iggy paths --- .../Platform/Common/UI/UIControl.cpp | 50 +++++++++++++++---- .../Platform/Common/UI/UIControl.h | 2 + .../Platform/Common/UI/UIController.cpp | 11 +++- .../Platform/Common/UI/UIScene.cpp | 12 +++++ Minecraft.Client/Platform/Common/UI/UIScene.h | 1 + Minecraft.Client/Platform/Linux/LinuxGL.cpp | 7 +-- Minecraft.Client/Rendering/Chunk.cpp | 25 ---------- Minecraft.Client/Textures/Textures.cpp | 3 ++ 8 files changed, 71 insertions(+), 40 deletions(-) diff --git a/Minecraft.Client/Platform/Common/UI/UIControl.cpp b/Minecraft.Client/Platform/Common/UI/UIControl.cpp index 234d9bb99..9a9426be3 100644 --- a/Minecraft.Client/Platform/Common/UI/UIControl.cpp +++ b/Minecraft.Client/Platform/Common/UI/UIControl.cpp @@ -10,7 +10,12 @@ UIControl::UIControl() { m_controlName = ""; m_isVisible = true; m_bHidden = false; + m_isValid = false; m_eControlType = eNoControl; + m_x = 0; + m_y = 0; + m_width = 0; + m_height = 0; } bool UIControl::setupControl(UIScene* scene, IggyValuePath* parent, @@ -20,6 +25,7 @@ bool UIControl::setupControl(UIScene* scene, IggyValuePath* parent, rrbool res = IggyValuePathMakeNameRef(&m_iggyPath, parent, controlName.c_str()); + m_isValid = res ? true : false; m_nameXPos = registerFastName(L"x"); m_nameYPos = registerFastName(L"y"); @@ -28,16 +34,32 @@ bool UIControl::setupControl(UIScene* scene, IggyValuePath* parent, m_funcSetAlpha = registerFastName(L"SetControlAlpha"); m_nameVisible = registerFastName(L"visible"); - F64 fx, fy, fwidth, fheight; - IggyValueGetF64RS(getIggyValuePath(), m_nameXPos, NULL, &fx); - IggyValueGetF64RS(getIggyValuePath(), m_nameYPos, NULL, &fy); - IggyValueGetF64RS(getIggyValuePath(), m_nameWidth, NULL, &fwidth); - IggyValueGetF64RS(getIggyValuePath(), m_nameHeight, NULL, &fheight); + if (m_isValid) { + IggyDatatype controlType = IGGY_DATATYPE__invalid_request; + IggyResult typeResult = + IggyValueGetTypeRS(getIggyValuePath(), 0, NULL, &controlType); + m_isValid = typeResult == IGGY_RESULT_SUCCESS && + controlType != IGGY_DATATYPE__invalid_request && + controlType != IGGY_DATATYPE_undefined; + } - m_x = (S32)fx; - m_y = (S32)fy; - m_width = (S32)Math::round(fwidth); - m_height = (S32)Math::round(fheight); + if (m_isValid) { + F64 fx, fy, fwidth, fheight; + IggyValueGetF64RS(getIggyValuePath(), m_nameXPos, NULL, &fx); + IggyValueGetF64RS(getIggyValuePath(), m_nameYPos, NULL, &fy); + IggyValueGetF64RS(getIggyValuePath(), m_nameWidth, NULL, &fwidth); + IggyValueGetF64RS(getIggyValuePath(), m_nameHeight, NULL, &fheight); + + m_x = (S32)fx; + m_y = (S32)fy; + m_width = (S32)Math::round(fwidth); + m_height = (S32)Math::round(fheight); + } else { + m_x = 0; + m_y = 0; + m_width = 0; + m_height = 0; + } return res; } @@ -57,6 +79,8 @@ void UIControl::UpdateControl() { #endif // __PSVITA__ void UIControl::ReInit() { + if (!m_isValid) return; + if (m_lastOpacity != 1.0f) { IggyDataValue result; IggyDataValue value[2]; @@ -91,6 +115,7 @@ S32 UIControl::getHeight() { return m_height; } void UIControl::setOpacity(float percent) { if (percent != m_lastOpacity) { m_lastOpacity = percent; + if (!m_isValid) return; IggyDataValue result; IggyDataValue value[2]; @@ -112,6 +137,11 @@ void UIControl::setOpacity(float percent) { void UIControl::setVisible(bool visible) { if (visible != m_isVisible) { + if (!m_isValid) { + m_isVisible = visible; + return; + } + rrbool succ = IggyValueSetBooleanRS(getIggyValuePath(), m_nameVisible, NULL, visible); if (succ) @@ -122,6 +152,8 @@ void UIControl::setVisible(bool visible) { } bool UIControl::getVisible() { + if (!m_isValid) return m_isVisible; + rrbool bVisible = false; IggyResult result = IggyValueGetBooleanRS(getIggyValuePath(), m_nameVisible, diff --git a/Minecraft.Client/Platform/Common/UI/UIControl.h b/Minecraft.Client/Platform/Common/UI/UIControl.h index 19cdb9ad4..807daa5dd 100644 --- a/Minecraft.Client/Platform/Common/UI/UIControl.h +++ b/Minecraft.Client/Platform/Common/UI/UIControl.h @@ -34,6 +34,7 @@ protected: eUIControlType m_eControlType; int m_id; bool m_bHidden; // set by the Remove call + bool m_isValid; public: void setControlType(eUIControlType eType) { m_eControlType = eType; } @@ -83,6 +84,7 @@ public: void setVisible(bool visible); bool getVisible(); bool isVisible() { return m_isVisible; } + bool isValid() { return m_isValid; } virtual bool hasFocus() { return false; } diff --git a/Minecraft.Client/Platform/Common/UI/UIController.cpp b/Minecraft.Client/Platform/Common/UI/UIController.cpp index 912e827df..3807ec7e0 100644 --- a/Minecraft.Client/Platform/Common/UI/UIController.cpp +++ b/Minecraft.Client/Platform/Common/UI/UIController.cpp @@ -77,6 +77,15 @@ static void RADLINK WarningCallback(void* user_callback_data, Iggy* player, // IGGY_RESULT_Error_UndefinedEntity = 504, // IGGY_RESULT_Error_OutOfMemory = 1001,}; + if (message != NULL) { + // Some Linux movie variants do not ship these optional hooks/controls. + // We guard the call sites, so drop the residual Iggy warning noise. + if (strstr(message, "LabelGamertag") != NULL || + strstr(message, "Method SetSafeZone was not a function") != NULL) { + return; + } + } + switch (code) { case IGGY_RESULT_Warning_CannotSustainFrameRate: // Ignore warning @@ -3233,4 +3242,4 @@ void UIController::SendTouchInput(unsigned int iPad, unsigned int key, } } -#endif \ No newline at end of file +#endif diff --git a/Minecraft.Client/Platform/Common/UI/UIScene.cpp b/Minecraft.Client/Platform/Common/UI/UIScene.cpp index 863e0f951..d46b97b37 100644 --- a/Minecraft.Client/Platform/Common/UI/UIScene.cpp +++ b/Minecraft.Client/Platform/Common/UI/UIScene.cpp @@ -19,6 +19,7 @@ UIScene::UIScene(int iPad, UILayer* parentLayer) { m_bVisible = true; m_bCanHandleInput = false; m_bIsReloading = false; + m_hasSetSafeZoneMethod = false; m_iFocusControl = -1; m_iFocusChild = 0; @@ -53,6 +54,7 @@ void UIScene::destroyMovie() { /* Destroy the Iggy player. */ IggyPlayerDestroy(swf); swf = NULL; + m_hasSetSafeZoneMethod = false; // Clear out the controls collection (doesn't delete the controls, and they // get re-setup later) @@ -76,6 +78,7 @@ void UIScene::reloadMovie(bool force) { // Clear out the controls collection (doesn't delete the controls, and // they get re-setup later) m_controls.clear(); + m_hasSetSafeZoneMethod = false; // Clear out all the fast names for the current movie m_fastNames.clear(); @@ -194,6 +197,8 @@ void UIScene::updateSafeZone() { void UIScene::setSafeZone(S32 safeTop, S32 safeBottom, S32 safeLeft, S32 safeRight) { + if (!m_hasSetSafeZoneMethod) return; + IggyDataValue result; IggyDataValue value[4]; @@ -251,6 +256,13 @@ bool UIScene::mapElementsAndNames() { m_funcSetAlpha = registerFastName(L"SetAlpha"); m_funcSetFocus = registerFastName(L"SetFocus"); m_funcHorizontalResizeCheck = registerFastName(L"DoHorizontalResizeCheck"); + + IggyDatatype safeZoneType = IGGY_DATATYPE__invalid_request; + IggyResult safeZoneResult = IggyValueGetTypeRS( + m_rootPath, m_funcSetSafeZone, NULL, &safeZoneType); + m_hasSetSafeZoneMethod = + safeZoneResult == IGGY_RESULT_SUCCESS && + safeZoneType == IGGY_DATATYPE_function; return true; } diff --git a/Minecraft.Client/Platform/Common/UI/UIScene.h b/Minecraft.Client/Platform/Common/UI/UIScene.h index b4948bfce..e7d746865 100644 --- a/Minecraft.Client/Platform/Common/UI/UIScene.h +++ b/Minecraft.Client/Platform/Common/UI/UIScene.h @@ -72,6 +72,7 @@ private: bool m_bUpdateOpacity; bool m_bVisible; bool m_bCanHandleInput; + bool m_hasSetSafeZoneMethod; UIScene* m_backScene; size_t m_callbackUniqueId; diff --git a/Minecraft.Client/Platform/Linux/LinuxGL.cpp b/Minecraft.Client/Platform/Linux/LinuxGL.cpp index a1d992ee3..a6ccce7cc 100644 --- a/Minecraft.Client/Platform/Linux/LinuxGL.cpp +++ b/Minecraft.Client/Platform/Linux/LinuxGL.cpp @@ -219,14 +219,11 @@ void LinuxGLLogLightmapState(const char* stage, int textureId, ::glActiveTexture(GL_TEXTURE1); GLint unit1Binding = 0; ::glGetIntegerv(GL_TEXTURE_BINDING_2D, &unit1Binding); - const bool unit1Enabled = (::glIsEnabled(GL_TEXTURE_2D) == GL_TRUE); ::glActiveTexture(restoreTexture); app.DebugPrintf( - "[linux-lightmap] %s tex=%d scale=%d active=%#x unit1Bound=%d " - "unit1Enabled=%d\n", - stage, textureId, scaleLight ? 1 : 0, activeTexture, unit1Binding, - unit1Enabled ? 1 : 0); + "[linux-lightmap] %s tex=%d scale=%d active=%#x unit1Bound=%d\n", + stage, textureId, scaleLight ? 1 : 0, activeTexture, unit1Binding); } #endif diff --git a/Minecraft.Client/Rendering/Chunk.cpp b/Minecraft.Client/Rendering/Chunk.cpp index a52ac7459..4df99432b 100644 --- a/Minecraft.Client/Rendering/Chunk.cpp +++ b/Minecraft.Client/Rendering/Chunk.cpp @@ -410,20 +410,8 @@ void Chunk::rebuild() { MemSect(31); glNewList(lists + currentLayer, GL_COMPILE); MemSect(0); - glPushMatrix(); glDepthMask(true); // 4J added t->useCompactVertices(true); // 4J added - translateToPos(); - float ss = 1.000001f; - // 4J - have removed this scale as I don't think we - // should need it, and have now optimised the vertex - // shader so it doesn't do anything other than - // translate with this matrix anyway -#if 0 - glTranslatef(-zs / 2.0f, -ys / 2.0f, -zs / 2.0f); - glScalef(ss, ss, ss); - glTranslatef(zs / 2.0f, ys / 2.0f, zs / 2.0f); -#endif t->begin(); t->offset((float)(-this->x), (float)(-this->y), (float)(-this->z)); @@ -471,7 +459,6 @@ void Chunk::rebuild() { #endif t->end(); bounds.addBounds(t->bounds); // 4J MGH - added - glPopMatrix(); glEndList(); t->useCompactVertices(false); // 4J added t->offset(0, 0, 0); @@ -734,19 +721,8 @@ void Chunk::rebuild_SPU() { { glNewList(lists + currentLayer, GL_COMPILE); MemSect(0); - glPushMatrix(); glDepthMask(true); // 4J added t->useCompactVertices(true); // 4J added - translateToPos(); - float ss = 1.000001f; - // 4J - have removed this scale as I don't think we should need it, - // and have now optimised the vertex shader so it doesn't do - // anything other than translate with this matrix anyway -#if 0 - glTranslatef(-zs / 2.0f, -ys / 2.0f, -zs / 2.0f); - glScalef(ss, ss, ss); - glTranslatef(zs / 2.0f, ys / 2.0f, zs / 2.0f); -#endif t->begin(); t->offset((float)(-this->x), (float)(-this->y), (float)(-this->z)); } @@ -806,7 +782,6 @@ void Chunk::rebuild_SPU() { { t->end(); bounds.addBounds(t->bounds); - glPopMatrix(); glEndList(); t->useCompactVertices(false); // 4J added t->offset(0, 0, 0); diff --git a/Minecraft.Client/Textures/Textures.cpp b/Minecraft.Client/Textures/Textures.cpp index 13c76e46c..a9927a1bf 100644 --- a/Minecraft.Client/Textures/Textures.cpp +++ b/Minecraft.Client/Textures/Textures.cpp @@ -543,6 +543,9 @@ void Textures::bindTextureLayers(ResourceLocation* resource) { void Textures::bind(int id) { // 4jcraft: Classic GUI code still performs some raw glBindTexture calls, so // this path must always rebind rather than trusting lastBoundId to be in sync. + // TODO(4jcraft): Long term, route all texture binds through one synchronized + // path or invalidate lastBoundId at every raw glBindTexture call so this can + // safely use cached binds again without breaking font/UI rendering. // if (id != lastBoundId) { if (id < 0) return; From e2a6c3f92cc877b8ad270e56dc0d79542c2fc2bd Mon Sep 17 00:00:00 2001 From: JuiceyDev Date: Sat, 28 Mar 2026 13:58:50 +0100 Subject: [PATCH 134/170] ss not here --- Minecraft.Client/Rendering/LevelRenderer.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Minecraft.Client/Rendering/LevelRenderer.cpp b/Minecraft.Client/Rendering/LevelRenderer.cpp index 7990e1737..911bc5aa7 100644 --- a/Minecraft.Client/Rendering/LevelRenderer.cpp +++ b/Minecraft.Client/Rendering/LevelRenderer.cpp @@ -2467,6 +2467,8 @@ void LevelRenderer::renderHitOutline(std::shared_ptr player, if (mode == 0 && h->type == HitResult::TILE) { int iPad = mc->player->GetXboxPad(); // 4J added + const float ss = 0.002f; + // 4J-PB - If Display HUD is false, don't render the hit outline if (app.GetGameSettings(iPad, eGameSetting_DisplayHUD) == 0) return; RenderManager.StateSetLightingEnable(false); From 4aa8106e52a35037b9d9498379c94aa0e108b1d7 Mon Sep 17 00:00:00 2001 From: JuiceyDev Date: Sat, 28 Mar 2026 15:21:52 +0100 Subject: [PATCH 135/170] rewrote & formatted meson, also added gles to renderer, no need to touch, it works, and it'll help for future support. basically a neat lil touch --- Minecraft.Client/Platform/Linux/LinuxGL.cpp | 67 +++++++------ Minecraft.Client/meson.build | 103 ++++++++++---------- meson.build | 66 +++++++++---- meson.options | 7 ++ 4 files changed, 146 insertions(+), 97 deletions(-) diff --git a/Minecraft.Client/Platform/Linux/LinuxGL.cpp b/Minecraft.Client/Platform/Linux/LinuxGL.cpp index a6ccce7cc..4b41d2961 100644 --- a/Minecraft.Client/Platform/Linux/LinuxGL.cpp +++ b/Minecraft.Client/Platform/Linux/LinuxGL.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include "../../Minecraft.World/IO/Streams/IntBuffer.h" #include "../../Minecraft.World/IO/Streams/FloatBuffer.h" @@ -27,7 +28,15 @@ #undef glReadPixels #undef glActiveTexture -// _4j suffix shit (todo: make ts better) +// Helper functions & stuff +inline GLuint* getIntPtr(IntBuffer* buf) { + return buf ? (GLuint*)((int*)buf->getBuffer() + buf->position()) : nullptr; +} +inline GLvoid* getBytePtr(ByteBuffer* buf) { + return buf ? (GLvoid*)((char*)buf->getBuffer() + buf->position()) : nullptr; +} + +// _4j suffix shit int glGenTextures() { GLuint id = 0; ::glGenTextures(1, &id); @@ -35,10 +44,11 @@ int glGenTextures() { } void glGenTextures_4J(IntBuffer* buf) { - GLuint id = 0; - ::glGenTextures(1, &id); - buf->put((int)id); - buf->flip(); + if (!buf) return; + int n = buf->limit() - buf->position(); + if (n > 0) { + ::glGenTextures(n, getIntPtr(buf)); + } } void glDeleteTextures(int id) { @@ -47,10 +57,10 @@ void glDeleteTextures(int id) { } void glDeleteTextures_4J(IntBuffer* buf) { - if (buf && buf->limit() > 0) { - int id = buf->get(0); - GLuint uid = (GLuint)id; - ::glDeleteTextures(1, &uid); + if (!buf) return; + int n = buf->limit() - buf->position(); + if (n > 0) { + ::glDeleteTextures(n, getIntPtr(buf)); } } @@ -79,13 +89,13 @@ void glTexCoordPointer_4J(int size, int type, FloatBuffer* pointer) { } void glNormalPointer_4J(int type, ByteBuffer* pointer) { - ::glNormalPointer((GLenum)type, 0, pointer->getBuffer()); + ::glNormalPointer((GLenum)type, 0, getBytePtr(pointer)); } void glColorPointer_4J(int size, bool normalized, int stride, ByteBuffer* pointer) { (void)normalized; - ::glColorPointer(size, GL_UNSIGNED_BYTE, stride, pointer->getBuffer()); + ::glColorPointer(size, GL_UNSIGNED_BYTE, stride, getBytePtr(pointer)); } void glVertexPointer_4J(int size, int type, FloatBuffer* pointer) { @@ -100,20 +110,22 @@ void glEndList_4J(int dummy) { void glTexImage2D_4J(int target, int level, int internalformat, int width, int height, int border, int format, int type, ByteBuffer* pixels) { - void* data = pixels ? pixels->getBuffer() : nullptr; ::glTexImage2D((GLenum)target, level, internalformat, width, height, border, - (GLenum)format, (GLenum)type, data); + (GLenum)format, (GLenum)type, getBytePtr(pixels)); } void glCallLists_4J(IntBuffer* lists) { + if (!lists) return; int count = lists->limit() - lists->position(); - ::glCallLists(count, GL_INT, lists->getBuffer()); + if (count > 0) { + ::glCallLists(count, GL_INT, getIntPtr(lists)); + } } void glReadPixels_4J(int x, int y, int width, int height, int format, int type, ByteBuffer* pixels) { ::glReadPixels(x, y, width, height, (GLenum)format, (GLenum)type, - pixels->getBuffer()); + getBytePtr(pixels)); } void glGetFloat(int pname, FloatBuffer* params) { @@ -173,11 +185,11 @@ static void initQueryFuncs() { void glGenQueriesARB_4J(IntBuffer* buf) { initQueryFuncs(); - if (_glGenQueriesARB) { - GLuint id = 0; - _glGenQueriesARB(1, &id); - buf->put((int)id); - buf->flip(); + if (_glGenQueriesARB && buf) { + int n = buf->limit() - buf->position(); + if (n > 0) { + _glGenQueriesARB(n, getIntPtr(buf)); + } } } void glGenQueriesARB(IntBuffer* buf) { glGenQueriesARB_4J(buf); } @@ -196,11 +208,10 @@ void glEndQueryARB(int target) { glEndQueryARB_4J(target); } void glGetQueryObjectuARB_4J(int id, int pname, IntBuffer* params) { initQueryFuncs(); - if (_glGetQueryObjectuivARB) { - GLuint val = 0; - _glGetQueryObjectuivARB((GLuint)id, (GLenum)pname, &val); - params->put((int)val); - params->flip(); + if (_glGetQueryObjectuivARB && params) { + // LWJGL does not change limits/positions during these calls, it + // reads/writes exactly at pointer!! + _glGetQueryObjectuivARB((GLuint)id, (GLenum)pname, getIntPtr(params)); } } void glGetQueryObjectuARB(int id, int pname, IntBuffer* params) { @@ -222,8 +233,8 @@ void LinuxGLLogLightmapState(const char* stage, int textureId, ::glActiveTexture(restoreTexture); app.DebugPrintf( - "[linux-lightmap] %s tex=%d scale=%d active=%#x unit1Bound=%d\n", - stage, textureId, scaleLight ? 1 : 0, activeTexture, unit1Binding); + "[linux-lightmap] %s tex=%d scale=%d active=%#x unit1Bound=%d\n", stage, + textureId, scaleLight ? 1 : 0, activeTexture, unit1Binding); } -#endif +#endif \ No newline at end of file diff --git a/Minecraft.Client/meson.build b/Minecraft.Client/meson.build index 9bb614fc4..f31407b0d 100644 --- a/Minecraft.Client/meson.build +++ b/Minecraft.Client/meson.build @@ -8,21 +8,21 @@ exclude_sources = [ # all sources except ./Platform/* client_sources = run_command( - 'sh', '-c', - 'find "' - + meson.current_source_dir() - + '" \\( -name "*.cpp" -o -name "*.c" \\)' - + ' '.join(exclude_sources), - check : true, + 'sh', + '-c', 'find "' + + meson.current_source_dir() + + '" \\( -name "*.cpp" -o -name "*.c" \\)' + + ' '.join(exclude_sources), + check: true, ).stdout().strip().split('\n') # all sources in ./Platform (top-level files only) platform_sources = run_command( - 'sh', '-c', - 'find "' - + meson.current_source_dir() / 'Platform' - + '" -maxdepth 1 \\( -name "*.cpp" -o -name "*.c" \\)', - check : true, + 'sh', + '-c', 'find "' + + meson.current_source_dir() / 'Platform' + + '" -maxdepth 1 \\( -name "*.cpp" -o -name "*.c" \\)', + check: true, ).stdout().strip().split('\n') # some platform-specific sources that are for some stupid reason in Common @@ -32,47 +32,47 @@ exclude_platform_common_sources = [ # we use system zlib instead, since this one is old as hell and isn't configured for linux correctly ' ! -path "*/zlib/*"', ' ! -name "SonyLeaderboardManager.cpp"', - ' ! -name "UIScene_InGameSaveManagementMenu.cpp"' + ' ! -name "UIScene_InGameSaveManagementMenu.cpp"', ] # all sources in in ./Platform/Common platform_sources += run_command( - 'sh', '-c', - 'find "' - + meson.current_source_dir() / 'Platform/Common' - + '" \\( -name "*.cpp" -o -name "*.c" \\)' - + ' '.join(exclude_platform_common_sources), - check : true, + 'sh', + '-c', 'find "' + + meson.current_source_dir() / 'Platform/Common' + + '" \\( -name "*.cpp" -o -name "*.c" \\)' + + ' '.join(exclude_platform_common_sources), + check: true, ).stdout().strip().split('\n') # linux-specific files (everything in Platform/Linux) if host_machine.system() == 'linux' platform_sources += run_command( - 'sh', '-c', - 'find "' - + meson.current_source_dir() / 'Platform/Linux' - + '" \\( -name "*.cpp" -o -name "*.c" \\) ', - check : true, + 'sh', + '-c', 'find "' + + meson.current_source_dir() / 'Platform/Linux' + + '" \\( -name "*.cpp" -o -name "*.c" \\) ', + check: true, ).stdout().strip().split('\n') endif client_dependencies = [ - render_dep, - input_dep, - profile_dep, - storage_dep, - assets_localisation_dep, - world_dep, - gl_dep, - glu_dep, - thread_dep, - thread_dep, - dependency('zlib'), - miniaudio_dep + render_dep, + input_dep, + profile_dep, + storage_dep, + assets_localisation_dep, + world_dep, + gl_dep, + glu_dep, + thread_dep, + dl_dep, + dependency('zlib'), + miniaudio_dep, ] if get_option('enable_vsync') - global_cpp_defs += '-DENABLE_VSYNC' + global_cpp_defs += ['-DENABLE_VSYNC'] endif if get_option('classic_panorama') @@ -85,8 +85,8 @@ if get_option('ui_backend') == 'shiggy' fallback : ['shiggy', 'shiggy_dep'], ) - global_cpp_defs += '-D_ENABLEIGGY' - client_dependencies += shiggy_dep + global_cpp_defs += ['-D_ENABLEIGGY'] + client_dependencies += shiggy_dep endif if get_option('ui_backend') == 'java' @@ -95,25 +95,30 @@ endif client = executable('Minecraft.Client', client_sources + platform_sources + localisation[1], - include_directories : [include_directories('Platform', 'Platform/Linux/Iggy/include'),stb], - dependencies : client_dependencies, - cpp_args : global_cpp_args + global_cpp_defs + [ - '-DUNICODE', '-D_UNICODE', + include_directories: [include_directories('Platform', 'Platform/Linux/Iggy/include'), stb], + dependencies: client_dependencies, + cpp_args: global_cpp_args + + global_cpp_defs + + [ + '-DUNICODE', + '-D_UNICODE', '-include', meson.current_source_dir() / 'Platform/stdafx.h', ], - c_args : global_cpp_defs + ['-DUNICODE', '-D_UNICODE'], - install : true, - install_dir : '' + c_args: global_cpp_defs + ['-DUNICODE', '-D_UNICODE'], + install: true, + install_dir: '', ) # To support actually running the client from the build folder, we need to # copy the generated assets from Minecraft.Assets into the working directory # of the client. -custom_target('copy_assets_to_client', +custom_target( + 'copy_assets_to_client', input: [client, media_archive], output: 'assets.stamp', # using a stamp file to avoid copying assets every time - command : [ - python, meson.project_source_root() / 'scripts/copy_assets_to_client.py', + command: [ + python, + meson.project_source_root() / 'scripts/copy_assets_to_client.py', meson.project_source_root(), meson.project_build_root(), meson.current_build_dir(), @@ -121,4 +126,4 @@ custom_target('copy_assets_to_client', '@OUTPUT@', ], build_by_default: true, -) +) \ No newline at end of file diff --git a/meson.build b/meson.build index cd2b7daa8..7d08e7faf 100644 --- a/meson.build +++ b/meson.build @@ -1,7 +1,9 @@ -project('4jcraft-chucklegrounds', ['cpp', 'c'], - version : '0.1.0', +project( + '4jcraft', + ['cpp', 'c'], + version: '0.1.0', meson_version: '>= 1.7', - default_options : [ + default_options: [ 'cpp_std=c++23', 'warning_level=0', 'buildtype=debug', # for now @@ -16,22 +18,6 @@ python = pymod.find_installation('python3', required: true) cc = meson.get_compiler('cpp') -# system deps -gl_dep = dependency('gl') -glu_dep = dependency('glu') -sdl2_dep = dependency('sdl2') # Yes.. i know sdl3 is out, but there's not point upgrading right now except when - # someone is gonna ask me "Hey juicey can you make it SDL3?" and i'd be like fuck you and still do it. -thread_dep = dependency('threads') -miniaudio_dep = dependency('miniaudio') -stb = subproject('stb').get_variable('stb_inc') -# compile flags (chagne ts juicey) -global_cpp_args = [ - '-fpermissive', - '-Wshift-count-overflow', - '-pipe', # use pipes instead of temp files between compiler stages -] - -# global ccp defs type shi global_cpp_defs = [ '-DSPLIT_SAVES', '-D_LARGE_WORLDS', @@ -49,11 +35,51 @@ if host_machine.system() == 'linux' ] endif +add_project_arguments(global_cpp_defs, language: ['cpp', 'c']) + +global_cpp_args = [ + '-fpermissive', + '-Wshift-count-overflow', + '-pipe', +] +add_project_arguments(global_cpp_args, language: 'cpp') + +sdl2_dep = dependency('sdl2') +thread_dep = dependency('threads') +dl_dep = cc.find_library('dl', required: true) + +if '-DGLES' in global_cpp_defs + gl_dep = dependency('glesv2') + glu_dep = dependency('', required: false) +else + gl_dep = dependency('gl') + glu_dep = dependency('glu') +endif + +stb = subproject('stb').get_variable('stb_inc') +stb_dep = declare_dependency(include_directories: stb) + +miniaudio_dep = dependency('miniaudio') + render_dep = dependency('4j-render', fallback: ['4jlibs', 'render_dep']) input_dep = dependency('4j-input', fallback: ['4jlibs', 'input_dep']) profile_dep = dependency('4j-profile', fallback: ['4jlibs', 'profile_dep']) storage_dep = dependency('4j-storage', fallback: ['4jlibs', 'storage_dep']) +all_deps = [ + gl_dep, + glu_dep, + sdl2_dep, + thread_dep, + dl_dep, + stb_dep, + miniaudio_dep, + render_dep, + input_dep, + profile_dep, + storage_dep, +] + subdir('Minecraft.Assets') subdir('Minecraft.World') -subdir('Minecraft.Client') +subdir('Minecraft.Client') \ No newline at end of file diff --git a/meson.options b/meson.options index 68eb92598..1121b453a 100644 --- a/meson.options +++ b/meson.options @@ -13,3 +13,10 @@ option('enable_vsync', type : 'boolean', value : true, description : 'Toggles V-Sync and adds options to unlock maximum in-game framerate.') + +option( + 'gles', + type: 'boolean', + value: true, + description: 'Use OpenGL ES instead of Desktop GL', +) From a2ec6610a5d21cc900a2412c1fa1e673617bf625 Mon Sep 17 00:00:00 2001 From: JuiceyDev Date: Sat, 28 Mar 2026 15:22:42 +0100 Subject: [PATCH 136/170] mistake while commit, gles was turned on by default. --- meson.options | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/meson.options b/meson.options index 1121b453a..6f4f4808b 100644 --- a/meson.options +++ b/meson.options @@ -17,6 +17,6 @@ option('enable_vsync', option( 'gles', type: 'boolean', - value: true, + value: false, description: 'Use OpenGL ES instead of Desktop GL', ) From d2e77c63ad2db763edae7f86b81da34c35de63e8 Mon Sep 17 00:00:00 2001 From: JuiceyDev Date: Sat, 28 Mar 2026 17:04:39 +0100 Subject: [PATCH 137/170] refactor meson and final gles support, cleaner gdraw --- .../Platform/Linux/Iggy/gdraw/gdraw.c | 233 +++++++++--------- Minecraft.Client/Platform/Linux/LinuxGL.cpp | 26 ++ Minecraft.Client/meson.build | 3 +- meson.build | 43 +++- 4 files changed, 179 insertions(+), 126 deletions(-) diff --git a/Minecraft.Client/Platform/Linux/Iggy/gdraw/gdraw.c b/Minecraft.Client/Platform/Linux/Iggy/gdraw/gdraw.c index c56cf237b..4fde9a91f 100644 --- a/Minecraft.Client/Platform/Linux/Iggy/gdraw/gdraw.c +++ b/Minecraft.Client/Platform/Linux/Iggy/gdraw/gdraw.c @@ -13,11 +13,11 @@ #include #include #include +#include #define true 1 #define false 0 - #ifndef _ENABLEIGGY void* IggyGDrawMallocAnnotated(SINTa size, const char* file, int line) { (void)file; @@ -43,9 +43,26 @@ void IggyDiscardVertexBufferCallback(void* owner, void* buf) { } #endif -// We track all the extensions we use. +static void* get_gl_proc(const char* name) { + void* p = SDL_GL_GetProcAddress(name); + if (!p) p = dlsym(RTLD_DEFAULT, name); + if (!p) { + char buf[256]; + strncpy(buf, name, sizeof(buf) - 1); + buf[255] = '\0'; + char* ext = strstr(buf, "ARB"); + if (!ext) ext = strstr(buf, "EXT"); + if (ext && ext == buf + strlen(buf) - 3) { + *ext = '\0'; + p = SDL_GL_GetProcAddress(buf); + if (!p) p = dlsym(RTLD_DEFAULT, buf); + } + } + return p; +} + #define GDRAW_GL_EXTENSION_LIST \ - /* identifier import procname */ \ + /* identifier import procname */ \ /* GL_ARB_vertex_buffer_object */ \ GLE(GenBuffers, "GenBuffersARB", GENBUFFERSARB) \ GLE(DeleteBuffers, "DeleteBuffersARB", DELETEBUFFERSARB) \ @@ -102,7 +119,6 @@ void IggyDiscardVertexBufferCallback(void* owner, void* buf) { RENDERBUFFERSTORAGEMULTISAMPLEEXT) \ /* */ - // Shared .inl #define gdraw_GLx_(id) gdraw_GL_##id #define GDRAW_GLx_(id) GDRAW_GL_##id @@ -118,7 +134,6 @@ typedef gdraw_gl_resourcetype gdraw_resourcetype; GDRAW_GL_EXTENSION_LIST #undef GLE - typedef const GLubyte*(APIENTRYP PFNGLGETSTRINGIPROC_)(GLenum name, GLuint index); static PFNGLGETSTRINGIPROC_ gdraw_glGetStringi = NULL; @@ -136,13 +151,11 @@ static GLuint gdraw_screenvbo = 0; static const void* gdraw_screenvbo_base = NULL; static size_t gdraw_expected_vbo_size = 0; - typedef void(APIENTRYP gdraw_drawelements_fn)(GLenum mode, GLsizei count, GLenum type, const void* indices); static gdraw_drawelements_fn gdraw_real_drawelements = NULL; static GLuint gdraw_screenibo = 0; - typedef GLuint(APIENTRYP gdraw_createshader_fn)(GLenum); typedef void(APIENTRYP gdraw_shadersource_fn)(GLuint, GLsizei, const GLchar**, const GLint*); @@ -159,7 +172,6 @@ typedef void(APIENTRYP gdraw_useprogram_fn)(GLuint); static gdraw_useprogram_fn gdraw_real_useprogram = NULL; static GLuint gdraw_null_program = 0; - typedef void(APIENTRYP gdraw_teximage2d_fn)(GLenum, GLint, GLint, GLsizei, GLsizei, GLint, GLenum, GLenum, const void*); @@ -169,17 +181,17 @@ typedef void(APIENTRYP gdraw_texsubimage2d_fn)(GLenum, GLint, GLint, GLint, static gdraw_teximage2d_fn gdraw_real_teximage2d = NULL; static gdraw_texsubimage2d_fn gdraw_real_texsubimage2d = NULL; -#define TRY(ptr, arb, core) \ - do { \ - void* _p = SDL_GL_GetProcAddress(core); \ - if (!_p) _p = SDL_GL_GetProcAddress(arb); \ - *(void**)&(ptr) = _p; \ +#define TRY(ptr, arb, core) \ + do { \ + void* _p = get_gl_proc(core); \ + if (!_p) _p = get_gl_proc(arb); \ + *(void**)&(ptr) = _p; \ } while (0) static void load_extensions(void) { // gl_shared requires ts shit ugh #define GLE(id, import, procname) \ - gl##id = (PFNGL##procname##PROC)SDL_GL_GetProcAddress("gl" import); + gl##id = (PFNGL##procname##PROC)get_gl_proc("gl" import); GDRAW_GL_EXTENSION_LIST #undef GLE @@ -240,24 +252,27 @@ static void load_extensions(void) { "glRenderbufferStorageMultisample"); // Save raw pointers before we #define over the names below - gdraw_real_vtxattrib = (gdraw_vtxattrib_fn)(void*)glVertexAttribPointer; - gdraw_real_createshader = (gdraw_createshader_fn)(void*)glCreateShader; - gdraw_real_shadersource = (gdraw_shadersource_fn)(void*)glShaderSource; - gdraw_real_compileshader = (gdraw_compileshader_fn)(void*)glCompileShader; - gdraw_real_linkprogram = (gdraw_linkprogram_fn)(void*)glLinkProgram; - gdraw_real_teximage2d = (gdraw_teximage2d_fn)(void*)glTexImage2D; - gdraw_real_texsubimage2d = (gdraw_texsubimage2d_fn)(void*)glTexSubImage2D; - gdraw_real_useprogram = (gdraw_useprogram_fn)(void*)glUseProgram; + gdraw_real_vtxattrib = + (gdraw_vtxattrib_fn)get_gl_proc("glVertexAttribPointer"); + gdraw_real_createshader = + (gdraw_createshader_fn)get_gl_proc("glCreateShader"); + gdraw_real_shadersource = + (gdraw_shadersource_fn)get_gl_proc("glShaderSource"); + gdraw_real_compileshader = + (gdraw_compileshader_fn)get_gl_proc("glCompileShader"); + gdraw_real_linkprogram = (gdraw_linkprogram_fn)get_gl_proc("glLinkProgram"); + gdraw_real_teximage2d = (gdraw_teximage2d_fn)get_gl_proc("glTexImage2D"); + gdraw_real_texsubimage2d = + (gdraw_texsubimage2d_fn)get_gl_proc("glTexSubImage2D"); + gdraw_real_useprogram = (gdraw_useprogram_fn)get_gl_proc("glUseProgram"); gdraw_real_drawelements = - (gdraw_drawelements_fn)SDL_GL_GetProcAddress("glDrawElements"); + (gdraw_drawelements_fn)get_gl_proc("glDrawElements"); - gdraw_glGetStringi = - (PFNGLGETSTRINGIPROC_)SDL_GL_GetProcAddress("glGetStringi"); - // VAO + gdraw_glGetStringi = (PFNGLGETSTRINGIPROC_)get_gl_proc("glGetStringi"); gdraw_glGenVertexArrays = - (PFNGLGENVERTEXARRAYSPROC_)SDL_GL_GetProcAddress("glGenVertexArrays"); + (PFNGLGENVERTEXARRAYSPROC_)get_gl_proc("glGenVertexArrays"); gdraw_glBindVertexArray = - (PFNGLBINDVERTEXARRAYPROC_)SDL_GL_GetProcAddress("glBindVertexArray"); + (PFNGLBINDVERTEXARRAYPROC_)get_gl_proc("glBindVertexArray"); if (gdraw_glGenVertexArrays && gdraw_glBindVertexArray && gdraw_vao == 0) { gdraw_glGenVertexArrays(1, &gdraw_vao); @@ -278,15 +293,15 @@ static void error_msg_platform_specific(const char* msg) { fprintf(stderr, "[GDraw] %s\n", msg); } -#define GDRAW_PLATFORM_REPORT_GL_SITE(site) \ - do { \ - if ((site) != NULL) \ - fprintf(stderr, "[GDraw] GL error site: %s\n", (site)); \ +#define GDRAW_PLATFORM_REPORT_GL_SITE(site) \ + do { \ + if ((site) != NULL) \ + fprintf(stderr, "[GDraw] GL error site: %s\n", (site)); \ } while (0) #define GDRAW_MULTISAMPLING -// i wish i could improve this function +// i wish i could improve this function #ifdef RR_BREAK #undef RR_BREAK #endif @@ -295,7 +310,6 @@ static void error_msg_platform_specific(const char* msg) { fprintf(stderr, "[GDraw] GL error at %s:%d\n", __FILE__, __LINE__); \ } while (0) - // the magic number that tropical told me #define GDRAW_MAX_SHADERS 64 static struct { @@ -305,8 +319,7 @@ static struct { static int gdraw_shader_type_count = 0; static GLenum gdraw_get_shader_type(GLuint shader) { - int i; - for (i = 0; i < gdraw_shader_type_count; i++) + for (int i = 0; i < gdraw_shader_type_count; i++) if (gdraw_shader_types[i].handle == shader) return gdraw_shader_types[i].type; return GL_FRAGMENT_SHADER; @@ -322,8 +335,6 @@ static GLuint gdraw_CreateShaderTracked(GLenum type) { return h; } - - static void gdraw_CompileShaderAndLog(GLuint shader) { GLint status = 0; gdraw_real_compileshader(shader); @@ -335,7 +346,6 @@ static void gdraw_CompileShaderAndLog(GLuint shader) { log[len] = '\0'; fprintf(stderr, "[GDraw GLSL] compile FAILED shader=%u:\n%s\n", shader, log); - fflush(stderr); } } @@ -350,7 +360,6 @@ static void gdraw_LinkProgramAndLog(GLuint program) { log[len] = '\0'; fprintf(stderr, "[GDraw GLSL] link FAILED program=%u:\n%s\n", program, log); - fflush(stderr); } } @@ -393,33 +402,27 @@ static char* gdraw_strreplace(char* src, const char* find, const char* rep) { static void gdraw_ShaderSourceUpgraded(GLuint shader, GLsizei count, const GLchar** strings, const GLint* lengths) { - int i; size_t total = 0; - char* src; - char* patched; - int is_vert; - const GLchar* patched_ptr; - - for (i = 0; i < count; i++) + for (int i = 0; i < count; i++) total += lengths ? (lengths[i] >= 0 ? (size_t)lengths[i] : strlen(strings[i])) : strlen(strings[i]); - src = (char*)malloc(total + 1); + char* src = (char*)malloc(total + 1); if (!src) { gdraw_real_shadersource(shader, count, strings, lengths); return; } src[0] = '\0'; - for (i = 0; i < count; i++) { + for (int i = 0; i < count; i++) { size_t len = lengths ? (lengths[i] >= 0 ? (size_t)lengths[i] : strlen(strings[i])) : strlen(strings[i]); strncat(src, strings[i], len); } - is_vert = (gdraw_get_shader_type(shader) == GL_VERTEX_SHADER); + int is_vert = (gdraw_get_shader_type(shader) == GL_VERTEX_SHADER); // Strip any existing #version directive as i'll add our own { @@ -451,30 +454,24 @@ static void gdraw_ShaderSourceUpgraded(GLuint shader, GLsizei count, src = gdraw_strreplace(src, "varying ", "in "); src = gdraw_strreplace(src, "varying\t", "in\t"); src = gdraw_strreplace(src, "varying\n", "in\n"); - } - if (!is_vert) { src = gdraw_strreplace(src, "gl_FragData[0]", "_gdraw_frag_out"); src = gdraw_strreplace(src, "gl_FragColor", "_gdraw_frag_out"); } - // finally turn it 330 - { - const char* vert_header = "#version 330 core\n"; - const char* frag_header = - "#version 330 core\nout vec4 _gdraw_frag_out;\n"; - const char* header = is_vert ? vert_header : frag_header; - patched = (char*)malloc(strlen(header) + strlen(src) + 2); - if (!patched) { - free(src); - gdraw_real_shadersource(shader, count, strings, lengths); - return; - } - strcpy(patched, header); - strcat(patched, src); + const char* header = is_vert + ? "#version 330 core\n" + : "#version 330 core\nout vec4 _gdraw_frag_out;\n"; + char* patched = (char*)malloc(strlen(header) + strlen(src) + 2); + if (!patched) { free(src); + gdraw_real_shadersource(shader, count, strings, lengths); + return; } + strcpy(patched, header); + strcat(patched, src); + free(src); - patched_ptr = (const GLchar*)patched; + const GLchar* patched_ptr = (const GLchar*)patched; gdraw_real_shadersource(shader, 1, &patched_ptr, NULL); free(patched); } @@ -482,7 +479,6 @@ static void gdraw_ShaderSourceUpgraded(GLuint shader, GLsizei count, #undef glShaderSource #define glShaderSource gdraw_ShaderSourceUpgraded - // Remap all the deprecated internal formats to their modern equivalents // (idk why but just the word "swizzle" is cracking me up) static void gdraw_apply_swizzle(GLenum internal_fmt) { @@ -524,6 +520,9 @@ static GLenum gdraw_remap_fmt(GLenum fmt) { static void gdraw_TexImage2D(GLenum target, GLint level, GLint ifmt, GLsizei w, GLsizei h, GLint border, GLenum fmt, GLenum type, const void* data) { + // ES strictly requires explicitly sized formats & stuff + if (ifmt == GL_RGBA && data == NULL) ifmt = GL_RGBA8; + GLenum new_ifmt = gdraw_remap_fmt((GLenum)ifmt); GLenum new_fmt = gdraw_remap_fmt(fmt); gdraw_real_teximage2d(target, level, (GLint)new_ifmt, w, h, border, new_fmt, @@ -556,15 +555,13 @@ static void gdraw_ClientVertexAttribPointer(GLuint index, GLint size, gdraw_glBindVertexArray(gdraw_vao); } - { - GLint current_vbo = 0; - glGetIntegerv(GL_ARRAY_BUFFER_BINDING, ¤t_vbo); + GLint current_vbo = 0; + glGetIntegerv(GL_ARRAY_BUFFER_BINDING, ¤t_vbo); - if (current_vbo != 0 && current_vbo != (GLint)gdraw_screenvbo) { - gdraw_real_vtxattrib(index, size, type, normalized, stride, - pointer); - return; - } + if (current_vbo != 0 && current_vbo != (GLint)gdraw_screenvbo) { + // no touchies + gdraw_real_vtxattrib(index, size, type, normalized, stride, pointer); + return; } if (pointer == NULL) { @@ -572,12 +569,19 @@ static void gdraw_ClientVertexAttribPointer(GLuint index, GLint size, return; } - if (gdraw_screenvbo_base == NULL) { + ptrdiff_t offset = + gdraw_screenvbo_base + ? ((const char*)pointer - (const char*)gdraw_screenvbo_base) + : -1; + + if (gdraw_screenvbo_base == NULL || offset < 0 || + offset >= (ptrdiff_t)gdraw_expected_vbo_size) { if (!gdraw_screenvbo) glGenBuffers(1, &gdraw_screenvbo); glBindBuffer(GL_ARRAY_BUFFER, gdraw_screenvbo); - size_t upload_size = - gdraw_expected_vbo_size > 0 ? gdraw_expected_vbo_size : 256; + size_t upload_size = gdraw_expected_vbo_size > 0 + ? (gdraw_expected_vbo_size + 256) + : 65536; glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)upload_size, pointer, GL_STREAM_DRAW); @@ -586,8 +590,6 @@ static void gdraw_ClientVertexAttribPointer(GLuint index, GLint size, (const void*)0); } else { glBindBuffer(GL_ARRAY_BUFFER, gdraw_screenvbo); - ptrdiff_t offset = - (const char*)pointer - (const char*)gdraw_screenvbo_base; gdraw_real_vtxattrib(index, size, type, normalized, stride, (const void*)offset); } @@ -641,7 +643,7 @@ static void gdraw_UseProgramSafe(GLuint program) { glDeleteShader(v); glDeleteShader(f); } - gdraw_real_useprogram(0); + gdraw_real_useprogram(gdraw_null_program); return; } gdraw_real_useprogram(program); @@ -649,25 +651,48 @@ static void gdraw_UseProgramSafe(GLuint program) { #undef glUseProgram #define glUseProgram gdraw_UseProgramSafe - #undef glCompileShader #define glCompileShader gdraw_CompileShaderAndLog - #undef glLinkProgram #define glLinkProgram gdraw_LinkProgramAndLog -// v ugh fuck you windows +static void gdraw_FramebufferRenderbufferSafe(GLenum target, GLenum attachment, + GLenum renderbuffertarget, + GLuint renderbuffer) { + static GLuint last_depth_rb = 0; + + if (attachment == GL_DEPTH_ATTACHMENT) { + last_depth_rb = renderbuffer; + (glFramebufferRenderbuffer)(target, attachment, renderbuffertarget, + renderbuffer); + } else if (attachment == GL_STENCIL_ATTACHMENT) { + if (renderbuffer == last_depth_rb && renderbuffer != 0) { + // If identical, bind as packed depth-stencil to satisfy strict GLES + // ^ how greedy -n- + (glFramebufferRenderbuffer)( + target, 0x821A /* GL_DEPTH_STENCIL_ATTACHMENT */, + renderbuffertarget, renderbuffer); + } else { + (glFramebufferRenderbuffer)(target, attachment, renderbuffertarget, + renderbuffer); + } + } else { + (glFramebufferRenderbuffer)(target, attachment, renderbuffertarget, + renderbuffer); + } +} +#define glFramebufferRenderbuffer_SAFE gdraw_FramebufferRenderbufferSafe +#define glFramebufferRenderbuffer glFramebufferRenderbuffer_SAFE + #include "../../../Windows64/Iggy/gdraw/gdraw_gl_shared.inl" #undef glVertexAttribPointer #define glVertexAttribPointer gdraw_real_vtxattrib -// 3.3 c extension static int hasext_core(const char* name) { GLint n = 0; - GLint i; if (!gdraw_glGetStringi) return 0; glGetIntegerv(GL_NUM_EXTENSIONS, &n); - for (i = 0; i < n; i++) { + for (GLint i = 0; i < n; i++) { const char* e = (const char*)gdraw_glGetStringi(GL_EXTENSIONS, (GLuint)i); if (e && strcmp(e, name) == 0) return 1; @@ -743,35 +768,21 @@ GDrawFunctions* gdraw_GL_CreateContext(S32 w, S32 h, S32 msaa_samples) { {0, 0, 0, 0, 0, 0, 0}, }; - GDrawFunctions* funcs; - GLint n; GLint major = 0, minor = 0; - - // incase everything goes wrong and it goes like 1.1 or smh glGetIntegerv(GL_MAJOR_VERSION, &major); glGetIntegerv(GL_MINOR_VERSION, &minor); - if (major < 3 || (major == 3 && minor < 3)) { - fprintf(stderr, "[GDraw] GL 3.3 or higher required (got %d.%d)\n", + if (major < 3) { + fprintf(stderr, "[GDraw] GL 3.0 or higher required (got %d.%d)\n", major, minor); return NULL; } - // FBO is core since 3.0 - if (!hasext_core("GL_EXT_framebuffer_object")) { - fprintf(stderr, - "[GDraw] GL_EXT_framebuffer_object not listed, " - "fuck it, let's continue.\n"); - } - - if (!hasext_core("GL_EXT_framebuffer_multisample") && msaa_samples > 1) - return NULL; - load_extensions(); if (gdraw_glBindVertexArray && gdraw_vao) gdraw_glBindVertexArray(gdraw_vao); - funcs = create_context(w, h); + GDrawFunctions* funcs = create_context(w, h); if (!funcs) return NULL; // hook the vtable entries for VBO reset and render state @@ -786,13 +797,13 @@ GDrawFunctions* gdraw_GL_CreateContext(S32 w, S32 h, S32 msaa_samples) { funcs->ClearID = gdraw_ClearID; gdraw->tex_formats = tex_formats; - gdraw->has_mapbuffer = true; + gdraw->has_mapbuffer = false; gdraw->has_depth24 = true; gdraw->has_texture_max_level = true; - if (hasext_core("GL_EXT_packed_depth_stencil")) - gdraw->has_packed_depth_stencil = true; + gdraw->has_packed_depth_stencil = true; + GLint n = 0; glGetIntegerv(GL_MAX_TEXTURE_SIZE, &n); gdraw->has_conditional_non_power_of_two = (n < 8192); @@ -802,10 +813,8 @@ GDrawFunctions* gdraw_GL_CreateContext(S32 w, S32 h, S32 msaa_samples) { } opengl_check(); - - fprintf(stderr, - "[GDraw] Context created successfully (%dx%d, msaa=%d)\n", w, h, - msaa_samples); + fprintf(stderr, "[GDraw] Context created successfully (%dx%d, msaa=%d)\n", + w, h, msaa_samples); return funcs; } diff --git a/Minecraft.Client/Platform/Linux/LinuxGL.cpp b/Minecraft.Client/Platform/Linux/LinuxGL.cpp index 4b41d2961..17f25fbcb 100644 --- a/Minecraft.Client/Platform/Linux/LinuxGL.cpp +++ b/Minecraft.Client/Platform/Linux/LinuxGL.cpp @@ -28,6 +28,32 @@ #undef glReadPixels #undef glActiveTexture +#ifdef GLES +extern "C" { +// TELL IT TO USE GLEW +extern void glClearDepthf(float depth); + +void glClearDepth(double depth) { glClearDepthf((float)depth); } + +void glTexGeni(unsigned int coord, unsigned int pname, int param) {} +void glTexGenfv(unsigned int coord, unsigned int pname, const float* params) {} +void glTexCoordPointer(int size, unsigned int type, int stride, + const void* pointer) {} +void glNormalPointer(unsigned int type, int stride, const void* pointer) {} +void glColorPointer(int size, unsigned int type, int stride, + const void* pointer) {} +void glVertexPointer(int size, unsigned int type, int stride, + const void* pointer) {} +void glEndList(void) {} +void glCallLists(int n, unsigned int type, const void* lists) {} +// Did you nose? +// Did you know if you sniff pizza too much your nose +// might think it. It's pizza? +// This. This is because pizza smells trick your nose into pizza thinking. +} + +#endif + // Helper functions & stuff inline GLuint* getIntPtr(IntBuffer* buf) { return buf ? (GLuint*)((int*)buf->getBuffer() + buf->position()) : nullptr; diff --git a/Minecraft.Client/meson.build b/Minecraft.Client/meson.build index f31407b0d..39bc97d2a 100644 --- a/Minecraft.Client/meson.build +++ b/Minecraft.Client/meson.build @@ -69,6 +69,7 @@ client_dependencies = [ dl_dep, dependency('zlib'), miniaudio_dep, + stb_dep, ] if get_option('enable_vsync') @@ -95,7 +96,7 @@ endif client = executable('Minecraft.Client', client_sources + platform_sources + localisation[1], - include_directories: [include_directories('Platform', 'Platform/Linux/Iggy/include'), stb], + include_directories: include_directories('Platform', 'Platform/Linux/Iggy/include'), dependencies: client_dependencies, cpp_args: global_cpp_args + global_cpp_defs diff --git a/meson.build b/meson.build index 7d08e7faf..a62becd63 100644 --- a/meson.build +++ b/meson.build @@ -18,6 +18,8 @@ python = pymod.find_installation('python3', required: true) cc = meson.get_compiler('cpp') +use_gles = get_option('gles') + global_cpp_defs = [ '-DSPLIT_SAVES', '-D_LARGE_WORLDS', @@ -28,11 +30,23 @@ global_cpp_defs = [ ] if host_machine.system() == 'linux' - global_cpp_defs += [ - '-Dlinux', - '-D__linux', - '-D__linux__', - ] + global_cpp_defs += ['-Dlinux', '-D__linux', '-D__linux__'] +endif + +if use_gles + global_cpp_defs += ['-DGLES'] +endif + +if get_option('enable_vsync') + global_cpp_defs += ['-DENABLE_VSYNC'] +endif + +if get_option('enable_shiggy') + global_cpp_defs += ['-D_ENABLEIGGY'] +endif + +if get_option('enable_java_guis') + global_cpp_defs += ['-DENABLE_JAVA_GUIS'] endif add_project_arguments(global_cpp_defs, language: ['cpp', 'c']) @@ -48,12 +62,13 @@ sdl2_dep = dependency('sdl2') thread_dep = dependency('threads') dl_dep = cc.find_library('dl', required: true) -if '-DGLES' in global_cpp_defs - gl_dep = dependency('glesv2') +# GLES vs Desktop GL +if use_gles + gl_dep = dependency('glesv2', required: true) glu_dep = dependency('', required: false) else - gl_dep = dependency('gl') - glu_dep = dependency('glu') + gl_dep = dependency('gl', required: true) + glu_dep = dependency('glu', required: true) endif stb = subproject('stb').get_variable('stb_inc') @@ -61,10 +76,12 @@ stb_dep = declare_dependency(include_directories: stb) miniaudio_dep = dependency('miniaudio') -render_dep = dependency('4j-render', fallback: ['4jlibs', 'render_dep']) -input_dep = dependency('4j-input', fallback: ['4jlibs', 'input_dep']) -profile_dep = dependency('4j-profile', fallback: ['4jlibs', 'profile_dep']) -storage_dep = dependency('4j-storage', fallback: ['4jlibs', 'storage_dep']) +sub_opts = ['gles=' + use_gles.to_string()] + +render_dep = dependency('4j-render', fallback: ['4jlibs', 'render_dep'], default_options: sub_opts) +input_dep = dependency('4j-input', fallback: ['4jlibs', 'input_dep'], default_options: sub_opts) +profile_dep = dependency('4j-profile', fallback: ['4jlibs', 'profile_dep'], default_options: sub_opts) +storage_dep = dependency('4j-storage', fallback: ['4jlibs', 'storage_dep'], default_options: sub_opts) all_deps = [ gl_dep, From 73a74f4872265401c8703229547cfc9d4eaea5ff Mon Sep 17 00:00:00 2001 From: Tropical <42101043+tropicaaal@users.noreply.github.com> Date: Sat, 28 Mar 2026 11:27:33 -0500 Subject: [PATCH 138/170] chore: clean up LevelRenderer diffs --- Minecraft.Client/Rendering/LevelRenderer.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Minecraft.Client/Rendering/LevelRenderer.cpp b/Minecraft.Client/Rendering/LevelRenderer.cpp index 911bc5aa7..03bb23057 100644 --- a/Minecraft.Client/Rendering/LevelRenderer.cpp +++ b/Minecraft.Client/Rendering/LevelRenderer.cpp @@ -2255,6 +2255,7 @@ bool LevelRenderer::updateDirtyChunks() { // int64_t startTime = System::currentTimeMillis(); // app.DebugPrintf("Rebuilding permaChunk %d\n", index); + permaChunk[index].rebuild(); if (index != 0) @@ -2493,7 +2494,7 @@ void LevelRenderer::renderHitOutline(std::shared_ptr player, AABB bb = Tile::tiles[tileId] ->getTileAABB(level[iPad], h->x, h->y, h->z) - .grow(0.002f, 0.002f, 0.002f) + .grow(ss, ss, ss) .move(-xo, -yo, -zo); render(&bb); From b963a61caf7f209fee922639b93959707cd2929c Mon Sep 17 00:00:00 2001 From: Tropical <42101043+tropicaaal@users.noreply.github.com> Date: Sat, 28 Mar 2026 11:35:47 -0500 Subject: [PATCH 139/170] refactor: use combo option for renderer selection --- meson.build | 2 +- meson.options | 15 +++++++-------- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/meson.build b/meson.build index a62becd63..bee78f958 100644 --- a/meson.build +++ b/meson.build @@ -18,7 +18,7 @@ python = pymod.find_installation('python3', required: true) cc = meson.get_compiler('cpp') -use_gles = get_option('gles') +use_gles = get_option('renderer') == 'gles' global_cpp_defs = [ '-DSPLIT_SAVES', diff --git a/meson.options b/meson.options index 6f4f4808b..bc73c0516 100644 --- a/meson.options +++ b/meson.options @@ -9,14 +9,13 @@ option('classic_panorama', value : false, description : 'Enable classic java edition panorama (ui_backend=java ONLY).') -option('enable_vsync', +option('renderer', + type : 'combo', + choices: ['gl2', 'gl3', 'gles'], + value : 'gl3', + description : 'Specifies a rendering implementation for the game.') + +option('enable_vsync', type : 'boolean', value : true, description : 'Toggles V-Sync and adds options to unlock maximum in-game framerate.') - -option( - 'gles', - type: 'boolean', - value: false, - description: 'Use OpenGL ES instead of Desktop GL', -) From 19d0af460ea828b0f350765a5fac9ec90d8fb7b5 Mon Sep 17 00:00:00 2001 From: Tropical <42101043+tropicaaal@users.noreply.github.com> Date: Sat, 28 Mar 2026 11:38:49 -0500 Subject: [PATCH 140/170] fix: remove gl2 option --- meson.options | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/meson.options b/meson.options index bc73c0516..3171bc298 100644 --- a/meson.options +++ b/meson.options @@ -11,7 +11,7 @@ option('classic_panorama', option('renderer', type : 'combo', - choices: ['gl2', 'gl3', 'gles'], + choices: ['gl3', 'gles'], value : 'gl3', description : 'Specifies a rendering implementation for the game.') From cb144f3debb80225eb3ac5c519bf4d147e4dfdce Mon Sep 17 00:00:00 2001 From: JuiceyDev Date: Sat, 28 Mar 2026 18:07:19 +0100 Subject: [PATCH 141/170] temp removal --- meson.build | 8 -------- 1 file changed, 8 deletions(-) diff --git a/meson.build b/meson.build index bee78f958..6ad549cbb 100644 --- a/meson.build +++ b/meson.build @@ -41,14 +41,6 @@ if get_option('enable_vsync') global_cpp_defs += ['-DENABLE_VSYNC'] endif -if get_option('enable_shiggy') - global_cpp_defs += ['-D_ENABLEIGGY'] -endif - -if get_option('enable_java_guis') - global_cpp_defs += ['-DENABLE_JAVA_GUIS'] -endif - add_project_arguments(global_cpp_defs, language: ['cpp', 'c']) global_cpp_args = [ From d6394de9004d9d7211546bc5ed16426ed08d034c Mon Sep 17 00:00:00 2001 From: Tropical <42101043+tropicaaal@users.noreply.github.com> Date: Sat, 28 Mar 2026 12:09:20 -0500 Subject: [PATCH 142/170] fix: get rid of redundant option check --- Minecraft.Client/Platform/Common/UI/UIController.cpp | 5 +++-- meson.build | 4 ---- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/Minecraft.Client/Platform/Common/UI/UIController.cpp b/Minecraft.Client/Platform/Common/UI/UIController.cpp index 3807ec7e0..6ee65e8ec 100644 --- a/Minecraft.Client/Platform/Common/UI/UIController.cpp +++ b/Minecraft.Client/Platform/Common/UI/UIController.cpp @@ -78,8 +78,9 @@ static void RADLINK WarningCallback(void* user_callback_data, Iggy* player, // IGGY_RESULT_Error_OutOfMemory = 1001,}; if (message != NULL) { - // Some Linux movie variants do not ship these optional hooks/controls. - // We guard the call sites, so drop the residual Iggy warning noise. + // 4jcraft: Some Linux movie variants do not ship these optional + // hooks/controls. We guard the call sites, so drop the residual Iggy + // warning noise. if (strstr(message, "LabelGamertag") != NULL || strstr(message, "Method SetSafeZone was not a function") != NULL) { return; diff --git a/meson.build b/meson.build index 6ad549cbb..1939a88ad 100644 --- a/meson.build +++ b/meson.build @@ -37,10 +37,6 @@ if use_gles global_cpp_defs += ['-DGLES'] endif -if get_option('enable_vsync') - global_cpp_defs += ['-DENABLE_VSYNC'] -endif - add_project_arguments(global_cpp_defs, language: ['cpp', 'c']) global_cpp_args = [ From bb50db7d9b55da1760451bebd0b5dc9d53b6b645 Mon Sep 17 00:00:00 2001 From: JuiceyDev Date: Sat, 28 Mar 2026 18:29:47 +0100 Subject: [PATCH 143/170] Cleaned up linuxGL.cpp --- Minecraft.Client/Platform/Linux/LinuxGL.cpp | 250 ++++++-------------- 1 file changed, 75 insertions(+), 175 deletions(-) diff --git a/Minecraft.Client/Platform/Linux/LinuxGL.cpp b/Minecraft.Client/Platform/Linux/LinuxGL.cpp index 17f25fbcb..c7fff72d5 100644 --- a/Minecraft.Client/Platform/Linux/LinuxGL.cpp +++ b/Minecraft.Client/Platform/Linux/LinuxGL.cpp @@ -1,196 +1,113 @@ #ifdef __linux__ #include "../stdafx.h" -#include -#include -#include -#include -#include +#include "4J_Render.h" #include "../../Minecraft.World/IO/Streams/IntBuffer.h" #include "../../Minecraft.World/IO/Streams/FloatBuffer.h" #include "../../Minecraft.World/IO/Streams/ByteBuffer.h" -#undef glGenTextures -#undef glDeleteTextures -#undef glLight -#undef glLightModel -#undef glGetFloat -#undef glTexGen -#undef glFog -#undef glTexCoordPointer -#undef glNormalPointer -#undef glColorPointer -#undef glVertexPointer -#undef glEndList -#undef glTexImage2D -#undef glCallLists -#undef glReadPixels -#undef glActiveTexture +extern C4JRender RenderManager; #ifdef GLES extern "C" { -// TELL IT TO USE GLEW extern void glClearDepthf(float depth); - void glClearDepth(double depth) { glClearDepthf((float)depth); } - -void glTexGeni(unsigned int coord, unsigned int pname, int param) {} -void glTexGenfv(unsigned int coord, unsigned int pname, const float* params) {} -void glTexCoordPointer(int size, unsigned int type, int stride, - const void* pointer) {} -void glNormalPointer(unsigned int type, int stride, const void* pointer) {} -void glColorPointer(int size, unsigned int type, int stride, - const void* pointer) {} -void glVertexPointer(int size, unsigned int type, int stride, - const void* pointer) {} +void glTexGeni(unsigned int, unsigned int, int) {} +void glTexGenfv(unsigned int, unsigned int, const float*) {} +void glTexCoordPointer(int, unsigned int, int, const void*) {} +void glNormalPointer(unsigned int, int, const void*) {} +void glColorPointer(int, unsigned int, int, const void*) {} +void glVertexPointer(int, unsigned int, int, const void*) {} void glEndList(void) {} -void glCallLists(int n, unsigned int type, const void* lists) {} -// Did you nose? -// Did you know if you sniff pizza too much your nose -// might think it. It's pizza? -// This. This is because pizza smells trick your nose into pizza thinking. +void glCallLists(int, unsigned int, const void*) {} } - #endif -// Helper functions & stuff -inline GLuint* getIntPtr(IntBuffer* buf) { - return buf ? (GLuint*)((int*)buf->getBuffer() + buf->position()) : nullptr; +inline int* getIntPtr(IntBuffer* buf) { + return buf ? (int*)buf->getBuffer() + buf->position() : nullptr; } -inline GLvoid* getBytePtr(ByteBuffer* buf) { - return buf ? (GLvoid*)((char*)buf->getBuffer() + buf->position()) : nullptr; -} - -// _4j suffix shit -int glGenTextures() { - GLuint id = 0; - ::glGenTextures(1, &id); - return (int)id; +inline void* getBytePtr(ByteBuffer* buf) { + return buf ? (char*)buf->getBuffer() + buf->position() : nullptr; } void glGenTextures_4J(IntBuffer* buf) { if (!buf) return; int n = buf->limit() - buf->position(); - if (n > 0) { - ::glGenTextures(n, getIntPtr(buf)); - } -} - -void glDeleteTextures(int id) { - GLuint uid = (GLuint)id; - ::glDeleteTextures(1, &uid); + int* dst = getIntPtr(buf); + for (int i = 0; i < n; i++) dst[i] = RenderManager.TextureCreate(); } void glDeleteTextures_4J(IntBuffer* buf) { if (!buf) return; int n = buf->limit() - buf->position(); - if (n > 0) { - ::glDeleteTextures(n, getIntPtr(buf)); - } -} - -void glLight_4J(int light, int pname, FloatBuffer* params) { - ::glLightfv((GLenum)light, (GLenum)pname, params->_getDataPointer()); -} - -void glLightModel_4J(int pname, FloatBuffer* params) { - ::glLightModelfv((GLenum)pname, params->_getDataPointer()); -} - -void glGetFloat_4J(int pname, FloatBuffer* params) { - ::glGetFloatv((GLenum)pname, params->_getDataPointer()); -} - -void glTexGen_4J(int coord, int pname, FloatBuffer* params) { - ::glTexGenfv((GLenum)coord, (GLenum)pname, params->_getDataPointer()); -} - -void glFog_4J(int pname, FloatBuffer* params) { - ::glFogfv((GLenum)pname, params->_getDataPointer()); -} - -void glTexCoordPointer_4J(int size, int type, FloatBuffer* pointer) { - ::glTexCoordPointer(size, (GLenum)type, 0, pointer->_getDataPointer()); -} - -void glNormalPointer_4J(int type, ByteBuffer* pointer) { - ::glNormalPointer((GLenum)type, 0, getBytePtr(pointer)); -} - -void glColorPointer_4J(int size, bool normalized, int stride, - ByteBuffer* pointer) { - (void)normalized; - ::glColorPointer(size, GL_UNSIGNED_BYTE, stride, getBytePtr(pointer)); -} - -void glVertexPointer_4J(int size, int type, FloatBuffer* pointer) { - ::glVertexPointer(size, (GLenum)type, 0, pointer->_getDataPointer()); -} - -void glEndList_4J(int dummy) { - (void)dummy; - ::glEndList(); + int* src = getIntPtr(buf); + for (int i = 0; i < n; i++) RenderManager.TextureFree(src[i]); } void glTexImage2D_4J(int target, int level, int internalformat, int width, int height, int border, int format, int type, ByteBuffer* pixels) { - ::glTexImage2D((GLenum)target, level, internalformat, width, height, border, - (GLenum)format, (GLenum)type, getBytePtr(pixels)); + (void)target; + (void)internalformat; + (void)border; + (void)format; + (void)type; + RenderManager.TextureData(width, height, getBytePtr(pixels), level, + C4JRender::TEXTURE_FORMAT_RxGyBzAw); +} + +void glLight_4J(int light, int pname, FloatBuffer* params) { + const float* p = params->_getDataPointer(); + int idx = (light == 0x4001) ? 1 : 0; + if (pname == 0x1203) + RenderManager.StateSetLightDirection(idx, p[0], p[1], p[2]); + else if (pname == 0x1201) + RenderManager.StateSetLightColour(idx, p[0], p[1], p[2]); + else if (pname == 0x1200) + RenderManager.StateSetLightAmbientColour(p[0], p[1], p[2]); +} + +void glLightModel_4J(int pname, FloatBuffer* params) { + if (pname == 0x0B53) { + const float* p = params->_getDataPointer(); + RenderManager.StateSetLightAmbientColour(p[0], p[1], p[2]); + } +} + +void glFog_4J(int pname, FloatBuffer* params) { + const float* p = params->_getDataPointer(); + if (pname == 0x0B66) RenderManager.StateSetFogColour(p[0], p[1], p[2]); +} + +void glGetFloat_4J(int pname, FloatBuffer* params) { + const float* m = RenderManager.MatrixGet(pname); + if (m) memcpy(params->_getDataPointer(), m, 16 * sizeof(float)); } void glCallLists_4J(IntBuffer* lists) { if (!lists) return; int count = lists->limit() - lists->position(); - if (count > 0) { - ::glCallLists(count, GL_INT, getIntPtr(lists)); - } + int* ids = getIntPtr(lists); + for (int i = 0; i < count; i++) RenderManager.CBuffCall(ids[i], false); } -void glReadPixels_4J(int x, int y, int width, int height, int format, int type, - ByteBuffer* pixels) { - ::glReadPixels(x, y, width, height, (GLenum)format, (GLenum)type, - getBytePtr(pixels)); +void glReadPixels_4J(int x, int y, int w, int h, int f, int t, ByteBuffer* p) { + (void)f; + (void)t; + RenderManager.ReadPixels(x, y, w, h, getBytePtr(p)); } -void glGetFloat(int pname, FloatBuffer* params) { - glGetFloat_4J(pname, params); -} -void glGenTextures(IntBuffer* buf) { glGenTextures_4J(buf); } -void glDeleteTextures(IntBuffer* buf) { glDeleteTextures_4J(buf); } -void glLight(int light, int pname, FloatBuffer* params) { - glLight_4J(light, pname, params); -} -void glLightModel(int pname, FloatBuffer* params) { - glLightModel_4J(pname, params); -} -void glTexGen(int coord, int pname, FloatBuffer* params) { - glTexGen_4J(coord, pname, params); -} -void glFog(int pname, FloatBuffer* params) { glFog_4J(pname, params); } -void glTexCoordPointer(int size, int type, FloatBuffer* pointer) { - glTexCoordPointer_4J(size, type, pointer); -} -void glNormalPointer(int type, ByteBuffer* pointer) { - glNormalPointer_4J(type, pointer); -} -void glColorPointer(int size, bool normalized, int stride, - ByteBuffer* pointer) { - glColorPointer_4J(size, normalized, stride, pointer); -} -void glVertexPointer(int size, int type, FloatBuffer* pointer) { - glVertexPointer_4J(size, type, pointer); -} -void glTexImage2D(int t, int l, int i, int w, int h, int b, int f, int ty, - ByteBuffer* p) { - glTexImage2D_4J(t, l, i, w, h, b, f, ty, p); -} -void glCallLists(IntBuffer* lists) { glCallLists_4J(lists); } -void glReadPixels(int x, int y, int w, int h, int f, int t, ByteBuffer* p) { - glReadPixels_4J(x, y, w, h, f, t, p); -} +// dead stubs +void glTexCoordPointer_4J(int, int, FloatBuffer*) {} +void glNormalPointer_4J(int, ByteBuffer*) {} +void glColorPointer_4J(int, bool, int, ByteBuffer*) {} +void glVertexPointer_4J(int, int, FloatBuffer*) {} +void glEndList_4J(int) {} +void glTexGen_4J(int, int, FloatBuffer*) {} +// query objects +#include static PFNGLGENQUERIESARBPROC _glGenQueriesARB = nullptr; static PFNGLBEGINQUERYARBPROC _glBeginQueryARB = nullptr; static PFNGLENDQUERYARBPROC _glEndQueryARB = nullptr; @@ -213,54 +130,37 @@ void glGenQueriesARB_4J(IntBuffer* buf) { initQueryFuncs(); if (_glGenQueriesARB && buf) { int n = buf->limit() - buf->position(); - if (n > 0) { - _glGenQueriesARB(n, getIntPtr(buf)); - } + if (n > 0) _glGenQueriesARB(n, (GLuint*)getIntPtr(buf)); } } -void glGenQueriesARB(IntBuffer* buf) { glGenQueriesARB_4J(buf); } void glBeginQueryARB_4J(int target, int id) { initQueryFuncs(); if (_glBeginQueryARB) _glBeginQueryARB((GLenum)target, (GLuint)id); } -void glBeginQueryARB(int target, int id) { glBeginQueryARB_4J(target, id); } void glEndQueryARB_4J(int target) { initQueryFuncs(); if (_glEndQueryARB) _glEndQueryARB((GLenum)target); } -void glEndQueryARB(int target) { glEndQueryARB_4J(target); } void glGetQueryObjectuARB_4J(int id, int pname, IntBuffer* params) { initQueryFuncs(); - if (_glGetQueryObjectuivARB && params) { + if (_glGetQueryObjectuivARB && params) // LWJGL does not change limits/positions during these calls, it // reads/writes exactly at pointer!! - _glGetQueryObjectuivARB((GLuint)id, (GLenum)pname, getIntPtr(params)); - } + _glGetQueryObjectuivARB((GLuint)id, (GLenum)pname, + (GLuint*)getIntPtr(params)); } -void glGetQueryObjectuARB(int id, int pname, IntBuffer* params) { - glGetQueryObjectuARB_4J(id, pname, params); +void glGetFloat(int pname, FloatBuffer* params) { + glGetFloat_4J(pname, params); } - void LinuxGLLogLightmapState(const char* stage, int textureId, bool scaleLight) { static int logCount = 0; if (logCount >= 16) return; ++logCount; - - GLint activeTexture = 0; - ::glGetIntegerv(GL_ACTIVE_TEXTURE, &activeTexture); - const GLint restoreTexture = activeTexture; - ::glActiveTexture(GL_TEXTURE1); - GLint unit1Binding = 0; - ::glGetIntegerv(GL_TEXTURE_BINDING_2D, &unit1Binding); - ::glActiveTexture(restoreTexture); - - app.DebugPrintf( - "[linux-lightmap] %s tex=%d scale=%d active=%#x unit1Bound=%d\n", stage, - textureId, scaleLight ? 1 : 0, activeTexture, unit1Binding); + fprintf(stderr, "[linux-lightmap] %s tex=%d scale=%d\n", stage, textureId, + scaleLight ? 1 : 0); } - #endif \ No newline at end of file From 5357e75037f285bb6f3e149d6fb15408e767955c Mon Sep 17 00:00:00 2001 From: JuiceyDev Date: Sat, 28 Mar 2026 19:45:28 +0100 Subject: [PATCH 144/170] gamerenderer bit more optimized --- Minecraft.Client/Rendering/GameRenderer.cpp | 248 +++++++++++--------- 1 file changed, 131 insertions(+), 117 deletions(-) diff --git a/Minecraft.Client/Rendering/GameRenderer.cpp b/Minecraft.Client/Rendering/GameRenderer.cpp index 6a1bbc614..617e67dc2 100644 --- a/Minecraft.Client/Rendering/GameRenderer.cpp +++ b/Minecraft.Client/Rendering/GameRenderer.cpp @@ -72,6 +72,9 @@ ResourceLocation GameRenderer::RAIN_LOCATION = ResourceLocation GameRenderer::SNOW_LOCATION = ResourceLocation(TN_ENVIRONMENT_SNOW); +// dirty light tracking +static bool s_lightTexDirty[XUSER_MAX_COUNT] = {true, true, true, true}; + GameRenderer::GameRenderer(Minecraft* mc) { // 4J - added this block of initialisers renderDistance = 0; @@ -871,6 +874,10 @@ void GameRenderer::tickLightTexture() { blr += (blrt - blr) * 1; blg += (blgt - blg) * 1; _updateLightTexture = true; + + // Mark all players dirty so updateLightTexture() knows when it actually + // needs to tick, preventz unessesary player recompute + for (int j = 0; j < XUSER_MAX_COUNT; j++) s_lightTexDirty[j] = true; } void GameRenderer::updateLightTexture(float a) { @@ -883,8 +890,10 @@ void GameRenderer::updateLightTexture(float a) { Minecraft::GetInstance()->localplayers[j]; if (player == NULL) continue; - Level* level = player->level; // 4J - was mc->level when it was just to - // update the one light texture + if (!s_lightTexDirty[j]) continue; + s_lightTexDirty[j] = false; + + Level* level = player->level; float skyDarken1 = level->getSkyDarken((float)1); for (int i = 0; i < 256; i++) { @@ -964,10 +973,10 @@ void GameRenderer::updateLightTexture(float a) { _b = _b * 0.96f + 0.03f; if (_r > 1) _r = 1; - if (_g > 1) _g = 1; - if (_b > 1) _b = 1; if (_r < 0) _r = 0; + if (_g > 1) _g = 1; if (_g < 0) _g = 0; + if (_b > 1) _b = 1; if (_b < 0) _b = 0; int alpha = 255; @@ -1180,24 +1189,19 @@ int GameRenderer::runUpdate(void* lpParam) { // We've got stacks for things that can only safely be deleted whilst // this thread isn't updating things - delete those things now EnterCriticalSection(&m_csDeleteStack); - for (unsigned int i = 0; i < m_deleteStackByte.size(); i++) { + for (unsigned int i = 0; i < m_deleteStackByte.size(); i++) delete m_deleteStackByte[i]; - } m_deleteStackByte.clear(); for (unsigned int i = 0; i < m_deleteStackSparseLightStorage.size(); - i++) { + i++) delete m_deleteStackSparseLightStorage[i]; - } m_deleteStackSparseLightStorage.clear(); for (unsigned int i = 0; i < m_deleteStackCompressedTileStorage.size(); - i++) { + i++) delete m_deleteStackCompressedTileStorage[i]; - } m_deleteStackCompressedTileStorage.clear(); - for (unsigned int i = 0; i < m_deleteStackSparseDataStorage.size(); - i++) { + for (unsigned int i = 0; i < m_deleteStackSparseDataStorage.size(); i++) delete m_deleteStackSparseDataStorage[i]; - } m_deleteStackSparseDataStorage.clear(); LeaveCriticalSection(&m_csDeleteStack); @@ -1700,135 +1704,144 @@ void GameRenderer::renderSnowAndRain(float a) { glColor4f(1, 1, 1, 1); - for (int x = x0 - r; x <= x0 + r; x++) + // two snow/rain rendering + mc->textures->bindTexture(&RAIN_LOCATION); + t->begin(); + for (int x = x0 - r; x <= x0 + r; x++) { for (int z = z0 - r; z <= z0 + r; z++) { int rainSlot = (z - z0 + 16) * 32 + (x - x0 + 16); float xa = rainXa[rainSlot] * 0.5f; float za = rainZa[rainSlot] * 0.5f; - // 4J - changes here brought forward from 1.8.2 Biome* b = level->getBiome(x, z); if (!b->hasRain() && !b->hasSnow()) continue; int floor = level->getTopRainBlock(x, z); - int yy0 = y0 - r; int yy1 = y0 + r; - if (yy0 < floor) yy0 = floor; if (yy1 < floor) yy1 = floor; - float s = 1; + if (yy0 == yy1) continue; int yl = floor; if (yl < yMin) yl = yMin; - if (yy0 != yy1) { - random->setSeed((x * x * 3121 + x * 45238971) ^ - (z * z * 418711 + z * 13761)); + float temp = b->getTemperature(); + if (level->getBiomeSource()->scaleTemp(temp, floor) < 0.15f) + continue; - // 4J - changes here brought forward from 1.8.2 - float temp = b->getTemperature(); - if (level->getBiomeSource()->scaleTemp(temp, floor) >= 0.15f) { - if (mode != 0) { - if (mode >= 0) t->end(); - mode = 0; - mc->textures->bindTexture(&RAIN_LOCATION); - t->begin(); - } + random->setSeed((x * x * 3121 + x * 45238971) ^ + (z * z * 418711 + z * 13761)); - float ra = (((_tick + x * x * 3121 + x * 45238971 + - z * z * 418711 + z * 13761) & - 31) + - a) / - 32.0f * (3 + random->nextFloat()); + float ra = (((_tick + x * x * 3121 + x * 45238971 + z * z * 418711 + + z * 13761) & + 31) + + a) / + 32.0f * (3 + random->nextFloat()); - double xd = (x + 0.5f) - player->x; - double zd = (z + 0.5f) - player->z; - float dd = (float)Mth::sqrt(xd * xd + zd * zd) / r; + double xd = (x + 0.5f) - player->x; + double zd = (z + 0.5f) - player->z; + float dd = (float)Mth::sqrt(xd * xd + zd * zd) / r; - float br = 1; - t->offset(-xo * 1, -yo * 1, -zo * 1); + float br = 1.0f; + float s = 1.0f; + t->offset(-xo, -yo, -zo); #ifdef __PSVITA__ - // AP - this will set up the 4 vertices in half the time - float Alpha = ((1 - dd * dd) * 0.5f + 0.5f) * rainLevel; - int tex2 = - (level->getLightColor(x, yl, z, 0) * 3 + 0xf000f0) / 4; - t->tileRainQuad( - x - xa + 0.5, yy0, z - za + 0.5, 0 * s, - yy0 * s / 4.0f + ra * s, x + xa + 0.5, yy0, - z + za + 0.5, 1 * s, yy0 * s / 4.0f + ra * s, - x + xa + 0.5, yy1, z + za + 0.5, 1 * s, - yy1 * s / 4.0f + ra * s, x - xa + 0.5, yy1, - z - za + 0.5, 0 * s, yy1 * s / 4.0f + ra * s, br, br, - br, Alpha, br, br, br, 0, tex2); + float Alpha = ((1 - dd * dd) * 0.5f + 0.5f) * rainLevel; + int tex2 = (level->getLightColor(x, yl, z, 0) * 3 + 0xf000f0) / 4; + t->tileRainQuad( + x - xa + 0.5, yy0, z - za + 0.5, 0 * s, yy0 * s / 4.0f + ra * s, + x + xa + 0.5, yy0, z + za + 0.5, 1 * s, yy0 * s / 4.0f + ra * s, + x + xa + 0.5, yy1, z + za + 0.5, 1 * s, yy1 * s / 4.0f + ra * s, + x - xa + 0.5, yy1, z - za + 0.5, 0 * s, yy1 * s / 4.0f + ra * s, + br, br, br, Alpha, br, br, br, 0, tex2); #else - t->tex2(level->getLightColor(x, yl, z, 0)); - t->color(br, br, br, - ((1 - dd * dd) * 0.5f + 0.5f) * rainLevel); - t->vertexUV(x - xa + 0.5, yy0, z - za + 0.5, 0 * s, - yy0 * s / 4.0f + ra * s); - t->vertexUV(x + xa + 0.5, yy0, z + za + 0.5, 1 * s, - yy0 * s / 4.0f + ra * s); - // 4jcraft: this color call made rain invisible - // t->color(br, br, br, 0.0f); - // // 4J - added to soften the top visible edge of the rain - t->vertexUV(x + xa + 0.5, yy1, z + za + 0.5, 1 * s, - yy1 * s / 4.0f + ra * s); - t->vertexUV(x - xa + 0.5, yy1, z - za + 0.5, 0 * s, - yy1 * s / 4.0f + ra * s); + t->tex2(level->getLightColor(x, yl, z, 0)); + t->color(br, br, br, ((1 - dd * dd) * 0.5f + 0.5f) * rainLevel); + t->vertexUV(x - xa + 0.5, yy0, z - za + 0.5, 0 * s, + yy0 * s / 4.0f + ra * s); + t->vertexUV(x + xa + 0.5, yy0, z + za + 0.5, 1 * s, + yy0 * s / 4.0f + ra * s); + t->vertexUV(x + xa + 0.5, yy1, z + za + 0.5, 1 * s, + yy1 * s / 4.0f + ra * s); + t->vertexUV(x - xa + 0.5, yy1, z - za + 0.5, 0 * s, + yy1 * s / 4.0f + ra * s); #endif - t->offset(0, 0, 0); - t->end(); - } else { - if (mode != 1) { - if (mode >= 0) t->end(); - mode = 1; - mc->textures->bindTexture(&SNOW_LOCATION); - t->begin(); - } - float ra = (((_tick) & 511) + a) / 512.0f; - float uo = random->nextFloat() + - time * 0.01f * (float)random->nextGaussian(); - float vo = random->nextFloat() + - time * (float)random->nextGaussian() * 0.001f; - double xd = (x + 0.5f) - player->x; - double zd = (z + 0.5f) - player->z; - float dd = (float)sqrt(xd * xd + zd * zd) / r; - float br = 1; - t->offset(-xo * 1, -yo * 1, -zo * 1); -#ifdef __PSVITA__ - // AP - this will set up the 4 vertices in half the time - float Alpha = ((1 - dd * dd) * 0.3f + 0.5f) * rainLevel; - int tex2 = - (level->getLightColor(x, yl, z, 0) * 3 + 0xf000f0) / 4; - t->tileRainQuad( - x - xa + 0.5, yy0, z - za + 0.5, 0 * s + uo, - yy0 * s / 4.0f + ra * s + vo, x + xa + 0.5, yy0, - z + za + 0.5, 1 * s + uo, yy0 * s / 4.0f + ra * s + vo, - x + xa + 0.5, yy1, z + za + 0.5, 1 * s + uo, - yy1 * s / 4.0f + ra * s + vo, x - xa + 0.5, yy1, - z - za + 0.5, 0 * s + uo, yy1 * s / 4.0f + ra * s + vo, - br, br, br, Alpha, br, br, br, Alpha, tex2); -#else - t->tex2((level->getLightColor(x, yl, z, 0) * 3 + 0xf000f0) / - 4); - t->color(br, br, br, - ((1 - dd * dd) * 0.3f + 0.5f) * rainLevel); - t->vertexUV(x - xa + 0.5, yy0, z - za + 0.5, 0 * s + uo, - yy0 * s / 4.0f + ra * s + vo); - t->vertexUV(x + xa + 0.5, yy0, z + za + 0.5, 1 * s + uo, - yy0 * s / 4.0f + ra * s + vo); - t->vertexUV(x + xa + 0.5, yy1, z + za + 0.5, 1 * s + uo, - yy1 * s / 4.0f + ra * s + vo); - t->vertexUV(x - xa + 0.5, yy1, z - za + 0.5, 0 * s + uo, - yy1 * s / 4.0f + ra * s + vo); -#endif - t->offset(0, 0, 0); - } - } + t->offset(0, 0, 0); } + } + t->end(); // single submit for all rain geometry + // sno time + mc->textures->bindTexture(&SNOW_LOCATION); + t->begin(); + for (int x = x0 - r; x <= x0 + r; x++) { + for (int z = z0 - r; z <= z0 + r; z++) { + int rainSlot = (z - z0 + 16) * 32 + (x - x0 + 16); + float xa = rainXa[rainSlot] * 0.5f; + float za = rainZa[rainSlot] * 0.5f; + + Biome* b = level->getBiome(x, z); + if (!b->hasRain() && !b->hasSnow()) continue; + + int floor = level->getTopRainBlock(x, z); + int yy0 = y0 - r; + int yy1 = y0 + r; + if (yy0 < floor) yy0 = floor; + if (yy1 < floor) yy1 = floor; + if (yy0 == yy1) continue; + + int yl = floor; + if (yl < yMin) yl = yMin; + + float temp = b->getTemperature(); + // only draw snow (not rain) in this pass + if (level->getBiomeSource()->scaleTemp(temp, floor) >= 0.15f) + continue; + + random->setSeed((x * x * 3121 + x * 45238971) ^ + (z * z * 418711 + z * 13761)); + + float ra = (((_tick) & 511) + a) / 512.0f; + float uo = random->nextFloat() + + time * 0.01f * (float)random->nextGaussian(); + float vo = random->nextFloat() + + time * (float)random->nextGaussian() * 0.001f; + + double xd = (x + 0.5f) - player->x; + double zd = (z + 0.5f) - player->z; + float dd = (float)sqrt(xd * xd + zd * zd) / r; + + float br = 1.0f; + float s = 1.0f; + t->offset(-xo, -yo, -zo); +#ifdef __PSVITA__ + float Alpha = ((1 - dd * dd) * 0.3f + 0.5f) * rainLevel; + int tex2 = (level->getLightColor(x, yl, z, 0) * 3 + 0xf000f0) / 4; + t->tileRainQuad( + x - xa + 0.5, yy0, z - za + 0.5, 0 * s + uo, + yy0 * s / 4.0f + ra * s + vo, x + xa + 0.5, yy0, z + za + 0.5, + 1 * s + uo, yy0 * s / 4.0f + ra * s + vo, x + xa + 0.5, yy1, + z + za + 0.5, 1 * s + uo, yy1 * s / 4.0f + ra * s + vo, + x - xa + 0.5, yy1, z - za + 0.5, 0 * s + uo, + yy1 * s / 4.0f + ra * s + vo, br, br, br, Alpha, br, br, br, + Alpha, tex2); +#else + t->tex2((level->getLightColor(x, yl, z, 0) * 3 + 0xf000f0) / 4); + t->color(br, br, br, ((1 - dd * dd) * 0.3f + 0.5f) * rainLevel); + t->vertexUV(x - xa + 0.5, yy0, z - za + 0.5, 0 * s + uo, + yy0 * s / 4.0f + ra * s + vo); + t->vertexUV(x + xa + 0.5, yy0, z + za + 0.5, 1 * s + uo, + yy0 * s / 4.0f + ra * s + vo); + t->vertexUV(x + xa + 0.5, yy1, z + za + 0.5, 1 * s + uo, + yy1 * s / 4.0f + ra * s + vo); + t->vertexUV(x - xa + 0.5, yy1, z - za + 0.5, 0 * s + uo, + yy1 * s / 4.0f + ra * s + vo); +#endif + t->offset(0, 0, 0); + } + } + t->end(); // single submit for all snow geometry - if (mode >= 0) t->end(); glEnable(GL_CULL_FACE); glDisable(GL_BLEND); glAlphaFunc(GL_GREATER, 0.1f); @@ -1846,7 +1859,8 @@ void GameRenderer::setupGuiScreen(int forceScale /*=-1*/) { // to ensure GUI scales correctly after a window resize. ScreenSizeCalculator ssc(mc->options, fbw, fbh, forceScale); - // 4jcraft: Java GUI screens still assume a clean 2D fixed-function style state. + // 4jcraft: Java GUI screens still assume a clean 2D fixed-function style + // state. RenderManager.StateSetFaceCull(false); glDisable(GL_LIGHTING); glDisable(GL_FOG); From 48935be0fa723b9ede60dfa5562063834c13eff8 Mon Sep 17 00:00:00 2001 From: JuiceyDev Date: Sat, 28 Mar 2026 19:55:49 +0100 Subject: [PATCH 145/170] format meson.options --- meson.options | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/meson.options b/meson.options index 3171bc298..cdf6457be 100644 --- a/meson.options +++ b/meson.options @@ -1,21 +1,27 @@ -option('ui_backend', - type : 'combo', +option( + 'ui_backend', + type: 'combo', choices: ['shiggy', 'java'], - value : 'shiggy', - description : 'Specifies a backend implementation for the game UI.') + value: 'shiggy', + description: 'Specifies a backend implementation for the game UI.', +) option('classic_panorama', type : 'boolean', value : false, description : 'Enable classic java edition panorama (ui_backend=java ONLY).') -option('renderer', - type : 'combo', +option( + 'renderer', + type: 'combo', choices: ['gl3', 'gles'], - value : 'gl3', - description : 'Specifies a rendering implementation for the game.') + value: 'gl3', + description: 'Specifies a rendering implementation for the game.', +) -option('enable_vsync', - type : 'boolean', - value : true, - description : 'Toggles V-Sync and adds options to unlock maximum in-game framerate.') +option( + 'enable_vsync', + type: 'boolean', + value: true, + description: 'Toggles V-Sync and adds options to unlock maximum in-game framerate.', +) \ No newline at end of file From 5e7bba862cd22c3519128fbd40e716230a3fab9a Mon Sep 17 00:00:00 2001 From: JuiceyDev Date: Sat, 28 Mar 2026 21:00:30 +0100 Subject: [PATCH 146/170] perf fix culler thing --- Minecraft.Client/Rendering/LevelRenderer.cpp | 63 ++++++++++++++------ 1 file changed, 45 insertions(+), 18 deletions(-) diff --git a/Minecraft.Client/Rendering/LevelRenderer.cpp b/Minecraft.Client/Rendering/LevelRenderer.cpp index 03bb23057..22ac311fb 100644 --- a/Minecraft.Client/Rendering/LevelRenderer.cpp +++ b/Minecraft.Client/Rendering/LevelRenderer.cpp @@ -846,6 +846,11 @@ int LevelRenderer::renderChunks(int from, int to, int layer, double alpha) { int count = 0; ClipChunk* pClipChunk = chunks[playerIndex].data; unsigned char emptyFlag = LevelRenderer::CHUNK_FLAG_EMPTY0 << layer; + static thread_local std::vector sortList; + sortList.clear(); + if (sortList.capacity() < (size_t)chunks[playerIndex].length) { + sortList.reserve(chunks[playerIndex].length); + } for (int i = 0; i < chunks[playerIndex].length; i++, pClipChunk++) { if (!pClipChunk->visible) continue; // This will be set if the chunk isn't visible, or isn't @@ -854,17 +859,47 @@ int LevelRenderer::renderChunks(int from, int to, int layer, double alpha) { continue; // Not sure if we should ever encounter this... TODO // check if ((globalChunkFlags[pClipChunk->globalIdx] & emptyFlag) == emptyFlag) - continue; // Check that this particular layer isn't empty + continue; - // List can be calculated directly from the chunk's global idex - int list = pClipChunk->globalIdx * 2 + layer; + sortList.push_back(pClipChunk); + } + // he sorts me till i + std::sort(sortList.begin(), sortList.end(), + [xOff, yOff, zOff, layer](ClipChunk* a, ClipChunk* b) { + float dxA = (float)((a->chunk->x + 8.0f) - xOff); + float dyA = (float)((a->chunk->y + 8.0f) - yOff); + float dzA = (float)((a->chunk->z + 8.0f) - zOff); + float distSqA = dxA * dxA + dyA * dyA + dzA * dzA; + + float dxB = (float)((b->chunk->x + 8.0f) - xOff); + float dyB = (float)((b->chunk->y + 8.0f) - yOff); + float dzB = (float)((b->chunk->z + 8.0f) - zOff); + float distSqB = dxB * dxB + dyB * dyB + dzB * dzB; + + if (layer == 0) + return distSqA < distSqB; // Opaque: Closest first + return distSqA > distSqB; // Transparent: Furthest first + }); + + for (ClipChunk* chunk : sortList) { + // ugly occluder + float dx = (chunk->chunk->x + 8.0f) - (float)xOff; + float dy = (chunk->chunk->y + 8.0f) - (float)yOff; + float dz = (chunk->chunk->z + 8.0f) - (float)zOff; + bool isVeryNear = (dx * dx + dy * dy + dz * dz) < (16.0f * 16.0f); + + if (!isVeryNear && layer == 0) { + // todo: occlusion flag + } + + int list = chunk->globalIdx * 2 + layer; list += chunkLists; // 4jcraft: replaced glPushMatrix/glTranslatef/glPopMatrix per chunk // no more full MVP upload per chunk, can also be bkwards compat - RenderManager.SetChunkOffset((float)pClipChunk->chunk->x, - (float)pClipChunk->chunk->y, - (float)pClipChunk->chunk->z); + RenderManager.SetChunkOffset((float)chunk->chunk->x, + (float)chunk->chunk->y, + (float)chunk->chunk->z); if (RenderManager.CBuffCall(list, first)) { first = false; @@ -945,31 +980,23 @@ int LevelRenderer::renderChunks(int from, int to, int layer, double alpha) { double yOff = player->yOld + (player->y - player->yOld) * alpha; double zOff = player->zOld + (player->z - player->zOld) * alpha; + for (int l = 0; l < RENDERLISTS_LENGTH; l++) renderLists[l].clear(); int lists = 0; - for (int l = 0; l < RENDERLISTS_LENGTH; l++) { - renderLists[l].clear(); - } - - AUTO_VAR(itEnd, _renderChunks.end()); - for (AUTO_VAR(it, _renderChunks.begin()); it != itEnd; it++) { - Chunk* chunk = *it; //_renderChunks[i]; - + for (auto it = _renderChunks.begin(); it != _renderChunks.end(); it++) { + Chunk* chunk = *it; int list = -1; for (int l = 0; l < lists; l++) { if (renderLists[l].isAt(chunk->xRender, chunk->yRender, - chunk->zRender)) { + chunk->zRender)) list = l; - } } if (list < 0) { list = lists++; renderLists[list].init(chunk->xRender, chunk->yRender, chunk->zRender, xOff, yOff, zOff); } - renderLists[list].add(chunk->getList(layer)); } - renderSameAsLast(layer, alpha); #endif From 21092cb686c9518b52263fec31b95b49270e4ef1 Mon Sep 17 00:00:00 2001 From: Tropical <42101043+tropicaaal@users.noreply.github.com> Date: Sat, 28 Mar 2026 18:08:27 -0500 Subject: [PATCH 147/170] fix: stub IggyValueGetTypeRS --- Minecraft.Client/Platform/Linux/Stubs/iggy_stubs.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Minecraft.Client/Platform/Linux/Stubs/iggy_stubs.h b/Minecraft.Client/Platform/Linux/Stubs/iggy_stubs.h index 701ad994f..a86f7a0ae 100644 --- a/Minecraft.Client/Platform/Linux/Stubs/iggy_stubs.h +++ b/Minecraft.Client/Platform/Linux/Stubs/iggy_stubs.h @@ -254,6 +254,14 @@ RADEXPFUNC inline void* RADEXPLINK IggyPerfmonCreate( } RADEXPFUNC inline void RADEXPLINK IggyInstallPerfmon(void* perfmon) { STUBBED; } +RADEXPFUNC IggyResult RADEXPLINK IggyValueGetTypeRS(IggyValuePath* var, + IggyName sub_name, + char const* sub_name_utf8, + IggyDatatype* result) { + STUBBED; + return IGGY_RESULT_SUCCESS; +} + // GDraw memory/warning functions are defined in gdraw_glfw.c (C linkage) // Juicey you stupid idiot do NOT define them here From 94a67d41b678ed934be49bf1391dd9e9e8c9ce80 Mon Sep 17 00:00:00 2001 From: Tropical <42101043+tropicaaal@users.noreply.github.com> Date: Sat, 28 Mar 2026 18:10:55 -0500 Subject: [PATCH 148/170] inline that --- Minecraft.Client/Platform/Linux/Stubs/iggy_stubs.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Minecraft.Client/Platform/Linux/Stubs/iggy_stubs.h b/Minecraft.Client/Platform/Linux/Stubs/iggy_stubs.h index a86f7a0ae..ca0c47ff1 100644 --- a/Minecraft.Client/Platform/Linux/Stubs/iggy_stubs.h +++ b/Minecraft.Client/Platform/Linux/Stubs/iggy_stubs.h @@ -254,7 +254,7 @@ RADEXPFUNC inline void* RADEXPLINK IggyPerfmonCreate( } RADEXPFUNC inline void RADEXPLINK IggyInstallPerfmon(void* perfmon) { STUBBED; } -RADEXPFUNC IggyResult RADEXPLINK IggyValueGetTypeRS(IggyValuePath* var, +RADEXPFUNC inline IggyResult RADEXPLINK IggyValueGetTypeRS(IggyValuePath* var, IggyName sub_name, char const* sub_name_utf8, IggyDatatype* result) { From f499eaee9c34b4ff0d12ec05101b31a6e22d2c53 Mon Sep 17 00:00:00 2001 From: MatthewBeshay <92357869+MatthewBeshay@users.noreply.github.com> Date: Sun, 29 Mar 2026 10:42:12 +1100 Subject: [PATCH 149/170] chore(linux): add diagnostics for iggy render-target exhaustion --- .../Windows64/Iggy/gdraw/gdraw_gl_shared.inl | 106 +++++++++++++++++- 1 file changed, 100 insertions(+), 6 deletions(-) diff --git a/Minecraft.Client/Platform/Windows64/Iggy/gdraw/gdraw_gl_shared.inl b/Minecraft.Client/Platform/Windows64/Iggy/gdraw/gdraw_gl_shared.inl index a7a965d19..e24dd7202 100644 --- a/Minecraft.Client/Platform/Windows64/Iggy/gdraw/gdraw_gl_shared.inl +++ b/Minecraft.Client/Platform/Windows64/Iggy/gdraw/gdraw_gl_shared.inl @@ -653,6 +653,90 @@ static void RADLINK gdraw_DescribeVertexBuffer(GDrawVertexBuffer *vbuf, GDraw_Ve // Create/free (or cache) render targets // +#ifdef __linux__ +typedef struct +{ + S32 free_count; + S32 live_count; + S32 locked_count; + S32 dead_count; + S32 pinned_count; + S32 user_owned_count; + S32 alloc_count; +} GDrawHandleStateCounts; + +enum +{ + GDRAW_RT_DIAG_color_memory = 1 << 0, + GDRAW_RT_DIAG_color_handles = 1 << 1, + GDRAW_RT_DIAG_cache_bitmap = 1 << 2, + GDRAW_RT_DIAG_stack_depth = 1 << 3, + GDRAW_RT_DIAG_empty_request = 1 << 4, +}; + +static U32 gdraw_rt_diag_emitted = 0; + +static void gdraw_CountHandleStates(GDrawHandleCache *cache, + GDrawHandleStateCounts *counts) +{ + S32 i; + counts->free_count = 0; + counts->live_count = 0; + counts->locked_count = 0; + counts->dead_count = 0; + counts->pinned_count = 0; + counts->user_owned_count = 0; + counts->alloc_count = 0; + + if (!cache) + return; + + for (i = 0; i < cache->max_handles; ++i) { + switch (cache->handle[i].state) { + case GDRAW_HANDLE_STATE_free: ++counts->free_count; break; + case GDRAW_HANDLE_STATE_live: ++counts->live_count; break; + case GDRAW_HANDLE_STATE_locked: ++counts->locked_count; break; + case GDRAW_HANDLE_STATE_dead: ++counts->dead_count; break; + case GDRAW_HANDLE_STATE_pinned: ++counts->pinned_count; break; + case GDRAW_HANDLE_STATE_user_owned: ++counts->user_owned_count; break; + case GDRAW_HANDLE_STATE_alloc: ++counts->alloc_count; break; + default: break; + } + } +} + +static void gdraw_ReportHandleCacheDiag(char const *label, + GDrawHandleCache *cache, + U32 once_bit, + S32 req_w, + S32 req_h) +{ + GDrawHandleStateCounts counts; + + if (gdraw_rt_diag_emitted & once_bit) + return; + gdraw_rt_diag_emitted |= once_bit; + + gdraw_CountHandleStates(cache, &counts); + IggyGDrawSendWarning(NULL, + "GDraw[%s] diag: frame=%dx%d tile=%dx%d padded=%dx%d req=%dx%d depth=%d bytes_free=%d total_bytes=%d handles free=%d live=%d locked=%d dead=%d pinned=%d user=%d alloc=%d", + label, + gdraw->frametex_width, gdraw->frametex_height, + gdraw->tw, gdraw->th, + gdraw->tpw, gdraw->tph, + req_w, req_h, + (int) (gdraw->cur - gdraw->frame), + cache ? cache->bytes_free : 0, + cache ? cache->total_bytes : 0, + counts.free_count, counts.live_count, counts.locked_count, + counts.dead_count, counts.pinned_count, counts.user_owned_count, + counts.alloc_count); +} +#else +#define gdraw_ReportHandleCacheDiag(label, cache, once_bit, req_w, req_h) \ + ((void) 0) +#endif + static GDrawHandle *get_rendertarget_texture(int width, int height, void *owner, GDrawStats *gstats) { S32 size; @@ -696,13 +780,17 @@ static GDrawHandle *get_color_rendertarget(GDrawStats *gstats) // ran out of RTs, allocate a new one size = gdraw->frametex_width * gdraw->frametex_height * 4; if (gdraw->rendertargets.bytes_free < size) { - IggyGDrawSendWarning(NULL, "GDraw exceeded available rendertarget memory"); + gdraw_ReportHandleCacheDiag("rt-color-memory", &gdraw->rendertargets, + GDRAW_RT_DIAG_color_memory, gdraw->tpw, gdraw->tph); + IggyGDrawSendWarning(NULL, "GDraw[rt-color] exceeded available rendertarget memory"); return NULL; } t = gdraw_HandleCacheAllocateBegin(&gdraw->rendertargets); if (!t) { - IggyGDrawSendWarning(NULL, "GDraw exceeded available rendertarget handles"); + gdraw_ReportHandleCacheDiag("rt-color-handles", &gdraw->rendertargets, + GDRAW_RT_DIAG_color_handles, gdraw->tpw, gdraw->tph); + IggyGDrawSendWarning(NULL, "GDraw[rt-color] exceeded available rendertarget handles"); return t; } @@ -1010,25 +1098,31 @@ static rrbool RADLINK gdraw_TextureDrawBufferBegin(gswf_recti *region, gdraw_tex GDrawHandle *t; int k; if (gdraw->tw == 0 || gdraw->th == 0) { - IggyGDrawSendWarning(NULL, "GDraw got a request for an empty rendertarget"); + gdraw_ReportHandleCacheDiag("rt-empty", &gdraw->rendertargets, + GDRAW_RT_DIAG_empty_request, region->x1 - region->x0, region->y1 - region->y0); + IggyGDrawSendWarning(NULL, "GDraw[rt-stack] got a request for an empty rendertarget"); return false; } if (n >= &gdraw->frame[MAX_RENDER_STACK_DEPTH]) { - IggyGDrawSendWarning(NULL, "GDraw rendertarget nesting exceeded MAX_RENDER_STACK_DEPTH"); + gdraw_ReportHandleCacheDiag("rt-stack-depth", &gdraw->rendertargets, + GDRAW_RT_DIAG_stack_depth, region->x1 - region->x0, region->y1 - region->y0); + IggyGDrawSendWarning(NULL, "GDraw[rt-stack] rendertarget nesting exceeded MAX_RENDER_STACK_DEPTH"); return false; } if (owner) { t = get_rendertarget_texture(region->x1 - region->x0, region->y1 - region->y0, owner, gstats); if (!t) { - IggyGDrawSendWarning(NULL, "GDraw ran out of rendertargets for cacheAsBItmap"); + gdraw_ReportHandleCacheDiag("rt-cacheAsBitmap", gdraw->texturecache, + GDRAW_RT_DIAG_cache_bitmap, region->x1 - region->x0, region->y1 - region->y0); + IggyGDrawSendWarning(NULL, "GDraw[rt-cacheAsBitmap] ran out of rendertargets"); return false; } } else { t = get_color_rendertarget(gstats); if (!t) { - IggyGDrawSendWarning(NULL, "GDraw ran out of rendertargets"); + IggyGDrawSendWarning(NULL, "GDraw[rt-color] ran out of rendertargets"); return false; } } From b5b4fc34fec65608d567d256107bb224c78a7202 Mon Sep 17 00:00:00 2001 From: MatthewBeshay <92357869+MatthewBeshay@users.noreply.github.com> Date: Sun, 29 Mar 2026 11:19:28 +1100 Subject: [PATCH 150/170] fix(linux): increase iggy render-target budget to 64mb --- Minecraft.Client/Platform/Linux/Linux_UIController.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Minecraft.Client/Platform/Linux/Linux_UIController.cpp b/Minecraft.Client/Platform/Linux/Linux_UIController.cpp index 4d99f518f..855c10b9d 100644 --- a/Minecraft.Client/Platform/Linux/Linux_UIController.cpp +++ b/Minecraft.Client/Platform/Linux/Linux_UIController.cpp @@ -48,7 +48,7 @@ void ConsoleUIController::init(S32 w, S32 h) { gdraw_GL_SetResourceLimits(GDRAW_GL_RESOURCE_texture, 5000, 128 * 1024 * 1024); gdraw_GL_SetResourceLimits(GDRAW_GL_RESOURCE_rendertarget, 10, - 32 * 1024 * 1024); + 64 * 1024 * 1024); IggySetGDraw(gdraw_funcs); #endif From 47b7d90835d1368ca08140dd06fe0e133f764c71 Mon Sep 17 00:00:00 2001 From: MatthewBeshay <92357869+MatthewBeshay@users.noreply.github.com> Date: Sun, 29 Mar 2026 12:10:19 +1100 Subject: [PATCH 151/170] feat(profiling): add low-overhead in-engine frame profiler --- Minecraft.Client/Rendering/GameRenderer.cpp | 73 +- Minecraft.Client/Rendering/LevelRenderer.cpp | 749 ++++++++++--------- Minecraft.Client/Utils/FrameProfiler.cpp | 260 +++++++ Minecraft.Client/Utils/FrameProfiler.h | 93 +++ Minecraft.Client/meson.build | 6 +- meson.options | 9 +- 6 files changed, 816 insertions(+), 374 deletions(-) create mode 100644 Minecraft.Client/Utils/FrameProfiler.cpp create mode 100644 Minecraft.Client/Utils/FrameProfiler.h diff --git a/Minecraft.Client/Rendering/GameRenderer.cpp b/Minecraft.Client/Rendering/GameRenderer.cpp index 617e67dc2..6a2272f7c 100644 --- a/Minecraft.Client/Rendering/GameRenderer.cpp +++ b/Minecraft.Client/Rendering/GameRenderer.cpp @@ -50,6 +50,7 @@ #include "../Textures/Packs/TexturePackRepository.h" #include "../Textures/Packs/TexturePack.h" #include "../Textures/TextureAtlas.h" +#include "../Utils/FrameProfiler.h" bool GameRenderer::anaglyph3d = false; int GameRenderer::anaglyphPass = 0; @@ -776,6 +777,7 @@ void GameRenderer::renderItemInHand(float a, int eye) { // 4J - change brought forward from 1.8.2 void GameRenderer::turnOffLightLayer(double alpha) { // 4J - TODO + FRAME_PROFILE_SCOPE(Lightmap); #ifdef __linux__ if (SharedConstants::TEXTURE_LIGHTING) { LinuxLogStubLightmapProbe(); @@ -807,6 +809,7 @@ void GameRenderer::turnOffLightLayer(double alpha) { // 4J - TODO void GameRenderer::turnOnLightLayer( double alpha, bool scaleLight) { // 4jcraft: added scaleLight for entity lighting + FRAME_PROFILE_SCOPE(Lightmap); #ifdef __linux__ if (!SharedConstants::TEXTURE_LIGHTING) return; @@ -881,6 +884,7 @@ void GameRenderer::tickLightTexture() { } void GameRenderer::updateLightTexture(float a) { + FRAME_PROFILE_SCOPE(Lightmap); // 4J-JEV: Now doing light textures on PER PLAYER basis. // 4J - we *had* added separate light textures for all dimensions, and this // loop to update them all here @@ -1025,6 +1029,8 @@ int GameRenderer::getLightTexture(int iPad, Level* level) { } void GameRenderer::render(float a, bool bFirst) { + FRAME_PROFILE_FRAME_SCOPE(); + if (_updateLightTexture && bFirst) updateLightTexture(a); if (Display::isActive()) { lastActiveTime = System::currentTimeMillis(); @@ -1083,6 +1089,7 @@ void GameRenderer::render(float a, bool bFirst) { lastNsTime = System::nanoTime(); if (!mc->options->hideGui || mc->screen != NULL) { + FRAME_PROFILE_SCOPE(UIHud); mc->gui->render(a, mc->screen != NULL, xMouse, yMouse); } } else { @@ -1097,6 +1104,7 @@ void GameRenderer::render(float a, bool bFirst) { } if (mc->screen != NULL) { + FRAME_PROFILE_SCOPE(UIHud); glClear(GL_DEPTH_BUFFER_BIT); mc->screen->render(xMouse, yMouse, a); if (mc->screen != NULL && mc->screen->particles != NULL) @@ -1244,6 +1252,8 @@ void GameRenderer::DisableUpdateThread() { } void GameRenderer::renderLevel(float a, int64_t until) { + FRAME_PROFILE_SCOPE(World); + // if (updateLightTexture) updateLightTexture(); // 4J - TODO - // Java 1.0.1 has this line enabled, should check why - don't want to put it // in now in case it breaks split-screen @@ -1296,9 +1306,12 @@ void GameRenderer::renderLevel(float a, int64_t until) { Frustum::getFrustum(); if (mc->options->viewDistance < 2) { setupFog(-1, a); - levelRenderer->renderSky(a); - if (mc->skins->getSelected()->getId() == 1026) - levelRenderer->renderHaloRing(a); + { + FRAME_PROFILE_SCOPE(WeatherSky); + levelRenderer->renderSky(a); + if (mc->skins->getSelected()->getId() == 1026) + levelRenderer->renderHaloRing(a); + } } // 4jcraft: needs to be enabled for proper transparent texturing on low // render dists this was done in renderSky() for the far and normal @@ -1320,7 +1333,10 @@ void GameRenderer::renderLevel(float a, int64_t until) { MemSect(0); frustum->prepare(xOff, yOff, zOff); - mc->levelRenderer->cull(frustum, a); + { + FRAME_PROFILE_SCOPE(ChunkCull); + mc->levelRenderer->cull(frustum, a); + } PIXEndNamedEvent(); #ifndef MULTITHREAD_ENABLE @@ -1347,6 +1363,7 @@ void GameRenderer::renderLevel(float a, int64_t until) { #endif if (cameraEntity->y < Level::genDepth) { + FRAME_PROFILE_SCOPE(WeatherSky); prepareAndRenderClouds(levelRenderer, a); } Frustum::getFrustum(); // 4J added - re-calculate frustum as rendering @@ -1385,7 +1402,10 @@ void GameRenderer::renderLevel(float a, int64_t until) { cameraPos.x = cameraPosTemp.x; cameraPos.y = cameraPosTemp.y; cameraPos.z = cameraPosTemp.z; - levelRenderer->renderEntities(&cameraPos, frustum, a); + { + FRAME_PROFILE_SCOPE(Entity); + levelRenderer->renderEntities(&cameraPos, frustum, a); + } #ifdef __PSVITA__ // AP - make sure we're using the Alpha cut out effect for particles glEnable(GL_ALPHA_TEST); @@ -1393,12 +1413,18 @@ void GameRenderer::renderLevel(float a, int64_t until) { PIXEndNamedEvent(); PIXBeginNamedEvent(0, "Particle render"); turnOnLightLayer(a); // 4J - brought forward from 1.8.2 - particleEngine->renderLit(cameraEntity, a, - ParticleEngine::OPAQUE_LIST); + { + FRAME_PROFILE_SCOPE(Particle); + particleEngine->renderLit(cameraEntity, a, + ParticleEngine::OPAQUE_LIST); + } Lighting::turnOff(); setupFog(0, a); - particleEngine->render(cameraEntity, a, - ParticleEngine::OPAQUE_LIST); + { + FRAME_PROFILE_SCOPE(Particle); + particleEngine->render(cameraEntity, a, + ParticleEngine::OPAQUE_LIST); + } PIXEndNamedEvent(); turnOffLightLayer(a); // 4J - brought forward from 1.8.2 @@ -1467,12 +1493,18 @@ void GameRenderer::renderLevel(float a, int64_t until) { PIXBeginNamedEvent(0, "Particle render (translucent)"); Lighting::turnOn(); turnOnLightLayer(a); // 4J - brought forward from 1.8.2 - particleEngine->renderLit(cameraEntity, a, - ParticleEngine::TRANSLUCENT_LIST); + { + FRAME_PROFILE_SCOPE(Particle); + particleEngine->renderLit(cameraEntity, a, + ParticleEngine::TRANSLUCENT_LIST); + } Lighting::turnOff(); setupFog(0, a); - particleEngine->render(cameraEntity, a, - ParticleEngine::TRANSLUCENT_LIST); + { + FRAME_PROFILE_SCOPE(Particle); + particleEngine->render(cameraEntity, a, + ParticleEngine::TRANSLUCENT_LIST); + } PIXEndNamedEvent(); turnOffLightLayer(a); // 4J - brought forward from 1.8.2 ////////////////////////// End of 4J added section @@ -1503,12 +1535,16 @@ void GameRenderer::renderLevel(float a, int64_t until) { glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE); - levelRenderer->renderDestroyAnimation( - Tesselator::getInstance(), - std::dynamic_pointer_cast(cameraEntity), a); + { + FRAME_PROFILE_SCOPE(WeatherSky); + levelRenderer->renderDestroyAnimation( + Tesselator::getInstance(), + std::dynamic_pointer_cast(cameraEntity), a); + } glDisable(GL_BLEND); if (cameraEntity->y >= Level::genDepth) { + FRAME_PROFILE_SCOPE(WeatherSky); prepareAndRenderClouds(levelRenderer, a); } @@ -1517,7 +1553,10 @@ void GameRenderer::renderLevel(float a, int64_t until) { setupFog(0, a); glEnable(GL_FOG); PIXBeginNamedEvent(0, "Rendering snow and rain"); - renderSnowAndRain(a); + { + FRAME_PROFILE_SCOPE(WeatherSky); + renderSnowAndRain(a); + } PIXEndNamedEvent(); glDisable(GL_FOG); diff --git a/Minecraft.Client/Rendering/LevelRenderer.cpp b/Minecraft.Client/Rendering/LevelRenderer.cpp index 22ac311fb..3da404243 100644 --- a/Minecraft.Client/Rendering/LevelRenderer.cpp +++ b/Minecraft.Client/Rendering/LevelRenderer.cpp @@ -63,6 +63,7 @@ #include "../Level/MultiPlayerLevel.h" #include "../../Minecraft.World/Util/SoundTypes.h" #include "FrustumCuller.h" +#include "../Utils/FrameProfiler.h" // #define DISABLE_SPU_CODE @@ -736,6 +737,8 @@ void LevelRenderer::resortChunks(int xc, int yc, int zc) { int LevelRenderer::render(std::shared_ptr player, int layer, double alpha, bool updateChunks) { + FRAME_PROFILE_SCOPE(Terrain); + int playerIndex = mc->player->GetXboxPad(); // 4J - added - if the number of players has changed, we need to rebuild @@ -851,49 +854,55 @@ int LevelRenderer::renderChunks(int from, int to, int layer, double alpha) { if (sortList.capacity() < (size_t)chunks[playerIndex].length) { sortList.reserve(chunks[playerIndex].length); } - for (int i = 0; i < chunks[playerIndex].length; i++, pClipChunk++) { - if (!pClipChunk->visible) - continue; // This will be set if the chunk isn't visible, or isn't - // compiled, or has both empty flags set - if (pClipChunk->globalIdx == -1) - continue; // Not sure if we should ever encounter this... TODO - // check - if ((globalChunkFlags[pClipChunk->globalIdx] & emptyFlag) == emptyFlag) - continue; + { + FRAME_PROFILE_SCOPE(ChunkCollect); + for (int i = 0; i < chunks[playerIndex].length; i++, pClipChunk++) { + if (!pClipChunk->visible) + continue; // This will be set if the chunk isn't visible, or + // isn't compiled, or has both empty flags set + if (pClipChunk->globalIdx == -1) + continue; // Not sure if we should ever encounter this... + // TODO check + if ((globalChunkFlags[pClipChunk->globalIdx] & emptyFlag) == + emptyFlag) + continue; - sortList.push_back(pClipChunk); - } - // he sorts me till i - std::sort(sortList.begin(), sortList.end(), - [xOff, yOff, zOff, layer](ClipChunk* a, ClipChunk* b) { - float dxA = (float)((a->chunk->x + 8.0f) - xOff); - float dyA = (float)((a->chunk->y + 8.0f) - yOff); - float dzA = (float)((a->chunk->z + 8.0f) - zOff); - float distSqA = dxA * dxA + dyA * dyA + dzA * dzA; - - float dxB = (float)((b->chunk->x + 8.0f) - xOff); - float dyB = (float)((b->chunk->y + 8.0f) - yOff); - float dzB = (float)((b->chunk->z + 8.0f) - zOff); - float distSqB = dxB * dxB + dyB * dyB + dzB * dzB; - - if (layer == 0) - return distSqA < distSqB; // Opaque: Closest first - return distSqA > distSqB; // Transparent: Furthest first - }); - - for (ClipChunk* chunk : sortList) { - // ugly occluder - float dx = (chunk->chunk->x + 8.0f) - (float)xOff; - float dy = (chunk->chunk->y + 8.0f) - (float)yOff; - float dz = (chunk->chunk->z + 8.0f) - (float)zOff; - bool isVeryNear = (dx * dx + dy * dy + dz * dz) < (16.0f * 16.0f); - - if (!isVeryNear && layer == 0) { - // todo: occlusion flag + sortList.push_back(pClipChunk); } + // he sorts me till i + std::sort(sortList.begin(), sortList.end(), + [xOff, yOff, zOff, layer](ClipChunk* a, ClipChunk* b) { + float dxA = (float)((a->chunk->x + 8.0f) - xOff); + float dyA = (float)((a->chunk->y + 8.0f) - yOff); + float dzA = (float)((a->chunk->z + 8.0f) - zOff); + float distSqA = dxA * dxA + dyA * dyA + dzA * dzA; - int list = chunk->globalIdx * 2 + layer; - list += chunkLists; + float dxB = (float)((b->chunk->x + 8.0f) - xOff); + float dyB = (float)((b->chunk->y + 8.0f) - yOff); + float dzB = (float)((b->chunk->z + 8.0f) - zOff); + float distSqB = dxB * dxB + dyB * dyB + dzB * dzB; + + if (layer == 0) + return distSqA < distSqB; // Opaque: Closest first + return distSqA > distSqB; // Transparent: Furthest + // first + }); + } + { + FRAME_PROFILE_SCOPE(ChunkPlayback); + for (ClipChunk* chunk : sortList) { + // ugly occluder + float dx = (chunk->chunk->x + 8.0f) - (float)xOff; + float dy = (chunk->chunk->y + 8.0f) - (float)yOff; + float dz = (chunk->chunk->z + 8.0f) - (float)zOff; + bool isVeryNear = (dx * dx + dy * dy + dz * dz) < (16.0f * 16.0f); + + if (!isVeryNear && layer == 0) { + // todo: occlusion flag + } + + int list = chunk->globalIdx * 2 + layer; + list += chunkLists; // 4jcraft: replaced glPushMatrix/glTranslatef/glPopMatrix per chunk // no more full MVP upload per chunk, can also be bkwards compat @@ -901,12 +910,13 @@ int LevelRenderer::renderChunks(int from, int to, int layer, double alpha) { (float)chunk->chunk->y, (float)chunk->chunk->z); - if (RenderManager.CBuffCall(list, first)) { - first = false; + if (RenderManager.CBuffCall(list, first)) { + first = false; + } + count++; } - count++; + RenderManager.SetChunkOffset(0.f, 0.f, 0.f); } - RenderManager.SetChunkOffset(0.f, 0.f, 0.f); #ifdef __PSVITA__ // AP - alpha cut out is expensive on vita. Now we render all the alpha cut @@ -917,25 +927,29 @@ int LevelRenderer::renderChunks(int from, int to, int layer, double alpha) { first = true; pClipChunk = chunks[playerIndex].data; emptyFlag = LevelRenderer::CHUNK_FLAG_EMPTY0 << layer; - for (int i = 0; i < chunks[playerIndex].length; i++, pClipChunk++) { - if (!pClipChunk->visible) - continue; // This will be set if the chunk isn't visible, or isn't - // compiled, or has both empty flags set - if (pClipChunk->globalIdx == -1) - continue; // Not sure if we should ever encounter this... TODO - // check - if ((globalChunkFlags[pClipChunk->globalIdx] & emptyFlag) == emptyFlag) - continue; // Check that this particular layer isn't empty - if (!(globalChunkFlags[pClipChunk->globalIdx] & - LevelRenderer::CHUNK_FLAG_CUT_OUT)) - continue; // Does this chunk contain any cut out geometry + { + FRAME_PROFILE_SCOPE(ChunkPlayback); + for (int i = 0; i < chunks[playerIndex].length; i++, pClipChunk++) { + if (!pClipChunk->visible) + continue; // This will be set if the chunk isn't visible, or + // isn't compiled, or has both empty flags set + if (pClipChunk->globalIdx == -1) + continue; // Not sure if we should ever encounter this... TODO + // check + if ((globalChunkFlags[pClipChunk->globalIdx] & emptyFlag) == + emptyFlag) + continue; // Check that this particular layer isn't empty + if (!(globalChunkFlags[pClipChunk->globalIdx] & + LevelRenderer::CHUNK_FLAG_CUT_OUT)) + continue; // Does this chunk contain any cut out geometry - // List can be calculated directly from the chunk's global idex - int list = pClipChunk->globalIdx * 2 + layer; - list += chunkLists; + // List can be calculated directly from the chunk's global idex + int list = pClipChunk->globalIdx * 2 + layer; + list += chunkLists; - if (RenderManager.CBuffCallCutOut(list, first)) { - first = false; + if (RenderManager.CBuffCallCutOut(list, first)) { + first = false; + } } } RenderManager.StateSetForceLOD(-1); // AP - back to normal mipmapping @@ -1959,312 +1973,319 @@ bool LevelRenderer::updateDirtyChunks() { // Set a flag if we should only rebuild existing chunks, not create anything // new - unsigned int memAlloc = RenderManager.CBuffSize(-1); - /* - static int throttle = 0; - if( ( throttle % 100 ) == 0 ) { - app.DebugPrintf("CBuffSize: %d\n",memAlloc/(1024*1024)); - } - throttle++; - */ - PIXAddNamedCounter(((float)memAlloc) / (1024.0f * 1024.0f), - "Command buffer allocations"); - bool onlyRebuild = (memAlloc >= MAX_COMMANDBUFFER_ALLOCATIONS); - EnterCriticalSection(&m_csDirtyChunks); + FRAME_PROFILE_SCOPE(ChunkDirtyScan); - // Move any dirty chunks stored in the lock free stack into global flags - int index = 0; - - do { - // See comment on dirtyChunksLockFreeStack.Push() regarding details of - // this casting/subtracting -2. - index = (size_t)dirtyChunksLockFreeStack.Pop(); -#ifdef _CRITICAL_CHUNKS - int oldIndex = index; - index &= 0x0fffffff; // remove the top bit that marked the chunk as - // non-critical -#endif - if (index == 1) - dirtyChunkPresent = - true; // 1 is a special value passed to let this thread know - // that a chunk which isn't on this stack has been set to - // dirty - else if (index > 1) { - int i2 = index - 2; - if (i2 >= DIMENSION_OFFSETS[2]) { - i2 -= DIMENSION_OFFSETS[2]; - int y2 = i2 & (CHUNK_Y_COUNT - 1); - i2 /= CHUNK_Y_COUNT; - int z2 = i2 / MAX_LEVEL_RENDER_SIZE[2]; - int x2 = i2 - z2 * MAX_LEVEL_RENDER_SIZE[2]; - x2 -= MAX_LEVEL_RENDER_SIZE[2] / 2; - z2 -= MAX_LEVEL_RENDER_SIZE[2] / 2; - } - setGlobalChunkFlag(index - 2, CHUNK_FLAG_DIRTY); - -#ifdef _CRITICAL_CHUNKS - if (!(oldIndex & 0x10000000)) // was this chunk not marked as - // non-critical. Ugh double negatives - { - setGlobalChunkFlag(index - 2, CHUNK_FLAG_CRITICAL); - } -#endif - - dirtyChunkPresent = true; + unsigned int memAlloc = RenderManager.CBuffSize(-1); + /* + static int throttle = 0; + if( ( throttle % 100 ) == 0 ) + { + app.DebugPrintf("CBuffSize: %d\n",memAlloc/(1024*1024)); } - } while (index); + throttle++; + */ + PIXAddNamedCounter(((float)memAlloc) / (1024.0f * 1024.0f), + "Command buffer allocations"); + bool onlyRebuild = (memAlloc >= MAX_COMMANDBUFFER_ALLOCATIONS); + EnterCriticalSection(&m_csDirtyChunks); - // Only bother searching round all the chunks if we have some dirty chunk(s) - if (dirtyChunkPresent) { - lastDirtyChunkFound = System::currentTimeMillis(); - PIXBeginNamedEvent(0, "Finding nearest chunk\n"); + // Move any dirty chunks stored in the lock free stack into global flags + int index = 0; + + do { + // See comment on dirtyChunksLockFreeStack.Push() regarding details of + // this casting/subtracting -2. + index = (size_t)dirtyChunksLockFreeStack.Pop(); +#ifdef _CRITICAL_CHUNKS + int oldIndex = index; + index &= 0x0fffffff; // remove the top bit that marked the chunk as + // non-critical +#endif + if (index == 1) + dirtyChunkPresent = + true; // 1 is a special value passed to let this thread know + // that a chunk which isn't on this stack has been set to + // dirty + else if (index > 1) { + int i2 = index - 2; + if (i2 >= DIMENSION_OFFSETS[2]) { + i2 -= DIMENSION_OFFSETS[2]; + int y2 = i2 & (CHUNK_Y_COUNT - 1); + i2 /= CHUNK_Y_COUNT; + int z2 = i2 / MAX_LEVEL_RENDER_SIZE[2]; + int x2 = i2 - z2 * MAX_LEVEL_RENDER_SIZE[2]; + x2 -= MAX_LEVEL_RENDER_SIZE[2] / 2; + z2 -= MAX_LEVEL_RENDER_SIZE[2] / 2; + } + setGlobalChunkFlag(index - 2, CHUNK_FLAG_DIRTY); + +#ifdef _CRITICAL_CHUNKS + if (!(oldIndex & 0x10000000)) // was this chunk not marked as + // non-critical. Ugh double negatives + { + setGlobalChunkFlag(index - 2, CHUNK_FLAG_CRITICAL); + } +#endif + + dirtyChunkPresent = true; + } + } while (index); + + // Only bother searching round all the chunks if we have some dirty chunk(s) + if (dirtyChunkPresent) { + lastDirtyChunkFound = System::currentTimeMillis(); + PIXBeginNamedEvent(0, "Finding nearest chunk\n"); #if defined __PS3__ && !defined DISABLE_SPU_CODE - // find the nearest chunk with a spu task, copy all the data over here - // for uploading to SPU - g_findNearestChunkDataIn.numGlobalChunks = getGlobalChunkCount(); - g_findNearestChunkDataIn.pGlobalChunkFlags = globalChunkFlags; - g_findNearestChunkDataIn.onlyRebuild = onlyRebuild; - g_findNearestChunkDataIn.lowerOffset = - (int)&((LevelChunk*)0) - ->lowerBlocks; // dodgy bit of class structure poking, as we - // don't want to try and get the whole of - // LevelChunk copmpiling on SPU - g_findNearestChunkDataIn.upperOffset = - (int)&((LevelChunk*)0)->upperBlocks; - g_findNearestChunkDataIn.xChunks = xChunks; - g_findNearestChunkDataIn.yChunks = yChunks; - g_findNearestChunkDataIn.zChunks = zChunks; + // find the nearest chunk with a spu task, copy all the data over here + // for uploading to SPU + g_findNearestChunkDataIn.numGlobalChunks = getGlobalChunkCount(); + g_findNearestChunkDataIn.pGlobalChunkFlags = globalChunkFlags; + g_findNearestChunkDataIn.onlyRebuild = onlyRebuild; + g_findNearestChunkDataIn.lowerOffset = + (int)&((LevelChunk*)0) + ->lowerBlocks; // dodgy bit of class structure poking, as we + // don't want to try and get the whole of + // LevelChunk copmpiling on SPU + g_findNearestChunkDataIn.upperOffset = + (int)&((LevelChunk*)0)->upperBlocks; + g_findNearestChunkDataIn.xChunks = xChunks; + g_findNearestChunkDataIn.yChunks = yChunks; + g_findNearestChunkDataIn.zChunks = zChunks; - for (int i = 0; i < 4; i++) { - g_findNearestChunkDataIn.chunks[i] = - (LevelRenderer_FindNearestChunk_DataIn::ClipChunk*)chunks[i] - .data; - g_findNearestChunkDataIn.chunkLengths[i] = chunks[i].length; - g_findNearestChunkDataIn.level[i] = level[i]; - g_findNearestChunkDataIn.playerData[i].bValid = - mc->localplayers[i] != NULL; - if (mc->localplayers[i] != NULL) { - g_findNearestChunkDataIn.playerData[i].x = - mc->localplayers[i]->x; - g_findNearestChunkDataIn.playerData[i].y = - mc->localplayers[i]->y; - g_findNearestChunkDataIn.playerData[i].z = - mc->localplayers[i]->z; + for (int i = 0; i < 4; i++) { + g_findNearestChunkDataIn.chunks[i] = + (LevelRenderer_FindNearestChunk_DataIn::ClipChunk*)chunks[i] + .data; + g_findNearestChunkDataIn.chunkLengths[i] = chunks[i].length; + g_findNearestChunkDataIn.level[i] = level[i]; + g_findNearestChunkDataIn.playerData[i].bValid = + mc->localplayers[i] != NULL; + if (mc->localplayers[i] != NULL) { + g_findNearestChunkDataIn.playerData[i].x = + mc->localplayers[i]->x; + g_findNearestChunkDataIn.playerData[i].y = + mc->localplayers[i]->y; + g_findNearestChunkDataIn.playerData[i].z = + mc->localplayers[i]->z; + } + if (level[i] != NULL) { + g_findNearestChunkDataIn.multiplayerChunkCache[i].XZOFFSET = + ((MultiPlayerChunkCache*)(level[i]->chunkSource))->XZOFFSET; + g_findNearestChunkDataIn.multiplayerChunkCache[i].XZSIZE = + ((MultiPlayerChunkCache*)(level[i]->chunkSource))->XZSIZE; + g_findNearestChunkDataIn.multiplayerChunkCache[i].cache = + (void**)((MultiPlayerChunkCache*)(level[i]->chunkSource)) + ->cache; + } } - if (level[i] != NULL) { - g_findNearestChunkDataIn.multiplayerChunkCache[i].XZOFFSET = - ((MultiPlayerChunkCache*)(level[i]->chunkSource))->XZOFFSET; - g_findNearestChunkDataIn.multiplayerChunkCache[i].XZSIZE = - ((MultiPlayerChunkCache*)(level[i]->chunkSource))->XZSIZE; - g_findNearestChunkDataIn.multiplayerChunkCache[i].cache = - (void**)((MultiPlayerChunkCache*)(level[i]->chunkSource)) - ->cache; - } - } - // assert(sizeof(LevelRenderer_FindNearestChunk_DataIn::Chunk) - // == sizeof(Chunk)); - C4JSpursJob_LevelRenderer_FindNearestChunk findJob( - &g_findNearestChunkDataIn); - m_jobPort_FindNearestChunk->submitJob(&findJob); - m_jobPort_FindNearestChunk->waitForCompletion(); - nearChunk = (ClipChunk*)g_findNearestChunkDataIn.nearChunk; - veryNearCount = g_findNearestChunkDataIn.veryNearCount; + // assert(sizeof(LevelRenderer_FindNearestChunk_DataIn::Chunk) + // == sizeof(Chunk)); + C4JSpursJob_LevelRenderer_FindNearestChunk findJob( + &g_findNearestChunkDataIn); + m_jobPort_FindNearestChunk->submitJob(&findJob); + m_jobPort_FindNearestChunk->waitForCompletion(); + nearChunk = (ClipChunk*)g_findNearestChunkDataIn.nearChunk; + veryNearCount = g_findNearestChunkDataIn.veryNearCount; #else // __PS3__ #ifdef _LARGE_WORLDS - int maxNearestChunks = MAX_CONCURRENT_CHUNK_REBUILDS; - // 4J Stu - On XboxOne we should cut this down if in a constrained state - // so the saving threads get more time + int maxNearestChunks = MAX_CONCURRENT_CHUNK_REBUILDS; + // 4J Stu - On XboxOne we should cut this down if in a constrained state + // so the saving threads get more time #endif - // Find nearest chunk that is dirty - for (int p = 0; p < XUSER_MAX_COUNT; p++) { - // It's possible that the localplayers member can be set to NULL on - // the main thread when a player chooses to exit the game So take a - // reference to the player object now. As it is a shared_ptr it - // should live as long as we need it - std::shared_ptr player = mc->localplayers[p]; - if (player == NULL) continue; - if (chunks[p].data == NULL) continue; - if (level[p] == NULL) continue; - if (chunks[p].length != xChunks * zChunks * CHUNK_Y_COUNT) continue; - int px = (int)player->x; - int py = (int)player->y; - int pz = (int)player->z; + // Find nearest chunk that is dirty + for (int p = 0; p < XUSER_MAX_COUNT; p++) { + // It's possible that the localplayers member can be set to NULL on + // the main thread when a player chooses to exit the game So take a + // reference to the player object now. As it is a shared_ptr it + // should live as long as we need it + std::shared_ptr player = mc->localplayers[p]; + if (player == NULL) continue; + if (chunks[p].data == NULL) continue; + if (level[p] == NULL) continue; + if (chunks[p].length != xChunks * zChunks * CHUNK_Y_COUNT) continue; + int px = (int)player->x; + int py = (int)player->y; + int pz = (int)player->z; - // app.DebugPrintf("!! %d %d %d, %d %d %d {%d,%d} - //",px,py,pz,stackChunkDirty,nonStackChunkDirty,onlyRebuild, - // xChunks, zChunks); + // app.DebugPrintf("!! %d %d %d, %d %d %d {%d,%d} + //",px,py,pz,stackChunkDirty,nonStackChunkDirty,onlyRebuild, + // xChunks, zChunks); - int considered = 0; - int wouldBeNearButEmpty = 0; - for (int x = 0; x < xChunks; x++) { - for (int z = 0; z < zChunks; z++) { - for (int y = 0; y < CHUNK_Y_COUNT; y++) { - ClipChunk* pClipChunk = - &chunks[p][(z * yChunks + y) * xChunks + x]; - // Get distance to this chunk - deliberately not calling - // the chunk's method of doing this to avoid overheads - // (passing entitie, type conversion etc.) that this - // involves - int xd = pClipChunk->xm - px; - int yd = pClipChunk->ym - py; - int zd = pClipChunk->zm - pz; - int distSq = xd * xd + yd * yd + zd * zd; - int distSqWeighted = - xd * xd + yd * yd * 4 + - zd * - zd; // Weighting against y to prioritise things - // in same x/z plane as player first + int considered = 0; + int wouldBeNearButEmpty = 0; + for (int x = 0; x < xChunks; x++) { + for (int z = 0; z < zChunks; z++) { + for (int y = 0; y < CHUNK_Y_COUNT; y++) { + ClipChunk* pClipChunk = + &chunks[p][(z * yChunks + y) * xChunks + x]; + // Get distance to this chunk - deliberately not calling + // the chunk's method of doing this to avoid overheads + // (passing entitie, type conversion etc.) that this + // involves + int xd = pClipChunk->xm - px; + int yd = pClipChunk->ym - py; + int zd = pClipChunk->zm - pz; + int distSq = xd * xd + yd * yd + zd * zd; + int distSqWeighted = + xd * xd + yd * yd * 4 + + zd * + zd; // Weighting against y to prioritise things + // in same x/z plane as player first - if (globalChunkFlags[pClipChunk->globalIdx] & - CHUNK_FLAG_DIRTY) { - if ((!onlyRebuild) || - globalChunkFlags[pClipChunk->globalIdx] & - CHUNK_FLAG_COMPILED || - (distSq < - 20 * 20)) // Always rebuild really near things - // or else building (say) at tower - // up into empty blocks when we are - // low on memory will not create - // render data - { - considered++; - // Is this chunk nearer than our nearest? -#ifdef _LARGE_WORLDS - bool isNearer = nearestClipChunks.empty(); - AUTO_VAR(itNearest, nearestClipChunks.begin()); - for (; itNearest != nearestClipChunks.end(); - ++itNearest) { - isNearer = - distSqWeighted < itNearest->second; - if (isNearer) break; - } - isNearer = - isNearer || (nearestClipChunks.size() < - maxNearestChunks); -#else - bool isNearer = distSqWeighted < minDistSq; -#endif - -#ifdef _CRITICAL_CHUNKS - // AP - this will make sure that if a deferred - // grouping has started, only critical chunks go - // into that grouping, even if a non-critical - // chunk is closer. - if ((!veryNearCount && isNearer) || - (distSq < 20 * 20 && - (globalChunkFlags[pClipChunk->globalIdx] & - CHUNK_FLAG_CRITICAL))) -#else - if (isNearer) -#endif + if (globalChunkFlags[pClipChunk->globalIdx] & + CHUNK_FLAG_DIRTY) { + if ((!onlyRebuild) || + globalChunkFlags[pClipChunk->globalIdx] & + CHUNK_FLAG_COMPILED || + (distSq < + 20 * 20)) // Always rebuild really near things + // or else building (say) at tower + // up into empty blocks when we are + // low on memory will not create + // render data { - // At this point we've got a chunk that we - // would like to consider for rendering, at - // least based on its proximity to the - // player(s). Its *quite* quick to generate - // empty render data for render chunks, but - // if we let the rebuilding do that then the - // after rebuilding we will have to start - // searching for the next nearest chunk from - // scratch again. Instead, its better to - // detect empty chunks at this stage, flag - // them up as not dirty (and empty), and - // carry on. The levelchunk's - // isRenderChunkEmpty method can be quite - // optimal as it can make use of the chunk's - // data compression to detect emptiness - // without actually testing as many data - // items as uncompressed data would. - Chunk* chunk = pClipChunk->chunk; - LevelChunk* lc = level[p]->getChunkAt( - chunk->x, chunk->z); - if (!lc->isRenderChunkEmpty(y * 16)) { - nearChunk = pClipChunk; - minDistSq = distSqWeighted; + considered++; + // Is this chunk nearer than our nearest? #ifdef _LARGE_WORLDS - nearestClipChunks.insert( - itNearest, - std::pair( - nearChunk, minDistSq)); - if (nearestClipChunks.size() > - maxNearestChunks) { - nearestClipChunks.pop_back(); - } -#endif - } else { - chunk->clearDirty(); - globalChunkFlags[pClipChunk - ->globalIdx] |= - CHUNK_FLAG_EMPTYBOTH; - wouldBeNearButEmpty++; + bool isNearer = nearestClipChunks.empty(); + AUTO_VAR(itNearest, nearestClipChunks.begin()); + for (; itNearest != nearestClipChunks.end(); + ++itNearest) { + isNearer = + distSqWeighted < itNearest->second; + if (isNearer) break; } - } + isNearer = + isNearer || (nearestClipChunks.size() < + maxNearestChunks); +#else + bool isNearer = distSqWeighted < minDistSq; +#endif #ifdef _CRITICAL_CHUNKS - // AP - is the chunk near and also critical - if (distSq < 20 * 20 && - ((globalChunkFlags[pClipChunk->globalIdx] & - CHUNK_FLAG_CRITICAL))) + // AP - this will make sure that if a deferred + // grouping has started, only critical chunks go + // into that grouping, even if a non-critical + // chunk is closer. + if ((!veryNearCount && isNearer) || + (distSq < 20 * 20 && + (globalChunkFlags[pClipChunk->globalIdx] & + CHUNK_FLAG_CRITICAL))) #else - if (distSq < 20 * 20) + if (isNearer) #endif - { - veryNearCount++; + { + // At this point we've got a chunk that we + // would like to consider for rendering, at + // least based on its proximity to the + // player(s). Its *quite* quick to generate + // empty render data for render chunks, but + // if we let the rebuilding do that then the + // after rebuilding we will have to start + // searching for the next nearest chunk from + // scratch again. Instead, its better to + // detect empty chunks at this stage, flag + // them up as not dirty (and empty), and + // carry on. The levelchunk's + // isRenderChunkEmpty method can be quite + // optimal as it can make use of the chunk's + // data compression to detect emptiness + // without actually testing as many data + // items as uncompressed data would. + Chunk* chunk = pClipChunk->chunk; + LevelChunk* lc = level[p]->getChunkAt( + chunk->x, chunk->z); + if (!lc->isRenderChunkEmpty(y * 16)) { + nearChunk = pClipChunk; + minDistSq = distSqWeighted; +#ifdef _LARGE_WORLDS + nearestClipChunks.insert( + itNearest, + std::pair( + nearChunk, minDistSq)); + if (nearestClipChunks.size() > + maxNearestChunks) { + nearestClipChunks.pop_back(); + } +#endif + } else { + chunk->clearDirty(); + globalChunkFlags[pClipChunk + ->globalIdx] |= + CHUNK_FLAG_EMPTYBOTH; + wouldBeNearButEmpty++; + } + } + +#ifdef _CRITICAL_CHUNKS + // AP - is the chunk near and also critical + if (distSq < 20 * 20 && + ((globalChunkFlags[pClipChunk->globalIdx] & + CHUNK_FLAG_CRITICAL))) +#else + if (distSq < 20 * 20) +#endif + { + veryNearCount++; + } } } } } } + // app.DebugPrintf("[%d,%d,%d]\n",nearestClipChunks.empty(),considered,wouldBeNearButEmpty); } - // app.DebugPrintf("[%d,%d,%d]\n",nearestClipChunks.empty(),considered,wouldBeNearButEmpty); - } #endif // __PS3__ - PIXEndNamedEvent(); + PIXEndNamedEvent(); + } } Chunk* chunk = NULL; #ifdef _LARGE_WORLDS if (!nearestClipChunks.empty()) { int index = 0; - for (AUTO_VAR(it, nearestClipChunks.begin()); - it != nearestClipChunks.end(); ++it) { - chunk = it->first->chunk; - // If this chunk is very near, then move the renderer into a - // deferred mode. This won't commit any command buffers for - // rendering until we call CBuffDeferredModeEnd(), allowing us to - // group any near changes into an atomic unit. This is essential so - // we don't temporarily create any holes in the environment whilst - // updating one chunk and not the neighbours. The "ver near" aspect - // of this is just a cosmetic nicety - exactly the same thing would - // happen further away, but we just don't care about it so much from - // terms of visual impact. - if (veryNearCount > 0) { - RenderManager.CBuffDeferredModeStart(); + { + FRAME_PROFILE_SCOPE(ChunkRebuildSchedule); + for (AUTO_VAR(it, nearestClipChunks.begin()); + it != nearestClipChunks.end(); ++it) { + chunk = it->first->chunk; + // If this chunk is very near, then move the renderer into a + // deferred mode. This won't commit any command buffers for + // rendering until we call CBuffDeferredModeEnd(), allowing us to + // group any near changes into an atomic unit. This is essential so + // we don't temporarily create any holes in the environment whilst + // updating one chunk and not the neighbours. The "ver near" aspect + // of this is just a cosmetic nicety - exactly the same thing would + // happen further away, but we just don't care about it so much from + // terms of visual impact. + if (veryNearCount > 0) { + RenderManager.CBuffDeferredModeStart(); + } + // Build this chunk & return false to continue processing + chunk->clearDirty(); + // Take a copy of the details that are required for chunk + // rebuilding, and rebuild That instead of the original chunk data. + // This is done within the m_csDirtyChunks critical section, which + // means that any chunks can't be repositioned whilst we are doing + // this copy. The copy will then be guaranteed to be consistent + // whilst rebuilding takes place outside of that critical section. + permaChunk[index].makeCopyForRebuild(chunk); + ++index; } - // Build this chunk & return false to continue processing - chunk->clearDirty(); - // Take a copy of the details that are required for chunk - // rebuilding, and rebuild That instead of the original chunk data. - // This is done within the m_csDirtyChunks critical section, which - // means that any chunks can't be repositioned whilst we are doing - // this copy. The copy will then be guaranteed to be consistent - // whilst rebuilding takes place outside of that critical section. - permaChunk[index].makeCopyForRebuild(chunk); - ++index; - } - LeaveCriticalSection(&m_csDirtyChunks); + LeaveCriticalSection(&m_csDirtyChunks); - --index; // Bring it back into 0 counted range + --index; // Bring it back into 0 counted range - for (int i = MAX_CHUNK_REBUILD_THREADS - 1; i >= 0; --i) { - // Set the events that won't run - if ((i + 1) > index) - s_rebuildCompleteEvents->Set(i); - else - break; + for (int i = MAX_CHUNK_REBUILD_THREADS - 1; i >= 0; --i) { + // Set the events that won't run + if ((i + 1) > index) + s_rebuildCompleteEvents->Set(i); + else + break; + } } for (; index >= 0; --index) { @@ -2283,13 +2304,18 @@ bool LevelRenderer::updateDirtyChunks() { // app.DebugPrintf("Rebuilding permaChunk %d\n", index); - permaChunk[index].rebuild(); + { + FRAME_PROFILE_SCOPE(ChunkRebuildBody); + permaChunk[index].rebuild(); + } - if (index != 0) + if (index != 0) { + FRAME_PROFILE_SCOPE(ChunkRebuildSchedule); s_rebuildCompleteEvents->Set( index - 1); // MGH - this rebuild happening on the main // thread instead, mark the thread it // should have been running on as complete + } // int64_t endTime = System::currentTimeMillis(); // totalTime += (endTime - startTime); @@ -2300,44 +2326,54 @@ bool LevelRenderer::updateDirtyChunks() { // 4J Stu - Ignore this path when in constrained mode on Xbox One else { // Activate thread to rebuild this chunk + FRAME_PROFILE_SCOPE(ChunkRebuildSchedule); s_activationEventA[index - 1]->Set(); } } // Wait for the other threads to be done as well - s_rebuildCompleteEvents->WaitForAll(INFINITE); + { + FRAME_PROFILE_SCOPE(ChunkRebuildSchedule); + s_rebuildCompleteEvents->WaitForAll(INFINITE); + } } #else if (nearChunk) { chunk = nearChunk->chunk; PIXBeginNamedEvent(0, "Rebuilding near chunk %d %d %d", chunk->x, chunk->y, chunk->z); - // If this chunk is very near, then move the renderer into a deferred - // mode. This won't commit any command buffers for rendering until we - // call CBuffDeferredModeEnd(), allowing us to group any near changes - // into an atomic unit. This is essential so we don't temporarily create - // any holes in the environment whilst updating one chunk and not the - // neighbours. The "ver near" aspect of this is just a cosmetic nicety - - // exactly the same thing would happen further away, but we just don't - // care about it so much from terms of visual impact. - if (veryNearCount > 0) { - RenderManager.CBuffDeferredModeStart(); - } - // Build this chunk & return false to continue processing - chunk->clearDirty(); - // Take a copy of the details that are required for chunk rebuilding, - // and rebuild That instead of the original chunk data. This is done - // within the m_csDirtyChunks critical section, which means that any - // chunks can't be repositioned whilst we are doing this copy. The copy - // will then be guaranteed to be consistent whilst rebuilding takes - // place outside of that critical section. static Chunk permaChunk; - permaChunk.makeCopyForRebuild(chunk); - LeaveCriticalSection(&m_csDirtyChunks); + { + FRAME_PROFILE_SCOPE(ChunkRebuildSchedule); + // If this chunk is very near, then move the renderer into a deferred + // mode. This won't commit any command buffers for rendering until we + // call CBuffDeferredModeEnd(), allowing us to group any near changes + // into an atomic unit. This is essential so we don't temporarily create + // any holes in the environment whilst updating one chunk and not the + // neighbours. The "ver near" aspect of this is just a cosmetic nicety - + // exactly the same thing would happen further away, but we just don't + // care about it so much from terms of visual impact. + if (veryNearCount > 0) { + RenderManager.CBuffDeferredModeStart(); + } + // Build this chunk & return false to continue processing + chunk->clearDirty(); + // Take a copy of the details that are required for chunk rebuilding, + // and rebuild That instead of the original chunk data. This is done + // within the m_csDirtyChunks critical section, which means that any + // chunks can't be repositioned whilst we are doing this copy. The copy + // will then be guaranteed to be consistent whilst rebuilding takes + // place outside of that critical section. + permaChunk.makeCopyForRebuild(chunk); + LeaveCriticalSection(&m_csDirtyChunks); + } // static int64_t totalTime = 0; // static int64_t countTime = 0; // int64_t startTime = System::currentTimeMillis(); - permaChunk.rebuild(); + { + FRAME_PROFILE_SCOPE(ChunkRebuildBody); + permaChunk.rebuild(); + } // int64_t endTime = System::currentTimeMillis(); // totalTime += (endTime - startTime); // countTime++; @@ -4102,7 +4138,10 @@ int LevelRenderer::rebuildChunkThreadProc(void* lpParam) { s_activationEventA[index]->WaitForSignal(INFINITE); // app.DebugPrintf("Rebuilding permaChunk %d\n", index + 1); - permaChunk[index + 1].rebuild(); + { + FRAME_PROFILE_SCOPE(ChunkRebuildBody); + permaChunk[index + 1].rebuild(); + } // Inform the producer thread that we are done with this chunk s_rebuildCompleteEvents->Set(index); diff --git a/Minecraft.Client/Utils/FrameProfiler.cpp b/Minecraft.Client/Utils/FrameProfiler.cpp new file mode 100644 index 000000000..d27889c44 --- /dev/null +++ b/Minecraft.Client/Utils/FrameProfiler.cpp @@ -0,0 +1,260 @@ +#include "../Platform/stdafx.h" +#include "FrameProfiler.h" + +#ifdef ENABLE_FRAME_PROFILER + +#include +#include +#include +#include +#include +#include + +#if defined(_MSC_VER) +#define FRAME_PROFILER_NOINLINE __declspec(noinline) +#elif defined(__GNUC__) || defined(__clang__) +#define FRAME_PROFILER_NOINLINE __attribute__((noinline)) +#else +#define FRAME_PROFILER_NOINLINE +#endif + +namespace { + +using FrameProfilerClock = std::chrono::steady_clock; +using Bucket = FrameProfiler::Bucket; +constexpr std::uint64_t kNsPerMs = 1000ULL * 1000ULL; +constexpr std::uint64_t kReportIntervalNs = 1000ULL * 1000ULL * 1000ULL; +constexpr std::size_t kBucketCount = FrameProfiler::BucketCount(); +constexpr auto kFalseTokens = std::to_array({ + "0", "false", "False", "FALSE", "no", "No", "NO", "off", "Off", "OFF", +}); +constexpr std::array + kBucketDescriptors = {{ + {Bucket::Frame, "frame"}, + {Bucket::World, "world"}, + {Bucket::Terrain, "terrain"}, + {Bucket::ChunkCull, "chunkCull"}, + {Bucket::ChunkCollect, "chunkCollect"}, + {Bucket::ChunkPlayback, "chunkPlayback"}, + {Bucket::ChunkDirtyScan, "chunkDirtyScan"}, + {Bucket::ChunkRebuildSchedule, "chunkRebuildSchedule"}, + {Bucket::ChunkRebuildBody, "chunkRebuildBody"}, + {Bucket::Entity, "entities"}, + {Bucket::Particle, "particles"}, + {Bucket::WeatherSky, "weather"}, + {Bucket::UIHud, "ui"}, + {Bucket::Lightmap, "lightmap"}, + }}; + +struct BucketTotals { + std::uint64_t totalNs{}; + std::uint64_t maxNs{}; + std::uint64_t calls{}; + + void Record(std::uint64_t elapsedNs) noexcept { + totalNs += elapsedNs; + ++calls; + if (elapsedNs > maxNs) maxNs = elapsedNs; + } + + void Merge(const BucketTotals& other) noexcept { + totalNs += other.totalNs; + calls += other.calls; + if (other.maxNs > maxNs) maxNs = other.maxNs; + } +}; + +struct AtomicBucketTotals { + std::atomic totalNs{0}; + std::atomic maxNs{0}; + std::atomic calls{0}; +}; + +struct ProfilerState { + std::array workerBuckets{}; +}; + +struct ThreadState { + std::uint32_t frameScopeDepth{}; + std::uint64_t windowStartNs{}; + std::array localBuckets{}; +}; + +constinit ProfilerState g_profilerState{}; +constinit thread_local ThreadState t_threadState{}; + +static_assert(kBucketDescriptors.size() == kBucketCount); + +[[nodiscard]] inline std::uint64_t nowNs() noexcept { + return static_cast( + std::chrono::duration_cast( + FrameProfilerClock::now().time_since_epoch()) + .count()); +} + +[[nodiscard]] constexpr double nsToMs(std::uint64_t ns) noexcept { + return static_cast(ns) / static_cast(kNsPerMs); +} + +[[nodiscard]] constexpr bool envSaysDisabled( + std::string_view value) noexcept { + if (value.empty()) return false; + + for (std::string_view falseToken : kFalseTokens) { + if (value == falseToken) return true; + } + return false; +} + +inline void updateAtomicMax(std::atomic& value, + std::uint64_t candidate) noexcept { + std::uint64_t current = value.load(std::memory_order_relaxed); + while (current < candidate && + !value.compare_exchange_weak(current, candidate, + std::memory_order_relaxed, + std::memory_order_relaxed)) { + } +} + +inline void recordWorkerBucket(Bucket bucket, std::uint64_t elapsedNs) noexcept { + AtomicBucketTotals& state = + g_profilerState.workerBuckets[FrameProfiler::BucketIndex(bucket)]; + state.totalNs.fetch_add(elapsedNs, std::memory_order_relaxed); + state.calls.fetch_add(1, std::memory_order_relaxed); + updateAtomicMax(state.maxNs, elapsedNs); +} + +[[nodiscard]] inline bool isFrameThread() noexcept { + return t_threadState.frameScopeDepth != 0; +} + +FRAME_PROFILER_NOINLINE +[[nodiscard]] bool computeEnabled() noexcept { + const char* const envValue = std::getenv("C4J_FRAME_PROFILER"); + if (envValue == nullptr) return true; + return !envSaysDisabled(envValue); +} + +FRAME_PROFILER_NOINLINE void emitWindowReport( + const std::array& buckets) noexcept { + const std::uint64_t frames = + buckets[FrameProfiler::BucketIndex(Bucket::Frame)].calls; + if (frames == 0) return; + + std::fprintf(stderr, + "[frame-prof] avg/frame(ms) frames=%llu", + static_cast(frames)); + for (const auto& descriptor : kBucketDescriptors) { + const BucketTotals& bucket = + buckets[FrameProfiler::BucketIndex(descriptor.bucket)]; + const std::string_view label = descriptor.label; + std::fprintf(stderr, " %.*s=%.2f", static_cast(label.size()), + label.data(), nsToMs(bucket.totalNs) / frames); + } + std::fputc('\n', stderr); + + std::fputs("[frame-prof] max(ms)/calls", stderr); + for (const auto& descriptor : kBucketDescriptors) { + const BucketTotals& bucket = + buckets[FrameProfiler::BucketIndex(descriptor.bucket)]; + const std::string_view label = descriptor.label; + std::fprintf(stderr, " %.*s=%.2f/%llu", + static_cast(label.size()), label.data(), + nsToMs(bucket.maxNs), + static_cast(bucket.calls)); + } + std::fputc('\n', stderr); + std::fflush(stderr); +} + +[[nodiscard]] std::array snapshotAndResetWorkerBuckets() + noexcept { + std::array snapshot = {}; + for (std::size_t i = 0; i < kBucketCount; ++i) { + AtomicBucketTotals& workerBucket = g_profilerState.workerBuckets[i]; + snapshot[i].totalNs = + workerBucket.totalNs.exchange(0, std::memory_order_relaxed); + snapshot[i].maxNs = + workerBucket.maxNs.exchange(0, std::memory_order_relaxed); + snapshot[i].calls = + workerBucket.calls.exchange(0, std::memory_order_relaxed); + } + return snapshot; +} + +} // namespace + +bool FrameProfiler::IsEnabled() noexcept { + static const bool enabled = computeEnabled(); + return enabled; +} + +void FrameProfiler::Record(Bucket bucket, std::uint64_t elapsedNs) noexcept { + if (isFrameThread()) { + t_threadState.localBuckets[BucketIndex(bucket)].Record(elapsedNs); + return; + } + + recordWorkerBucket(bucket, elapsedNs); +} + +void FrameProfiler::EndFrame(std::uint64_t elapsedNs) noexcept { + Record(Bucket::Frame, elapsedNs); + + ThreadState& threadState = t_threadState; + const std::uint64_t now = nowNs(); + + if (threadState.windowStartNs == 0) { + threadState.windowStartNs = now; + return; + } + + if ((now - threadState.windowStartNs) < kReportIntervalNs) return; + + std::array combined = threadState.localBuckets; + const auto workerSnapshot = snapshotAndResetWorkerBuckets(); + + for (std::size_t i = 0; i < kBucketCount; ++i) { + combined[i].Merge(workerSnapshot[i]); + } + + emitWindowReport(combined); + + threadState.windowStartNs = now; + threadState.localBuckets = {}; +} + +FrameProfiler::Scope::Scope(Bucket bucket) noexcept + : m_startNs(0), m_bucket(bucket), m_enabled(FrameProfiler::IsEnabled()) { + if (m_enabled) m_startNs = nowNs(); +} + +FrameProfiler::Scope::~Scope() noexcept { + if (!m_enabled) return; + FrameProfiler::Record(m_bucket, nowNs() - m_startNs); +} + +FrameProfiler::FrameScope::FrameScope() noexcept + : m_startNs(0), m_enabled(false) { + if (!FrameProfiler::IsEnabled()) return; + + m_enabled = (t_threadState.frameScopeDepth++ == 0); + if (m_enabled) m_startNs = nowNs(); +} + +FrameProfiler::FrameScope::~FrameScope() noexcept { + if (!m_enabled) { + if (t_threadState.frameScopeDepth > 0) { + --t_threadState.frameScopeDepth; + } + return; + } + + FrameProfiler::EndFrame(nowNs() - m_startNs); + + if (t_threadState.frameScopeDepth > 0) { + --t_threadState.frameScopeDepth; + } +} + +#endif diff --git a/Minecraft.Client/Utils/FrameProfiler.h b/Minecraft.Client/Utils/FrameProfiler.h new file mode 100644 index 000000000..5fbb71b12 --- /dev/null +++ b/Minecraft.Client/Utils/FrameProfiler.h @@ -0,0 +1,93 @@ +#pragma once + +#ifdef ENABLE_FRAME_PROFILER + +#include +#include +#include + +class FrameProfiler { +public: + enum class Bucket : std::uint8_t { + Frame, + World, + Terrain, + ChunkCull, + ChunkCollect, + ChunkPlayback, + ChunkDirtyScan, + ChunkRebuildSchedule, + ChunkRebuildBody, + Entity, + Particle, + WeatherSky, + UIHud, + Lightmap, + Count, + }; + + struct BucketDescriptor { + Bucket bucket; + const char* label; + }; + + [[nodiscard]] static constexpr std::size_t BucketIndex( + Bucket bucket) noexcept { + return static_cast(std::to_underlying(bucket)); + } + + [[nodiscard]] static constexpr std::size_t BucketCount() noexcept { + return BucketIndex(Bucket::Count); + } + + [[nodiscard]] static bool IsEnabled() noexcept; + + class Scope { + public: + explicit Scope(Bucket bucket) noexcept; + Scope(const Scope&) = delete; + Scope& operator=(const Scope&) = delete; + Scope(Scope&&) = delete; + Scope& operator=(Scope&&) = delete; + ~Scope() noexcept; + + private: + std::uint64_t m_startNs; + Bucket m_bucket; + bool m_enabled; + }; + + class FrameScope { + public: + FrameScope() noexcept; + FrameScope(const FrameScope&) = delete; + FrameScope& operator=(const FrameScope&) = delete; + FrameScope(FrameScope&&) = delete; + FrameScope& operator=(FrameScope&&) = delete; + ~FrameScope() noexcept; + + private: + std::uint64_t m_startNs; + bool m_enabled; + }; + +private: + static void Record(Bucket bucket, std::uint64_t elapsedNs) noexcept; + static void EndFrame(std::uint64_t elapsedNs) noexcept; +}; + +#define FRAME_PROFILE_CONCAT_INNER(a, b) a##b +#define FRAME_PROFILE_CONCAT(a, b) FRAME_PROFILE_CONCAT_INNER(a, b) +#define FRAME_PROFILE_SCOPE(bucket_name) \ + FrameProfiler::Scope FRAME_PROFILE_CONCAT(frameProfileScope_, __LINE__)( \ + FrameProfiler::Bucket::bucket_name) +#define FRAME_PROFILE_FRAME_SCOPE() \ + FrameProfiler::FrameScope FRAME_PROFILE_CONCAT(frameProfileFrameScope_, \ + __LINE__) + +#else + +#define FRAME_PROFILE_SCOPE(bucket_name) ((void)0) +#define FRAME_PROFILE_FRAME_SCOPE() ((void)0) + +#endif diff --git a/Minecraft.Client/meson.build b/Minecraft.Client/meson.build index 39bc97d2a..abbb3b1ef 100644 --- a/Minecraft.Client/meson.build +++ b/Minecraft.Client/meson.build @@ -80,6 +80,10 @@ if get_option('classic_panorama') global_cpp_defs += '-DCLASSIC_PANORAMA' endif +if get_option('enable_frame_profiler') + global_cpp_defs += ['-DENABLE_FRAME_PROFILER'] +endif + if get_option('ui_backend') == 'shiggy' shiggy_dep = dependency( 'shiggy', @@ -127,4 +131,4 @@ custom_target( '@OUTPUT@', ], build_by_default: true, -) \ No newline at end of file +) diff --git a/meson.options b/meson.options index cdf6457be..0290c8005 100644 --- a/meson.options +++ b/meson.options @@ -24,4 +24,11 @@ option( type: 'boolean', value: true, description: 'Toggles V-Sync and adds options to unlock maximum in-game framerate.', -) \ No newline at end of file +) + +option( + 'enable_frame_profiler', + type: 'boolean', + value: false, + description: 'Enable the in-engine frame profiler for render hotspot discovery.', +) From a3f7f7d03cff7a8b10573e33f0de43cad79ea9e8 Mon Sep 17 00:00:00 2001 From: MatthewBeshay <92357869+MatthewBeshay@users.noreply.github.com> Date: Sun, 29 Mar 2026 15:52:55 +1100 Subject: [PATCH 152/170] perf(render): improve chunk scheduling and refine rebuild profiling --- Minecraft.Client/Rendering/Chunk.cpp | 176 +++++++++--------- .../EntityRenderers/TileRenderer.cpp | 27 ++- Minecraft.Client/Rendering/LevelRenderer.cpp | 80 ++++---- Minecraft.Client/Utils/FrameProfiler.cpp | 5 + Minecraft.Client/Utils/FrameProfiler.h | 5 + 5 files changed, 171 insertions(+), 122 deletions(-) diff --git a/Minecraft.Client/Rendering/Chunk.cpp b/Minecraft.Client/Rendering/Chunk.cpp index 4df99432b..7980f241e 100644 --- a/Minecraft.Client/Rendering/Chunk.cpp +++ b/Minecraft.Client/Rendering/Chunk.cpp @@ -7,6 +7,7 @@ #include "../../Minecraft.World/Headers/net.minecraft.world.level.tile.h" #include "../../Minecraft.World/Headers/net.minecraft.world.level.tile.entity.h" #include "LevelRenderer.h" +#include "../Utils/FrameProfiler.h" #ifdef __PS3__ #include "../Platform/PS3/SPU_Tasks/ChunkUpdate/ChunkRebuildData.h" @@ -252,94 +253,97 @@ void Chunk::rebuild() { // into this category. By far the largest category of these are tiles in // solid regions of rock. bool empty = true; - for (int yy = y0; yy < y1; yy++) { - for (int zz = 0; zz < 16; zz++) { - for (int xx = 0; xx < 16; xx++) { - // 4J Stu - tile data is ordered in 128 blocks of full width, - // lower 128 then upper 128 - int indexY = yy; - int offset = 0; - if (indexY >= Level::COMPRESSED_CHUNK_SECTION_HEIGHT) { - indexY -= Level::COMPRESSED_CHUNK_SECTION_HEIGHT; - offset = Level::COMPRESSED_CHUNK_SECTION_TILES; - } - - unsigned char tileId = - tileIds[offset + (((xx + 0) << 11) | ((zz + 0) << 7) | - (indexY + 0))]; - if (tileId > 0) empty = false; - - // Don't bother trying to work out neighbours for this tile if - // we are at the edge of the chunk - apart from the very bottom - // of the world where we shouldn't ever be able to see - if (yy == (Level::maxBuildHeight - 1)) continue; - if ((xx == 0) || (xx == 15)) continue; - if ((zz == 0) || (zz == 15)) continue; - - // Establish whether this tile and its neighbours are all made - // of rock, dirt, unbreakable tiles, or have already been - // determined to meet this criteria themselves and have a tile - // of 255 set. - if (!((tileId == Tile::stone_Id) || (tileId == Tile::dirt_Id) || - (tileId == Tile::unbreakable_Id) || (tileId == 255))) - continue; - tileId = tileIds[offset + (((xx - 1) << 11) | ((zz + 0) << 7) | - (indexY + 0))]; - if (!((tileId == Tile::stone_Id) || (tileId == Tile::dirt_Id) || - (tileId == Tile::unbreakable_Id) || (tileId == 255))) - continue; - tileId = tileIds[offset + (((xx + 1) << 11) | ((zz + 0) << 7) | - (indexY + 0))]; - if (!((tileId == Tile::stone_Id) || (tileId == Tile::dirt_Id) || - (tileId == Tile::unbreakable_Id) || (tileId == 255))) - continue; - tileId = tileIds[offset + (((xx + 0) << 11) | ((zz - 1) << 7) | - (indexY + 0))]; - if (!((tileId == Tile::stone_Id) || (tileId == Tile::dirt_Id) || - (tileId == Tile::unbreakable_Id) || (tileId == 255))) - continue; - tileId = tileIds[offset + (((xx + 0) << 11) | ((zz + 1) << 7) | - (indexY + 0))]; - if (!((tileId == Tile::stone_Id) || (tileId == Tile::dirt_Id) || - (tileId == Tile::unbreakable_Id) || (tileId == 255))) - continue; - // Treat the bottom of the world differently - we shouldn't ever - // be able to look up at this, so consider tiles as invisible if - // they are surrounded on sides other than the bottom - if (yy > 0) { - int indexYMinusOne = yy - 1; - int yMinusOneOffset = 0; - if (indexYMinusOne >= - Level::COMPRESSED_CHUNK_SECTION_HEIGHT) { - indexYMinusOne -= - Level::COMPRESSED_CHUNK_SECTION_HEIGHT; - yMinusOneOffset = Level::COMPRESSED_CHUNK_SECTION_TILES; + { + FRAME_PROFILE_SCOPE(ChunkPrepass); + for (int yy = y0; yy < y1; yy++) { + for (int zz = 0; zz < 16; zz++) { + for (int xx = 0; xx < 16; xx++) { + // 4J Stu - tile data is ordered in 128 blocks of full width, + // lower 128 then upper 128 + int indexY = yy; + int offset = 0; + if (indexY >= Level::COMPRESSED_CHUNK_SECTION_HEIGHT) { + indexY -= Level::COMPRESSED_CHUNK_SECTION_HEIGHT; + offset = Level::COMPRESSED_CHUNK_SECTION_TILES; } - tileId = tileIds[yMinusOneOffset + (((xx + 0) << 11) | - ((zz + 0) << 7) | - indexYMinusOne)]; - if (!((tileId == Tile::stone_Id) || - (tileId == Tile::dirt_Id) || + + unsigned char tileId = + tileIds[offset + (((xx + 0) << 11) | ((zz + 0) << 7) | + (indexY + 0))]; + if (tileId > 0) empty = false; + + // Don't bother trying to work out neighbours for this tile if + // we are at the edge of the chunk - apart from the very bottom + // of the world where we shouldn't ever be able to see + if (yy == (Level::maxBuildHeight - 1)) continue; + if ((xx == 0) || (xx == 15)) continue; + if ((zz == 0) || (zz == 15)) continue; + + // Establish whether this tile and its neighbours are all made + // of rock, dirt, unbreakable tiles, or have already been + // determined to meet this criteria themselves and have a tile + // of 255 set. + if (!((tileId == Tile::stone_Id) || (tileId == Tile::dirt_Id) || + (tileId == Tile::unbreakable_Id) || (tileId == 255))) + continue; + tileId = tileIds[offset + (((xx - 1) << 11) | ((zz + 0) << 7) | + (indexY + 0))]; + if (!((tileId == Tile::stone_Id) || (tileId == Tile::dirt_Id) || + (tileId == Tile::unbreakable_Id) || (tileId == 255))) + continue; + tileId = tileIds[offset + (((xx + 1) << 11) | ((zz + 0) << 7) | + (indexY + 0))]; + if (!((tileId == Tile::stone_Id) || (tileId == Tile::dirt_Id) || + (tileId == Tile::unbreakable_Id) || (tileId == 255))) + continue; + tileId = tileIds[offset + (((xx + 0) << 11) | ((zz - 1) << 7) | + (indexY + 0))]; + if (!((tileId == Tile::stone_Id) || (tileId == Tile::dirt_Id) || + (tileId == Tile::unbreakable_Id) || (tileId == 255))) + continue; + tileId = tileIds[offset + (((xx + 0) << 11) | ((zz + 1) << 7) | + (indexY + 0))]; + if (!((tileId == Tile::stone_Id) || (tileId == Tile::dirt_Id) || + (tileId == Tile::unbreakable_Id) || (tileId == 255))) + continue; + // Treat the bottom of the world differently - we shouldn't ever + // be able to look up at this, so consider tiles as invisible if + // they are surrounded on sides other than the bottom + if (yy > 0) { + int indexYMinusOne = yy - 1; + int yMinusOneOffset = 0; + if (indexYMinusOne >= + Level::COMPRESSED_CHUNK_SECTION_HEIGHT) { + indexYMinusOne -= + Level::COMPRESSED_CHUNK_SECTION_HEIGHT; + yMinusOneOffset = Level::COMPRESSED_CHUNK_SECTION_TILES; + } + tileId = tileIds[yMinusOneOffset + (((xx + 0) << 11) | + ((zz + 0) << 7) | + indexYMinusOne)]; + if (!((tileId == Tile::stone_Id) || + (tileId == Tile::dirt_Id) || + (tileId == Tile::unbreakable_Id) || (tileId == 255))) + continue; + } + int indexYPlusOne = yy + 1; + int yPlusOneOffset = 0; + if (indexYPlusOne >= Level::COMPRESSED_CHUNK_SECTION_HEIGHT) { + indexYPlusOne -= Level::COMPRESSED_CHUNK_SECTION_HEIGHT; + yPlusOneOffset = Level::COMPRESSED_CHUNK_SECTION_TILES; + } + tileId = + tileIds[yPlusOneOffset + (((xx + 0) << 11) | + ((zz + 0) << 7) | indexYPlusOne)]; + if (!((tileId == Tile::stone_Id) || (tileId == Tile::dirt_Id) || (tileId == Tile::unbreakable_Id) || (tileId == 255))) continue; - } - int indexYPlusOne = yy + 1; - int yPlusOneOffset = 0; - if (indexYPlusOne >= Level::COMPRESSED_CHUNK_SECTION_HEIGHT) { - indexYPlusOne -= Level::COMPRESSED_CHUNK_SECTION_HEIGHT; - yPlusOneOffset = Level::COMPRESSED_CHUNK_SECTION_TILES; - } - tileId = - tileIds[yPlusOneOffset + (((xx + 0) << 11) | - ((zz + 0) << 7) | indexYPlusOne)]; - if (!((tileId == Tile::stone_Id) || (tileId == Tile::dirt_Id) || - (tileId == Tile::unbreakable_Id) || (tileId == 255))) - continue; - // This tile is surrounded. Flag it as not requiring to be - // rendered by setting its id to 255. - tileIds[offset + (((xx + 0) << 11) | ((zz + 0) << 7) | - (indexY + 0))] = 0xff; + // This tile is surrounded. Flag it as not requiring to be + // rendered by setting its id to 255. + tileIds[offset + (((xx + 0) << 11) | ((zz + 0) << 7) | + (indexY + 0))] = 0xff; + } } } } @@ -752,7 +756,7 @@ void Chunk::rebuild_SPU() { if (currentLayer == 0 && Tile::tiles[tileId]->isEntityTile()) { std::shared_ptr et = - region.getTileEntity(x, y, z); + region->getTileEntity(x, y, z); if (TileEntityRenderDispatcher::instance ->hasRenderer(et)) { renderableTileEntities.push_back(et); @@ -770,7 +774,7 @@ void Chunk::rebuild_SPU() { } else if (renderLayer == currentLayer) { // if(currentLayer == 0) // numRenderedLayer0++; - rendered |= tileRenderer.tesselateInWorld( + rendered |= tileRenderer->tesselateInWorld( tile, x, y, z); } } diff --git a/Minecraft.Client/Rendering/EntityRenderers/TileRenderer.cpp b/Minecraft.Client/Rendering/EntityRenderers/TileRenderer.cpp index 3ee4ff71a..f1f91018c 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/TileRenderer.cpp +++ b/Minecraft.Client/Rendering/EntityRenderers/TileRenderer.cpp @@ -11,6 +11,7 @@ #include "../../../Minecraft.World/Headers/net.minecraft.h" #include "../../../Minecraft.World/Headers/net.minecraft.world.h" #include "../Tesselator.h" +#include "../../Utils/FrameProfiler.h" #include "EntityTileRenderer.h" #include "../../GameState/Options.h" @@ -267,7 +268,12 @@ bool TileRenderer::tesselateInWorld( { Tesselator* t = Tesselator::getInstance(); int shape = tt->getRenderShape(); - tt->updateShape(level, x, y, z, forceData, forceEntity); + if (shape == Tile::SHAPE_BLOCK) { + FRAME_PROFILE_SCOPE(ChunkBlockShape); + tt->updateShape(level, x, y, z, forceData, forceEntity); + } else { + tt->updateShape(level, x, y, z, forceData, forceEntity); + } // AP - now that the culling is done earlier we don't need to call setShape // until later on (only for SHAPE_BLOCK) if (shape != Tile::SHAPE_BLOCK) { @@ -278,6 +284,11 @@ bool TileRenderer::tesselateInWorld( bool retVal = false; switch (shape) { case Tile::SHAPE_BLOCK: { + { + FRAME_PROFILE_SCOPE(ChunkBlockShape); + setShape(tt); + } + // 4J - added these faceFlags so we can detect whether this block is // going to have no visible faces and early out the original code // checked noCulling and shouldRenderFace directly where faceFlags @@ -290,6 +301,7 @@ bool TileRenderer::tesselateInWorld( if (noCulling) { faceFlags = 0x3f; } else { + FRAME_PROFILE_SCOPE(ChunkBlockFaceCull); // these block types can take advantage of a faster version of // shouldRenderFace there are others but this is an easy check // which covers the majority Note: This now covers rock, grass, @@ -319,9 +331,6 @@ bool TileRenderer::tesselateInWorld( break; } - // now we need to set the shape - setShape(tt); - retVal = tesselateBlockInWorld(tt, x, y, z, faceFlags); } break; case Tile::SHAPE_TREE: @@ -4828,9 +4837,11 @@ bool TileRenderer::tesselateBlockInWorld(Tile* tt, int x, int y, int z) { if (Tile::lightEmission[tt->id] == 0) // 4J - TODO/remove (Minecraft::useAmbientOcclusion()) { + FRAME_PROFILE_SCOPE(ChunkBlockLighting); return tesselateBlockInWorldWithAmbienceOcclusionTexLighting( tt, x, y, z, r, g, b, 0, smoothShapeLighting); } else { + FRAME_PROFILE_SCOPE(ChunkBlockLighting); return tesselateBlockInWorld(tt, x, y, z, r, g, b); } } @@ -4856,9 +4867,11 @@ bool TileRenderer::tesselateBlockInWorld(Tile* tt, int x, int y, int z, if (Tile::lightEmission[tt->id] == 0) // 4J - TODO/remove (Minecraft::useAmbientOcclusion()) { + FRAME_PROFILE_SCOPE(ChunkBlockLighting); return tesselateBlockInWorldWithAmbienceOcclusionTexLighting( tt, x, y, z, r, g, b, faceFlags, smoothShapeLighting); } else { + FRAME_PROFILE_SCOPE(ChunkBlockLighting); return tesselateBlockInWorld(tt, x, y, z, r, g, b); } } @@ -7049,6 +7062,7 @@ bool TileRenderer::tesselateDoorInWorld(Tile* tt, int x, int y, int z) { void TileRenderer::renderFaceDown(Tile* tt, double x, double y, double z, Icon* tex) { + FRAME_PROFILE_SCOPE(ChunkBlockEmit); Tesselator* t = Tesselator::getInstance(); if (hasFixedTexture()) tex = fixedTexture; @@ -7167,6 +7181,7 @@ void TileRenderer::renderFaceDown(Tile* tt, double x, double y, double z, void TileRenderer::renderFaceUp(Tile* tt, double x, double y, double z, Icon* tex) { + FRAME_PROFILE_SCOPE(ChunkBlockEmit); Tesselator* t = Tesselator::getInstance(); if (hasFixedTexture()) tex = fixedTexture; @@ -7286,6 +7301,7 @@ void TileRenderer::renderFaceUp(Tile* tt, double x, double y, double z, void TileRenderer::renderNorth(Tile* tt, double x, double y, double z, Icon* tex) { + FRAME_PROFILE_SCOPE(ChunkBlockEmit); Tesselator* t = Tesselator::getInstance(); if (hasFixedTexture()) tex = fixedTexture; @@ -7410,6 +7426,7 @@ void TileRenderer::renderNorth(Tile* tt, double x, double y, double z, void TileRenderer::renderSouth(Tile* tt, double x, double y, double z, Icon* tex) { + FRAME_PROFILE_SCOPE(ChunkBlockEmit); Tesselator* t = Tesselator::getInstance(); if (hasFixedTexture()) tex = fixedTexture; @@ -7534,6 +7551,7 @@ void TileRenderer::renderSouth(Tile* tt, double x, double y, double z, void TileRenderer::renderWest(Tile* tt, double x, double y, double z, Icon* tex) { + FRAME_PROFILE_SCOPE(ChunkBlockEmit); Tesselator* t = Tesselator::getInstance(); if (hasFixedTexture()) tex = fixedTexture; @@ -7658,6 +7676,7 @@ void TileRenderer::renderWest(Tile* tt, double x, double y, double z, void TileRenderer::renderEast(Tile* tt, double x, double y, double z, Icon* tex) { + FRAME_PROFILE_SCOPE(ChunkBlockEmit); Tesselator* t = Tesselator::getInstance(); if (hasFixedTexture()) tex = fixedTexture; diff --git a/Minecraft.Client/Rendering/LevelRenderer.cpp b/Minecraft.Client/Rendering/LevelRenderer.cpp index 3da404243..177b8e021 100644 --- a/Minecraft.Client/Rendering/LevelRenderer.cpp +++ b/Minecraft.Client/Rendering/LevelRenderer.cpp @@ -1,5 +1,6 @@ #include #include +#include #include "../Platform/stdafx.h" #include "LevelRenderer.h" @@ -904,11 +905,12 @@ int LevelRenderer::renderChunks(int from, int to, int layer, double alpha) { int list = chunk->globalIdx * 2 + layer; list += chunkLists; - // 4jcraft: replaced glPushMatrix/glTranslatef/glPopMatrix per chunk - // no more full MVP upload per chunk, can also be bkwards compat - RenderManager.SetChunkOffset((float)chunk->chunk->x, - (float)chunk->chunk->y, - (float)chunk->chunk->z); + // 4jcraft: replaced glPushMatrix/glTranslatef/glPopMatrix per + // chunk no more full MVP upload per chunk, can also be bkwards + // compat + RenderManager.SetChunkOffset((float)chunk->chunk->x, + (float)chunk->chunk->y, + (float)chunk->chunk->z); if (RenderManager.CBuffCall(list, first)) { first = false; @@ -1964,7 +1966,41 @@ void LevelRenderer::renderAdvancedClouds(float alpha) { bool LevelRenderer::updateDirtyChunks() { #ifdef _LARGE_WORLDS - std::list > nearestClipChunks; + struct NearestClipChunkSet { + std::array, MAX_CONCURRENT_CHUNK_REBUILDS> + items; + int count = 0; + + bool empty() const noexcept { return count == 0; } + int size() const noexcept { return count; } + + bool wouldAccept(int distSqWeighted) const noexcept { + return (count < MAX_CONCURRENT_CHUNK_REBUILDS) || + (distSqWeighted < items[count - 1].second); + } + + void insert(ClipChunk* chunk, int distSqWeighted) noexcept { + int pos = 0; + while ((pos < count) && (items[pos].second <= distSqWeighted)) { + ++pos; + } + + if ((count == MAX_CONCURRENT_CHUNK_REBUILDS) && + (pos >= MAX_CONCURRENT_CHUNK_REBUILDS)) { + return; + } + + const int newCount = + (count < MAX_CONCURRENT_CHUNK_REBUILDS) + ? (count + 1) + : MAX_CONCURRENT_CHUNK_REBUILDS; + for (int i = newCount - 1; i > pos; --i) { + items[i] = items[i - 1]; + } + items[pos] = std::pair(chunk, distSqWeighted); + count = newCount; + } + } nearestClipChunks; #endif ClipChunk* nearChunk = NULL; // Nearest chunk that is dirty @@ -2090,11 +2126,6 @@ bool LevelRenderer::updateDirtyChunks() { veryNearCount = g_findNearestChunkDataIn.veryNearCount; #else // __PS3__ -#ifdef _LARGE_WORLDS - int maxNearestChunks = MAX_CONCURRENT_CHUNK_REBUILDS; - // 4J Stu - On XboxOne we should cut this down if in a constrained state - // so the saving threads get more time -#endif // Find nearest chunk that is dirty for (int p = 0; p < XUSER_MAX_COUNT; p++) { // It's possible that the localplayers member can be set to NULL on @@ -2150,17 +2181,9 @@ bool LevelRenderer::updateDirtyChunks() { considered++; // Is this chunk nearer than our nearest? #ifdef _LARGE_WORLDS - bool isNearer = nearestClipChunks.empty(); - AUTO_VAR(itNearest, nearestClipChunks.begin()); - for (; itNearest != nearestClipChunks.end(); - ++itNearest) { - isNearer = - distSqWeighted < itNearest->second; - if (isNearer) break; - } - isNearer = - isNearer || (nearestClipChunks.size() < - maxNearestChunks); + bool isNearer = + nearestClipChunks.wouldAccept( + distSqWeighted); #else bool isNearer = distSqWeighted < minDistSq; #endif @@ -2203,13 +2226,7 @@ bool LevelRenderer::updateDirtyChunks() { minDistSq = distSqWeighted; #ifdef _LARGE_WORLDS nearestClipChunks.insert( - itNearest, - std::pair( - nearChunk, minDistSq)); - if (nearestClipChunks.size() > - maxNearestChunks) { - nearestClipChunks.pop_back(); - } + nearChunk, minDistSq); #endif } else { chunk->clearDirty(); @@ -2249,9 +2266,8 @@ bool LevelRenderer::updateDirtyChunks() { int index = 0; { FRAME_PROFILE_SCOPE(ChunkRebuildSchedule); - for (AUTO_VAR(it, nearestClipChunks.begin()); - it != nearestClipChunks.end(); ++it) { - chunk = it->first->chunk; + for (int i = 0; i < nearestClipChunks.size(); ++i) { + chunk = nearestClipChunks.items[i].first->chunk; // If this chunk is very near, then move the renderer into a // deferred mode. This won't commit any command buffers for // rendering until we call CBuffDeferredModeEnd(), allowing us to diff --git a/Minecraft.Client/Utils/FrameProfiler.cpp b/Minecraft.Client/Utils/FrameProfiler.cpp index d27889c44..89db484eb 100644 --- a/Minecraft.Client/Utils/FrameProfiler.cpp +++ b/Minecraft.Client/Utils/FrameProfiler.cpp @@ -39,6 +39,11 @@ constexpr std::array {Bucket::ChunkDirtyScan, "chunkDirtyScan"}, {Bucket::ChunkRebuildSchedule, "chunkRebuildSchedule"}, {Bucket::ChunkRebuildBody, "chunkRebuildBody"}, + {Bucket::ChunkPrepass, "chunkPrepass"}, + {Bucket::ChunkBlockShape, "chunkBlockShape"}, + {Bucket::ChunkBlockFaceCull, "chunkBlockFaceCull"}, + {Bucket::ChunkBlockLighting, "chunkBlockLighting"}, + {Bucket::ChunkBlockEmit, "chunkBlockEmit"}, {Bucket::Entity, "entities"}, {Bucket::Particle, "particles"}, {Bucket::WeatherSky, "weather"}, diff --git a/Minecraft.Client/Utils/FrameProfiler.h b/Minecraft.Client/Utils/FrameProfiler.h index 5fbb71b12..7abf56255 100644 --- a/Minecraft.Client/Utils/FrameProfiler.h +++ b/Minecraft.Client/Utils/FrameProfiler.h @@ -18,6 +18,11 @@ public: ChunkDirtyScan, ChunkRebuildSchedule, ChunkRebuildBody, + ChunkPrepass, + ChunkBlockShape, + ChunkBlockFaceCull, + ChunkBlockLighting, + ChunkBlockEmit, Entity, Particle, WeatherSky, From abba4b57ce7a341e0ca43c1920e3612a74171d51 Mon Sep 17 00:00:00 2001 From: JuiceyDev Date: Mon, 30 Mar 2026 00:24:23 +0200 Subject: [PATCH 153/170] Fixed broken LevelRenderer.cpp and removed merge garbage --- Minecraft.Client/Rendering/Chunk.cpp | 154 ++++- Minecraft.Client/Rendering/Chunk.h | 2 +- Minecraft.Client/Rendering/LevelRenderer.cpp | 608 +++++++++++++------ Minecraft.Client/Rendering/LevelRenderer.h | 5 +- Minecraft.Client/meson.build | 21 +- meson.options | 9 + 6 files changed, 609 insertions(+), 190 deletions(-) diff --git a/Minecraft.Client/Rendering/Chunk.cpp b/Minecraft.Client/Rendering/Chunk.cpp index 7980f241e..ff0550717 100644 --- a/Minecraft.Client/Rendering/Chunk.cpp +++ b/Minecraft.Client/Rendering/Chunk.cpp @@ -73,6 +73,7 @@ void Chunk::setPos(int x, int y, int z) { clipChunk->globalIdx = LevelRenderer::getGlobalIndexForChunk(x, y, z, level); + levelRenderer->setGlobalChunkConnectivity(clipChunk->globalIdx, ~0ULL); #if 1 // 4J - we're not using offsetted renderlists anymore, so just set the full @@ -358,6 +359,12 @@ void Chunk::rebuild() { RenderManager.CBuffClear(lists + currentLayer); } + int globalIdx = levelRenderer->getGlobalIndexForChunk(this->x, this->y, + this->z, level); + levelRenderer->setGlobalChunkConnectivity(globalIdx, ~0ULL); + levelRenderer->setGlobalChunkFlag(this->x, this->y, this->z, level, + LevelRenderer::CHUNK_FLAG_COMPILED); + delete region; delete tileRenderer; return; @@ -495,6 +502,11 @@ void Chunk::rebuild() { bb = {bounds.boundingBox[0], bounds.boundingBox[1], bounds.boundingBox[2], bounds.boundingBox[3], bounds.boundingBox[4], bounds.boundingBox[5]}; + uint64_t conn = computeConnectivity(tileIds); // pass tileIds + int globalIdx = + levelRenderer->getGlobalIndexForChunk(this->x, this->y, this->z, level); + levelRenderer->setGlobalChunkConnectivity(globalIdx, conn); + delete tileRenderer; delete region; @@ -958,6 +970,142 @@ float Chunk::squishedDistanceToSqr(std::shared_ptr player) { return xd * xd + yd * yd + zd * zd; } +uint64_t Chunk::computeConnectivity(const uint8_t* tileIds) { + const int W = 16; + const int H = 16; + const int VOLUME = W * H * W; + + auto idx = [&](int x, int y, int z) -> int { + return y * W * W + z * W + x; + }; + + auto isOpen = [&](int lx, int ly, int lz) -> bool { + int worldY = this->y + ly; + int offset = 0; + int indexY = worldY; + if (indexY >= Level::COMPRESSED_CHUNK_SECTION_HEIGHT) { + indexY -= Level::COMPRESSED_CHUNK_SECTION_HEIGHT; + offset = Level::COMPRESSED_CHUNK_SECTION_TILES; + } + + uint8_t tileId = tileIds[offset + ((lx << 11) | (lz << 7) | indexY)]; + + if (tileId == 0) return true; // air + if (tileId == 0xFF) return false; // hidden tile (yeah) + + Tile* t = Tile::tiles[tileId]; + return (t == nullptr) || !t->isSolidRender(); + }; + + uint8_t visited[6][512]; + memset(visited, 0, sizeof(visited)); + + static const int FX[6] = {1, -1, 0, 0, 0, 0}; + static const int FY[6] = {0, 0, 1, -1, 0, 0}; + static const int FZ[6] = {0, 0, 0, 0, 1, -1}; + + struct Cell { + int8_t x, y, z; + }; + static thread_local std::vector queue; + + uint64_t result = 0; + + for (int entryFace = 0; entryFace < 6; entryFace++) { + uint8_t* vis = visited[entryFace]; + queue.clear(); + int x0s, x1s, y0s, y1s, z0s, z1s; + switch (entryFace) { + case 0: + x0s = W - 1; + x1s = W - 1; + y0s = 0; + y1s = H - 1; + z0s = 0; + z1s = W - 1; + break; // +X + case 1: + x0s = 0; + x1s = 0; + y0s = 0; + y1s = H - 1; + z0s = 0; + z1s = W - 1; + break; // -X + case 2: + x0s = 0; + x1s = W - 1; + y0s = H - 1; + y1s = H - 1; + z0s = 0; + z1s = W - 1; + break; // +Y + case 3: + x0s = 0; + x1s = W - 1; + y0s = 0; + y1s = 0; + z0s = 0; + z1s = W - 1; + break; // -Y + case 4: + x0s = 0; + x1s = W - 1; + y0s = 0; + y1s = H - 1; + z0s = W - 1; + z1s = W - 1; + break; // +Z + case 5: + x0s = 0; + x1s = W - 1; + y0s = 0; + y1s = H - 1; + z0s = 0; + z1s = 0; + break; // -Z + default: + continue; + } + + for (int sy = y0s; sy <= y1s; sy++) + for (int sz = z0s; sz <= z1s; sz++) + for (int sx = x0s; sx <= x1s; sx++) { + if (!isOpen(sx, sy, sz)) continue; + int i = idx(sx, sy, sz); + if (vis[i >> 3] & (1 << (i & 7))) continue; + vis[i >> 3] |= (1 << (i & 7)); + queue.push_back({(int8_t)sx, (int8_t)sy, (int8_t)sz}); + } + + for (int qi = 0; qi < (int)queue.size(); qi++) { + Cell cur = queue[qi]; + + for (int nb = 0; nb < 6; nb++) { + int nx = cur.x + FX[nb]; + int ny = cur.y + FY[nb]; + int nz = cur.z + FZ[nb]; + + // entry exit conn + if (nx < 0 || nx >= W || ny < 0 || ny >= H || nz < 0 || + nz >= W) { + // nb IS the exit face because FX,FY,FZ are aligned + result |= ((uint64_t)1 << (entryFace * 6 + nb)); + continue; + } + + if (!isOpen(nx, ny, nz)) continue; + + int i = idx(nx, ny, nz); + if (vis[i >> 3] & (1 << (i & 7))) continue; + vis[i >> 3] |= (1 << (i & 7)); + queue.push_back({(int8_t)nx, (int8_t)ny, (int8_t)nz}); + } + } + } + + return result; +} void Chunk::reset() { if (assigned) { EnterCriticalSection(&levelRenderer->m_csDirtyChunks); @@ -1002,7 +1150,11 @@ int Chunk::getList(int layer) { return -1; } -void Chunk::cull(Culler* culler) { clipChunk->visible = culler->isVisible(&bb); } +void Chunk::cull(Culler* culler) { + if (clipChunk->visible) { + clipChunk->visible = culler->isVisible(&bb); + } +} void Chunk::renderBB() { // glCallList(lists + 2); // 4J - removed - TODO put back in diff --git a/Minecraft.Client/Rendering/Chunk.h b/Minecraft.Client/Rendering/Chunk.h index e6d214ab2..c524c69ce 100644 --- a/Minecraft.Client/Rendering/Chunk.h +++ b/Minecraft.Client/Rendering/Chunk.h @@ -48,7 +48,7 @@ public: int xm, ym, zm; AABB bb; ClipChunk* clipChunk; - + uint64_t computeConnectivity(const uint8_t* tileIds); int id; // public: // std::vector > renderableTileEntities; diff --git a/Minecraft.Client/Rendering/LevelRenderer.cpp b/Minecraft.Client/Rendering/LevelRenderer.cpp index 177b8e021..b73ee025c 100644 --- a/Minecraft.Client/Rendering/LevelRenderer.cpp +++ b/Minecraft.Client/Rendering/LevelRenderer.cpp @@ -91,6 +91,9 @@ ResourceLocation LevelRenderer::END_SKY_LOCATION = const unsigned int HALO_RING_RADIUS = 100; +uint64_t* LevelRenderer::globalChunkConnectivity = + nullptr; // bad placement do bettr juicey + #ifdef _LARGE_WORLDS Chunk LevelRenderer::permaChunk[MAX_CONCURRENT_CHUNK_REBUILDS]; C4JThread* LevelRenderer::rebuildThreads[MAX_CHUNK_REBUILD_THREADS]; @@ -189,6 +192,10 @@ LevelRenderer::LevelRenderer(Minecraft* mc, Textures* textures) { globalChunkFlags = new unsigned char[getGlobalChunkCount()]; memset(globalChunkFlags, 0, getGlobalChunkCount()); + globalChunkConnectivity = new uint64_t[getGlobalChunkCount()]; + memset(globalChunkConnectivity, 0xFF, + getGlobalChunkCount() * sizeof(uint64_t)); // 0xFF >> Fully open + starList = MemoryTracker::genLists(4); glPushMatrix(); @@ -801,14 +808,14 @@ int compare(const void* a, const void* b) { #endif +// 4jcraft: removed the vita & ps3 versions because they were SEVERELY annoying +// me it looked so ugly, god. +// if you ever hate me for it, deal with it, the source code is STILL visible if +// you look at someone elses fork. like steamcmd int LevelRenderer::renderChunks(int from, int to, int layer, double alpha) { - int playerIndex = mc->player->GetXboxPad(); // 4J added + int playerIndex = mc->player->GetXboxPad(); + if (chunks[playerIndex].data == NULL) return 0; -#if 1 - // 4J - cut down version, we're not using offsetted render lists, or a - // sorted chunk list, anymore - mc->gameRenderer->turnOnLightLayer( - alpha); // 4J - brought forward from 1.8.2 std::shared_ptr player = mc->cameraTargetPlayer; double xOff = player->xOld + (player->x - player->xOld) * alpha; double yOff = player->yOld + (player->y - player->yOld) * alpha; @@ -817,14 +824,9 @@ int LevelRenderer::renderChunks(int from, int to, int layer, double alpha) { glPushMatrix(); glTranslatef((float)-xOff, (float)-yOff, (float)-zOff); -#ifdef __PSVITA__ - // AP - also set the camera position so we can work out if a chunk is fogged - // or not - RenderManager.SetCameraPosition((float)-xOff, (float)-yOff, (float)-zOff); -#endif - -#if defined __PS3__ && !defined DISABLE_SPU_CODE - // pre- calc'd on the SPU + ClipChunk* pClipChunk = chunks[playerIndex].data; + unsigned char emptyFlag = LevelRenderer::CHUNK_FLAG_EMPTY0 << layer; + bool first = true; int count = 0; waitForCull_SPU(); if (layer == 0) { @@ -905,12 +907,11 @@ int LevelRenderer::renderChunks(int from, int to, int layer, double alpha) { int list = chunk->globalIdx * 2 + layer; list += chunkLists; - // 4jcraft: replaced glPushMatrix/glTranslatef/glPopMatrix per - // chunk no more full MVP upload per chunk, can also be bkwards - // compat - RenderManager.SetChunkOffset((float)chunk->chunk->x, - (float)chunk->chunk->y, - (float)chunk->chunk->z); + // 4jcraft: replaced glPushMatrix/glTranslatef/glPopMatrix per chunk + // no more full MVP upload per chunk, can also be bkwards compat + RenderManager.SetChunkOffset((float)pClipChunk->chunk->x, + (float)pClipChunk->chunk->y, + (float)pClipChunk->chunk->z); if (RenderManager.CBuffCall(list, first)) { first = false; @@ -960,61 +961,7 @@ int LevelRenderer::renderChunks(int from, int to, int layer, double alpha) { #endif // __PS3__ glPopMatrix(); - mc->gameRenderer->turnOffLightLayer( - alpha); // 4J - brought forward from 1.8.2 - -#else - _renderChunks.clear(); - // int p = 0; - int count = 0; - for (int i = from; i < to; i++) { - if (layer == 0) { - totalChunks++; - if (sortedChunks[playerIndex]->at(i)->emptyFlagSet(layer)) - emptyChunks++; - else if (!sortedChunks[playerIndex]->at(i)->visible) - offscreenChunks++; - else - renderedChunks++; - } - - // if (!sortedChunks[i].empty[layer] && - // sortedChunks[i].visible && - // (sortedChunks[i].occlusion_visible)) { - if (!(sortedChunks[playerIndex]->at(i)->emptyFlagSet(layer) && - sortedChunks[playerIndex]->at(i)->visible)) { - int list = sortedChunks[playerIndex]->at(i)->getList(layer); - if (list >= 0) { - _renderChunks.push_back(sortedChunks[playerIndex]->at(i)); - count++; - } - } - } - - std::shared_ptr player = mc->cameraTargetPlayer; - double xOff = player->xOld + (player->x - player->xOld) * alpha; - double yOff = player->yOld + (player->y - player->yOld) * alpha; - double zOff = player->zOld + (player->z - player->zOld) * alpha; - - for (int l = 0; l < RENDERLISTS_LENGTH; l++) renderLists[l].clear(); - int lists = 0; - for (auto it = _renderChunks.begin(); it != _renderChunks.end(); it++) { - Chunk* chunk = *it; - int list = -1; - for (int l = 0; l < lists; l++) { - if (renderLists[l].isAt(chunk->xRender, chunk->yRender, - chunk->zRender)) - list = l; - } - if (list < 0) { - list = lists++; - renderLists[list].init(chunk->xRender, chunk->yRender, - chunk->zRender, xOff, yOff, zOff); - } - renderLists[list].add(chunk->getList(layer)); - } - renderSameAsLast(layer, alpha); -#endif + mc->gameRenderer->turnOffLightLayer(alpha); return count; } @@ -1990,10 +1937,9 @@ bool LevelRenderer::updateDirtyChunks() { return; } - const int newCount = - (count < MAX_CONCURRENT_CHUNK_REBUILDS) - ? (count + 1) - : MAX_CONCURRENT_CHUNK_REBUILDS; + const int newCount = (count < MAX_CONCURRENT_CHUNK_REBUILDS) + ? (count + 1) + : MAX_CONCURRENT_CHUNK_REBUILDS; for (int i = newCount - 1; i > pos; --i) { items[i] = items[i - 1]; } @@ -2030,8 +1976,8 @@ bool LevelRenderer::updateDirtyChunks() { int index = 0; do { - // See comment on dirtyChunksLockFreeStack.Push() regarding details of - // this casting/subtracting -2. + // See comment on dirtyChunksLockFreeStack.Push() regarding details + // of this casting/subtracting -2. index = (size_t)dirtyChunksLockFreeStack.Pop(); #ifdef _CRITICAL_CHUNKS int oldIndex = index; @@ -2040,9 +1986,9 @@ bool LevelRenderer::updateDirtyChunks() { #endif if (index == 1) dirtyChunkPresent = - true; // 1 is a special value passed to let this thread know - // that a chunk which isn't on this stack has been set to - // dirty + true; // 1 is a special value passed to let this thread + // know that a chunk which isn't on this stack has + // been set to dirty else if (index > 1) { int i2 = index - 2; if (i2 >= DIMENSION_OFFSETS[2]) { @@ -2057,8 +2003,9 @@ bool LevelRenderer::updateDirtyChunks() { setGlobalChunkFlag(index - 2, CHUNK_FLAG_DIRTY); #ifdef _CRITICAL_CHUNKS - if (!(oldIndex & 0x10000000)) // was this chunk not marked as - // non-critical. Ugh double negatives + if (!(oldIndex & + 0x10000000)) // was this chunk not marked as + // non-critical. Ugh double negatives { setGlobalChunkFlag(index - 2, CHUNK_FLAG_CRITICAL); } @@ -2068,20 +2015,21 @@ bool LevelRenderer::updateDirtyChunks() { } } while (index); - // Only bother searching round all the chunks if we have some dirty chunk(s) + // Only bother searching round all the chunks if we have some dirty + // chunk(s) if (dirtyChunkPresent) { lastDirtyChunkFound = System::currentTimeMillis(); PIXBeginNamedEvent(0, "Finding nearest chunk\n"); #if defined __PS3__ && !defined DISABLE_SPU_CODE - // find the nearest chunk with a spu task, copy all the data over here - // for uploading to SPU + // find the nearest chunk with a spu task, copy all the data over + // here for uploading to SPU g_findNearestChunkDataIn.numGlobalChunks = getGlobalChunkCount(); g_findNearestChunkDataIn.pGlobalChunkFlags = globalChunkFlags; g_findNearestChunkDataIn.onlyRebuild = onlyRebuild; g_findNearestChunkDataIn.lowerOffset = (int)&((LevelChunk*)0) - ->lowerBlocks; // dodgy bit of class structure poking, as we - // don't want to try and get the whole of + ->lowerBlocks; // dodgy bit of class structure poking, as + // we don't want to try and get the whole of // LevelChunk copmpiling on SPU g_findNearestChunkDataIn.upperOffset = (int)&((LevelChunk*)0)->upperBlocks; @@ -2107,11 +2055,14 @@ bool LevelRenderer::updateDirtyChunks() { } if (level[i] != NULL) { g_findNearestChunkDataIn.multiplayerChunkCache[i].XZOFFSET = - ((MultiPlayerChunkCache*)(level[i]->chunkSource))->XZOFFSET; + ((MultiPlayerChunkCache*)(level[i]->chunkSource)) + ->XZOFFSET; g_findNearestChunkDataIn.multiplayerChunkCache[i].XZSIZE = - ((MultiPlayerChunkCache*)(level[i]->chunkSource))->XZSIZE; + ((MultiPlayerChunkCache*)(level[i]->chunkSource)) + ->XZSIZE; g_findNearestChunkDataIn.multiplayerChunkCache[i].cache = - (void**)((MultiPlayerChunkCache*)(level[i]->chunkSource)) + (void**)((MultiPlayerChunkCache*)(level[i] + ->chunkSource)) ->cache; } } @@ -2128,20 +2079,22 @@ bool LevelRenderer::updateDirtyChunks() { // Find nearest chunk that is dirty for (int p = 0; p < XUSER_MAX_COUNT; p++) { - // It's possible that the localplayers member can be set to NULL on - // the main thread when a player chooses to exit the game So take a - // reference to the player object now. As it is a shared_ptr it - // should live as long as we need it + // It's possible that the localplayers member can be set to NULL + // on the main thread when a player chooses to exit the game So + // take a reference to the player object now. As it is a + // shared_ptr it should live as long as we need it std::shared_ptr player = mc->localplayers[p]; if (player == NULL) continue; if (chunks[p].data == NULL) continue; if (level[p] == NULL) continue; - if (chunks[p].length != xChunks * zChunks * CHUNK_Y_COUNT) continue; + if (chunks[p].length != xChunks * zChunks * CHUNK_Y_COUNT) + continue; int px = (int)player->x; int py = (int)player->y; int pz = (int)player->z; - // app.DebugPrintf("!! %d %d %d, %d %d %d {%d,%d} + // app.DebugPrintf("!! %d %d %d, %d %d %d + //{%d,%d} //",px,py,pz,stackChunkDirty,nonStackChunkDirty,onlyRebuild, // xChunks, zChunks); @@ -2152,19 +2105,19 @@ bool LevelRenderer::updateDirtyChunks() { for (int y = 0; y < CHUNK_Y_COUNT; y++) { ClipChunk* pClipChunk = &chunks[p][(z * yChunks + y) * xChunks + x]; - // Get distance to this chunk - deliberately not calling - // the chunk's method of doing this to avoid overheads - // (passing entitie, type conversion etc.) that this - // involves + // Get distance to this chunk - deliberately not + // calling the chunk's method of doing this to avoid + // overheads (passing entitie, type conversion etc.) + // that this involves int xd = pClipChunk->xm - px; int yd = pClipChunk->ym - py; int zd = pClipChunk->zm - pz; int distSq = xd * xd + yd * yd + zd * zd; int distSqWeighted = xd * xd + yd * yd * 4 + - zd * - zd; // Weighting against y to prioritise things - // in same x/z plane as player first + zd * zd; // Weighting against y to prioritise + // things in same x/z plane as player + // first if (globalChunkFlags[pClipChunk->globalIdx] & CHUNK_FLAG_DIRTY) { @@ -2172,11 +2125,11 @@ bool LevelRenderer::updateDirtyChunks() { globalChunkFlags[pClipChunk->globalIdx] & CHUNK_FLAG_COMPILED || (distSq < - 20 * 20)) // Always rebuild really near things - // or else building (say) at tower - // up into empty blocks when we are - // low on memory will not create - // render data + 20 * 20)) // Always rebuild really near + // things or else building (say) + // at tower up into empty blocks + // when we are low on memory + // will not create render data { considered++; // Is this chunk nearer than our nearest? @@ -2189,33 +2142,36 @@ bool LevelRenderer::updateDirtyChunks() { #endif #ifdef _CRITICAL_CHUNKS - // AP - this will make sure that if a deferred - // grouping has started, only critical chunks go - // into that grouping, even if a non-critical - // chunk is closer. + // AP - this will make sure that if a + // deferred grouping has started, only + // critical chunks go into that grouping, + // even if a non-critical chunk is closer. if ((!veryNearCount && isNearer) || (distSq < 20 * 20 && - (globalChunkFlags[pClipChunk->globalIdx] & + (globalChunkFlags[pClipChunk + ->globalIdx] & CHUNK_FLAG_CRITICAL))) #else if (isNearer) #endif { - // At this point we've got a chunk that we - // would like to consider for rendering, at - // least based on its proximity to the - // player(s). Its *quite* quick to generate - // empty render data for render chunks, but - // if we let the rebuilding do that then the - // after rebuilding we will have to start - // searching for the next nearest chunk from - // scratch again. Instead, its better to - // detect empty chunks at this stage, flag - // them up as not dirty (and empty), and - // carry on. The levelchunk's - // isRenderChunkEmpty method can be quite - // optimal as it can make use of the chunk's - // data compression to detect emptiness + // At this point we've got a chunk that + // we would like to consider for + // rendering, at least based on its + // proximity to the player(s). Its + // *quite* quick to generate empty + // render data for render chunks, but if + // we let the rebuilding do that then + // the after rebuilding we will have to + // start searching for the next nearest + // chunk from scratch again. Instead, + // its better to detect empty chunks at + // this stage, flag them up as not dirty + // (and empty), and carry on. The + // levelchunk's isRenderChunkEmpty + // method can be quite optimal as it can + // make use of the chunk's data + // compression to detect emptiness // without actually testing as many data // items as uncompressed data would. Chunk* chunk = pClipChunk->chunk; @@ -2225,8 +2181,8 @@ bool LevelRenderer::updateDirtyChunks() { nearChunk = pClipChunk; minDistSq = distSqWeighted; #ifdef _LARGE_WORLDS - nearestClipChunks.insert( - nearChunk, minDistSq); + nearestClipChunks.insert(nearChunk, + minDistSq); #endif } else { chunk->clearDirty(); @@ -2240,7 +2196,8 @@ bool LevelRenderer::updateDirtyChunks() { #ifdef _CRITICAL_CHUNKS // AP - is the chunk near and also critical if (distSq < 20 * 20 && - ((globalChunkFlags[pClipChunk->globalIdx] & + ((globalChunkFlags[pClipChunk + ->globalIdx] & CHUNK_FLAG_CRITICAL))) #else if (distSq < 20 * 20) @@ -2270,24 +2227,25 @@ bool LevelRenderer::updateDirtyChunks() { chunk = nearestClipChunks.items[i].first->chunk; // If this chunk is very near, then move the renderer into a // deferred mode. This won't commit any command buffers for - // rendering until we call CBuffDeferredModeEnd(), allowing us to - // group any near changes into an atomic unit. This is essential so - // we don't temporarily create any holes in the environment whilst - // updating one chunk and not the neighbours. The "ver near" aspect - // of this is just a cosmetic nicety - exactly the same thing would - // happen further away, but we just don't care about it so much from - // terms of visual impact. + // rendering until we call CBuffDeferredModeEnd(), allowing us + // to group any near changes into an atomic unit. This is + // essential so we don't temporarily create any holes in the + // environment whilst updating one chunk and not the neighbours. + // The "ver near" aspect of this is just a cosmetic nicety - + // exactly the same thing would happen further away, but we just + // don't care about it so much from terms of visual impact. if (veryNearCount > 0) { RenderManager.CBuffDeferredModeStart(); } // Build this chunk & return false to continue processing chunk->clearDirty(); // Take a copy of the details that are required for chunk - // rebuilding, and rebuild That instead of the original chunk data. - // This is done within the m_csDirtyChunks critical section, which - // means that any chunks can't be repositioned whilst we are doing - // this copy. The copy will then be guaranteed to be consistent - // whilst rebuilding takes place outside of that critical section. + // rebuilding, and rebuild That instead of the original chunk + // data. This is done within the m_csDirtyChunks critical + // section, which means that any chunks can't be repositioned + // whilst we are doing this copy. The copy will then be + // guaranteed to be consistent whilst rebuilding takes place + // outside of that critical section. permaChunk[index].makeCopyForRebuild(chunk); ++index; } @@ -2361,25 +2319,26 @@ bool LevelRenderer::updateDirtyChunks() { static Chunk permaChunk; { FRAME_PROFILE_SCOPE(ChunkRebuildSchedule); - // If this chunk is very near, then move the renderer into a deferred - // mode. This won't commit any command buffers for rendering until we - // call CBuffDeferredModeEnd(), allowing us to group any near changes - // into an atomic unit. This is essential so we don't temporarily create - // any holes in the environment whilst updating one chunk and not the - // neighbours. The "ver near" aspect of this is just a cosmetic nicety - - // exactly the same thing would happen further away, but we just don't - // care about it so much from terms of visual impact. + // If this chunk is very near, then move the renderer into a + // deferred mode. This won't commit any command buffers for + // rendering until we call CBuffDeferredModeEnd(), allowing us to + // group any near changes into an atomic unit. This is essential so + // we don't temporarily create any holes in the environment whilst + // updating one chunk and not the neighbours. The "ver near" aspect + // of this is just a cosmetic nicety - exactly the same thing would + // happen further away, but we just don't care about it so much from + // terms of visual impact. if (veryNearCount > 0) { RenderManager.CBuffDeferredModeStart(); } // Build this chunk & return false to continue processing chunk->clearDirty(); - // Take a copy of the details that are required for chunk rebuilding, - // and rebuild That instead of the original chunk data. This is done - // within the m_csDirtyChunks critical section, which means that any - // chunks can't be repositioned whilst we are doing this copy. The copy - // will then be guaranteed to be consistent whilst rebuilding takes - // place outside of that critical section. + // Take a copy of the details that are required for chunk + // rebuilding, and rebuild That instead of the original chunk data. + // This is done within the m_csDirtyChunks critical section, which + // means that any chunks can't be repositioned whilst we are doing + // this copy. The copy will then be guaranteed to be consistent + // whilst rebuilding takes place outside of that critical section. permaChunk.makeCopyForRebuild(chunk); LeaveCriticalSection(&m_csDirtyChunks); } @@ -2879,13 +2838,16 @@ void LevelRenderer::waitForCull_SPU() { } #endif // __PS3__ +// 4jcraft: optional occlusion culling system, i hope to upgrade it soon +// gives better performances but mostly breaks chunk rendering void LevelRenderer::cull(Culler* culler, float a) { - int playerIndex = mc->player->GetXboxPad(); // 4J added + int playerIndex = mc->player->GetXboxPad(); + if (chunks[playerIndex].data == nullptr) return; #if defined __PS3__ && !defined DISABLE_SPU_CODE cull_SPU(playerIndex, culler, a); return; -#endif // __PS3__ +#endif FrustumCuller* fc = (FrustumCuller*)culler; FrustumData* fd = fc->frustum; @@ -2901,28 +2863,297 @@ void LevelRenderer::cull(Culler* culler, float a) { (fy * -fc->yOff) + (fz * -fc->zOff)); } - ClipChunk* pClipChunk = chunks[playerIndex].data; - int vis = 0; - int total = 0; - int numWrong = 0; +#if defined(OCCLUSION_MODE_NONE) + // just check if chunk is compiled and non-empty for (unsigned int i = 0; i < chunks[playerIndex].length; i++) { - unsigned char flags = pClipChunk->globalIdx == -1 - ? 0 - : globalChunkFlags[pClipChunk->globalIdx]; - - if ((flags & CHUNK_FLAG_COMPILED) && - ((flags & CHUNK_FLAG_EMPTYBOTH) != CHUNK_FLAG_EMPTYBOTH)) { - bool clipres = clip(pClipChunk->aabb, fdraw); - pClipChunk->visible = clipres; - if (pClipChunk->visible) vis++; - total++; - } else { - pClipChunk->visible = false; + ClipChunk* cc = &chunks[playerIndex][i]; + if (cc->globalIdx < 0) { + cc->visible = false; + continue; } - pClipChunk++; - } -} + unsigned char flags = globalChunkFlags[cc->globalIdx]; + bool isCompiled = (flags & CHUNK_FLAG_COMPILED) != 0; + bool isEmptyBoth = + (flags & CHUNK_FLAG_EMPTYBOTH) == CHUNK_FLAG_EMPTYBOTH; + + cc->visible = isCompiled && !isEmptyBoth; + } + +#elif defined(OCCLUSION_MODE_FRUSTUM) + // Just ~~monika~~ frustum culling + for (unsigned int i = 0; i < chunks[playerIndex].length; i++) { + ClipChunk* cc = &chunks[playerIndex][i]; + if (cc->globalIdx < 0) { + cc->visible = false; + continue; + } + + unsigned char flags = globalChunkFlags[cc->globalIdx]; + bool isCompiled = (flags & CHUNK_FLAG_COMPILED) != 0; + bool isEmptyBoth = + (flags & CHUNK_FLAG_EMPTYBOTH) == CHUNK_FLAG_EMPTYBOTH; + + if (isCompiled && !isEmptyBoth) { + float cellBounds[6] = {(float)cc->chunk->x - 0.1f, + (float)cc->chunk->y - 0.1f, + (float)cc->chunk->z - 0.1f, + (float)cc->chunk->x + CHUNK_XZSIZE + 0.1f, + (float)cc->chunk->y + CHUNK_SIZE + 0.1f, + (float)cc->chunk->z + CHUNK_XZSIZE + 0.1f}; + cc->visible = clip(cellBounds, fdraw); + } else { + cc->visible = false; + } + } + +#elif defined(OCCLUSION_MODE_HARDWARE) +// TODO: Hardware occlusion culling using GPU queries +// For now, fall back to frustum culling +#warning \ + "OCCLUSION_MODE_HARDWARE is not implemented yet, falling back to frustum culling" + for (unsigned int i = 0; i < chunks[playerIndex].length; i++) { + ClipChunk* cc = &chunks[playerIndex][i]; + if (cc->globalIdx < 0) { + cc->visible = false; + continue; + } + + unsigned char flags = globalChunkFlags[cc->globalIdx]; + bool isCompiled = (flags & CHUNK_FLAG_COMPILED) != 0; + bool isEmptyBoth = + (flags & CHUNK_FLAG_EMPTYBOTH) == CHUNK_FLAG_EMPTYBOTH; + + if (isCompiled && !isEmptyBoth) { + float cellBounds[6] = {(float)cc->chunk->x - 0.1f, + (float)cc->chunk->y - 0.1f, + (float)cc->chunk->z - 0.1f, + (float)cc->chunk->x + CHUNK_XZSIZE + 0.1f, + (float)cc->chunk->y + CHUNK_SIZE + 0.1f, + (float)cc->chunk->z + CHUNK_XZSIZE + 0.1f}; + cc->visible = clip(cellBounds, fdraw); + } else { + cc->visible = false; + } + } + +#elif defined(OCCLUSION_MODE_BFS) + // Experimental BFS occlusion culling. + // Check https://tomcc.github.io/2014/08/31/visibility-1.html + // And https://tomcc.github.io/2014/08/31/visibility-2.html + // And finally https://en.wikipedia.org/wiki/Breadth-first_search + std::shared_ptr player = mc->cameraTargetPlayer; + float camX = (float)(player->xOld + (player->x - player->xOld) * a); + float camY = (float)(player->yOld + (player->y - player->yOld) * a); + float camZ = (float)(player->zOld + (player->z - player->zOld) * a); + + auto intFloorDiv = [](int v, int div) { + if (v < 0 && v % div != 0) return (v / div) - 1; + return v / div; + }; + + auto floatFloorDiv = [](float v, int div) { + int iv = (int)v; + if (v < 0 && v != iv) iv--; + if (iv < 0 && iv % div != 0) return (iv / div) - 1; + return iv / div; + }; + + int minCx = INT_MAX, minCy = INT_MAX, minCz = INT_MAX; + int maxCx = INT_MIN, maxCy = INT_MIN, maxCz = INT_MIN; + + for (unsigned int i = 0; i < chunks[playerIndex].length; i++) { + ClipChunk* cc = &chunks[playerIndex][i]; + cc->visible = false; + if (cc->globalIdx < 0) continue; + + int cx = intFloorDiv(cc->chunk->x, CHUNK_XZSIZE); + int cy = intFloorDiv(cc->chunk->y, CHUNK_SIZE); + int cz = intFloorDiv(cc->chunk->z, CHUNK_XZSIZE); + + if (cx < minCx) minCx = cx; + if (cy < minCy) minCy = cy; + if (cz < minCz) minCz = cz; + if (cx > maxCx) maxCx = cx; + if (cy > maxCy) maxCy = cy; + if (cz > maxCz) maxCz = cz; + } + + if (minCx > maxCx) return; + + int sizeX = maxCx - minCx + 1; + int sizeY = maxCy - minCy + 1; + int sizeZ = maxCz - minCz + 1; + + std::vector grid(sizeX * sizeY * sizeZ, nullptr); + for (unsigned int i = 0; i < chunks[playerIndex].length; i++) { + ClipChunk* cc = &chunks[playerIndex][i]; + if (cc->globalIdx < 0) continue; + int lx = intFloorDiv(cc->chunk->x, CHUNK_XZSIZE) - minCx; + int ly = intFloorDiv(cc->chunk->y, CHUNK_SIZE) - minCy; + int lz = intFloorDiv(cc->chunk->z, CHUNK_XZSIZE) - minCz; + grid[(lx * sizeY + ly) * sizeZ + lz] = cc; + } + + auto getChunkAt = [&](int cx, int cy, int cz) -> ClipChunk* { + int lx = cx - minCx; + int ly = cy - minCy; + int lz = cz - minCz; + if (lx >= 0 && lx < sizeX && ly >= 0 && ly < sizeY && lz >= 0 && + lz < sizeZ) { + return grid[(lx * sizeY + ly) * sizeZ + lz]; + } + return nullptr; + }; + + int startCx = floatFloorDiv(camX, CHUNK_XZSIZE); + int startCy = floatFloorDiv(camY, CHUNK_SIZE); + int startCz = floatFloorDiv(camZ, CHUNK_XZSIZE); + + if (startCx < minCx) + startCx = minCx; + else if (startCx > maxCx) + startCx = maxCx; + if (startCy < minCy) + startCy = minCy; + else if (startCy > maxCy) + startCy = maxCy; + if (startCz < minCz) + startCz = minCz; + else if (startCz > maxCz) + startCz = maxCz; + + ClipChunk* startChunk = getChunkAt(startCx, startCy, startCz); + + if (!startChunk) { + float minDist = 1e30f; + for (unsigned int i = 0; i < chunks[playerIndex].length; i++) { + ClipChunk* cc = &chunks[playerIndex][i]; + if (cc->globalIdx < 0) continue; + float midX = cc->chunk->x + CHUNK_XZSIZE * 0.5f; + float midY = cc->chunk->y + CHUNK_SIZE * 0.5f; + float midZ = cc->chunk->z + CHUNK_XZSIZE * 0.5f; + float dist = (camX - midX) * (camX - midX) + + (camY - midY) * (camY - midY) + + (camZ - midZ) * (camZ - midZ); + if (dist < minDist) { + minDist = dist; + startChunk = cc; + } + } + } + + if (!startChunk) return; + + struct BFSNode { + ClipChunk* cc; + int incomingFace; + }; + + std::vector q; + q.reserve(chunks[playerIndex].length * 2); + int qHead = 0; + + std::vector visitedFaces(chunks[playerIndex].length, 0); + + q.push_back({startChunk, -1}); + visitedFaces[startChunk - chunks[playerIndex].data] = 0x3F; + + static const int OFFSETS[6][3] = { + {0, -1, 0}, // 0: -Y + {0, 1, 0}, // 1: +Y + {0, 0, -1}, // 2: -Z + {0, 0, 1}, // 3: +Z + {-1, 0, 0}, // 4: -X + {1, 0, 0} // 5: +X + }; + + while (qHead < (int)q.size()) { + BFSNode node = q[qHead++]; + ClipChunk* curr = node.cc; + int incFace = node.incomingFace; + + unsigned char flags = globalChunkFlags[curr->globalIdx]; + bool isCompiled = (flags & CHUNK_FLAG_COMPILED) != 0; + bool isEmptyBoth = + (flags & CHUNK_FLAG_EMPTYBOTH) == CHUNK_FLAG_EMPTYBOTH; + + if (isCompiled && !isEmptyBoth) { + curr->visible = true; + } + + int cx = intFloorDiv(curr->chunk->x, CHUNK_XZSIZE); + int cy = intFloorDiv(curr->chunk->y, CHUNK_SIZE); + int cz = intFloorDiv(curr->chunk->z, CHUNK_XZSIZE); + + uint64_t conn = getGlobalChunkConnectivity(curr->globalIdx); + + for (int i = 0; i < 6; i++) { + int outFace = i; + + bool canGo = false; + float chkX = curr->chunk->x; + float chkY = curr->chunk->y; + float chkZ = curr->chunk->z; + switch (outFace) { + case 0: + canGo = camY >= chkY; + break; + case 1: + canGo = camY <= chkY + CHUNK_SIZE; + break; + case 2: + canGo = camZ >= chkZ; + break; + case 3: + canGo = camZ <= chkZ + CHUNK_XZSIZE; + break; + case 4: + canGo = camX >= chkX; + break; + case 5: + canGo = camX <= chkX + CHUNK_XZSIZE; + break; + } + if (!canGo) continue; + + if (incFace != -1) { + int shift = (incFace * 6) + outFace; + if ((conn & (1ULL << shift)) == 0) continue; + } + + int nx = cx + OFFSETS[i][0]; + int ny = cy + OFFSETS[i][1]; + int nz = cz + OFFSETS[i][2]; + + ClipChunk* neighbor = getChunkAt(nx, ny, nz); + if (!neighbor) continue; + + int nIdx = neighbor - chunks[playerIndex].data; + int nextIncFace = outFace ^ 1; + + if ((visitedFaces[nIdx] & (1 << nextIncFace)) != 0) continue; + + float cellBounds[6] = { + (float)neighbor->chunk->x - 0.1f, + (float)neighbor->chunk->y - 0.1f, + (float)neighbor->chunk->z - 0.1f, + (float)neighbor->chunk->x + CHUNK_XZSIZE + 0.1f, + (float)neighbor->chunk->y + CHUNK_SIZE + 0.1f, + (float)neighbor->chunk->z + CHUNK_XZSIZE + 0.1f}; + + if (!clip(cellBounds, fdraw)) continue; + + visitedFaces[nIdx] |= (1 << nextIncFace); + q.push_back({neighbor, nextIncFace}); + } + } + +#else +#error \ + "Unknown occlusion mode, this should NEVER happen, check meson.build for misconfiguration" +#endif +} void LevelRenderer::playStreamingMusic(const std::wstring& name, int x, int y, int z) { if (name != L"") { @@ -3891,6 +4122,19 @@ void LevelRenderer::setGlobalChunkFlag(int x, int y, int z, Level* level, } } +void LevelRenderer::setGlobalChunkConnectivity(int index, uint64_t conn) { + if (index >= 0 && index < getGlobalChunkCount()) { + globalChunkConnectivity[index] = conn; + } +} + +uint64_t LevelRenderer::getGlobalChunkConnectivity(int index) { + if (index >= 0 && index < getGlobalChunkCount()) { + return globalChunkConnectivity[index]; + } + return ~(uint64_t)0; // out of bounds +} + void LevelRenderer::clearGlobalChunkFlag(int x, int y, int z, Level* level, unsigned char flag, unsigned char shift) { diff --git a/Minecraft.Client/Rendering/LevelRenderer.h b/Minecraft.Client/Rendering/LevelRenderer.h index 58f194a3b..081aa98b9 100644 --- a/Minecraft.Client/Rendering/LevelRenderer.h +++ b/Minecraft.Client/Rendering/LevelRenderer.h @@ -209,7 +209,8 @@ private: emptyChunks; static const int RENDERLISTS_LENGTH = 4; // 4J - added OffsettedRenderList renderLists[RENDERLISTS_LENGTH]; - + void setGlobalChunkConnectivity(int index, uint64_t conn); + uint64_t getGlobalChunkConnectivity(int index); std::unordered_map destroyingBlocks; Icon** breakingTextures; @@ -296,6 +297,8 @@ public: void clearGlobalChunkFlag(int x, int y, int z, Level* level, unsigned char flag, unsigned char shift = 0); + static uint64_t* globalChunkConnectivity; + // Get/set whole byte of flags unsigned char getGlobalChunkFlags(int x, int y, int z, Level* level); void setGlobalChunkFlags(int x, int y, int z, Level* level, diff --git a/Minecraft.Client/meson.build b/Minecraft.Client/meson.build index abbb3b1ef..123320903 100644 --- a/Minecraft.Client/meson.build +++ b/Minecraft.Client/meson.build @@ -85,10 +85,10 @@ if get_option('enable_frame_profiler') endif if get_option('ui_backend') == 'shiggy' - shiggy_dep = dependency( - 'shiggy', - fallback : ['shiggy', 'shiggy_dep'], - ) + shiggy_dep = dependency( + 'shiggy', + fallback: ['shiggy', 'shiggy_dep'], + ) global_cpp_defs += ['-D_ENABLEIGGY'] client_dependencies += shiggy_dep @@ -98,7 +98,18 @@ if get_option('ui_backend') == 'java' global_cpp_defs += '-DENABLE_JAVA_GUIS' endif -client = executable('Minecraft.Client', +occlusion_mode = get_option('occlusion_culling') +if occlusion_mode == 'off' + global_cpp_defs += ['-DOCCLUSION_MODE_NONE'] +elif occlusion_mode == 'frustum' + global_cpp_defs += ['-DOCCLUSION_MODE_FRUSTUM'] +elif occlusion_mode == 'bfs' + global_cpp_defs += ['-DOCCLUSION_MODE_BFS', '-DUSE_OCCLUSION_CULLING'] +elif occlusion_mode == 'hardware' + global_cpp_defs += ['-DOCCLUSION_MODE_HARDWARE', '-DUSE_OCCLUSION_CULLING'] +endif +client = executable( + 'Minecraft.Client', client_sources + platform_sources + localisation[1], include_directories: include_directories('Platform', 'Platform/Linux/Iggy/include'), dependencies: client_dependencies, diff --git a/meson.options b/meson.options index 0290c8005..f92698ac4 100644 --- a/meson.options +++ b/meson.options @@ -27,8 +27,17 @@ option( ) option( +<<<<<<< HEAD 'enable_frame_profiler', type: 'boolean', value: false, description: 'Enable the in-engine frame profiler for render hotspot discovery.', ) +======= + 'occlusion_culling', + type: 'combo', + choices: ['off', 'frustum', 'bfs', 'hardware'], + value: 'frustum', + description: 'Occlusion culling mode. Off disables ALL CULLING (debug only!), Frustum disables offscreen rendering (default), BFS is experimental connectivity culling, hardware uses GPU queries.', +) +>>>>>>> db062d4ba (new culler) From 51ad1434db4ad2730372b20dc9a033fcf07f7534 Mon Sep 17 00:00:00 2001 From: JuiceyDev Date: Sun, 29 Mar 2026 23:29:16 +0200 Subject: [PATCH 154/170] new culler --- Minecraft.Client/Rendering/LevelRenderer.cpp | 24 +++----------------- meson.options | 5 ++-- 2 files changed, 5 insertions(+), 24 deletions(-) diff --git a/Minecraft.Client/Rendering/LevelRenderer.cpp b/Minecraft.Client/Rendering/LevelRenderer.cpp index b73ee025c..a91df96dd 100644 --- a/Minecraft.Client/Rendering/LevelRenderer.cpp +++ b/Minecraft.Client/Rendering/LevelRenderer.cpp @@ -807,11 +807,6 @@ int compare(const void* a, const void* b) { } #endif - -// 4jcraft: removed the vita & ps3 versions because they were SEVERELY annoying -// me it looked so ugly, god. -// if you ever hate me for it, deal with it, the source code is STILL visible if -// you look at someone elses fork. like steamcmd int LevelRenderer::renderChunks(int from, int to, int layer, double alpha) { int playerIndex = mc->player->GetXboxPad(); if (chunks[playerIndex].data == NULL) return 0; @@ -824,17 +819,13 @@ int LevelRenderer::renderChunks(int from, int to, int layer, double alpha) { glPushMatrix(); glTranslatef((float)-xOff, (float)-yOff, (float)-zOff); - ClipChunk* pClipChunk = chunks[playerIndex].data; - unsigned char emptyFlag = LevelRenderer::CHUNK_FLAG_EMPTY0 << layer; - bool first = true; - int count = 0; +#ifdef __PS3__ waitForCull_SPU(); if (layer == 0) { count = g_cullDataIn[playerIndex].numToRender_layer0; RenderManager.CBuffCallMultiple( g_cullDataIn[playerIndex].listArray_layer0, count); - } else // layer == 1 - { + } else { // layer == 1 count = g_cullDataIn[playerIndex].numToRender_layer1; RenderManager.CBuffCallMultiple( g_cullDataIn[playerIndex].listArray_layer1, count); @@ -891,19 +882,10 @@ int LevelRenderer::renderChunks(int from, int to, int layer, double alpha) { // first }); } + { FRAME_PROFILE_SCOPE(ChunkPlayback); for (ClipChunk* chunk : sortList) { - // ugly occluder - float dx = (chunk->chunk->x + 8.0f) - (float)xOff; - float dy = (chunk->chunk->y + 8.0f) - (float)yOff; - float dz = (chunk->chunk->z + 8.0f) - (float)zOff; - bool isVeryNear = (dx * dx + dy * dy + dz * dz) < (16.0f * 16.0f); - - if (!isVeryNear && layer == 0) { - // todo: occlusion flag - } - int list = chunk->globalIdx * 2 + layer; list += chunkLists; diff --git a/meson.options b/meson.options index f92698ac4..4dc73f322 100644 --- a/meson.options +++ b/meson.options @@ -27,17 +27,16 @@ option( ) option( -<<<<<<< HEAD 'enable_frame_profiler', type: 'boolean', value: false, description: 'Enable the in-engine frame profiler for render hotspot discovery.', ) -======= + +option( 'occlusion_culling', type: 'combo', choices: ['off', 'frustum', 'bfs', 'hardware'], value: 'frustum', description: 'Occlusion culling mode. Off disables ALL CULLING (debug only!), Frustum disables offscreen rendering (default), BFS is experimental connectivity culling, hardware uses GPU queries.', ) ->>>>>>> db062d4ba (new culler) From c6fa51d5928b1c56ab7f637037237625bf6b21d0 Mon Sep 17 00:00:00 2001 From: MatthewBeshay <92357869+MatthewBeshay@users.noreply.github.com> Date: Mon, 30 Mar 2026 09:26:35 +1100 Subject: [PATCH 155/170] perf(render): optimise tile entity cleanup and profiling --- Minecraft.Client/Rendering/Chunk.cpp | 177 ++++++++---------- Minecraft.Client/Rendering/Chunk.h | 2 + Minecraft.Client/Rendering/LevelRenderer.cpp | 112 ++++++++--- Minecraft.Client/Rendering/LevelRenderer.h | 22 ++- Minecraft.Client/Utils/FrameProfiler.cpp | 5 +- Minecraft.Client/Utils/FrameProfiler.h | 2 + .../Blocks/TileEntities/TileEntity.cpp | 11 +- .../Blocks/TileEntities/TileEntity.h | 3 +- Minecraft.World/Level/Level.cpp | 17 +- Minecraft.World/Level/Level.h | 4 +- Minecraft.World/Level/LevelChunk.cpp | 10 +- 11 files changed, 213 insertions(+), 152 deletions(-) diff --git a/Minecraft.Client/Rendering/Chunk.cpp b/Minecraft.Client/Rendering/Chunk.cpp index ff0550717..9b294d5e8 100644 --- a/Minecraft.Client/Rendering/Chunk.cpp +++ b/Minecraft.Client/Rendering/Chunk.cpp @@ -8,6 +8,7 @@ #include "../../Minecraft.World/Headers/net.minecraft.world.level.tile.entity.h" #include "LevelRenderer.h" #include "../Utils/FrameProfiler.h" +#include #ifdef __PS3__ #include "../Platform/PS3/SPU_Tasks/ChunkUpdate/ChunkRebuildData.h" @@ -36,6 +37,66 @@ Tesselator* Chunk::t = Tesselator::getInstance(); #endif LevelRenderer* Chunk::levelRenderer; +void Chunk::reconcileRenderableTileEntities( + const std::vector >& renderableTileEntities) { + int key = + levelRenderer->getGlobalIndexForChunk(this->x, this->y, this->z, level); + AUTO_VAR(it, globalRenderableTileEntities->find(key)); + if (!renderableTileEntities.empty()) { + std::unordered_set currentRenderableTileEntitySet; + currentRenderableTileEntitySet.reserve(renderableTileEntities.size()); + for (size_t i = 0; i < renderableTileEntities.size(); i++) { + currentRenderableTileEntitySet.insert(renderableTileEntities[i].get()); + } + + if (it != globalRenderableTileEntities->end()) { + LevelRenderer::RenderableTileEntityBucket& existingBucket = + it->second; + + for (AUTO_VAR(it2, existingBucket.tiles.begin()); + it2 != existingBucket.tiles.end(); it2++) { + TileEntity* tileEntity = (*it2).get(); + if (currentRenderableTileEntitySet.find(tileEntity) == + currentRenderableTileEntitySet.end()) { + (*it2)->setRenderRemoveStage( + TileEntity::e_RenderRemoveStageFlaggedAtChunk); + levelRenderer->queueRenderableTileEntityForRemoval_Locked( + key, tileEntity); + } else { + (*it2)->setRenderRemoveStage( + TileEntity::e_RenderRemoveStageKeep); + } + } + + for (size_t i = 0; i < renderableTileEntities.size(); i++) { + renderableTileEntities[i]->setRenderRemoveStage( + TileEntity::e_RenderRemoveStageKeep); + if (existingBucket.indexByTile.find(renderableTileEntities[i].get()) == + existingBucket.indexByTile.end()) { + levelRenderer->addRenderableTileEntity_Locked( + key, renderableTileEntities[i]); + } + } + } else { + for (size_t i = 0; i < renderableTileEntities.size(); i++) { + renderableTileEntities[i]->setRenderRemoveStage( + TileEntity::e_RenderRemoveStageKeep); + levelRenderer->addRenderableTileEntity_Locked( + key, renderableTileEntities[i]); + } + } + } else if (it != globalRenderableTileEntities->end()) { + for (AUTO_VAR(it2, it->second.tiles.begin()); + it2 != it->second.tiles.end(); + it2++) { + (*it2)->setRenderRemoveStage( + TileEntity::e_RenderRemoveStageFlaggedAtChunk); + levelRenderer->queueRenderableTileEntityForRemoval_Locked(key, + (*it2).get()); + } + } +} + // TODO - 4J see how input entity vector is set up and decide what way is best // to pass this to the function Chunk::Chunk(Level* level, LevelRenderer::rteMap& globalRenderableTileEntities, @@ -519,57 +580,8 @@ void Chunk::rebuild() { // from the dimension and chunk position (using same index as is used for // global flags) #if 1 - int key = - levelRenderer->getGlobalIndexForChunk(this->x, this->y, this->z, level); EnterCriticalSection(globalRenderableTileEntities_cs); - if (renderableTileEntities.size()) { - AUTO_VAR(it, globalRenderableTileEntities->find(key)); - if (it != globalRenderableTileEntities->end()) { - // We've got some renderable tile entities that we want associated - // with this chunk, and an existing list of things that used to be. - // We need to flag any that we don't need any more to be removed, - // keep those that we do, and add any new ones - - // First pass - flag everything already existing to be removed - for (AUTO_VAR(it2, it->second.begin()); it2 != it->second.end(); - it2++) { - (*it2)->setRenderRemoveStage( - TileEntity::e_RenderRemoveStageFlaggedAtChunk); - } - - // Now go through the current list. If these are already in the - // list, then unflag the remove flag. If they aren't, then add - for (int i = 0; i < renderableTileEntities.size(); i++) { - AUTO_VAR(it2, find(it->second.begin(), it->second.end(), - renderableTileEntities[i])); - if (it2 == it->second.end()) { - (*globalRenderableTileEntities)[key].push_back( - renderableTileEntities[i]); - } else { - (*it2)->setRenderRemoveStage( - TileEntity::e_RenderRemoveStageKeep); - } - } - } else { - // Easy case - nothing already existing for this chunk. Add them all - // in. - for (int i = 0; i < renderableTileEntities.size(); i++) { - (*globalRenderableTileEntities)[key].push_back( - renderableTileEntities[i]); - } - } - } else { - // Another easy case - we don't want any renderable tile entities - // associated with this chunk. Flag all to be removed. - AUTO_VAR(it, globalRenderableTileEntities->find(key)); - if (it != globalRenderableTileEntities->end()) { - for (AUTO_VAR(it2, it->second.begin()); it2 != it->second.end(); - it2++) { - (*it2)->setRenderRemoveStage( - TileEntity::e_RenderRemoveStageFlaggedAtChunk); - } - } - } + reconcileRenderableTileEntities(renderableTileEntities); LeaveCriticalSection(globalRenderableTileEntities_cs); PIXEndNamedEvent(); #else @@ -831,57 +843,8 @@ void Chunk::rebuild_SPU() { // from the dimension and chunk position (using same index as is used for // global flags) #if 1 - int key = - levelRenderer->getGlobalIndexForChunk(this->x, this->y, this->z, level); EnterCriticalSection(globalRenderableTileEntities_cs); - if (renderableTileEntities.size()) { - AUTO_VAR(it, globalRenderableTileEntities->find(key)); - if (it != globalRenderableTileEntities->end()) { - // We've got some renderable tile entities that we want associated - // with this chunk, and an existing list of things that used to be. - // We need to flag any that we don't need any more to be removed, - // keep those that we do, and add any new ones - - // First pass - flag everything already existing to be removed - for (AUTO_VAR(it2, it->second.begin()); it2 != it->second.end(); - it2++) { - (*it2)->setRenderRemoveStage( - TileEntity::e_RenderRemoveStageFlaggedAtChunk); - } - - // Now go through the current list. If these are already in the - // list, then unflag the remove flag. If they aren't, then add - for (int i = 0; i < renderableTileEntities.size(); i++) { - AUTO_VAR(it2, find(it->second.begin(), it->second.end(), - renderableTileEntities[i])); - if (it2 == it->second.end()) { - (*globalRenderableTileEntities)[key].push_back( - renderableTileEntities[i]); - } else { - (*it2)->setRenderRemoveStage( - TileEntity::e_RenderRemoveStageKeep); - } - } - } else { - // Easy case - nothing already existing for this chunk. Add them all - // in. - for (int i = 0; i < renderableTileEntities.size(); i++) { - (*globalRenderableTileEntities)[key].push_back( - renderableTileEntities[i]); - } - } - } else { - // Another easy case - we don't want any renderable tile entities - // associated with this chunk. Flag all to be removed. - AUTO_VAR(it, globalRenderableTileEntities->find(key)); - if (it != globalRenderableTileEntities->end()) { - for (AUTO_VAR(it2, it->second.begin()); it2 != it->second.end(); - it2++) { - (*it2)->setRenderRemoveStage( - TileEntity::e_RenderRemoveStageFlaggedAtChunk); - } - } - } + reconcileRenderableTileEntities(renderableTileEntities); LeaveCriticalSection(globalRenderableTileEntities_cs); #else // Find the removed ones: @@ -1108,15 +1071,19 @@ uint64_t Chunk::computeConnectivity(const uint8_t* tileIds) { } void Chunk::reset() { if (assigned) { + int oldKey = -1; + bool retireRenderableTileEntities = false; + EnterCriticalSection(&levelRenderer->m_csDirtyChunks); + oldKey = levelRenderer->getGlobalIndexForChunk(x, y, z, level); unsigned char refCount = levelRenderer->decGlobalChunkRefCount(x, y, z, level); assigned = false; // printf("\t\t [dec] refcount %d at %d, %d, //%d\n",refCount,x,y,z); - if (refCount == 0) { - int lists = - levelRenderer->getGlobalIndexForChunk(x, y, z, level) * 2; + if (refCount == 0 && oldKey != -1) { + retireRenderableTileEntities = true; + int lists = oldKey * 2; if (lists >= 0) { lists += levelRenderer->chunkLists; for (int i = 0; i < 2; i++) { @@ -1128,6 +1095,10 @@ void Chunk::reset() { } } LeaveCriticalSection(&levelRenderer->m_csDirtyChunks); + + if (retireRenderableTileEntities) { + levelRenderer->retireRenderableTileEntitiesForChunkKey(oldKey); + } } clipChunk->visible = false; diff --git a/Minecraft.Client/Rendering/Chunk.h b/Minecraft.Client/Rendering/Chunk.h index c524c69ce..fded430cf 100644 --- a/Minecraft.Client/Rendering/Chunk.h +++ b/Minecraft.Client/Rendering/Chunk.h @@ -69,6 +69,8 @@ public: private: void translateToPos(); + void reconcileRenderableTileEntities( + const std::vector >& renderableTileEntities); public: void makeCopyForRebuild(Chunk* source); diff --git a/Minecraft.Client/Rendering/LevelRenderer.cpp b/Minecraft.Client/Rendering/LevelRenderer.cpp index a91df96dd..763611cca 100644 --- a/Minecraft.Client/Rendering/LevelRenderer.cpp +++ b/Minecraft.Client/Rendering/LevelRenderer.cpp @@ -410,8 +410,12 @@ void LevelRenderer::setLevel(int playerIndex, MultiPlayerLevel* level) { // tile entities in the world dissappear We should only do this when // actually exiting the game, so only when the primary player sets there // level to NULL - if (playerIndex == ProfileManager.GetPrimaryPad()) + if (playerIndex == ProfileManager.GetPrimaryPad()) { + EnterCriticalSection(&m_csRenderableTileEntities); renderableTileEntities.clear(); + m_renderableTileEntitiesPendingRemoval.clear(); + LeaveCriticalSection(&m_csRenderableTileEntities); + } } } @@ -641,34 +645,13 @@ void LevelRenderer::renderEntities(Vec3* cam, Culler* culler, float a) { // Don't render if it isn't in the same dimension as this player if (!isGlobalIndexInSameDimension(idx, level[playerIndex])) continue; - for (AUTO_VAR(it2, it->second.begin()); it2 != it->second.end(); + for (AUTO_VAR(it2, it->second.tiles.begin()); + it2 != it->second.tiles.end(); it2++) { TileEntityRenderDispatcher::instance->render(*it2, a); } } - // Now consider if any of these renderable tile entities have been flagged - // for removal, and if so, remove - for (AUTO_VAR(it, renderableTileEntities.begin()); - it != renderableTileEntities.end();) { - int idx = it->first; - - for (AUTO_VAR(it2, it->second.begin()); it2 != it->second.end();) { - // If it has been flagged for removal, remove - if ((*it2)->shouldRemoveForRender()) { - it2 = it->second.erase(it2); - } else { - it2++; - } - } - - // If there aren't any entities left for this key, then delete the key - if (it->second.size() == 0) { - it = renderableTileEntities.erase(it); - } else { - it++; - } - } LeaveCriticalSection(&m_csRenderableTileEntities); @@ -4181,16 +4164,87 @@ unsigned char LevelRenderer::decGlobalChunkRefCount(int x, int y, int z, } } +void LevelRenderer::queueRenderableTileEntityForRemoval_Locked( + int key, TileEntity* tileEntity) { + m_renderableTileEntitiesPendingRemoval[key].insert(tileEntity); +} + +void LevelRenderer::addRenderableTileEntity_Locked( + int key, const std::shared_ptr& tileEntity) { + RenderableTileEntityBucket& bucket = renderableTileEntities[key]; + TileEntity* tileEntityPtr = tileEntity.get(); + if (bucket.indexByTile.find(tileEntityPtr) != bucket.indexByTile.end()) { + return; + } + + size_t index = bucket.tiles.size(); + bucket.tiles.push_back(tileEntity); + bucket.indexByTile.insert(std::make_pair(tileEntityPtr, index)); +} + +void LevelRenderer::eraseRenderableTileEntity_Locked( + RenderableTileEntityBucket& bucket, TileEntity* tileEntity) { + auto it = bucket.indexByTile.find(tileEntity); + if (it == bucket.indexByTile.end()) { + return; + } + + size_t index = it->second; + size_t lastIndex = bucket.tiles.size() - 1; + if (index != lastIndex) { + std::shared_ptr moved = bucket.tiles[lastIndex]; + bucket.tiles[index] = moved; + bucket.indexByTile[moved.get()] = index; + } + + bucket.tiles.pop_back(); + bucket.indexByTile.erase(it); +} + +void LevelRenderer::retireRenderableTileEntitiesForChunkKey(int key) { + if (key == -1) return; + + EnterCriticalSection(&m_csRenderableTileEntities); + renderableTileEntities.erase(key); + m_renderableTileEntitiesPendingRemoval.erase(key); + LeaveCriticalSection(&m_csRenderableTileEntities); +} + // 4J added void LevelRenderer::fullyFlagRenderableTileEntitiesToBeRemoved() { + FRAME_PROFILE_SCOPE(RenderableTileEntityCleanup); + EnterCriticalSection(&m_csRenderableTileEntities); - AUTO_VAR(itChunkEnd, renderableTileEntities.end()); - for (AUTO_VAR(it, renderableTileEntities.begin()); it != itChunkEnd; it++) { - AUTO_VAR(itTEEnd, it->second.end()); - for (AUTO_VAR(it2, it->second.begin()); it2 != itTEEnd; it2++) { - (*it2)->upgradeRenderRemoveStage(); + if (m_renderableTileEntitiesPendingRemoval.empty()) { + LeaveCriticalSection(&m_csRenderableTileEntities); + return; + } + + auto itKeyEnd = m_renderableTileEntitiesPendingRemoval.end(); + for (auto itKey = m_renderableTileEntitiesPendingRemoval.begin(); + itKey != itKeyEnd; itKey++) { + auto itChunk = renderableTileEntities.find(itKey->first); + if (itChunk == renderableTileEntities.end()) continue; + + RenderableTileEntityBucket& bucket = itChunk->second; + for (AUTO_VAR(itPending, itKey->second.begin()); + itPending != itKey->second.end(); itPending++) { + if (bucket.indexByTile.find(*itPending) == bucket.indexByTile.end()) { + continue; + } + + if (!(*itPending)->finalizeRenderRemoveStage()) { + continue; + } + + eraseRenderableTileEntity_Locked(bucket, *itPending); + } + + if (bucket.tiles.empty()) { + renderableTileEntities.erase(itChunk); } } + m_renderableTileEntitiesPendingRemoval.clear(); LeaveCriticalSection(&m_csRenderableTileEntities); } diff --git a/Minecraft.Client/Rendering/LevelRenderer.h b/Minecraft.Client/Rendering/LevelRenderer.h index 081aa98b9..fbafa7ce8 100644 --- a/Minecraft.Client/Rendering/LevelRenderer.h +++ b/Minecraft.Client/Rendering/LevelRenderer.h @@ -10,6 +10,7 @@ #ifdef __PS3__ #include "../Platform/PS3/PS3Extras/C4JSpursJob.h" #endif +#include class MultiPlayerLevel; class Textures; class Chunk; @@ -163,8 +164,13 @@ public: void destroyTileProgress(int id, int x, int y, int z, int progress); void registerTextures(IconRegister* iconRegister); - typedef std::unordered_map >, - IntKeyHash, IntKeyEq> + struct RenderableTileEntityBucket { + std::vector > tiles; + std::unordered_map indexByTile; + }; + + typedef std::unordered_map rteMap; private: @@ -176,6 +182,10 @@ private: rteMap renderableTileEntities; // 4J - changed - was // std::vector, // now hashed by chunk so we can find them + typedef std::unordered_set rtePendingRemovalSet; + typedef std::unordered_map + rtePendingRemovalMap; + rtePendingRemovalMap m_renderableTileEntitiesPendingRemoval; CRITICAL_SECTION m_csRenderableTileEntities; MultiPlayerLevel* level[4]; // 4J - now one per player Textures* textures; @@ -214,6 +224,14 @@ private: std::unordered_map destroyingBlocks; Icon** breakingTextures; + void addRenderableTileEntity_Locked( + int key, const std::shared_ptr& tileEntity); + void eraseRenderableTileEntity_Locked( + RenderableTileEntityBucket& bucket, TileEntity* tileEntity); + void queueRenderableTileEntityForRemoval_Locked(int key, + TileEntity* tileEntity); + void retireRenderableTileEntitiesForChunkKey(int key); + public: void fullyFlagRenderableTileEntitiesToBeRemoved(); // 4J added diff --git a/Minecraft.Client/Utils/FrameProfiler.cpp b/Minecraft.Client/Utils/FrameProfiler.cpp index 89db484eb..53ddaa42f 100644 --- a/Minecraft.Client/Utils/FrameProfiler.cpp +++ b/Minecraft.Client/Utils/FrameProfiler.cpp @@ -44,6 +44,8 @@ constexpr std::array {Bucket::ChunkBlockFaceCull, "chunkBlockFaceCull"}, {Bucket::ChunkBlockLighting, "chunkBlockLighting"}, {Bucket::ChunkBlockEmit, "chunkBlockEmit"}, + {Bucket::RenderableTileEntityCleanup, "renderableTileEntityCleanup"}, + {Bucket::TileEntityUnloadCleanup, "tileEntityUnloadCleanup"}, {Bucket::Entity, "entities"}, {Bucket::Particle, "particles"}, {Bucket::WeatherSky, "weather"}, @@ -133,8 +135,7 @@ inline void recordWorkerBucket(Bucket bucket, std::uint64_t elapsedNs) noexcept return t_threadState.frameScopeDepth != 0; } -FRAME_PROFILER_NOINLINE -[[nodiscard]] bool computeEnabled() noexcept { +FRAME_PROFILER_NOINLINE bool computeEnabled() noexcept { const char* const envValue = std::getenv("C4J_FRAME_PROFILER"); if (envValue == nullptr) return true; return !envSaysDisabled(envValue); diff --git a/Minecraft.Client/Utils/FrameProfiler.h b/Minecraft.Client/Utils/FrameProfiler.h index 7abf56255..c22351f69 100644 --- a/Minecraft.Client/Utils/FrameProfiler.h +++ b/Minecraft.Client/Utils/FrameProfiler.h @@ -23,6 +23,8 @@ public: ChunkBlockFaceCull, ChunkBlockLighting, ChunkBlockEmit, + RenderableTileEntityCleanup, + TileEntityUnloadCleanup, Entity, Particle, WeatherSky, diff --git a/Minecraft.World/Blocks/TileEntities/TileEntity.cpp b/Minecraft.World/Blocks/TileEntities/TileEntity.cpp index 24986046f..66ae1afac 100644 --- a/Minecraft.World/Blocks/TileEntities/TileEntity.cpp +++ b/Minecraft.World/Blocks/TileEntities/TileEntity.cpp @@ -187,6 +187,15 @@ void TileEntity::upgradeRenderRemoveStage() { } } +bool TileEntity::finalizeRenderRemoveStage() { + if (renderRemoveStage == e_RenderRemoveStageFlaggedAtChunk) { + renderRemoveStage = e_RenderRemoveStageRemove; + return true; + } + + return renderRemoveStage == e_RenderRemoveStageRemove; +} + // 4J Added void TileEntity::clone(std::shared_ptr tileEntity) { tileEntity->level = this->level; @@ -195,4 +204,4 @@ void TileEntity::clone(std::shared_ptr tileEntity) { tileEntity->z = this->z; tileEntity->data = this->data; tileEntity->tile = this->tile; -} \ No newline at end of file +} diff --git a/Minecraft.World/Blocks/TileEntities/TileEntity.h b/Minecraft.World/Blocks/TileEntities/TileEntity.h index e640ae2e4..fc382b673 100644 --- a/Minecraft.World/Blocks/TileEntities/TileEntity.h +++ b/Minecraft.World/Blocks/TileEntities/TileEntity.h @@ -49,6 +49,7 @@ public: void setRenderRemoveStage(unsigned char stage); // 4J added void upgradeRenderRemoveStage(); // 4J added + bool finalizeRenderRemoveStage(); // 4J added bool shouldRemoveForRender(); // 4J added virtual Level* getLevel(); @@ -77,4 +78,4 @@ public: protected: void clone(std::shared_ptr tileEntity); -}; \ No newline at end of file +}; diff --git a/Minecraft.World/Level/Level.cpp b/Minecraft.World/Level/Level.cpp index ab251a833..06c99a2ae 100644 --- a/Minecraft.World/Level/Level.cpp +++ b/Minecraft.World/Level/Level.cpp @@ -38,6 +38,7 @@ #include "../../Minecraft.Client/Platform/Common/DLC/DLCPack.h" #include "../../Minecraft.Client/Platform/PS3/PS3Extras/ShutdownManager.h" #include "../../Minecraft.Client/MinecraftServer.h" +#include "../../Minecraft.Client/Utils/FrameProfiler.h" #include #include #include @@ -2206,19 +2207,11 @@ void Level::tickEntities() { // 4J-PB - Stuart - check this is correct here if (!tileEntitiesToUnload.empty()) { - // tileEntityList.removeAll(tileEntitiesToUnload); + FRAME_PROFILE_SCOPE(TileEntityUnloadCleanup); for (AUTO_VAR(it, tileEntityList.begin()); it != tileEntityList.end();) { - bool found = false; - for (AUTO_VAR(it2, tileEntitiesToUnload.begin()); - it2 != tileEntitiesToUnload.end(); it2++) { - if ((*it) == (*it2)) { - found = true; - break; - } - } - if (found) { + if (tileEntitiesToUnload.find(*it) != tileEntitiesToUnload.end()) { if (isClientSide) { __debugbreak(); } @@ -2731,7 +2724,9 @@ void Level::removeTileEntity(int x, int y, int z) { } void Level::markForRemoval(std::shared_ptr entity) { - tileEntitiesToUnload.push_back(entity); + EnterCriticalSection(&m_tileEntityListCS); + tileEntitiesToUnload.insert(entity); + LeaveCriticalSection(&m_tileEntityListCS); } bool Level::isSolidRenderTile(int x, int y, int z) { diff --git a/Minecraft.World/Level/Level.h b/Minecraft.World/Level/Level.h index d28d1cda5..50910ada0 100644 --- a/Minecraft.World/Level/Level.h +++ b/Minecraft.World/Level/Level.h @@ -10,6 +10,7 @@ #include "../WorldGen/Biomes/Biome.h" #include "../Util/C4JThread.h" #include +#include #ifdef __PSVITA__ #include "../../Minecraft.Client/Platform/PSVita/PSVitaExtras/CustomSet.h" @@ -118,7 +119,7 @@ public: private: std::vector > pendingTileEntities; - std::vector > tileEntitiesToUnload; + std::unordered_set > tileEntitiesToUnload; bool updatingTileEntities; public: @@ -665,3 +666,4 @@ public: bool canCreateMore(eINSTANCEOF type, ESPAWN_TYPE spawnType); }; +#include diff --git a/Minecraft.World/Level/LevelChunk.cpp b/Minecraft.World/Level/LevelChunk.cpp index 5f95fd9d2..52193665f 100644 --- a/Minecraft.World/Level/LevelChunk.cpp +++ b/Minecraft.World/Level/LevelChunk.cpp @@ -1558,13 +1558,19 @@ void LevelChunk::unload(bool unloadTileEntities) // 4J - added parameter { loaded = false; if (unloadTileEntities) { + std::vector > tileEntitiesToRemove; EnterCriticalSection(&m_csTileEntities); for (AUTO_VAR(it, tileEntities.begin()); it != tileEntities.end(); it++) { - // 4J-PB -m 1.7.3 was it->second->setRemoved(); - level->markForRemoval(it->second); + tileEntitiesToRemove.push_back(it->second); } LeaveCriticalSection(&m_csTileEntities); + + AUTO_VAR(itEnd, tileEntitiesToRemove.end()); + for (AUTO_VAR(it, tileEntitiesToRemove.begin()); it != itEnd; it++) { + // 4J-PB -m 1.7.3 was it->second->setRemoved(); + level->markForRemoval(*it); + } } #ifdef _ENTITIES_RW_SECTION From 3986e4642ba7b977ed1883b28da110368b412125 Mon Sep 17 00:00:00 2001 From: JuiceyDev Date: Mon, 30 Mar 2026 00:36:50 +0200 Subject: [PATCH 156/170] ghost segfault??????? --- Minecraft.Client/Rendering/LevelRenderer.cpp | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/Minecraft.Client/Rendering/LevelRenderer.cpp b/Minecraft.Client/Rendering/LevelRenderer.cpp index 763611cca..596a06055 100644 --- a/Minecraft.Client/Rendering/LevelRenderer.cpp +++ b/Minecraft.Client/Rendering/LevelRenderer.cpp @@ -646,13 +646,11 @@ void LevelRenderer::renderEntities(Vec3* cam, Culler* culler, float a) { if (!isGlobalIndexInSameDimension(idx, level[playerIndex])) continue; for (AUTO_VAR(it2, it->second.tiles.begin()); - it2 != it->second.tiles.end(); - it2++) { + it2 != it->second.tiles.end(); it2++) { TileEntityRenderDispatcher::instance->render(*it2, a); } } - LeaveCriticalSection(&m_csRenderableTileEntities); mc->gameRenderer->turnOffLightLayer(a); // 4J - brought forward from 1.8.2 @@ -874,9 +872,9 @@ int LevelRenderer::renderChunks(int from, int to, int layer, double alpha) { // 4jcraft: replaced glPushMatrix/glTranslatef/glPopMatrix per chunk // no more full MVP upload per chunk, can also be bkwards compat - RenderManager.SetChunkOffset((float)pClipChunk->chunk->x, - (float)pClipChunk->chunk->y, - (float)pClipChunk->chunk->z); + RenderManager.SetChunkOffset((float)chunk->chunk->x, + (float)chunk->chunk->y, + (float)chunk->chunk->z); if (RenderManager.CBuffCall(list, first)) { first = false; @@ -4229,7 +4227,8 @@ void LevelRenderer::fullyFlagRenderableTileEntitiesToBeRemoved() { RenderableTileEntityBucket& bucket = itChunk->second; for (AUTO_VAR(itPending, itKey->second.begin()); itPending != itKey->second.end(); itPending++) { - if (bucket.indexByTile.find(*itPending) == bucket.indexByTile.end()) { + if (bucket.indexByTile.find(*itPending) == + bucket.indexByTile.end()) { continue; } From 19e7386d125fd945be32d2239fcc9fd2cef76b9f Mon Sep 17 00:00:00 2001 From: JuiceyDev Date: Mon, 30 Mar 2026 01:25:35 +0200 Subject: [PATCH 157/170] light fix --- Minecraft.Client/Rendering/LevelRenderer.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Minecraft.Client/Rendering/LevelRenderer.cpp b/Minecraft.Client/Rendering/LevelRenderer.cpp index 596a06055..c15b3027a 100644 --- a/Minecraft.Client/Rendering/LevelRenderer.cpp +++ b/Minecraft.Client/Rendering/LevelRenderer.cpp @@ -767,10 +767,10 @@ int LevelRenderer::render(std::shared_ptr player, int layer, } Lighting::turnOff(); glColor4f(1, 1, 1, 1); - glColor4f(1, 1, 1, 1); + mc->gameRenderer->turnOnLightLayer(alpha); int count = renderChunks(0, (int)chunks[playerIndex].length, layer, alpha); - + mc->gameRenderer->turnOffLightLayer(alpha); return count; } @@ -791,13 +791,14 @@ int compare(const void* a, const void* b) { int LevelRenderer::renderChunks(int from, int to, int layer, double alpha) { int playerIndex = mc->player->GetXboxPad(); if (chunks[playerIndex].data == NULL) return 0; - + mc->gameRenderer->turnOnLightLayer(alpha); std::shared_ptr player = mc->cameraTargetPlayer; double xOff = player->xOld + (player->x - player->xOld) * alpha; double yOff = player->yOld + (player->y - player->yOld) * alpha; double zOff = player->zOld + (player->z - player->zOld) * alpha; glPushMatrix(); + glTranslatef((float)-xOff, (float)-yOff, (float)-zOff); #ifdef __PS3__ From f25b105beed41734b060d72de74b9742e07f5c75 Mon Sep 17 00:00:00 2001 From: JuiceyDev Date: Mon, 30 Mar 2026 01:46:49 +0200 Subject: [PATCH 158/170] slight optimizations --- Minecraft.Client/Rendering/LevelRenderer.cpp | 31 ++++++++++++++------ Minecraft.Client/Rendering/LevelRenderer.h | 6 ++-- 2 files changed, 26 insertions(+), 11 deletions(-) diff --git a/Minecraft.Client/Rendering/LevelRenderer.cpp b/Minecraft.Client/Rendering/LevelRenderer.cpp index c15b3027a..160b945c1 100644 --- a/Minecraft.Client/Rendering/LevelRenderer.cpp +++ b/Minecraft.Client/Rendering/LevelRenderer.cpp @@ -2948,15 +2948,20 @@ void LevelRenderer::cull(Culler* culler, float a) { int sizeX = maxCx - minCx + 1; int sizeY = maxCy - minCy + 1; int sizeZ = maxCz - minCz + 1; + int gridSize = sizeX * sizeY * sizeZ; - std::vector grid(sizeX * sizeY * sizeZ, nullptr); + if (m_bfsGrid.size() < gridSize) { + m_bfsGrid.resize(gridSize); + } + + memset(m_bfsGrid.data(), 0, gridSize * sizeof(ClipChunk*)); for (unsigned int i = 0; i < chunks[playerIndex].length; i++) { ClipChunk* cc = &chunks[playerIndex][i]; if (cc->globalIdx < 0) continue; int lx = intFloorDiv(cc->chunk->x, CHUNK_XZSIZE) - minCx; int ly = intFloorDiv(cc->chunk->y, CHUNK_SIZE) - minCy; int lz = intFloorDiv(cc->chunk->z, CHUNK_XZSIZE) - minCz; - grid[(lx * sizeY + ly) * sizeZ + lz] = cc; + m_bfsGrid[(lx * sizeY + ly) * sizeZ + lz] = cc; } auto getChunkAt = [&](int cx, int cy, int cz) -> ClipChunk* { @@ -2965,7 +2970,7 @@ void LevelRenderer::cull(Culler* culler, float a) { int lz = cz - minCz; if (lx >= 0 && lx < sizeX && ly >= 0 && ly < sizeY && lz >= 0 && lz < sizeZ) { - return grid[(lx * sizeY + ly) * sizeZ + lz]; + return m_bfsGrid[(lx * sizeY + ly) * sizeZ + lz]; } return nullptr; }; @@ -3014,14 +3019,20 @@ void LevelRenderer::cull(Culler* culler, float a) { int incomingFace; }; - std::vector q; - q.reserve(chunks[playerIndex].length * 2); + static thread_local std::vector q; + q.clear(); + q.reserve(chunks[playerIndex].length); int qHead = 0; - std::vector visitedFaces(chunks[playerIndex].length, 0); + int visitedSize = chunks[playerIndex].length; + if (m_bfsVisitedFaces[playerIndex].size() < visitedSize) { + m_bfsVisitedFaces[playerIndex].resize(visitedSize, 0); + } + memset(m_bfsVisitedFaces[playerIndex].data(), 0, visitedSize); q.push_back({startChunk, -1}); - visitedFaces[startChunk - chunks[playerIndex].data] = 0x3F; + m_bfsVisitedFaces[playerIndex][startChunk - chunks[playerIndex].data] = + 0x3F; static const int OFFSETS[6][3] = { {0, -1, 0}, // 0: -Y @@ -3096,7 +3107,9 @@ void LevelRenderer::cull(Culler* culler, float a) { int nIdx = neighbor - chunks[playerIndex].data; int nextIncFace = outFace ^ 1; - if ((visitedFaces[nIdx] & (1 << nextIncFace)) != 0) continue; + if ((m_bfsVisitedFaces[playerIndex][nIdx] & (1 << nextIncFace)) != + 0) + continue; float cellBounds[6] = { (float)neighbor->chunk->x - 0.1f, @@ -3108,7 +3121,7 @@ void LevelRenderer::cull(Culler* culler, float a) { if (!clip(cellBounds, fdraw)) continue; - visitedFaces[nIdx] |= (1 << nextIncFace); + m_bfsVisitedFaces[playerIndex][nIdx] |= (1 << nextIncFace); q.push_back({neighbor, nextIncFace}); } } diff --git a/Minecraft.Client/Rendering/LevelRenderer.h b/Minecraft.Client/Rendering/LevelRenderer.h index fbafa7ce8..ec925ebbe 100644 --- a/Minecraft.Client/Rendering/LevelRenderer.h +++ b/Minecraft.Client/Rendering/LevelRenderer.h @@ -221,13 +221,15 @@ private: OffsettedRenderList renderLists[RENDERLISTS_LENGTH]; void setGlobalChunkConnectivity(int index, uint64_t conn); uint64_t getGlobalChunkConnectivity(int index); + std::vector m_bfsGrid; + std::vector m_bfsVisitedFaces[4]; std::unordered_map destroyingBlocks; Icon** breakingTextures; void addRenderableTileEntity_Locked( int key, const std::shared_ptr& tileEntity); - void eraseRenderableTileEntity_Locked( - RenderableTileEntityBucket& bucket, TileEntity* tileEntity); + void eraseRenderableTileEntity_Locked(RenderableTileEntityBucket& bucket, + TileEntity* tileEntity); void queueRenderableTileEntityForRemoval_Locked(int key, TileEntity* tileEntity); void retireRenderableTileEntitiesForChunkKey(int key); From 4b8ebbb8240d65e24a12063ce59bb29a3d0ccd7d Mon Sep 17 00:00:00 2001 From: Tropical <42101043+tropicaaal@users.noreply.github.com> Date: Sun, 29 Mar 2026 21:02:24 -0500 Subject: [PATCH 159/170] what if i --- flake.nix | 60 ------------------------------------------------------- 1 file changed, 60 deletions(-) diff --git a/flake.nix b/flake.nix index 05ceb4fef..eed2e5ce2 100644 --- a/flake.nix +++ b/flake.nix @@ -4,36 +4,6 @@ inputs = { nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; flake-utils.url = "github:numtide/flake-utils"; - - shiggy = { - url = "github:4jcraft/shiggy/main"; - flake = false; - }; - - "4jlibs" = { - url = "github:4jcraft/4jlibs/main"; - flake = false; - }; - - miniaudio = { - url = "https://github.com/mackron/miniaudio/archive/refs/tags/0.11.22.tar.gz"; - flake = false; - }; - - miniaudio-patch = { - url = "https://wrapdb.mesonbuild.com/v2/miniaudio_0.11.22-2/get_patch"; - flake = false; - }; - - stb = { - url = "github:nothings/stb/master"; - flake = false; - }; - - simdutf = { - url = "github:simdutf/simdutf"; - flake = false; - }; }; outputs = @@ -57,36 +27,6 @@ dontFixup = true; dontUseCmakeConfigure = true; - # 4jcraft - Meson expects this subprojects structure - postUnpack = '' - mkdir -p $sourceRoot/subprojects - - cp -r ${inputs.shiggy} $sourceRoot/subprojects/shiggy - cp -r ${inputs."4jlibs"} $sourceRoot/subprojects/4jlibs - cp -r ${inputs.stb} $sourceRoot/subprojects/stb - cp -r ${inputs.simdutf} $sourceRoot/subprojects/simdutf - cp -r ${inputs.miniaudio} $sourceRoot/subprojects/miniaudio - - chmod -R u+w $sourceRoot/subprojects - ''; - - # 4jcraft - `stb` and `simdutf` patches - postPatch = '' - cp subprojects/packagefiles/stb/meson.build subprojects/stb/meson.build - cp subprojects/packagefiles/simdutf/meson.build subprojects/simdutf/meson.build - cp subprojects/packagefiles/simdutf/meson.options subprojects/simdutf/meson.options - - unzip ${inputs.miniaudio-patch} -d miniaudio-patch-tmp - cp -r miniaudio-patch-tmp/*/. subprojects/miniaudio/ - - cat > subprojects/miniaudio.wrap < Date: Sun, 29 Mar 2026 21:06:57 -0500 Subject: [PATCH 160/170] THAT IS SO ANNOYING WHY NIX --- flake.nix | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/flake.nix b/flake.nix index eed2e5ce2..05ceb4fef 100644 --- a/flake.nix +++ b/flake.nix @@ -4,6 +4,36 @@ inputs = { nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; flake-utils.url = "github:numtide/flake-utils"; + + shiggy = { + url = "github:4jcraft/shiggy/main"; + flake = false; + }; + + "4jlibs" = { + url = "github:4jcraft/4jlibs/main"; + flake = false; + }; + + miniaudio = { + url = "https://github.com/mackron/miniaudio/archive/refs/tags/0.11.22.tar.gz"; + flake = false; + }; + + miniaudio-patch = { + url = "https://wrapdb.mesonbuild.com/v2/miniaudio_0.11.22-2/get_patch"; + flake = false; + }; + + stb = { + url = "github:nothings/stb/master"; + flake = false; + }; + + simdutf = { + url = "github:simdutf/simdutf"; + flake = false; + }; }; outputs = @@ -27,6 +57,36 @@ dontFixup = true; dontUseCmakeConfigure = true; + # 4jcraft - Meson expects this subprojects structure + postUnpack = '' + mkdir -p $sourceRoot/subprojects + + cp -r ${inputs.shiggy} $sourceRoot/subprojects/shiggy + cp -r ${inputs."4jlibs"} $sourceRoot/subprojects/4jlibs + cp -r ${inputs.stb} $sourceRoot/subprojects/stb + cp -r ${inputs.simdutf} $sourceRoot/subprojects/simdutf + cp -r ${inputs.miniaudio} $sourceRoot/subprojects/miniaudio + + chmod -R u+w $sourceRoot/subprojects + ''; + + # 4jcraft - `stb` and `simdutf` patches + postPatch = '' + cp subprojects/packagefiles/stb/meson.build subprojects/stb/meson.build + cp subprojects/packagefiles/simdutf/meson.build subprojects/simdutf/meson.build + cp subprojects/packagefiles/simdutf/meson.options subprojects/simdutf/meson.options + + unzip ${inputs.miniaudio-patch} -d miniaudio-patch-tmp + cp -r miniaudio-patch-tmp/*/. subprojects/miniaudio/ + + cat > subprojects/miniaudio.wrap < Date: Mon, 30 Mar 2026 13:38:50 +1100 Subject: [PATCH 161/170] fix: sign entry crash and remove blocking callback workaround - Initialize m_iEditingLine to 0 in SignEntryMenu constructor (was uninitialized, causing out-of-bounds array access) - Add bounds check on m_iEditingLine before array access in callback - Only truncate sign text if longer than 15 chars (avoid padding) - Remove manual KeyboardCompleteSeedCallback call in LaunchMoreOptionsMenu (no longer needed since RequestKeyboard now fires callbacks asynchronously from Tick) --- .../Platform/Common/UI/UIScene_LaunchMoreOptionsMenu.cpp | 1 - .../Platform/Common/UI/UIScene_SignEntryMenu.cpp | 5 +++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Minecraft.Client/Platform/Common/UI/UIScene_LaunchMoreOptionsMenu.cpp b/Minecraft.Client/Platform/Common/UI/UIScene_LaunchMoreOptionsMenu.cpp index 8a7e7efda..fdd814ab7 100644 --- a/Minecraft.Client/Platform/Common/UI/UIScene_LaunchMoreOptionsMenu.cpp +++ b/Minecraft.Client/Platform/Common/UI/UIScene_LaunchMoreOptionsMenu.cpp @@ -644,7 +644,6 @@ void UIScene_LaunchMoreOptionsMenu::handlePress(F64 controlId, F64 childId) { 0, 60, &UIScene_LaunchMoreOptionsMenu::KeyboardCompleteSeedCallback, this, C_4JInput::EKeyboardMode_Default); - KeyboardCompleteSeedCallback(this, true); #endif } break; } diff --git a/Minecraft.Client/Platform/Common/UI/UIScene_SignEntryMenu.cpp b/Minecraft.Client/Platform/Common/UI/UIScene_SignEntryMenu.cpp index 70288fb1f..ad79dc97a 100644 --- a/Minecraft.Client/Platform/Common/UI/UIScene_SignEntryMenu.cpp +++ b/Minecraft.Client/Platform/Common/UI/UIScene_SignEntryMenu.cpp @@ -18,6 +18,7 @@ UIScene_SignEntryMenu::UIScene_SignEntryMenu(int iPad, void* _initData, SignEntryScreenInput* initData = (SignEntryScreenInput*)_initData; m_sign = initData->sign; + m_iEditingLine = 0; m_bConfirmed = false; m_bIgnoreInput = false; @@ -141,12 +142,12 @@ int UIScene_SignEntryMenu::KeyboardCompleteCallback(void* lpParam, bool bRes) { // 4J HEG - No reason to set value if keyboard was cancelled UIScene_SignEntryMenu* pClass = (UIScene_SignEntryMenu*)lpParam; pClass->m_bIgnoreInput = false; - if (bRes) { + if (bRes && pClass->m_iEditingLine >= 0 && pClass->m_iEditingLine < 4) { uint16_t pchText[128]; ZeroMemory(pchText, 128 * sizeof(uint16_t)); InputManager.GetText(pchText); std::wstring str = uint16_to_wstring(pchText); - str.resize(15); + if (str.size() > 15) str.resize(15); pClass->m_textInputLines[pClass->m_iEditingLine].setLabel(str); } return 0; From 95e0a14b363667f8b902e19aa5ec0a33a5fd4a0b Mon Sep 17 00:00:00 2001 From: MatthewBeshay <92357869+MatthewBeshay@users.noreply.github.com> Date: Mon, 30 Mar 2026 14:10:14 +1100 Subject: [PATCH 162/170] refactor: use convStringToWstring for text input instead of uint16 helpers GetText now returns UTF-8 directly so callers go through simdutf via convStringToWstring(). Remove dead uint16_to_wstring helpers. --- .../Platform/Common/UI/UIScene_AnvilMenu.cpp | 8 +++----- .../Platform/Common/UI/UIScene_CreateWorldMenu.cpp | 11 ++++------- .../Common/UI/UIScene_DebugCreateSchematic.cpp | 9 +++------ .../Platform/Common/UI/UIScene_DebugSetCamera.cpp | 9 +++------ .../Common/UI/UIScene_LaunchMoreOptionsMenu.cpp | 14 +++----------- .../Platform/Common/UI/UIScene_LoadOrJoinMenu.cpp | 7 ++----- .../Platform/Common/UI/UIScene_SignEntryMenu.cpp | 5 +---- Minecraft.World/Util/StringHelpers.cpp | 12 ------------ Minecraft.World/Util/StringHelpers.h | 3 --- 9 files changed, 19 insertions(+), 59 deletions(-) diff --git a/Minecraft.Client/Platform/Common/UI/UIScene_AnvilMenu.cpp b/Minecraft.Client/Platform/Common/UI/UIScene_AnvilMenu.cpp index c00466165..f3296c5a9 100644 --- a/Minecraft.Client/Platform/Common/UI/UIScene_AnvilMenu.cpp +++ b/Minecraft.Client/Platform/Common/UI/UIScene_AnvilMenu.cpp @@ -298,11 +298,9 @@ int UIScene_AnvilMenu::KeyboardCompleteCallback(void* lpParam, bool bRes) { pClass->setIgnoreInput(false); if (bRes) { - uint16_t pchText[128]; - ZeroMemory(pchText, 128 * sizeof(uint16_t)); - InputManager.GetText(pchText); - pClass->setEditNameValue(uint16_to_wstring(pchText)); - pClass->m_itemName = uint16_to_wstring(pchText); + std::wstring str = convStringToWstring(InputManager.GetText()); + pClass->setEditNameValue(str); + pClass->m_itemName = std::move(str); pClass->updateItemName(); } return 0; diff --git a/Minecraft.Client/Platform/Common/UI/UIScene_CreateWorldMenu.cpp b/Minecraft.Client/Platform/Common/UI/UIScene_CreateWorldMenu.cpp index 76beb132a..4a3c44c61 100644 --- a/Minecraft.Client/Platform/Common/UI/UIScene_CreateWorldMenu.cpp +++ b/Minecraft.Client/Platform/Common/UI/UIScene_CreateWorldMenu.cpp @@ -718,13 +718,10 @@ int UIScene_CreateWorldMenu::KeyboardCompleteWorldNameCallback(void* lpParam, pClass->m_bIgnoreInput = false; // 4J HEG - No reason to set value if keyboard was cancelled if (bRes) { - uint16_t pchText[128]; - ZeroMemory(pchText, 128 * sizeof(uint16_t)); - InputManager.GetText(pchText); - - if (pchText[0] != 0) { - pClass->m_editWorldName.setLabel(uint16_to_wstring(pchText)); - pClass->m_worldName = uint16_to_wstring(pchText); + std::wstring str = convStringToWstring(InputManager.GetText()); + if (!str.empty()) { + pClass->m_editWorldName.setLabel(str); + pClass->m_worldName = std::move(str); } pClass->m_buttonCreateWorld.setEnable(!pClass->m_worldName.empty()); diff --git a/Minecraft.Client/Platform/Common/UI/UIScene_DebugCreateSchematic.cpp b/Minecraft.Client/Platform/Common/UI/UIScene_DebugCreateSchematic.cpp index 00b175887..6eb2c7bb4 100644 --- a/Minecraft.Client/Platform/Common/UI/UIScene_DebugCreateSchematic.cpp +++ b/Minecraft.Client/Platform/Common/UI/UIScene_DebugCreateSchematic.cpp @@ -141,12 +141,9 @@ int UIScene_DebugCreateSchematic::KeyboardCompleteCallback(void* lpParam, UIScene_DebugCreateSchematic* pClass = (UIScene_DebugCreateSchematic*)lpParam; - uint16_t pchText[128]; - ZeroMemory(pchText, 128 * sizeof(uint16_t)); - InputManager.GetText(pchText); - - if (pchText[0] != 0) { - std::wstring value = uint16_to_wstring(pchText); + const char* text = InputManager.GetText(); + if (text[0] != '\0') { + std::wstring value = convStringToWstring(text); int iVal = 0; if (!value.empty()) iVal = _fromString(value); switch (pClass->m_keyboardCallbackControl) { diff --git a/Minecraft.Client/Platform/Common/UI/UIScene_DebugSetCamera.cpp b/Minecraft.Client/Platform/Common/UI/UIScene_DebugSetCamera.cpp index 1472864e3..74787f726 100644 --- a/Minecraft.Client/Platform/Common/UI/UIScene_DebugSetCamera.cpp +++ b/Minecraft.Client/Platform/Common/UI/UIScene_DebugSetCamera.cpp @@ -119,12 +119,9 @@ void UIScene_DebugSetCamera::handleCheckboxToggled(F64 controlId, int UIScene_DebugSetCamera::KeyboardCompleteCallback(void* lpParam, bool bRes) { UIScene_DebugSetCamera* pClass = (UIScene_DebugSetCamera*)lpParam; - uint16_t pchText[2048]; //[128]; - ZeroMemory(pchText, 2048 /*128*/ * sizeof(uint16_t)); - InputManager.GetText(pchText); - - if (pchText[0] != 0) { - std::wstring value = uint16_to_wstring(pchText); + const char* text = InputManager.GetText(); + if (text[0] != '\0') { + std::wstring value = convStringToWstring(text); double val = 0; if (!value.empty()) val = _fromString(value); switch (pClass->m_keyboardCallbackControl) { diff --git a/Minecraft.Client/Platform/Common/UI/UIScene_LaunchMoreOptionsMenu.cpp b/Minecraft.Client/Platform/Common/UI/UIScene_LaunchMoreOptionsMenu.cpp index fdd814ab7..3aa26be48 100644 --- a/Minecraft.Client/Platform/Common/UI/UIScene_LaunchMoreOptionsMenu.cpp +++ b/Minecraft.Client/Platform/Common/UI/UIScene_LaunchMoreOptionsMenu.cpp @@ -592,17 +592,9 @@ int UIScene_LaunchMoreOptionsMenu::KeyboardCompleteSeedCallback(void* lpParam, (UIScene_LaunchMoreOptionsMenu*)lpParam; // 4J HEG - No reason to set value if keyboard was cancelled if (bRes) { -#ifdef __PSVITA__ - // CD - Changed to 2048 [SCE_IME_MAX_TEXT_LENGTH] - uint16_t pchText[2048]; - ZeroMemory(pchText, 2048 * sizeof(uint16_t)); -#else - uint16_t pchText[128]; - ZeroMemory(pchText, 128 * sizeof(uint16_t)); -#endif - InputManager.GetText(pchText); - pClass->m_editSeed.setLabel(uint16_to_wstring(pchText)); - pClass->m_params->seed = uint16_to_wstring(pchText); + std::wstring str = convStringToWstring(InputManager.GetText()); + pClass->m_editSeed.setLabel(str); + pClass->m_params->seed = std::move(str); } pClass->m_bIgnoreInput = false; return 0; diff --git a/Minecraft.Client/Platform/Common/UI/UIScene_LoadOrJoinMenu.cpp b/Minecraft.Client/Platform/Common/UI/UIScene_LoadOrJoinMenu.cpp index 31e09f0fb..73a87a38d 100644 --- a/Minecraft.Client/Platform/Common/UI/UIScene_LoadOrJoinMenu.cpp +++ b/Minecraft.Client/Platform/Common/UI/UIScene_LoadOrJoinMenu.cpp @@ -1177,12 +1177,9 @@ int UIScene_LoadOrJoinMenu::KeyboardCompleteWorldNameCallback(void* lpParam, UIScene_LoadOrJoinMenu* pClass = (UIScene_LoadOrJoinMenu*)lpParam; pClass->m_bIgnoreInput = false; if (bRes) { - std::uint16_t ui16Text[128]; - ZeroMemory(ui16Text, 128 * sizeof(std::uint16_t)); - InputManager.GetText(ui16Text); - + const char* text = InputManager.GetText(); // check the name is valid - if (ui16Text[0] != 0) { + if (text[0] != '\0') { #if (defined __PS3__ || defined __ORBIS__ || defined _DURANGO || \ defined(__PSVITA__)) // open the save and overwrite the metadata diff --git a/Minecraft.Client/Platform/Common/UI/UIScene_SignEntryMenu.cpp b/Minecraft.Client/Platform/Common/UI/UIScene_SignEntryMenu.cpp index ad79dc97a..e8a8cd848 100644 --- a/Minecraft.Client/Platform/Common/UI/UIScene_SignEntryMenu.cpp +++ b/Minecraft.Client/Platform/Common/UI/UIScene_SignEntryMenu.cpp @@ -143,10 +143,7 @@ int UIScene_SignEntryMenu::KeyboardCompleteCallback(void* lpParam, bool bRes) { UIScene_SignEntryMenu* pClass = (UIScene_SignEntryMenu*)lpParam; pClass->m_bIgnoreInput = false; if (bRes && pClass->m_iEditingLine >= 0 && pClass->m_iEditingLine < 4) { - uint16_t pchText[128]; - ZeroMemory(pchText, 128 * sizeof(uint16_t)); - InputManager.GetText(pchText); - std::wstring str = uint16_to_wstring(pchText); + std::wstring str = convStringToWstring(InputManager.GetText()); if (str.size() > 15) str.resize(15); pClass->m_textInputLines[pClass->m_iEditingLine].setLabel(str); } diff --git a/Minecraft.World/Util/StringHelpers.cpp b/Minecraft.World/Util/StringHelpers.cpp index 43cfb171a..da690b354 100644 --- a/Minecraft.World/Util/StringHelpers.cpp +++ b/Minecraft.World/Util/StringHelpers.cpp @@ -36,18 +36,6 @@ bool equalsIgnoreCase(const std::wstring& a, const std::wstring& b) { return out; } -size_t uint16_len(const uint16_t* str) { - return std::char_traits::length( - reinterpret_cast(str)); -} - -std::u16string uint16_to_u16string(const uint16_t* str) { - return std::u16string(reinterpret_cast(str), uint16_len(str)); -} - -std::wstring uint16_to_wstring(const uint16_t* str) { - return u16string_to_wstring(uint16_to_u16string(str)); -} std::wstring convStringToWstring(const std::string& converting) { std::wstring converted(converting.length(), L' '); diff --git a/Minecraft.World/Util/StringHelpers.h b/Minecraft.World/Util/StringHelpers.h index 4f41be369..8ed4bc987 100644 --- a/Minecraft.World/Util/StringHelpers.h +++ b/Minecraft.World/Util/StringHelpers.h @@ -29,9 +29,6 @@ T _fromHEXString(const std::wstring& s) { return t; } -size_t uint16_len(const uint16_t* str); -std::u16string uint16_to_u16string(const uint16_t* str); -std::wstring uint16_to_wstring(const uint16_t* str); std::wstring convStringToWstring(const std::string& converting); std::wstring u16string_to_wstring(const std::u16string& converting); From 7545b7dd87aabd16f9ed93c52a8acaf57f2f582e Mon Sep 17 00:00:00 2001 From: MatthewBeshay <92357869+MatthewBeshay@users.noreply.github.com> Date: Mon, 30 Mar 2026 14:41:27 +1100 Subject: [PATCH 163/170] fix: remove extra blank lines to pass clang-format check --- Minecraft.World/Util/StringHelpers.cpp | 1 - Minecraft.World/Util/StringHelpers.h | 1 - 2 files changed, 2 deletions(-) diff --git a/Minecraft.World/Util/StringHelpers.cpp b/Minecraft.World/Util/StringHelpers.cpp index da690b354..9f47f92b8 100644 --- a/Minecraft.World/Util/StringHelpers.cpp +++ b/Minecraft.World/Util/StringHelpers.cpp @@ -36,7 +36,6 @@ bool equalsIgnoreCase(const std::wstring& a, const std::wstring& b) { return out; } - std::wstring convStringToWstring(const std::string& converting) { std::wstring converted(converting.length(), L' '); copy(converting.begin(), converting.end(), converted.begin()); diff --git a/Minecraft.World/Util/StringHelpers.h b/Minecraft.World/Util/StringHelpers.h index 8ed4bc987..871e46d87 100644 --- a/Minecraft.World/Util/StringHelpers.h +++ b/Minecraft.World/Util/StringHelpers.h @@ -29,7 +29,6 @@ T _fromHEXString(const std::wstring& s) { return t; } - std::wstring convStringToWstring(const std::string& converting); std::wstring u16string_to_wstring(const std::u16string& converting); std::u16string wstring_to_u16string(const std::wstring& converting); From a5b66ec4625c7372de836937148e1ed7556deb90 Mon Sep 17 00:00:00 2001 From: Tropical <42101043+tropicaaal@users.noreply.github.com> Date: Sun, 29 Mar 2026 22:46:00 -0500 Subject: [PATCH 164/170] revert CI --- .github/workflows/build-linux.yml | 40 ++++++++++++++++++++++++++----- 1 file changed, 34 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build-linux.yml b/.github/workflows/build-linux.yml index e1ff0b0fd..37d28139b 100644 --- a/.github/workflows/build-linux.yml +++ b/.github/workflows/build-linux.yml @@ -22,17 +22,45 @@ on: jobs: build-linux: runs-on: ubuntu-latest + + env: + CC: ccache clang + CXX: ccache clang++ + CCACHE_DIR: ${{ runner.temp }}/ccache + steps: - name: Checkout repository uses: actions/checkout@v6 - - name: Install Nix - uses: cachix/install-nix-action@v31 + - name: Install system dependencies + uses: daaku/gh-action-apt-install@v4 with: - nix_path: nixpkgs=channel:nixos-unstable + packages: build-essential ccache python3 python3-pip ninja-build libsdl2-dev libgl-dev libglu1-mesa-dev libpthread-stubs0-dev patchelf + + - name: Install meson from pip + run: | + python -m pip install meson + + - name: Restore ccache + uses: actions/cache@v4 + with: + path: ${{ runner.temp }}/ccache + key: ${{ runner.os }}-ccache-${{ hashFiles('**/meson.build') }} + restore-keys: | + ${{ runner.os }}-ccache- + + - name: Configure ccache + run: ccache -M 5G + + - name: Configure Meson + run: meson setup build --wipe --native-file=./scripts/llvm_native.txt - name: Build - run: nix build --print-build-logs + run: meson compile -C build -j $(nproc) -v Minecraft.Client - - name: Flake integrity - run: nix flake check + - name: Upload artifact + uses: actions/upload-artifact@v4 + with: + name: minecraft-client-linux-${{ github.sha }} + path: build/Minecraft.Client/Minecraft.Client + retention-days: 7 From 1128e602fdabf28a044842856d4b4f58edd8e6e6 Mon Sep 17 00:00:00 2001 From: Tropical <42101043+tropicaaal@users.noreply.github.com> Date: Sun, 29 Mar 2026 22:51:54 -0500 Subject: [PATCH 165/170] overcomplicating it --- .github/workflows/build-linux.yml | 37 +++++++++++++++++++++++-------- 1 file changed, 28 insertions(+), 9 deletions(-) diff --git a/.github/workflows/build-linux.yml b/.github/workflows/build-linux.yml index 37d28139b..969a9e817 100644 --- a/.github/workflows/build-linux.yml +++ b/.github/workflows/build-linux.yml @@ -40,27 +40,46 @@ jobs: - name: Install meson from pip run: | python -m pip install meson + ccache -M 5G || true - name: Restore ccache uses: actions/cache@v4 with: - path: ${{ runner.temp }}/ccache + path: ~/.ccache key: ${{ runner.os }}-ccache-${{ hashFiles('**/meson.build') }} - restore-keys: | - ${{ runner.os }}-ccache- - - name: Configure ccache - run: ccache -M 5G + - name: Restore meson cache + uses: actions/cache@v4 + with: + path: ~/.cache/meson + key: ${{ runner.os }}-meson-${{ hashFiles('**/meson.build') }} - name: Configure Meson - run: meson setup build --wipe --native-file=./scripts/llvm_native.txt + env: + CC: "ccache clang" + CXX: "ccache clang++" + CCACHE_DIR: ${{ runner.temp }}/ccache + run: | + mkdir -p "$CCACHE_DIR" + export CCACHE_DIR="$CCACHE_DIR" + meson setup build --wipe --native-file=./scripts/llvm_native.txt - - name: Build - run: meson compile -C build -j $(nproc) -v Minecraft.Client + - name: Build with Meson + env: + CC: "ccache clang" + CXX: "ccache clang++" + CCACHE_DIR: ${{ runner.temp }}/ccache + run: | + export CCACHE_DIR="${{ runner.temp }}/ccache" + # Use all available cores for faster parallel builds + meson compile -C build -j $(nproc) -v Minecraft.Client + + - name: Install patchelf + run: sudo apt-get install -y patchelf - name: Upload artifact uses: actions/upload-artifact@v4 with: name: minecraft-client-linux-${{ github.sha }} path: build/Minecraft.Client/Minecraft.Client - retention-days: 7 + retention-days: 7 \ No newline at end of file From cf1d3436f11906d38fd0793684b139a570a21964 Mon Sep 17 00:00:00 2001 From: Tropical <42101043+tropicaaal@users.noreply.github.com> Date: Sun, 29 Mar 2026 22:56:05 -0500 Subject: [PATCH 166/170] remove env field --- .github/workflows/build-linux.yml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/.github/workflows/build-linux.yml b/.github/workflows/build-linux.yml index 969a9e817..a7bab7f27 100644 --- a/.github/workflows/build-linux.yml +++ b/.github/workflows/build-linux.yml @@ -23,11 +23,6 @@ jobs: build-linux: runs-on: ubuntu-latest - env: - CC: ccache clang - CXX: ccache clang++ - CCACHE_DIR: ${{ runner.temp }}/ccache - steps: - name: Checkout repository uses: actions/checkout@v6 From 2ce1b0b2610b255fee9dfd1f413285dbf946a2b3 Mon Sep 17 00:00:00 2001 From: Tropical <42101043+tropicaaal@users.noreply.github.com> Date: Sun, 29 Mar 2026 22:56:53 -0500 Subject: [PATCH 167/170] add libglm-dev --- .github/workflows/build-linux.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-linux.yml b/.github/workflows/build-linux.yml index a7bab7f27..4b9475573 100644 --- a/.github/workflows/build-linux.yml +++ b/.github/workflows/build-linux.yml @@ -30,7 +30,7 @@ jobs: - name: Install system dependencies uses: daaku/gh-action-apt-install@v4 with: - packages: build-essential ccache python3 python3-pip ninja-build libsdl2-dev libgl-dev libglu1-mesa-dev libpthread-stubs0-dev patchelf + packages: build-essential ccache python3 python3-pip ninja-build libsdl2-dev libgl-dev libglu1-mesa-dev libpthread-stubs0-dev patchelf libglm-dev - name: Install meson from pip run: | From 8f61c9b01abd06f60ef5062c6ad81dd4f01f8315 Mon Sep 17 00:00:00 2001 From: MatthewBeshay <92357869+MatthewBeshay@users.noreply.github.com> Date: Mon, 30 Mar 2026 14:57:56 +1100 Subject: [PATCH 168/170] fix: update 4jlibs flake input to latest main Resolves build failure caused by 4jlibs:gles being an unknown option. --- flake.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/flake.lock b/flake.lock index 5a5335f73..f2128808e 100644 --- a/flake.lock +++ b/flake.lock @@ -3,11 +3,11 @@ "4jlibs": { "flake": false, "locked": { - "lastModified": 1774012501, - "narHash": "sha256-NoM5LtKcU+3LFPVZUtep1L+hfZS6YSQ4P/xkJU/2NY4=", + "lastModified": 1774836469, + "narHash": "sha256-ukp6tLThQugPlREYFDDB6IaunjGte08f0Ler/c8cvaY=", "owner": "4jcraft", "repo": "4jlibs", - "rev": "df5f4a1fc3288fdc021b3d8ee2abaed3083de460", + "rev": "ab37891dabba90cf1e568660f750cebf46ba83f6", "type": "github" }, "original": { From 4ee9175501625b2eddc7b6467de8c85f6563ae2b Mon Sep 17 00:00:00 2001 From: Tropical <42101043+tropicaaal@users.noreply.github.com> Date: Sun, 29 Mar 2026 22:59:23 -0500 Subject: [PATCH 169/170] don't use apt-install github action --- .github/workflows/build-linux.yml | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build-linux.yml b/.github/workflows/build-linux.yml index 4b9475573..5077b7def 100644 --- a/.github/workflows/build-linux.yml +++ b/.github/workflows/build-linux.yml @@ -28,14 +28,13 @@ jobs: uses: actions/checkout@v6 - name: Install system dependencies - uses: daaku/gh-action-apt-install@v4 - with: - packages: build-essential ccache python3 python3-pip ninja-build libsdl2-dev libgl-dev libglu1-mesa-dev libpthread-stubs0-dev patchelf libglm-dev - - - name: Install meson from pip run: | + sudo apt-get update + sudo apt-get install -y build-essential ccache python3 python3-pip ninja-build libsdl2-dev libgl-dev libglu1-mesa-dev libpthread-stubs0-dev python -m pip install meson + # Set a reasonable ccache size ccache -M 5G || true + python -m pip install meson - name: Restore ccache uses: actions/cache@v4 From b5b9b66307c1f0b3cd269fd9ed89c9c633a10de7 Mon Sep 17 00:00:00 2001 From: Tropical <42101043+tropicaaal@users.noreply.github.com> Date: Sun, 29 Mar 2026 23:00:46 -0500 Subject: [PATCH 170/170] add libglm dependency again --- .github/workflows/build-linux.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-linux.yml b/.github/workflows/build-linux.yml index 5077b7def..ece858d39 100644 --- a/.github/workflows/build-linux.yml +++ b/.github/workflows/build-linux.yml @@ -30,7 +30,7 @@ jobs: - name: Install system dependencies run: | sudo apt-get update - sudo apt-get install -y build-essential ccache python3 python3-pip ninja-build libsdl2-dev libgl-dev libglu1-mesa-dev libpthread-stubs0-dev + sudo apt-get install -y build-essential ccache python3 python3-pip ninja-build libsdl2-dev libgl-dev libglu1-mesa-dev libpthread-stubs0-dev libglm-dev python -m pip install meson # Set a reasonable ccache size ccache -M 5G || true