diff --git a/ClassicalSharp/Game/PickingHandler.cs b/ClassicalSharp/Game/PickingHandler.cs index e6483139c..edb5e2c4a 100644 --- a/ClassicalSharp/Game/PickingHandler.cs +++ b/ClassicalSharp/Game/PickingHandler.cs @@ -42,7 +42,7 @@ namespace ClassicalSharp { Vector3I pos = game.SelectedPos.BlockPos; if (!game.SelectedPos.Valid || !game.World.IsValidPos(pos)) return; - BlockID old = game.World.GetBlock(pos); + BlockID old = game.World.GetBlock(pos.X, pos.Y, pos.Z); if (BlockInfo.Draw[old] == DrawType.Gas || !BlockInfo.CanDelete[old]) return; game.UpdateBlock(pos.X, pos.Y, pos.Z, Block.Air); @@ -51,7 +51,7 @@ namespace ClassicalSharp { Vector3I pos = game.SelectedPos.TranslatedPos; if (!game.SelectedPos.Valid || !game.World.IsValidPos(pos)) return; - BlockID old = game.World.GetBlock(pos); + BlockID old = game.World.GetBlock(pos.X, pos.Y, pos.Z); BlockID block = inv.Selected; if (game.AutoRotate) block = AutoRotate.RotateBlock(game, block); @@ -66,7 +66,7 @@ namespace ClassicalSharp { } else if (middle) { Vector3I pos = game.SelectedPos.BlockPos; if (!game.SelectedPos.Valid || !game.World.IsValidPos(pos)) return; - BlockID cur = game.World.GetBlock(pos); + BlockID cur = game.World.GetBlock(pos.X, pos.Y, pos.Z); if (BlockInfo.Draw[cur] == DrawType.Gas) return; if (!(BlockInfo.CanPlace[cur] || BlockInfo.CanDelete[cur])) return; diff --git a/ClassicalSharp/Map/World.cs b/ClassicalSharp/Map/World.cs index 6b48cc4c1..ab6fab973 100644 --- a/ClassicalSharp/Map/World.cs +++ b/ClassicalSharp/Map/World.cs @@ -56,7 +56,7 @@ namespace ClassicalSharp.Map { blocks[i] = (BlockRaw)blockId; // defer allocation of second map array if possible - if (blocks == blocks2) { + if (blocks == blocks2) { if (blockId < 256) return; blocks2 = new BlockRaw[blocks.Length]; BlockInfo.SetMaxUsed(767); @@ -83,7 +83,7 @@ namespace ClassicalSharp.Map { } public BlockID SafeGetBlock(Vector3I p) { - return IsValidPos(p.X, p.Y, p.Z) ? GetBlock(p) : Block.Air; + return IsValidPos(p) ? GetBlock(p.X, p.Y, p.Z) : Block.Air; } public bool IsValidPos(int x, int y, int z) { diff --git a/src/AsyncDownloader.c b/src/AsyncDownloader.c index 7c4c6aa3f..dbdc408b3 100644 --- a/src/AsyncDownloader.c +++ b/src/AsyncDownloader.c @@ -78,7 +78,7 @@ bool ManageCookies; bool KeepAlive; /* TODO: Connection pooling */ -static void AsyncDownloader_Add(const String* url, bool priority, const String* id, UInt8 type, UInt64* lastModified, const String* etag, const String* data) { +static void AsyncDownloader_Add(const String* url, bool priority, const String* id, UInt8 type, TimeMS* lastModified, const String* etag, const String* data) { Mutex_Lock(async_pendingMutex); { struct AsyncRequest req = { 0 }; @@ -134,14 +134,14 @@ void AsyncDownloader_PostString(const String* url, bool priority, const String* AsyncDownloader_Add(url, priority, id, REQUEST_TYPE_DATA, NULL, NULL, contents); } -void AsyncDownloader_GetDataEx(const String* url, bool priority, const String* id, UInt64* lastModified, const String* etag) { +void AsyncDownloader_GetDataEx(const String* url, bool priority, const String* id, TimeMS* lastModified, const String* etag) { AsyncDownloader_Add(url, priority, id, REQUEST_TYPE_DATA, lastModified, etag, NULL); } void AsyncDownloader_PurgeOldEntriesTask(struct ScheduledTask* task) { Mutex_Lock(async_processedMutex); { - UInt64 now = DateTime_CurrentUTC_MS(); + TimeMS now = DateTime_CurrentUTC_MS(); Int32 i; for (i = async_processed.Count - 1; i >= 0; i--) { diff --git a/src/AsyncDownloader.h b/src/AsyncDownloader.h index 05c1f4840..d6be75a6d 100644 --- a/src/AsyncDownloader.h +++ b/src/AsyncDownloader.h @@ -19,14 +19,14 @@ struct AsyncRequest { char URL[STRING_SIZE]; char ID[STRING_SIZE]; - UInt64 TimeAdded, TimeDownloaded; + TimeMS TimeAdded, TimeDownloaded; Int32 StatusCode; ReturnCode Result; void* ResultData; UInt32 ResultSize; - UInt64 LastModified; /* Time item cached at (if at all) */ + TimeMS LastModified; /* Time item cached at (if at all) */ char Etag[STRING_SIZE]; /* ETag of cached item (if any) */ UInt8 RequestType; }; @@ -39,7 +39,7 @@ void AsyncDownloader_GetData(const String* url, bool priority, const String* id) void AsyncDownloader_GetContentLength(const String* url, bool priority, const String* id); /* TODO: Implement post */ /* void AsyncDownloader_PostString(const String* url, bool priority, const String* id, const String* contents); */ -void AsyncDownloader_GetDataEx(const String* url, bool priority, const String* id, UInt64* lastModified, const String* etag); +void AsyncDownloader_GetDataEx(const String* url, bool priority, const String* id, TimeMS* lastModified, const String* etag); bool AsyncDownloader_Get(const String* id, struct AsyncRequest* item); bool AsyncDownloader_GetCurrent(struct AsyncRequest* request, Int32* progress); diff --git a/src/Block.c b/src/Block.c index e64a7e90a..4866c79c8 100644 --- a/src/Block.c +++ b/src/Block.c @@ -37,6 +37,13 @@ UInt8 Block_BottomTex[BLOCK_CPE_COUNT] = { 0, 1, 2, 2, 16, 4, 15, 17, 14, 72, 73, 74, 75, 76, 77, 78, 79, 13, 12, 29, 28, 56, 55, 6, 6, 7, 10, 4, 36, 37, 16, 11, 57, 50, 38, 80, 81, 82, 83, 84, 51, 54, 86, 58, 53, 52 }; +#ifdef EXTENDED_BLOCKS +void Block_SetUsedCount(Int32 count) { + Block_UsedCount = count; + Block_IDMask = Math_NextPowOf2(count) - 1; +} +#endif + void Block_Reset(void) { Block_Init(); Block_RecalculateSpriteBB(); diff --git a/src/Block.h b/src/Block.h index 5f38be509..81bcd5e14 100644 --- a/src/Block.h +++ b/src/Block.h @@ -78,6 +78,11 @@ UInt8 Block_Hidden[BLOCK_COUNT * BLOCK_COUNT]; /* Gets a bit flags of which faces of a block can stretch with greedy meshing. */ UInt8 Block_CanStretch[BLOCK_COUNT]; +#ifdef EXTENDED_BLOCKS +Int32 Block_UsedCount, Block_IDMask; +void Block_SetUsedCount(Int32 count); +#endif + void Block_Reset(void); void Block_Init(void); void Block_SetDefaultPerms(void); diff --git a/src/BlockPhysics.c b/src/BlockPhysics.c index d565bdb7f..b34288859 100644 --- a/src/BlockPhysics.c +++ b/src/BlockPhysics.c @@ -241,8 +241,8 @@ static void Physics_HandleSapling(Int32 index, BlockID block) { Game_UpdateBlock(x, y, z, BLOCK_AIR); if (TreeGen_CanGrow(x, y, z, treeHeight)) { - Vector3I coords[Tree_BufferCount]; - BlockID blocks[Tree_BufferCount]; + Vector3I coords[TREE_MAX_COUNT]; + BlockRaw blocks[TREE_MAX_COUNT]; Int32 count = TreeGen_Grow(x, y, z, treeHeight, coords, blocks); Int32 m; diff --git a/src/Chat.c b/src/Chat.c index 812974469..9249e1f03 100644 --- a/src/Chat.c +++ b/src/Chat.c @@ -17,11 +17,11 @@ #include "GameStructs.h" #define CHAT_LOGTIMES_DEF_ELEMS 256 -UInt64 Chat_DefaultLogTimes[CHAT_LOGTIMES_DEF_ELEMS]; -UInt64* Chat_LogTimes = Chat_DefaultLogTimes; +TimeMS Chat_DefaultLogTimes[CHAT_LOGTIMES_DEF_ELEMS]; +TimeMS* Chat_LogTimes = Chat_DefaultLogTimes; Int32 Chat_LogTimesMax = CHAT_LOGTIMES_DEF_ELEMS, Chat_LogTimesCount; -UInt64 Chat_GetLogTime(Int32 i) { +TimeMS Chat_GetLogTime(Int32 i) { if (i < 0 || i >= Chat_LogTimesCount) ErrorHandler_Fail("Tried to get time past LogTime end"); return Chat_LogTimes[i]; } @@ -29,10 +29,10 @@ UInt64 Chat_GetLogTime(Int32 i) { static void Chat_AppendLogTime(void) { if (Chat_LogTimesCount == Chat_LogTimesMax) { Chat_LogTimes = Utils_Resize(Chat_LogTimes, &Chat_LogTimesMax, - sizeof(UInt64), CHAT_LOGTIMES_DEF_ELEMS, 512); + sizeof(TimeMS), CHAT_LOGTIMES_DEF_ELEMS, 512); } - UInt64 now = DateTime_CurrentUTC_MS(); + TimeMS now = DateTime_CurrentUTC_MS(); Chat_LogTimes[Chat_LogTimesCount++] = now; } diff --git a/src/Chat.h b/src/Chat.h index e61fb8a4d..790031d49 100644 --- a/src/Chat.h +++ b/src/Chat.h @@ -22,10 +22,10 @@ enum MSG_TYPE { MSG_TYPE_CLIENTSTATUS_3 = 258, /* Tab list matching names*/ }; -struct ChatLine { char Buffer[STRING_SIZE]; UInt64 Received; }; +struct ChatLine { char Buffer[STRING_SIZE]; TimeMS Received; }; struct ChatLine Chat_Status[3], Chat_BottomRight[3], Chat_ClientStatus[3], Chat_Announcement; StringsBuffer Chat_Log, Chat_InputLog; -UInt64 Chat_GetLogTime(Int32 i); +TimeMS Chat_GetLogTime(Int32 i); void Chat_MakeComponent(struct IGameComponent* comp); void Chat_SetLogName(const String* name); diff --git a/src/Core.h b/src/Core.h index 101b2e2c8..662a4dd4b 100644 --- a/src/Core.h +++ b/src/Core.h @@ -42,16 +42,25 @@ typedef UInt8 bool; #define false 0 #define NULL ((void*)0) -#ifdef INF_ID +//#define EXTENDED_BLOCKS +#ifdef EXTENDED_BLOCKS typedef UInt16 BlockID; #else typedef UInt8 BlockID; #endif + +#define EXTENDED_TEXTURES +#ifdef EXTENDED_TEXTURES +typedef UInt16 TextureLoc; +#else +typedef UInt8 TextureLoc; +#endif + typedef UInt8 BlockRaw; typedef UInt8 EntityID; -typedef UInt16 TextureLoc; typedef UInt8 Face; typedef UInt32 ReturnCode; +typedef UInt64 TimeMS; typedef struct Rect2D_ { Int32 X, Y, Width, Height; } Rect2D; typedef struct Point2D_ { Int32 X, Y; } Point2D; diff --git a/src/EnvRenderer.c b/src/EnvRenderer.c index f2ebb2429..1dff231e1 100644 --- a/src/EnvRenderer.c +++ b/src/EnvRenderer.c @@ -348,16 +348,28 @@ static void EnvRenderer_InitWeatherHeightmap(void) { } } +#define EnvRenderer_RainCalcBody(get_block)\ +for (y = maxY; y >= 0; y--, i -= World_OneY) {\ + UInt8 draw = Block_Draw[get_block];\ + if (!(draw == DRAW_GAS || draw == DRAW_SPRITE)) {\ + Weather_Heightmap[index] = y;\ + return y;\ + }\ +} + static Int32 EnvRenderer_CalcRainHeightAt(Int32 x, Int32 maxY, Int32 z, Int32 index) { Int32 i = World_Pack(x, maxY, z), y; - for (y = maxY; y >= 0; y--, i -= World_OneY) { - UInt8 draw = Block_Draw[World_Blocks[i]]; - if (!(draw == DRAW_GAS || draw == DRAW_SPRITE)) { - Weather_Heightmap[index] = y; - return y; - } +#ifndef EXTENDED_BLOCKS + EnvRenderer_RainCalcBody(World_Blocks[i]); +#else + if (Block_UsedCount <= 256) { + EnvRenderer_RainCalcBody(World_Blocks[i]); + } else { + EnvRenderer_RainCalcBody(World_Blocks[i] | (World_Blocks2[i] << 8)); } +#endif + Weather_Heightmap[index] = -1; return -1; } diff --git a/src/ExtMath.c b/src/ExtMath.c index 5d0f48842..2bf05c1e9 100644 --- a/src/ExtMath.c +++ b/src/ExtMath.c @@ -116,7 +116,7 @@ double Math_FastExp(double x) { void Random_Init(Random* seed, Int32 seedInit) { Random_SetSeed(seed, seedInit); } void Random_InitFromCurrentTime(Random* rnd) { - UInt64 now = DateTime_CurrentUTC_MS(); + TimeMS now = DateTime_CurrentUTC_MS(); Random_Init(rnd, (Int32)now); } diff --git a/src/Formats.c b/src/Formats.c index 8d6354b92..a7ed84b68 100644 --- a/src/Formats.c +++ b/src/Formats.c @@ -371,7 +371,7 @@ static bool Cw_Callback_1(struct NbtTag* tag) { if (IsTag(tag, "BlockArray")) { World_BlocksSize = tag->DataSize; if (tag->DataSize < NBT_SMALL_SIZE) { - World_Blocks = Mem_Alloc(World_BlocksSize, sizeof(UInt8), ".cw map blocks"); + World_Blocks = Mem_Alloc(World_BlocksSize, 1, ".cw map blocks"); Mem_Copy(World_Blocks, tag->DataSmall, tag->DataSize); } else { World_Blocks = tag->DataBig; @@ -954,8 +954,8 @@ ReturnCode Cw_Save(struct Stream* stream) { col = Env_ShadowCol; tmp[253] = col.R; tmp[259] = col.G; tmp[265] = col.B; col = Env_SunCol; tmp[283] = col.R; tmp[289] = col.G; tmp[295] = col.B; - tmp[352] = Env_SidesBlock; - tmp[365] = Env_EdgeBlock; + tmp[352] = (BlockRaw)Env_SidesBlock; + tmp[365] = (BlockRaw)Env_EdgeBlock; Stream_SetU16_BE(&tmp[378], Env_EdgeHeight); } Int32 b, len = Cw_WriteEndString(&tmp[393], &World_TextureUrl); diff --git a/src/Game.c b/src/Game.c index d6237e95d..bbfa99af9 100644 --- a/src/Game.c +++ b/src/Game.c @@ -445,6 +445,9 @@ void Game_Load(void) { Event_RegisterVoid(&WindowEvents_Resized, NULL, Game_OnResize); Event_RegisterVoid(&WindowEvents_Closed, NULL, Game_Free); +#ifdef EXTENDED_BLOCKS + Block_SetUsedCount(256); +#endif Block_Init(); ModelCache_Init(); diff --git a/src/InputHandler.c b/src/InputHandler.c index 3a9ae3288..cc17cb827 100644 --- a/src/InputHandler.c +++ b/src/InputHandler.c @@ -22,7 +22,7 @@ bool input_buttonsDown[3]; Int32 input_pickingId = -1; Int32 input_normViewDists[10] = { 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096 }; Int32 input_classicViewDists[4] = { 8, 32, 128, 512 }; -UInt64 input_lastClick; +TimeMS input_lastClick; float input_fovIndex = -1.0f; bool InputHandler_IsMousePressed(MouseButton button) { @@ -300,7 +300,7 @@ static bool InputHandler_CheckIsFree(BlockID block) { } void InputHandler_PickBlocks(bool cooldown, bool left, bool middle, bool right) { - UInt64 now = DateTime_CurrentUTC_MS(); + TimeMS now = DateTime_CurrentUTC_MS(); Int32 delta = (Int32)(now - input_lastClick); if (cooldown && delta < 250) return; /* 4 times per second */ @@ -318,19 +318,19 @@ void InputHandler_PickBlocks(bool cooldown, bool left, bool middle, bool right) /* always play delete animations, even if we aren't picking a block */ HeldBlockRenderer_ClickAnim(true); - Vector3I pos = Game_SelectedPos.BlockPos; - if (!Game_SelectedPos.Valid || !World_IsValidPos_3I(pos)) return; + Vector3I p = Game_SelectedPos.BlockPos; + if (!Game_SelectedPos.Valid || !World_IsValidPos_3I(p)) return; - BlockID old = World_GetBlock_3I(pos); + BlockID old = World_GetBlock(p.X, p.Y, p.Z); if (Block_Draw[old] == DRAW_GAS || !Block_CanDelete[old]) return; - Game_UpdateBlock(pos.X, pos.Y, pos.Z, BLOCK_AIR); - Event_RaiseBlock(&UserEvents_BlockChanged, pos, old, BLOCK_AIR); + Game_UpdateBlock(p.X, p.Y, p.Z, BLOCK_AIR); + Event_RaiseBlock(&UserEvents_BlockChanged, p, old, BLOCK_AIR); } else if (right) { - Vector3I pos = Game_SelectedPos.TranslatedPos; - if (!Game_SelectedPos.Valid || !World_IsValidPos_3I(pos)) return; + Vector3I p = Game_SelectedPos.TranslatedPos; + if (!Game_SelectedPos.Valid || !World_IsValidPos_3I(p)) return; - BlockID old = World_GetBlock_3I(pos); + BlockID old = World_GetBlock(p.X, p.Y, p.Z); BlockID block = Inventory_SelectedBlock; if (Game_AutoRotate) { block = AutoRotate_RotateBlock(block); } @@ -339,13 +339,13 @@ void InputHandler_PickBlocks(bool cooldown, bool left, bool middle, bool right) if (Block_Draw[block] == DRAW_GAS && Block_Draw[old] != DRAW_GAS) return; if (!InputHandler_CheckIsFree(block)) return; - Game_UpdateBlock(pos.X, pos.Y, pos.Z, block); - Event_RaiseBlock(&UserEvents_BlockChanged, pos, old, block); + Game_UpdateBlock(p.X, p.Y, p.Z, block); + Event_RaiseBlock(&UserEvents_BlockChanged, p, old, block); } else if (middle) { - Vector3I pos = Game_SelectedPos.BlockPos; - if (!Game_SelectedPos.Valid || !World_IsValidPos_3I(pos)) return; + Vector3I p = Game_SelectedPos.BlockPos; + if (!Game_SelectedPos.Valid || !World_IsValidPos_3I(p)) return; - BlockID cur = World_GetBlock_3I(pos); + BlockID cur = World_GetBlock(p.X, p.Y, p.Z); if (Block_Draw[cur] == DRAW_GAS) return; if (!(Block_CanPlace[cur] || Block_CanDelete[cur])) return; if (!Inventory_CanChangeSelected() || Inventory_SelectedBlock == cur) return; diff --git a/src/Lighting.c b/src/Lighting.c index d4ca0769e..f01baabb9 100644 --- a/src/Lighting.c +++ b/src/Lighting.c @@ -8,17 +8,31 @@ #include "Event.h" #include "GameStructs.h" +#define HEIGHT_UNCALCULATED Int16_MaxValue + +#define Lighting_CalcBody(get_block)\ +for (y = maxY; y >= 0; y--, i -= World_OneY) {\ + BlockID block = get_block;\ + if (Block_BlocksLight[block]) {\ + Int32 offset = (Block_LightOffset[block] >> FACE_YMAX) & 1;\ + Lighting_Heightmap[index] = y - offset;\ + return y - offset;\ + }\ +} + static Int32 Lighting_CalcHeightAt(Int32 x, Int32 maxY, Int32 z, Int32 index) { Int32 y, i = World_Pack(x, maxY, z); - for (y = maxY; y >= 0; y--, i -= World_OneY) { - BlockID block = World_Blocks[i]; - if (Block_BlocksLight[block]) { - Int32 offset = (Block_LightOffset[block] >> FACE_YMAX) & 1; - Lighting_Heightmap[index] = y - offset; - return y - offset; - } +#ifndef EXTENDED_BLOCKS + Lighting_CalcBody(World_Blocks[i]); +#else + if (Block_UsedCount <= 256) { + Lighting_CalcBody(World_Blocks[i]); + } else { + Lighting_CalcBody(World_Blocks[i] | (World_Blocks2[i] << 8)); } +#endif + Lighting_Heightmap[index] = -10; return -10; } @@ -26,7 +40,7 @@ static Int32 Lighting_CalcHeightAt(Int32 x, Int32 maxY, Int32 z, Int32 index) { static Int32 Lighting_GetLightHeight(Int32 x, Int32 z) { Int32 index = (z * World_Width) + x; Int32 lightH = Lighting_Heightmap[index]; - return lightH == Int16_MaxValue ? Lighting_CalcHeightAt(x, World_Height - 1, z, index) : lightH; + return lightH == HEIGHT_UNCALCULATED ? Lighting_CalcHeightAt(x, World_Height - 1, z, index) : lightH; } /* Outside colour is same as sunlight colour, so we reuse when possible */ @@ -65,7 +79,7 @@ PackedCol Lighting_Col_ZSide_Fast(Int32 x, Int32 y, Int32 z) { void Lighting_Refresh(void) { Int32 i; for (i = 0; i < World_Width * World_Length; i++) { - Lighting_Heightmap[i] = Int16_MaxValue; + Lighting_Heightmap[i] = HEIGHT_UNCALCULATED; } } @@ -74,7 +88,7 @@ void Lighting_Refresh(void) { *----------------------------------------------------Lighting update------------------------------------------------------* *#########################################################################################################################*/ static void Lighting_UpdateLighting(Int32 x, Int32 y, Int32 z, BlockID oldBlock, BlockID newBlock, Int32 index, Int32 lightH) { - bool didBlock = Block_BlocksLight[oldBlock]; + bool didBlock = Block_BlocksLight[oldBlock]; bool nowBlocks = Block_BlocksLight[newBlock]; Int32 oldOffset = (Block_LightOffset[oldBlock] >> FACE_YMAX) & 1; Int32 newOffset = (Block_LightOffset[newBlock] >> FACE_YMAX) & 1; @@ -111,13 +125,24 @@ static bool Lighting_Needs(BlockID block, BlockID other) { return Block_Draw[block] != DRAW_OPAQUE || Block_Draw[other] != DRAW_GAS; } +#define Lighting_NeedsNeighourBody(get_block)\ +/* Update if any blocks in the chunk are affected by light change. */ \ +for (; y >= minY; y--, index -= World_OneY) {\ + BlockID other = World_Blocks[index];\ + bool affected = y == nY ? Lighting_Needs(block, other) : Block_Draw[other] != DRAW_GAS;\ + if (affected) return true;\ +} + static bool Lighting_NeedsNeighour(BlockID block, Int32 index, Int32 minY, Int32 y, Int32 nY) { - /* Update if any blocks in the chunk are affected by light change. */ - for (; y >= minY; y--, index -= World_OneY) { - BlockID other = World_Blocks[index]; - bool affected = y == nY ? Lighting_Needs(block, other) : Block_Draw[other] != DRAW_GAS; - if (affected) return true; +#ifndef EXTENDED_BLOCKS + Lighting_NeedsNeighourBody(World_Blocks[i]); +#else + if (Block_UsedCount <= 256) { + Lighting_NeedsNeighourBody(World_Blocks[i]); + } else { + Lighting_NeedsNeighourBody(World_Blocks[i] | (World_Blocks2[i] << 8)); } +#endif return false; } @@ -187,7 +212,7 @@ void Lighting_OnBlockChanged(Int32 x, Int32 y, Int32 z, BlockID oldBlock, BlockI Int32 lightH = Lighting_Heightmap[index]; /* Since light wasn't checked to begin with, means column never had meshes for any of its chunks built. */ /* So we don't need to do anything. */ - if (lightH == Int16_MaxValue) return; + if (lightH == HEIGHT_UNCALCULATED) return; Lighting_UpdateLighting(x, y, z, oldBlock, newBlock, index, lightH); Int32 newHeight = Lighting_Heightmap[index] + 1; @@ -207,7 +232,7 @@ static Int32 Lighting_InitialHeightmapCoverage(Int32 x1, Int32 z1, Int32 xCount, for (x = 0; x < xCount; x++) { Int32 lightH = Lighting_Heightmap[heightmapIndex++]; skip[index] = 0; - if (lightH == Int16_MaxValue) { + if (lightH == HEIGHT_UNCALCULATED) { elemsLeft++; curRunCount = 0; } else { @@ -275,7 +300,7 @@ static void Lighting_FinishHeightmapCoverage(Int32 x1, Int32 z1, Int32 xCount, I Int32 heightmapIndex = Lighting_Pack(x1, z1 + z); for (x = 0; x < xCount; x++) { Int32 lightH = Lighting_Heightmap[heightmapIndex]; - if (lightH == Int16_MaxValue) + if (lightH == HEIGHT_UNCALCULATED) Lighting_Heightmap[heightmapIndex] = -10; heightmapIndex++; } @@ -283,10 +308,10 @@ static void Lighting_FinishHeightmapCoverage(Int32 x1, Int32 z1, Int32 xCount, I } void Lighting_LightHint(Int32 startX, Int32 startZ) { - Int32 x1 = max(startX, 0), x2 = min(World_Width, startX + 18); - Int32 z1 = max(startZ, 0), z2 = min(World_Length, startZ + 18); + Int32 x1 = max(startX, 0), x2 = min(World_Width, startX + EXTCHUNK_SIZE); + Int32 z1 = max(startZ, 0), z2 = min(World_Length, startZ + EXTCHUNK_SIZE); Int32 xCount = x2 - x1, zCount = z2 - z1; - Int32 skip[18 * 18]; + Int32 skip[EXTCHUNK_SIZE * EXTCHUNK_SIZE]; Int32 elemsLeft = Lighting_InitialHeightmapCoverage(x1, z1, xCount, zCount, skip); if (!Lighting_CalculateHeightmapCoverage(x1, z1, xCount, zCount, elemsLeft, skip)) { diff --git a/src/MapGenerator.c b/src/MapGenerator.c index 24e24514e..b483c2fc8 100644 --- a/src/MapGenerator.c +++ b/src/MapGenerator.c @@ -453,8 +453,8 @@ static void NotchyGen_PlantTrees(void) { BlockRaw blockUnder = treeY > 0 ? Gen_Blocks[index - oneY] : BLOCK_AIR; if (blockUnder == BLOCK_GRASS && TreeGen_CanGrow(treeX, treeY, treeZ, treeHeight)) { - Vector3I coords[Tree_BufferCount]; - BlockRaw blocks[Tree_BufferCount]; + Vector3I coords[TREE_MAX_COUNT]; + BlockRaw blocks[TREE_MAX_COUNT]; Int32 count = TreeGen_Grow(treeX, treeY, treeZ, treeHeight, coords, blocks); for (m = 0; m < count; m++) { diff --git a/src/MapGenerator.h b/src/MapGenerator.h index 0b74070f9..b10ae7949 100644 --- a/src/MapGenerator.h +++ b/src/MapGenerator.h @@ -37,7 +37,7 @@ Int32 Tree_Width, Tree_Height, Tree_Length; BlockRaw* Tree_Blocks; Random* Tree_Rnd; /* Appropriate buffer size to hold positions and blocks generated by the tree generator. */ -#define Tree_BufferCount 96 +#define TREE_MAX_COUNT 96 bool TreeGen_CanGrow(Int32 treeX, Int32 treeY, Int32 treeZ, Int32 treeHeight); Int32 TreeGen_Grow(Int32 treeX, Int32 treeY, Int32 treeZ, Int32 height, Vector3I* coords, BlockRaw* blocks); diff --git a/src/PacketHandlers.c b/src/PacketHandlers.c index 0bd878f21..f94f52513 100644 --- a/src/PacketHandlers.c +++ b/src/PacketHandlers.c @@ -25,11 +25,36 @@ #include "Errors.h" #include "TerrainAtlas.h" +/* Classic state */ +UInt8 classic_tabList[256 >> 3]; + +/* CPE state */ +Int32 cpe_serverExtensionsCount, cpe_pingTicks; +Int32 cpe_envMapVer = 2, cpe_blockDefsExtVer = 2; +bool cpe_twoWayPing, cpe_extTextures, cpe_extBlocks; + /*########################################################################################################################* *-----------------------------------------------------Common handlers-----------------------------------------------------* *#########################################################################################################################*/ -UInt8 classicTabList[256 >> 3]; -#define Handlers_ReadBlock(data) *data++; + + +#ifndef EXTENDED_BLOCKS +#define Handlers_ReadBlock(data, value) value = *data++; +#else +#define Handlers_ReadBlock(data, value)\ +if (cpe_extBlocks) {\ + value = Stream_GetU16_BE(data, value); data += 2;\ +} else { value = *data++; } +#endif + +#ifndef EXTENDED_BLOCKS +#define Handlers_WriteBlock(data, value) *data++ = value; +#else +#define Handlers_WriteBlock(data, value)\ +if (cpe_extBlocks) {\ + Stream_SetU16_BE(data, value); data += 2;\ +} else { *data++ = value; } +#endif static void Handlers_ReadString(UInt8** ptr, String* str) { Int32 i, length = 0; @@ -140,10 +165,10 @@ void Handlers_RemoveEntity(EntityID id) { /* See comment about some servers in Classic_AddEntity */ Int32 mask = id >> 3, bit = 1 << (id & 0x7); - if (!(classicTabList[mask] & bit)) return; + if (!(classic_tabList[mask] & bit)) return; Handlers_RemoveTablistEntry(id); - classicTabList[mask] &= (UInt8)~bit; + classic_tabList[mask] &= (UInt8)~bit; } static void Handlers_UpdateLocation(EntityID playerId, struct LocationUpdate* update, bool interpolate) { @@ -284,7 +309,7 @@ static void WoM_Tick(void) { /*########################################################################################################################* *----------------------------------------------------Classic protocol-----------------------------------------------------* *#########################################################################################################################*/ -UInt64 mapReceiveStart; +TimeMS mapReceiveStart; struct InflateState mapInflateState; struct Stream mapInflateStream; bool mapInflateInited; @@ -298,65 +323,62 @@ bool receivedFirstPosition; void Classic_WriteChat(const String* text, bool partial) { UInt8* data = ServerConnection_WriteBuffer; - data[0] = OPCODE_MESSAGE; + *data++ = OPCODE_MESSAGE; { - data[1] = ServerConnection_SupportsPartialMessages ? partial : ENTITIES_SELF_ID; - Handlers_WriteString(&data[2], text); + *data++ = ServerConnection_SupportsPartialMessages ? partial : ENTITIES_SELF_ID; + Handlers_WriteString(data, text); data += STRING_SIZE; } - ServerConnection_WriteBuffer += 66; + ServerConnection_WriteBuffer = data; } void Classic_WritePosition(Vector3 pos, float rotY, float headX) { UInt8* data = ServerConnection_WriteBuffer; - data[0] = OPCODE_ENTITY_TELEPORT; - Int32 len; + *data++ = OPCODE_ENTITY_TELEPORT; { - data[1] = cpe_sendHeldBlock ? Inventory_SelectedBlock : ENTITIES_SELF_ID; /* TODO: extended blocks */ + *data++ = cpe_sendHeldBlock ? Inventory_SelectedBlock : ENTITIES_SELF_ID; /* TODO: extended blocks */ Int32 x = (Int32)(pos.X * 32); Int32 y = (Int32)(pos.Y * 32) + 51; Int32 z = (Int32)(pos.Z * 32); if (cpe_extEntityPos) { - Stream_SetU32_BE(&data[2], x); - Stream_SetU32_BE(&data[6], y); - Stream_SetU32_BE(&data[10], z); - len = 14; + Stream_SetU32_BE(data, x); data += 4; + Stream_SetU32_BE(data, y); data += 4; + Stream_SetU32_BE(data, z); data += 4; } else { - Stream_SetU16_BE(&data[2], x); - Stream_SetU16_BE(&data[4], y); - Stream_SetU16_BE(&data[6], z); - len = 8; + Stream_SetU16_BE(data, x); data += 2; + Stream_SetU16_BE(data, y); data += 2; + Stream_SetU16_BE(data, z); data += 2; } - data[len++] = Math_Deg2Packed(rotY); - data[len++] = Math_Deg2Packed(headX); + *data++ = Math_Deg2Packed(rotY); + *data++ = Math_Deg2Packed(headX); } - ServerConnection_WriteBuffer += len; + ServerConnection_WriteBuffer = data; } void Classic_WriteSetBlock(Int32 x, Int32 y, Int32 z, bool place, BlockID block) { UInt8* data = ServerConnection_WriteBuffer; - data[0] = OPCODE_SET_BLOCK_CLIENT; + *data++ = OPCODE_SET_BLOCK_CLIENT; { - Stream_SetU16_BE(&data[1], x); - Stream_SetU16_BE(&data[3], y); - Stream_SetU16_BE(&data[5], z); - data[7] = place; - data[8] = block; /* TODO: extended blocks */ + Stream_SetU16_BE(data, x); data += 2; + Stream_SetU16_BE(data, y); data += 2; + Stream_SetU16_BE(data, z); data += 2; + *data++ = place; + *data++ = block; /* TODO: extended blocks */ } - ServerConnection_WriteBuffer += 9; + ServerConnection_WriteBuffer = data; } void Classic_WriteLogin(const String* username, const String* verKey) { UInt8* data = ServerConnection_WriteBuffer; - data[0] = OPCODE_HANDSHAKE; + *data++ = OPCODE_HANDSHAKE; { - data[1] = 7; /* protocol version */ - Handlers_WriteString(&data[2], username); - Handlers_WriteString(&data[66], verKey); - data[130] = Game_UseCPE ? 0x42 : 0x00; + *data++ = 7; /* protocol version */ + Handlers_WriteString(data, username); data += STRING_SIZE; + Handlers_WriteString(data, verKey); data += STRING_SIZE; + *data++ = Game_UseCPE ? 0x42 : 0x00; } - ServerConnection_WriteBuffer += 131; + ServerConnection_WriteBuffer = data; } static void Classic_Handshake(UInt8* data) { @@ -485,7 +507,7 @@ static void Classic_SetBlock(UInt8* data) { Int32 z = Stream_GetU16_BE(&data[4]); data += 6; - BlockID block = Handlers_ReadBlock(data); + BlockID block; Handlers_ReadBlock(data, block); if (World_IsValidPos(x, y, z)) { Game_UpdateBlock(x, y, z, block); } @@ -505,7 +527,7 @@ static void Classic_AddEntity(UInt8* data) { /* Workaround for some servers that declare support for ExtPlayerList but don't send ExtAddPlayerName */ String group = String_FromConst("Players"); Handlers_AddTablistEntry(id, &name, &name, &group, 0); - classicTabList[id >> 3] |= (UInt8)(1 << (id & 0x7)); + classic_tabList[id >> 3] |= (UInt8)(1 << (id & 0x7)); } static void Classic_EntityTeleport(UInt8* data) { @@ -648,11 +670,6 @@ static void Classic_Tick(void) { /*########################################################################################################################* *------------------------------------------------------CPE protocol-------------------------------------------------------* *#########################################################################################################################*/ - -Int32 cpe_serverExtensionsCount, cpe_pingTicks; -Int32 cpe_envMapVer = 2, cpe_blockDefsExtVer = 2; -bool cpe_twoWayPing, cpe_extTextures; - const char* cpe_clientExtensions[29] = { "ClickDistance", "CustomBlocks", "HeldBlock", "EmoteFix", "TextHotKey", "ExtPlayerList", "EnvColors", "SelectionCuboid", "BlockPermissions", "ChangeModel", "EnvMapAppearance", @@ -667,76 +684,80 @@ static void CPE_SetMapEnvUrl(UInt8* data); void CPE_WritePlayerClick(MouseButton button, bool buttonDown, UInt8 targetId, struct PickedPos* pos) { struct Entity* p = &LocalPlayer_Instance.Base; UInt8* data = ServerConnection_WriteBuffer; - data[0] = OPCODE_PLAYER_CLICK; + *data++ = OPCODE_PLAYER_CLICK; { - data[1] = button; - data[2] = buttonDown; - Stream_SetU16_BE(&data[3], Ext_Deg2Packed(p->HeadY)); - Stream_SetU16_BE(&data[5], Ext_Deg2Packed(p->HeadX)); + *data++ = button; + *data++ = buttonDown; + Stream_SetU16_BE(data, Ext_Deg2Packed(p->HeadY)); data += 2; + Stream_SetU16_BE(data, Ext_Deg2Packed(p->HeadX)); data += 2; - data[7] = targetId; - Stream_SetU16_BE(&data[8], pos->BlockPos.X); - Stream_SetU16_BE(&data[10], pos->BlockPos.Y); - Stream_SetU16_BE(&data[12], pos->BlockPos.Z); + *data++ = targetId; + Stream_SetU16_BE(data, pos->BlockPos.X); data += 2; + Stream_SetU16_BE(data, pos->BlockPos.Y); data += 2; + Stream_SetU16_BE(data, pos->BlockPos.Z); data += 2; - data[14] = 255; + *data = 255; /* Our own face values differ from CPE block face */ switch (pos->ClosestFace) { - case FACE_XMAX: data[14] = 0; break; - case FACE_XMIN: data[14] = 1; break; - case FACE_YMAX: data[14] = 2; break; - case FACE_YMIN: data[14] = 3; break; - case FACE_ZMAX: data[14] = 4; break; - case FACE_ZMIN: data[14] = 5; break; + case FACE_XMAX: *data = 0; break; + case FACE_XMIN: *data = 1; break; + case FACE_YMAX: *data = 2; break; + case FACE_YMIN: *data = 3; break; + case FACE_ZMAX: *data = 4; break; + case FACE_ZMIN: *data = 5; break; } + data++; } ServerConnection_WriteBuffer += 15; } static void CPE_WriteExtInfo(const String* appName, Int32 extensionsCount) { UInt8* data = ServerConnection_WriteBuffer; - data[0] = OPCODE_EXT_INFO; + *data++ = OPCODE_EXT_INFO; { - Handlers_WriteString(&data[1], appName); - Stream_SetU16_BE(&data[65], extensionsCount); + Handlers_WriteString(data, appName); data += STRING_SIZE; + Stream_SetU16_BE(data, extensionsCount); data += 2; } - ServerConnection_WriteBuffer += 67; + ServerConnection_WriteBuffer = data; } static void CPE_WriteExtEntry(const String* extensionName, Int32 extensionVersion) { UInt8* data = ServerConnection_WriteBuffer; - data[0] = OPCODE_EXT_ENTRY; + *data++ = OPCODE_EXT_ENTRY; { - Handlers_WriteString(&data[1], extensionName); - Stream_SetU32_BE(&data[65], extensionVersion); + Handlers_WriteString(data, extensionName); data += STRING_SIZE; + Stream_SetU32_BE(data, extensionVersion); data += 4; } - ServerConnection_WriteBuffer += 69; + ServerConnection_WriteBuffer = data; } static void CPE_WriteCustomBlockLevel(UInt8 version) { UInt8* data = ServerConnection_WriteBuffer; - data[0] = OPCODE_CUSTOM_BLOCK_LEVEL; + *data++ = OPCODE_CUSTOM_BLOCK_LEVEL; { - data[1] = version; + *data++ = version; } - ServerConnection_WriteBuffer += 2; + ServerConnection_WriteBuffer = data; } static void CPE_WriteTwoWayPing(bool serverToClient, UInt16 payload) { UInt8* data = ServerConnection_WriteBuffer; - data[0] = OPCODE_TWO_WAY_PING; + *data++ = OPCODE_TWO_WAY_PING; { - data[1] = serverToClient; - Stream_SetU16_BE(&data[2], payload); + *data++ = serverToClient; + Stream_SetU16_BE(data, payload); data += 2; } - ServerConnection_WriteBuffer += 4; + ServerConnection_WriteBuffer = data; } static void CPE_SendCpeExtInfoReply(void) { if (cpe_serverExtensionsCount) return; Int32 count = Array_Elems(cpe_clientExtensions); - if (!Game_AllowCustomBlocks) count -= 2; +#ifndef EXTENDED_TEXTURES + count--; +#endif + if (!Game_AllowCustomBlocks) count -= 2; CPE_WriteExtInfo(&ServerConnection_AppName, count); Net_SendPacket(); Int32 i, ver; @@ -753,6 +774,10 @@ static void CPE_SendCpeExtInfoReply(void) { if (String_CaselessEqualsConst(&name, "BlockDefinitions")) continue; } +#ifndef EXTENDED_TEXTURES + if (String_CaselessEqualsConst(&name, "ExtendedTextures")) continue; +#endif + CPE_WriteExtEntry(&name, ver); Net_SendPacket(); } @@ -818,11 +843,14 @@ static void CPE_ExtEntry(UInt8* data) { } else if (String_CaselessEqualsConst(&ext, "FastMap")) { Net_PacketSizes[OPCODE_LEVEL_BEGIN] += 4; cpe_fastMap = true; - } else if (String_CaselessEqualsConst(&ext, "ExtendedTextures")) { + } +#ifdef EXTENDED_TEXTURES + else if (String_CaselessEqualsConst(&ext, "ExtendedTextures")) { Net_PacketSizes[OPCODE_DEFINE_BLOCK] += 3; Net_PacketSizes[OPCODE_DEFINE_BLOCK_EXT] += 6; cpe_extTextures = true; } +#endif } static void CPE_SetClickDistance(UInt8* data) { @@ -837,7 +865,7 @@ static void CPE_CustomBlockLevel(UInt8* data) { } static void CPE_HoldThis(UInt8* data) { - BlockID block = Handlers_ReadBlock(data); + BlockID block; Handlers_ReadBlock(data, block); bool canChange = *data == 0; Inventory_CanChangeHeldBlock = true; @@ -891,7 +919,7 @@ static void CPE_ExtAddPlayerName(UInt8* data) { /* Workarond for server software that declares support for ExtPlayerList, but sends AddEntity then AddPlayerName */ Int32 mask = id >> 3, bit = 1 << (id & 0x7); - classicTabList[mask] &= (UInt8)~bit; + classic_tabList[mask] &= (UInt8)~bit; Handlers_AddTablistEntry(id, &playerName, &listName, &groupName, groupRank); } @@ -901,7 +929,7 @@ static void CPE_ExtAddEntity(UInt8* data) { String displayName = String_FromArray(displayNameBuffer); String skinName = String_FromArray(skinNameBuffer); - UInt8 id = *data++; + EntityID id = *data++; Handlers_ReadString(&data, &displayName); Handlers_ReadString(&data, &skinName); @@ -960,7 +988,7 @@ static void CPE_SetEnvCol(UInt8* data) { } static void CPE_SetBlockPermission(UInt8* data) { - BlockID block = Handlers_ReadBlock(data); + BlockID block; Handlers_ReadBlock(data, block); Block_CanPlace[block] = *data++ != 0; Block_CanDelete[block] = *data++ != 0; Event_RaiseVoid(&BlockEvents_PermissionsChanged); @@ -1021,7 +1049,7 @@ static void CPE_ExtAddEntity2(UInt8* data) { String displayName = String_FromArray(displayNameBuffer); String skinName = String_FromArray(skinNameBuffer); - UInt8 id = *data++; + EntityID id = *data++; Handlers_ReadString(&data, &displayName); Handlers_ReadString(&data, &skinName); @@ -1031,7 +1059,7 @@ static void CPE_ExtAddEntity2(UInt8* data) { #define BULK_MAX_BLOCKS 256 static void CPE_BulkBlockUpdate(UInt8* data) { - Int32 i, count = *data++ + 1; + Int32 i, count = 1 + *data++; UInt32 indices[BULK_MAX_BLOCKS]; for (i = 0; i < count; i++) { @@ -1119,7 +1147,7 @@ static void CPE_SetMapEnvProperty(UInt8* data) { } static void CPE_SetEntityProperty(UInt8* data) { - UInt8 id = *data++; + EntityID id = *data++; UInt8 type = *data++; Int32 value = (Int32)Stream_GetU32_BE(data); @@ -1167,8 +1195,8 @@ static void CPE_TwoWayPing(UInt8* data) { } static void CPE_SetInventoryOrder(UInt8* data) { - BlockID block = Handlers_ReadBlock(data); - BlockID order = Handlers_ReadBlock(data); + BlockID block; Handlers_ReadBlock(data, block); + BlockID order; Handlers_ReadBlock(data, order); Inventory_Remove(block); if (order) { Inventory_Map[order - 1] = block; } @@ -1248,7 +1276,7 @@ static BlockID BlockDefs_DefineBlockCommonStart(UInt8** ptr, bool uniqueSideTexs char nameBuffer[STRING_SIZE]; String name = String_FromArray(nameBuffer); - BlockID block = Handlers_ReadBlock(data); + BlockID block; Handlers_ReadBlock(data, block); bool didBlockLight = Block_BlocksLight[block]; Block_ResetProps(block); @@ -1317,7 +1345,7 @@ static void BlockDefs_DefineBlock(UInt8* data) { } static void BlockDefs_UndefineBlock(UInt8* data) { - BlockID block = Handlers_ReadBlock(data); + BlockID block; Handlers_ReadBlock(data, block); bool didBlockLight = Block_BlocksLight[block]; Block_ResetProps(block); diff --git a/src/Platform.c b/src/Platform.c index 3d523c257..554a4fd2f 100644 --- a/src/Platform.c +++ b/src/Platform.c @@ -189,7 +189,7 @@ void Platform_Log(const String* message) { #define FILETIME_EPOCH 50491123200000ULL #define FileTime_TotalMS(time) ((time / 10000) + FILETIME_EPOCH) -UInt64 DateTime_CurrentUTC_MS(void) { +TimeMS DateTime_CurrentUTC_MS(void) { FILETIME ft; GetSystemTimeAsFileTime(&ft); /* in 100 nanosecond units, since Jan 1 1601 */ UInt64 raw = ft.dwLowDateTime | ((UInt64)ft.dwHighDateTime << 32); @@ -238,7 +238,7 @@ void Platform_Log(const String* message) { #define UNIX_EPOCH 62135596800000ULL #define UnixTime_TotalMS(time) ((UInt64)time.tv_sec * 1000 + UNIX_EPOCH + (time.tv_usec / 1000)) -UInt64 DateTime_CurrentUTC_MS(void) { +TimeMS DateTime_CurrentUTC_MS(void) { struct timeval cur; gettimeofday(&cur, NULL); return UnixTime_TotalMS(cur); @@ -332,7 +332,7 @@ ReturnCode Directory_Enum(const String* path, void* obj, Directory_EnumCallback return Win_Return(result == ERROR_NO_MORE_FILES); } -ReturnCode File_GetModifiedTime_MS(const String* path, UInt64* time) { +ReturnCode File_GetModifiedTime_MS(const String* path, TimeMS* time) { void* file; ReturnCode result = File_Open(&file, path); if (result) return result; @@ -443,7 +443,7 @@ ReturnCode Directory_Enum(const String* path, void* obj, Directory_EnumCallback return result; } -ReturnCode File_GetModifiedTime_MS(const String* path, UInt64* time) { +ReturnCode File_GetModifiedTime_MS(const String* path, TimeMS* time) { char str[600]; Platform_ConvertString(str, path); struct stat sb; if (stat(str, &sb) == -1) return errno; diff --git a/src/Platform.h b/src/Platform.h index 639ca5e66..433668969 100644 --- a/src/Platform.h +++ b/src/Platform.h @@ -46,7 +46,7 @@ void Platform_Log2(const char* format, const void* a1, const void* a2); void Platform_Log3(const char* format, const void* a1, const void* a2, const void* a3); void Platform_Log4(const char* format, const void* a1, const void* a2, const void* a3, const void* a4); -UInt64 DateTime_CurrentUTC_MS(void); +TimeMS DateTime_CurrentUTC_MS(void); void DateTime_CurrentUTC(DateTime* time); void DateTime_CurrentLocal(DateTime* time); void Stopwatch_Measure(UInt64* timer); @@ -57,7 +57,7 @@ ReturnCode Directory_Create(const String* path); typedef void Directory_EnumCallback(const String* filename, void* obj); ReturnCode Directory_Enum(const String* path, void* obj, Directory_EnumCallback callback); bool File_Exists(const String* path); -ReturnCode File_GetModifiedTime_MS(const String* path, UInt64* ms); +ReturnCode File_GetModifiedTime_MS(const String* path, TimeMS* ms); ReturnCode File_Create(void** file, const String* path); ReturnCode File_Open(void** file, const String* path); diff --git a/src/Screens.c b/src/Screens.c index c014d34dd..653fe01e3 100644 --- a/src/Screens.c +++ b/src/Screens.c @@ -93,7 +93,7 @@ struct ChatScreen { struct DisconnectScreen { Screen_Layout - UInt64 InitTime; + TimeMS InitTime; bool CanReconnect, LastActive; Int32 LastSecsLeft; struct ButtonWidget Reconnect; @@ -1111,7 +1111,7 @@ static void ChatScreen_Render(void* screen, double delta) { Texture_Render(&tex); } - UInt64 now = DateTime_CurrentUTC_MS(); + TimeMS now = DateTime_CurrentUTC_MS(); if (s->HandlesAllInput) { Elem_Render(&s->Chat, delta); } else { diff --git a/src/ServerConnection.c b/src/ServerConnection.c index fcc70911e..1e9d60f0a 100644 --- a/src/ServerConnection.c +++ b/src/ServerConnection.c @@ -53,7 +53,7 @@ void ServerConnection_DownloadTexturePack(const String* url) { if (TextureCache_HasDenied(url)) return; char etagBuffer[STRING_SIZE]; String etag = String_FromArray(etagBuffer); - UInt64 lastModified = 0; + TimeMS lastModified = 0; if (TextureCache_HasUrl(url)) { TextureCache_GetLastModified(url, &lastModified); @@ -247,12 +247,12 @@ UInt8* net_readCurrent; bool net_writeFailed; Int32 net_ticks; -UInt64 net_lastPacket; +TimeMS net_lastPacket; UInt8 net_lastOpcode; double net_discAccumulator; bool net_connecting; -UInt64 net_connectTimeout; +TimeMS net_connectTimeout; #define NET_TIMEOUT_MS (15 * 1000) static void MPConnection_BlockChanged(void* obj, Vector3I p, BlockID old, BlockID now) { @@ -302,7 +302,7 @@ static void MPConnection_TickConnect(void) { MPConnection_FailConnect(err); return; } - UInt64 now = DateTime_CurrentUTC_MS(); + TimeMS now = DateTime_CurrentUTC_MS(); bool poll_write = false; Socket_Select(net_socket, SOCKET_SELECT_WRITE, &poll_write); @@ -378,7 +378,7 @@ static void MPConnection_Tick(struct ScheduledTask* task) { if (net_connecting) { MPConnection_TickConnect(); return; } /* over 30 seconds since last packet */ - UInt64 now = DateTime_CurrentUTC_MS(); + TimeMS now = DateTime_CurrentUTC_MS(); if (net_lastPacket + (30 * 1000) < now) { MPConnection_CheckDisconnection(task->Interval); } diff --git a/src/TerrainAtlas.h b/src/TerrainAtlas.h index e7f6f0c47..49cbbc291 100644 --- a/src/TerrainAtlas.h +++ b/src/TerrainAtlas.h @@ -8,7 +8,11 @@ #define ATLAS2D_TILES_PER_ROW 16 #define ATLAS2D_MASK 15 #define ATLAS2D_SHIFT 4 +#ifdef EXTENDED_TEXTURES #define ATLAS2D_MAX_ROWS_COUNT 32 +#else +#define ATLAS2D_MAX_ROWS_COUNT 16 +#endif #define ATLAS1D_MAX_ATLASES (ATLAS2D_TILES_PER_ROW * ATLAS2D_MAX_ROWS_COUNT) Bitmap Atlas2D_Bitmap; diff --git a/src/TexturePack.c b/src/TexturePack.c index 022eb27fd..96af4b82b 100644 --- a/src/TexturePack.c +++ b/src/TexturePack.c @@ -334,11 +334,11 @@ void TexturePack_GetFromTags(const String* url, String* result, struct EntryList } } -void TextureCache_GetLastModified(const String* url, UInt64* time) { +void TextureCache_GetLastModified(const String* url, TimeMS* time) { char entryBuffer[STRING_SIZE]; String entry = String_FromArray(entryBuffer); TexturePack_GetFromTags(url, &entry, &cache_lastModified); - UInt64 temp; + TimeMS temp; if (entry.length && Convert_TryParseUInt64(&entry, &temp)) { *time = temp / TEXCACHE_TICKS_PER_MS; @@ -393,7 +393,7 @@ void TextureCache_AddETag(const String* url, const String* etag) { TextureCache_AddToTags(url, etag, &cache_eTags); } -void TextureCache_AddLastModified(const String* url, UInt64* lastModified) { +void TextureCache_AddLastModified(const String* url, TimeMS* lastModified) { if (!lastModified) return; UInt64 ticks = (*lastModified) * TEXCACHE_TICKS_PER_MS; diff --git a/src/TexturePack.h b/src/TexturePack.h index c7e835b5f..12a360b38 100644 --- a/src/TexturePack.h +++ b/src/TexturePack.h @@ -30,11 +30,11 @@ void TextureCache_Deny(const String* url); bool TextureCache_HasUrl(const String* url); bool TextureCache_GetStream(const String* url, struct Stream* stream); -void TextureCache_GetLastModified(const String* url, UInt64* time); +void TextureCache_GetLastModified(const String* url, TimeMS* time); void TextureCache_GetETag(const String* url, String* etag); void TextureCache_AddData(const String* url, UInt8* data, UInt32 length); void TextureCache_AddETag(const String* url, const String* etag); -void TextureCache_AddLastModified(const String* url, UInt64* lastModified); +void TextureCache_AddLastModified(const String* url, TimeMS* lastModified); void TexturePack_ExtractZip_File(const String* filename); void TexturePack_ExtractDefault(void); diff --git a/src/Utils.c b/src/Utils.c index 41b6ed9a4..780b2c353 100644 --- a/src/Utils.c +++ b/src/Utils.c @@ -38,7 +38,7 @@ Int32 DateTime_TotalDays(DateTime* time) { return days; } -UInt64 DateTime_TotalMs(DateTime* time) { +TimeMS DateTime_TotalMs(DateTime* time) { Int32 days = DateTime_TotalDays(time); UInt64 seconds = (UInt64)days * DATETIME_SECONDS_PER_DAY + @@ -48,7 +48,7 @@ UInt64 DateTime_TotalMs(DateTime* time) { return seconds * DATETIME_MILLIS_PER_SEC + time->Milli; } -void DateTime_FromTotalMs(DateTime* time, UInt64 ms) { +void DateTime_FromTotalMs(DateTime* time, TimeMS ms) { /* Work out time component for just this day */ Int32 dayMS = (Int32)(ms % DATETIME_MILLISECS_PER_DAY); time->Milli = dayMS % DATETIME_MILLIS_PER_SEC; dayMS /= DATETIME_MILLIS_PER_SEC; @@ -81,7 +81,7 @@ void DateTime_FromTotalMs(DateTime* time, UInt64 ms) { } } -void DateTime_HttpDate(UInt64 ms, String* str) { +void DateTime_HttpDate(TimeMS ms, String* str) { static char* days_of_weeks[7] = { "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun" }; static char* month_names[13] = { NULL, "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; diff --git a/src/Utils.h b/src/Utils.h index e4ac7f510..20017a2ae 100644 --- a/src/Utils.h +++ b/src/Utils.h @@ -17,9 +17,9 @@ typedef struct DateTime_ { } DateTime; #define DATETIME_MILLIS_PER_SEC 1000 -UInt64 DateTime_TotalMs(DateTime* time); -void DateTime_FromTotalMs(DateTime* time, UInt64 ms); -void DateTime_HttpDate(UInt64 ms, String* str); +TimeMS DateTime_TotalMs(DateTime* time); +void DateTime_FromTotalMs(DateTime* time, TimeMS ms); +void DateTime_HttpDate(TimeMS ms, String* str); UInt32 Utils_ParseEnum(const String* text, UInt32 defValue, const char** names, UInt32 namesCount); bool Utils_IsValidInputChar(char c, bool supportsCP437); diff --git a/src/World.c b/src/World.c index 8138fa399..ae31c62f3 100644 --- a/src/World.c +++ b/src/World.c @@ -44,6 +44,9 @@ void World_SetNewMap(BlockRaw* blocks, Int32 blocksSize, Int32 width, Int32 heig if (blocksSize != (width * height * length)) { ErrorHandler_Fail("Blocks array size does not match volume of map"); } +#ifdef EXTENDED_BLOCKS + World_Blocks2 = World_Blocks; +#endif World_OneY = width * length; World_MaxX = width - 1; @@ -59,6 +62,25 @@ void World_SetNewMap(BlockRaw* blocks, Int32 blocksSize, Int32 width, Int32 heig } +#ifdef EXTENDED_BLOCKS +void World_SetBlock(Int32 x, Int32 y, Int32 z, BlockID block) { + Int32 i = World_Pack(x, y, z); + World_Blocks[i] = (BlockRaw)block; + + /* defer allocation of second map array if possible */ + if (World_Blocks == World_Blocks2) { + if (block < 256) return; + World_Blocks2 = Mem_Alloc(World_BlocksSize, 1, "blocks array upper"); + Block_SetUsedCount(768); + } + World_Blocks2[i] = (BlockRaw)(block >> 8); +} +#else +void World_SetBlock(Int32 x, Int32 y, Int32 z, BlockID block) { + World_Blocks[World_Pack(x, y, z)] = block; +} +#endif + BlockID World_GetPhysicsBlock(Int32 x, Int32 y, Int32 z) { if (x < 0 || x >= World_Width || z < 0 || z >= World_Length || y < 0) return BLOCK_BEDROCK; if (y >= World_Height) return BLOCK_AIR; diff --git a/src/World.h b/src/World.h index 624a38a91..2fd25e35d 100644 --- a/src/World.h +++ b/src/World.h @@ -12,7 +12,11 @@ struct AABB; #define World_Pack(x, y, z) (((y) * World_Length + (z)) * World_Width + (x)) BlockRaw* World_Blocks; +#ifdef EXTENDED_BLOCKS +BlockRaw* World_Blocks2; +#endif Int32 World_BlocksSize; + Int32 World_Width, World_Height, World_Length; Int32 World_MaxX, World_MaxY, World_MaxZ; Int32 World_OneY; @@ -21,12 +25,19 @@ extern String World_TextureUrl; void World_Reset(void); void World_SetNewMap(BlockRaw* blocks, Int32 blocksSize, Int32 width, Int32 height, Int32 length); -BlockID World_GetPhysicsBlock(Int32 x, Int32 y, Int32 z); -#define World_SetBlock(x, y, z, blockId) World_Blocks[World_Pack(x, y, z)] = blockId -#define World_SetBlock_3I(p, blockId) World_Blocks[World_Pack(p.X, p.Y, p.Z)] = blockId +#ifdef EXTENDED_BLOCKS +extern Int32 Block_IDMask; +static inline BlockID World_GetBlock(Int32 x, Int32 y, Int32 z) { + Int32 i = World_Pack(x, y, z); + return (BlockID)((World_Blocks[i] | (World_Blocks2[i] << 8)) & Block_IDMask); +} +#else #define World_GetBlock(x, y, z) World_Blocks[World_Pack(x, y, z)] -#define World_GetBlock_3I(p) World_Blocks[World_Pack(p.X, p.Y, p.Z)] +#endif + +BlockID World_GetPhysicsBlock(Int32 x, Int32 y, Int32 z); +void World_SetBlock(Int32 x, Int32 y, Int32 z, BlockID block); BlockID World_SafeGetBlock_3I(Vector3I p); bool World_IsValidPos(Int32 x, Int32 y, Int32 z); bool World_IsValidPos_3I(Vector3I p); @@ -39,8 +50,7 @@ enum ENV_VAR { ENV_VAR_SHADOW_COL, }; -BlockID Env_EdgeBlock; -BlockID Env_SidesBlock; +BlockID Env_EdgeBlock, Env_SidesBlock; Int32 Env_EdgeHeight; Int32 Env_SidesOffset; #define Env_SidesHeight (Env_EdgeHeight + Env_SidesOffset) @@ -53,23 +63,18 @@ float Env_WeatherSpeed; float Env_WeatherFade; Int32 Env_Weather; bool Env_ExpFog; -float Env_SkyboxHorSpeed; -float Env_SkyboxVerSpeed; +float Env_SkyboxHorSpeed, Env_SkyboxVerSpeed; -PackedCol Env_SkyCol; -extern PackedCol Env_DefaultSkyCol; -#define ENV_DEFAULT_SKYCOL_HEX "99CCFF" -PackedCol Env_FogCol; -extern PackedCol Env_DefaultFogCol; -#define ENV_DEFAULT_FOGCOL_HEX "FFFFFF" -PackedCol Env_CloudsCol; -extern PackedCol Env_DefaultCloudsCol; -#define ENV_DEFAULT_CLOUDSCOL_HEX "FFFFFF" -PackedCol Env_SunCol, Env_SunXSide, Env_SunZSide, Env_SunYMin; -extern PackedCol Env_DefaultSunCol; -#define ENV_DEFAULT_SUNCOL_HEX "FFFFFF" +PackedCol Env_SkyCol, Env_FogCol, Env_CloudsCol; +extern PackedCol Env_DefaultSkyCol, Env_DefaultFogCol, Env_DefaultCloudsCol; +PackedCol Env_SunCol, Env_SunXSide, Env_SunZSide, Env_SunYMin; PackedCol Env_ShadowCol, Env_ShadowXSide, Env_ShadowZSide, Env_ShadowYMin; -extern PackedCol Env_DefaultShadowCol; +extern PackedCol Env_DefaultSunCol, Env_DefaultShadowCol; + +#define ENV_DEFAULT_SKYCOL_HEX "99CCFF" +#define ENV_DEFAULT_FOGCOL_HEX "FFFFFF" +#define ENV_DEFAULT_CLOUDSCOL_HEX "FFFFFF" +#define ENV_DEFAULT_SUNCOL_HEX "FFFFFF" #define ENV_DEFAULT_SHADOWCOL_HEX "9B9B9B" void Env_Reset(void);