diff --git a/src/Builder.c b/src/Builder.c index 2464390e4..942467c5f 100644 --- a/src/Builder.c +++ b/src/Builder.c @@ -412,14 +412,14 @@ void Builder_MakeChunk(struct ChunkInfo* info) { hasMesh = BuildChunk(x, y, z, info); if (!hasMesh) return; - partsIndex = MapRenderer_Pack(x >> CHUNK_SHIFT, y >> CHUNK_SHIFT, z >> CHUNK_SHIFT); + partsIndex = World_ChunkPack(x >> CHUNK_SHIFT, y >> CHUNK_SHIFT, z >> CHUNK_SHIFT); offset = 0; hasNorm = false; hasTran = false; for (i = 0; i < MapRenderer_1DUsedCount; i++) { j = i + ATLAS1D_MAX_ATLASES; - curIdx = partsIndex + i * MapRenderer_ChunksCount; + curIdx = partsIndex + i * World.ChunksCount; SetPartInfo(&Builder_Parts[i], &offset, &MapRenderer_PartsNormal[curIdx], &hasNorm); SetPartInfo(&Builder_Parts[j], &offset, &MapRenderer_PartsTranslucent[curIdx], &hasTran); diff --git a/src/Lighting.c b/src/Lighting.c index 2e15c2dd3..d0ca20117 100644 --- a/src/Lighting.c +++ b/src/Lighting.c @@ -218,13 +218,13 @@ static void ClassicLighting_RefreshAffected(int x, int y, int z, BlockID block, ClassicLighting_ResetNeighbour(x, y, z - 1, block, cx, cy, cz - 1, minCy, maxCy); } - if (bX == 15 && cx < MapRenderer_ChunksX - 1) { + if (bX == 15 && cx < World.ChunksX - 1) { ClassicLighting_ResetNeighbour(x + 1, y, z, block, cx + 1, cy, cz, minCy, maxCy); } - if (bY == 15 && cy < MapRenderer_ChunksY - 1 && ClassicLighting_Needs(block, World_GetBlock(x, y + 1, z))) { + if (bY == 15 && cy < World.ChunksY - 1 && ClassicLighting_Needs(block, World_GetBlock(x, y + 1, z))) { MapRenderer_RefreshChunk(cx, cy + 1, cz); } - if (bZ == 15 && cz < MapRenderer_ChunksZ - 1) { + if (bZ == 15 && cz < World.ChunksZ - 1) { ClassicLighting_ResetNeighbour(x, y, z + 1, block, cx, cy, cz + 1, minCy, maxCy); } } diff --git a/src/MapRenderer.c b/src/MapRenderer.c index 77f806c14..16135af77 100644 --- a/src/MapRenderer.c +++ b/src/MapRenderer.c @@ -15,8 +15,7 @@ #include "World.h" #include "Options.h" -int MapRenderer_ChunksX, MapRenderer_ChunksY, MapRenderer_ChunksZ; -int MapRenderer_1DUsedCount, MapRenderer_ChunksCount; +int MapRenderer_1DUsedCount; struct ChunkPartInfo* MapRenderer_PartsNormal; struct ChunkPartInfo* MapRenderer_PartsTranslucent; @@ -117,7 +116,7 @@ if (drawMin && drawMax) { \ } static void RenderNormalBatch(int batch) { - int batchOffset = MapRenderer_ChunksCount * batch; + int batchOffset = World.ChunksCount * batch; struct ChunkInfo* info; struct ChunkPartInfo part; cc_bool drawMin, drawMax; @@ -221,7 +220,7 @@ if (drawMin && drawMax) { \ } static void RenderTranslucentBatch(int batch) { - int batchOffset = MapRenderer_ChunksCount * batch; + int batchOffset = World.ChunksCount * batch; struct ChunkInfo* info; struct ChunkPartInfo part; cc_bool drawMin, drawMax; @@ -324,7 +323,7 @@ static void DeleteChunk(struct ChunkInfo* info) { if (info->NormalParts) { ptr = info->NormalParts; - for (i = 0; i < MapRenderer_1DUsedCount; i++, ptr += MapRenderer_ChunksCount) { + for (i = 0; i < MapRenderer_1DUsedCount; i++, ptr += World.ChunksCount) { if (ptr->Offset < 0) continue; normPartsCount[i]--; #ifdef CC_BUILD_GL11 @@ -336,7 +335,7 @@ static void DeleteChunk(struct ChunkInfo* info) { if (info->TranslucentParts) { ptr = info->TranslucentParts; - for (i = 0; i < MapRenderer_1DUsedCount; i++, ptr += MapRenderer_ChunksCount) { + for (i = 0; i < MapRenderer_1DUsedCount; i++, ptr += World.ChunksCount) { if (ptr->Offset < 0) continue; tranPartsCount[i]--; #ifdef CC_BUILD_GL11 @@ -363,14 +362,14 @@ static void BuildChunk(struct ChunkInfo* info, int* chunkUpdates) { if (info->NormalParts) { ptr = info->NormalParts; - for (i = 0; i < MapRenderer_1DUsedCount; i++, ptr += MapRenderer_ChunksCount) { + for (i = 0; i < MapRenderer_1DUsedCount; i++, ptr += World.ChunksCount) { if (ptr->Offset >= 0) normPartsCount[i]++; } } if (info->TranslucentParts) { ptr = info->TranslucentParts; - for (i = 0; i < MapRenderer_1DUsedCount; i++, ptr += MapRenderer_ChunksCount) { + for (i = 0; i < MapRenderer_1DUsedCount; i++, ptr += World.ChunksCount) { if (ptr->Offset >= 0) tranPartsCount[i]++; } } @@ -400,7 +399,7 @@ static void FreeChunks(void) { static void AllocateParts(void) { struct ChunkPartInfo* ptr; - cc_uint32 count = MapRenderer_ChunksCount * MapRenderer_1DUsedCount; + cc_uint32 count = World.ChunksCount * MapRenderer_1DUsedCount; ptr = (struct ChunkPartInfo*)Mem_AllocCleared(count * 2, sizeof(struct ChunkPartInfo), "chunk parts"); MapRenderer_PartsNormal = ptr; @@ -408,10 +407,10 @@ static void AllocateParts(void) { } static void AllocateChunks(void) { - mapChunks = (struct ChunkInfo*) Mem_Alloc(MapRenderer_ChunksCount, sizeof(struct ChunkInfo), "chunk info"); - sortedChunks = (struct ChunkInfo**)Mem_Alloc(MapRenderer_ChunksCount, sizeof(struct ChunkInfo*), "sorted chunk info"); - renderChunks = (struct ChunkInfo**)Mem_Alloc(MapRenderer_ChunksCount, sizeof(struct ChunkInfo*), "render chunk info"); - distances = (cc_uint32*)Mem_Alloc(MapRenderer_ChunksCount, 4, "chunk distances"); + mapChunks = (struct ChunkInfo*) Mem_Alloc(World.ChunksCount, sizeof(struct ChunkInfo), "chunk info"); + sortedChunks = (struct ChunkInfo**)Mem_Alloc(World.ChunksCount, sizeof(struct ChunkInfo*), "sorted chunk info"); + renderChunks = (struct ChunkInfo**)Mem_Alloc(World.ChunksCount, sizeof(struct ChunkInfo*), "render chunk info"); + distances = (cc_uint32*)Mem_Alloc(World.ChunksCount, 4, "chunk distances"); } static void ResetPartFlags(void) { @@ -463,7 +462,7 @@ static void DeleteChunks(void) { int i; if (!mapChunks) return; - for (i = 0; i < MapRenderer_ChunksCount; i++) { + for (i = 0; i < World.ChunksCount; i++) { DeleteChunk(&mapChunks[i]); } ResetPartCounts(); @@ -496,10 +495,10 @@ static void RefreshBorderChunks(int maxHeight) { chunkPos = IVec3_MaxValue(); if (!mapChunks || !World.Blocks) return; - for (cz = 0; cz < MapRenderer_ChunksZ; cz++) { - for (cy = 0; cy < MapRenderer_ChunksY; cy++) { - for (cx = 0; cx < MapRenderer_ChunksX; cx++) { - onBorder = cx == 0 || cz == 0 || cx == (MapRenderer_ChunksX - 1) || cz == (MapRenderer_ChunksZ - 1); + for (cz = 0; cz < World.ChunksZ; cz++) { + for (cy = 0; cy < World.ChunksY; cy++) { + for (cx = 0; cx < World.ChunksX; cx++) { + onBorder = cx == 0 || cz == 0 || cx == (World.ChunksX - 1) || cz == (World.ChunksZ - 1); if (onBorder && (cy * CHUNK_SIZE) < maxHeight) { MapRenderer_RefreshChunk(cx, cy, cz); @@ -543,7 +542,7 @@ static int UpdateChunksAndVisibility(int* chunkUpdates) { int i, j = 0, distSqr; cc_bool noData; - for (i = 0; i < MapRenderer_ChunksCount; i++) { + for (i = 0; i < World.ChunksCount; i++) { info = sortedChunks[i]; if (info->Empty) continue; @@ -576,7 +575,7 @@ static int UpdateChunksStill(int* chunkUpdates) { int i, j = 0, distSqr; cc_bool noData; - for (i = 0; i < MapRenderer_ChunksCount; i++) { + for (i = 0; i < World.ChunksCount; i++) { info = sortedChunks[i]; if (info->Empty) continue; @@ -661,9 +660,9 @@ static void UpdateSortOrder(void) { /* If in same chunk, don't need to recalculate sort order */ if (pos.X == chunkPos.X && pos.Y == chunkPos.Y && pos.Z == chunkPos.Z) return; chunkPos = pos; - if (!MapRenderer_ChunksCount) return; + if (!World.ChunksCount) return; - for (i = 0; i < MapRenderer_ChunksCount; i++) { + for (i = 0; i < World.ChunksCount; i++) { info = sortedChunks[i]; /* Calculate distance to chunk centre */ dx = info->CentreX - pos.X; dy = info->CentreY - pos.Y; dz = info->CentreZ - pos.Z; @@ -682,7 +681,7 @@ static void UpdateSortOrder(void) { info->DrawYMin = dy >= 0; info->DrawYMax = dy <= 0; } - SortMapChunks(0, MapRenderer_ChunksCount - 1); + SortMapChunks(0, World.ChunksCount - 1); ResetPartFlags(); /*SimpleOcclusionCulling();*/ } @@ -699,10 +698,9 @@ void MapRenderer_Update(double delta) { *#########################################################################################################################*/ void MapRenderer_RefreshChunk(int cx, int cy, int cz) { struct ChunkInfo* info; - if (cx < 0 || cy < 0 || cz < 0 || cx >= MapRenderer_ChunksX - || cy >= MapRenderer_ChunksY || cz >= MapRenderer_ChunksZ) return; + if (cx < 0 || cy < 0 || cz < 0 || cx >= World.ChunksX || cy >= World.ChunksY || cz >= World.ChunksZ) return; - info = &mapChunks[MapRenderer_Pack(cx, cy, cz)]; + info = &mapChunks[World_ChunkPack(cx, cy, cz)]; if (info->AllAir) return; /* do not recreate chunks completely air */ info->Empty = false; info->PendingDelete = true; @@ -712,7 +710,7 @@ void MapRenderer_OnBlockChanged(int x, int y, int z, BlockID block) { int cx = x >> CHUNK_SHIFT, cy = y >> CHUNK_SHIFT, cz = z >> CHUNK_SHIFT; struct ChunkInfo* chunk; - chunk = &mapChunks[MapRenderer_Pack(cx, cy, cz)]; + chunk = &mapChunks[World_ChunkPack(cx, cy, cz)]; chunk->AllAir &= Blocks.Draw[block] == DRAW_GAS; /* TODO: Don't lookup twice, refresh directly using chunk pointer */ MapRenderer_RefreshChunk(cx, cy, cz); @@ -767,15 +765,9 @@ static void OnNewMap(void) { } static void OnNewMapLoaded(void) { - int count; - MapRenderer_ChunksX = (World.Width + CHUNK_MAX) >> CHUNK_SHIFT; - MapRenderer_ChunksY = (World.Height + CHUNK_MAX) >> CHUNK_SHIFT; - MapRenderer_ChunksZ = (World.Length + CHUNK_MAX) >> CHUNK_SHIFT; - - count = MapRenderer_ChunksX * MapRenderer_ChunksY * MapRenderer_ChunksZ; /* TODO: Only perform reallocation when map volume has changed */ - /*if (MapRenderer_ChunksCount != count) { */ - MapRenderer_ChunksCount = count; + /*if (MapRenderer_ChunksCount != World.ChunksCount) { */ + /* MapRenderer_ChunksCount = World.ChunksCount; */ FreeChunks(); FreeParts(); AllocateChunks(); diff --git a/src/MapRenderer.h b/src/MapRenderer.h index d7fddc9b3..238d8508d 100644 --- a/src/MapRenderer.h +++ b/src/MapRenderer.h @@ -10,14 +10,8 @@ struct IGameComponent; extern struct IGameComponent MapRenderer_Component; -extern int MapRenderer_ChunksX, MapRenderer_ChunksY, MapRenderer_ChunksZ; -#define MapRenderer_Pack(cx, cy, cz) (((cz) * MapRenderer_ChunksY + (cy)) * MapRenderer_ChunksX + (cx)) -/* TODO: Swap Y and Z? Make sure to update ChunkUpdater's ResetChunkCache and ClearChunkCache methods! */ - /* Max used 1D atlases. (i.e. Atlas1D_Index(maxTextureLoc) + 1) */ extern int MapRenderer_1DUsedCount; -/* Number of chunks in the world, or ChunksX * ChunksY * ChunksZ */ -extern int MapRenderer_ChunksCount; /* Buffer for all chunk parts. There are (MapRenderer_ChunksCount * Atlas1D_Count) parts in the buffer, with parts for 'normal' buffer being in lower half. */ diff --git a/src/Window_Win.c b/src/Window_Win.c index ea4056575..4706a2c5a 100644 --- a/src/Window_Win.c +++ b/src/Window_Win.c @@ -197,7 +197,7 @@ static LRESULT CALLBACK Window_Procedure(HWND handle, UINT message, WPARAM wPara /* To understand reasoning behind the following code, see Remarks in */ /* https://docs.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-rawmouse */ static int prevPosX, prevPosY; - isVirtual = (raw.data.mouse.usFlags & MOUSE_VIRTUAL_DESKTOP); + isVirtual = raw.data.mouse.usFlags & MOUSE_VIRTUAL_DESKTOP; width = GetSystemMetrics(isVirtual ? SM_CXVIRTUALSCREEN : SM_CXSCREEN); height = GetSystemMetrics(isVirtual ? SM_CYVIRTUALSCREEN : SM_CYSCREEN); diff --git a/src/World.c b/src/World.c index cead7de9c..4658857ae 100644 --- a/src/World.c +++ b/src/World.c @@ -91,6 +91,12 @@ CC_NOINLINE void World_SetDimensions(int width, int height, int length) { World.MaxX = width - 1; World.MaxY = height - 1; World.MaxZ = length - 1; + + World.ChunksX = (width + CHUNK_MAX) >> CHUNK_SHIFT; + World.ChunksY = (height + CHUNK_MAX) >> CHUNK_SHIFT; + World.ChunksZ = (length + CHUNK_MAX) >> CHUNK_SHIFT; + + World.ChunksCount = World.ChunksX * World.ChunksY * World.ChunksZ; } #ifdef EXTENDED_BLOCKS diff --git a/src/World.h b/src/World.h index 73ad96e68..af1a8f027 100644 --- a/src/World.h +++ b/src/World.h @@ -15,6 +15,10 @@ extern struct IGameComponent World_Component; #define World_Pack(x, y, z) (((y) * World.Length + (z)) * World.Width + (x)) #define WORLD_UUID_LEN 16 +#define World_ChunkPack(cx, cy, cz) (((cz) * World.ChunksY + (cy)) * World.ChunksX + (cx)) +/* TODO: Swap Y and Z? Make sure to update MapRenderer's ResetChunkCache and ClearChunkCache methods! */ + + CC_VAR extern struct _WorldData { /* The blocks in the world. */ BlockRaw* Blocks; @@ -48,6 +52,10 @@ CC_VAR extern struct _WorldData { double LastSave; /* Default name of the world when saving */ cc_string Name; + /* Number of chunks on each axis the world is subdivided into */ + int ChunksX, ChunksY, ChunksZ; + /* Number of chunks in the world, or ChunksX * ChunksY * ChunksZ */ + int ChunksCount; } World; /* Frees the blocks array, sets dimensions to 0, resets environment to default. */