From b7c712fc0332b5a031e2626df70148637c63d7d2 Mon Sep 17 00:00:00 2001 From: UnknownShadow200 Date: Fri, 11 May 2018 23:30:02 +1000 Subject: [PATCH] Fix crashing and glitchiness when using texture pack of different size in C client --- src/Client/ChunkUpdater.c | 92 +++++++++++++++++++++++---------------- src/Client/MapRenderer.c | 8 ++-- src/Client/TerrainAtlas.c | 2 +- 3 files changed, 59 insertions(+), 43 deletions(-) diff --git a/src/Client/ChunkUpdater.c b/src/Client/ChunkUpdater.c index 0004996b6..302a29a4f 100644 --- a/src/Client/ChunkUpdater.c +++ b/src/Client/ChunkUpdater.c @@ -59,9 +59,9 @@ void ChunkUpdater_TerrainAtlasChanged(void* obj) { } void ChunkUpdater_BlockDefinitionChanged(void* obj) { + ChunkUpdater_Refresh(); MapRenderer_1DUsedCount = Atlas1D_UsedAtlasesCount(); ChunkUpdater_ResetPartFlags(); - ChunkUpdater_Refresh(); } void ChunkUpdater_ProjectionChanged(void* obj) { @@ -72,11 +72,62 @@ void ChunkUpdater_ViewDistanceChanged(void* obj) { cu_lastCamPos = Vector3_BigPos(); } + +void ChunkUpdater_FreePartsAllocations(void) { + Platform_MemFree(&MapRenderer_PartsBuffer_Raw); + MapRenderer_PartsNormal = NULL; + MapRenderer_PartsTranslucent = NULL; +} + +void ChunkUpdater_FreeAllocations(void) { + if (MapRenderer_Chunks == NULL) return; + Platform_MemFree(&MapRenderer_Chunks); + Platform_MemFree(&MapRenderer_SortedChunks); + Platform_MemFree(&MapRenderer_RenderChunks); + Platform_MemFree(&ChunkUpdater_Distances); + ChunkUpdater_FreePartsAllocations(); +} + +void ChunkUpdater_PerformPartsAllocations(void) { + UInt32 partsCount = MapRenderer_ChunksCount * MapRenderer_1DUsedCount; + MapRenderer_PartsBuffer_Raw = Platform_MemAlloc(partsCount * 2, sizeof(ChunkPartInfo)); + if (MapRenderer_PartsBuffer_Raw == NULL) ErrorHandler_Fail("ChunkUpdater - failed to allocate chunk parts buffer"); + + UInt32 partsSize = partsCount * 2 * (UInt32)sizeof(ChunkPartInfo); + Platform_MemSet(MapRenderer_PartsBuffer_Raw, 0, partsSize); + MapRenderer_PartsNormal = MapRenderer_PartsBuffer_Raw; + MapRenderer_PartsTranslucent = MapRenderer_PartsBuffer_Raw + partsCount; +} + +void ChunkUpdater_PerformAllocations(void) { + MapRenderer_Chunks = Platform_MemAlloc(MapRenderer_ChunksCount, sizeof(ChunkInfo)); + if (MapRenderer_Chunks == NULL) ErrorHandler_Fail("ChunkUpdater - failed to allocate chunk info"); + + MapRenderer_SortedChunks = Platform_MemAlloc(MapRenderer_ChunksCount, sizeof(ChunkInfo*)); + if (MapRenderer_Chunks == NULL) ErrorHandler_Fail("ChunkUpdater - failed to allocate sorted chunk info"); + + MapRenderer_RenderChunks = Platform_MemAlloc(MapRenderer_ChunksCount, sizeof(ChunkInfo*)); + if (MapRenderer_RenderChunks == NULL) ErrorHandler_Fail("ChunkUpdater - failed to allocate render chunk info"); + + ChunkUpdater_Distances = Platform_MemAlloc(MapRenderer_ChunksCount, sizeof(Int32)); + if (ChunkUpdater_Distances == NULL) ErrorHandler_Fail("ChunkUpdater - failed to allocate chunk distances"); + + ChunkUpdater_PerformPartsAllocations(); +} + void ChunkUpdater_Refresh(void) { ChunkUpdater_ChunkPos = Vector3I_MaxValue(); if (MapRenderer_Chunks != NULL && World_Blocks != NULL) { ChunkUpdater_ClearChunkCache(); ChunkUpdater_ResetChunkCache(); + + Int32 old_atlasesCount = MapRenderer_1DUsedCount; + MapRenderer_1DUsedCount = Atlas1D_UsedAtlasesCount(); + /* Need to reallocate parts array in this case */ + if (MapRenderer_1DUsedCount != old_atlasesCount) { + ChunkUpdater_FreePartsAllocations(); + ChunkUpdater_PerformPartsAllocations(); + } } ChunkUpdater_ResetPartCounts(); } @@ -102,6 +153,7 @@ void ChunkUpdater_RefreshBorders(Int32 clipLevel) { } } + void ChunkUpdater_ApplyMeshBuilder(void) { if (Game_SmoothLighting) { /* TODO: Implement advanced lighting builder.*/ @@ -111,42 +163,6 @@ void ChunkUpdater_ApplyMeshBuilder(void) { } } - -void ChunkUpdater_FreeAllocations(void) { - if (MapRenderer_Chunks == NULL) return; - Platform_MemFree(&MapRenderer_Chunks); - Platform_MemFree(&MapRenderer_SortedChunks); - Platform_MemFree(&MapRenderer_RenderChunks); - Platform_MemFree(&ChunkUpdater_Distances); - Platform_MemFree(&MapRenderer_PartsBuffer_Raw); - - MapRenderer_PartsNormal = NULL; - MapRenderer_PartsTranslucent = NULL; -} - -void ChunkUpdater_PerformAllocations(void) { - MapRenderer_Chunks = Platform_MemAlloc(MapRenderer_ChunksCount, sizeof(ChunkInfo)); - if (MapRenderer_Chunks == NULL) ErrorHandler_Fail("ChunkUpdater - failed to allocate chunk info"); - - MapRenderer_SortedChunks = Platform_MemAlloc(MapRenderer_ChunksCount, sizeof(ChunkInfo*)); - if (MapRenderer_Chunks == NULL) ErrorHandler_Fail("ChunkUpdater - failed to allocate sorted chunk info"); - - MapRenderer_RenderChunks = Platform_MemAlloc(MapRenderer_ChunksCount, sizeof(ChunkInfo*)); - if (MapRenderer_RenderChunks == NULL) ErrorHandler_Fail("ChunkUpdater - failed to allocate render chunk info"); - - ChunkUpdater_Distances = Platform_MemAlloc(MapRenderer_ChunksCount, sizeof(Int32)); - if (ChunkUpdater_Distances == NULL) ErrorHandler_Fail("ChunkUpdater - failed to allocate chunk distances"); - - UInt32 partsCount = MapRenderer_ChunksCount * MapRenderer_1DUsedCount; - MapRenderer_PartsBuffer_Raw = Platform_MemAlloc(partsCount * 2, sizeof(ChunkPartInfo)); - if (MapRenderer_PartsBuffer_Raw == NULL) ErrorHandler_Fail("ChunkUpdater - failed to allocate chunk parts buffer"); - - UInt32 partsSize = partsCount * 2 * (UInt32)sizeof(ChunkPartInfo); - Platform_MemSet(MapRenderer_PartsBuffer_Raw, 0, partsSize); - MapRenderer_PartsNormal = MapRenderer_PartsBuffer_Raw; - MapRenderer_PartsTranslucent = MapRenderer_PartsBuffer_Raw + partsCount; -} - void ChunkUpdater_OnNewMap(void* obj) { Game_ChunkUpdates = 0; ChunkUpdater_ClearChunkCache(); @@ -156,7 +172,7 @@ void ChunkUpdater_OnNewMap(void* obj) { } void ChunkUpdater_OnNewMapLoaded(void* obj) { - MapRenderer_ChunksX = (World_Width + CHUNK_MAX) >> CHUNK_SHIFT; + MapRenderer_ChunksX = (World_Width + CHUNK_MAX) >> CHUNK_SHIFT; MapRenderer_ChunksY = (World_Height + CHUNK_MAX) >> CHUNK_SHIFT; MapRenderer_ChunksZ = (World_Length + CHUNK_MAX) >> CHUNK_SHIFT; diff --git a/src/Client/MapRenderer.c b/src/Client/MapRenderer.c index f6e81cdcd..beeb4e972 100644 --- a/src/Client/MapRenderer.c +++ b/src/Client/MapRenderer.c @@ -39,12 +39,12 @@ void MapRenderer_CheckWeather(Real64 deltaTime) { } void MapRenderer_RenderNormalBatch(UInt32 batch) { - UInt32 i; + UInt32 i, offset = MapRenderer_ChunksCount * batch; for (i = 0; i < MapRenderer_RenderChunksCount; i++) { ChunkInfo* info = MapRenderer_RenderChunks[i]; if (info->NormalParts == NULL) continue; - ChunkPartInfo part = info->NormalParts[batch]; + ChunkPartInfo part = *(info->NormalParts + offset); if (!part.HasVertices) continue; MapRenderer_HasNormalParts[batch] = true; @@ -144,12 +144,12 @@ void MapRenderer_RenderNormal(Real64 deltaTime) { } void MapRenderer_RenderTranslucentBatch(UInt32 batch) { - UInt32 i; + UInt32 i, offset = MapRenderer_ChunksCount * batch; for (i = 0; i < MapRenderer_RenderChunksCount; i++) { ChunkInfo* info = MapRenderer_RenderChunks[i]; if (info->TranslucentParts == NULL) continue; - ChunkPartInfo part = info->TranslucentParts[batch]; + ChunkPartInfo part = *(info->TranslucentParts + offset); if (!part.HasVertices) continue; MapRenderer_HasTranslucentParts[batch] = true; diff --git a/src/Client/TerrainAtlas.c b/src/Client/TerrainAtlas.c index 01fec818b..878162fa4 100644 --- a/src/Client/TerrainAtlas.c +++ b/src/Client/TerrainAtlas.c @@ -77,7 +77,7 @@ void Atlas1D_Make1DTexture(Int32 i, Int32 atlas1DHeight, Int32* index) { void Atlas1D_Convert2DTo1D(Int32 atlasesCount, Int32 atlas1DHeight) { Atlas1D_Count = atlasesCount; - Platform_Log2("Loaded new atlas: %i bmps, %i per bmp", &atlasesCount, &Atlas1D_ElementsPerBitmap); + Platform_Log2("Loaded new atlas: %i bmps, %i per bmp", &atlasesCount, &Atlas1D_ElementsPerAtlas); Int32 index = 0, i; for (i = 0; i < atlasesCount; i++) {