C client: start work on inf id

This commit is contained in:
UnknownShadow200 2018-09-27 22:27:05 +10:00
parent a57d261703
commit 834c387a04
30 changed files with 323 additions and 203 deletions

View File

@ -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;

View File

@ -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) {

View File

@ -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--) {

View File

@ -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);

View File

@ -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();

View File

@ -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);

View File

@ -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;

View File

@ -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;
}

View File

@ -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);

View File

@ -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;

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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);

View File

@ -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();

View File

@ -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;

View File

@ -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)) {

View File

@ -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++) {

View File

@ -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);

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -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 {

View File

@ -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);
}

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -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" };

View File

@ -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);

View File

@ -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;

View File

@ -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);