and even more

This commit is contained in:
UnknownShadow200 2018-10-23 17:09:40 +11:00
parent d098e7731c
commit 0a51bfaa1e
18 changed files with 366 additions and 256 deletions

View File

@ -126,16 +126,13 @@ void Block_SetCollide(BlockID block, CollideType collide) {
} }
void Block_SetDrawType(BlockID block, DrawType draw) { void Block_SetDrawType(BlockID block, DrawType draw) {
if (draw == DRAW_OPAQUE && Block_Collide[block] != COLLIDE_SOLID) { if (draw == DRAW_OPAQUE && Block_Collide[block] != COLLIDE_SOLID) draw = DRAW_TRANSPARENT;
draw = DRAW_TRANSPARENT;
}
Block_Draw[block] = draw; Block_Draw[block] = draw;
Block_RecalcIsLiquid(block); Block_RecalcIsLiquid(block);
Vector3 zero = Vector3_Zero; Vector3 one = Vector3_One;
Block_FullOpaque[block] = draw == DRAW_OPAQUE Block_FullOpaque[block] = draw == DRAW_OPAQUE
&& Vector3_Equals(&Block_MinBB[block], &zero) && Vector3_Equals(&Block_MinBB[block], &Vector3_Zero)
&& Vector3_Equals(&Block_MaxBB[block], &one); && Vector3_Equals(&Block_MaxBB[block], &Vector3_One);
} }
@ -181,8 +178,8 @@ void Block_ResetProps(BlockID block) {
Block_MinBB[block] = Vector3_Create3(2.50f / 16.0f, 0.0f, 2.50f / 16.0f); Block_MinBB[block] = Vector3_Create3(2.50f / 16.0f, 0.0f, 2.50f / 16.0f);
Block_MaxBB[block] = Vector3_Create3(13.5f / 16.0f, 1.0f, 13.5f / 16.0f); Block_MaxBB[block] = Vector3_Create3(13.5f / 16.0f, 1.0f, 13.5f / 16.0f);
} else { } else {
Vector3 zero = Vector3_Zero; Block_MinBB[block] = zero; Block_MinBB[block] = Vector3_Zero;
Vector3 one = Vector3_One; Block_MaxBB[block] = one; Block_MaxBB[block] = Vector3_One;
Block_MaxBB[block].Y = DefaultSet_Height(block); Block_MaxBB[block].Y = DefaultSet_Height(block);
} }

View File

@ -288,13 +288,21 @@ static void Builder_ReadChunkData(int x1, int y1, int z1, bool* outAllAir, bool*
} }
static bool Builder_BuildChunk(int x1, int y1, int z1, bool* allAir) { static bool Builder_BuildChunk(int x1, int y1, int z1, bool* allAir) {
BlockID chunk[EXTCHUNK_SIZE_3]; Builder_Chunk = chunk; BlockID chunk[EXTCHUNK_SIZE_3];
uint8_t counts[CHUNK_SIZE_3 * FACE_COUNT]; Builder_Counts = counts; uint8_t counts[CHUNK_SIZE_3 * FACE_COUNT];
int bitFlags[EXTCHUNK_SIZE_3]; Builder_BitFlags = bitFlags; int bitFlags[EXTCHUNK_SIZE_3];
bool allSolid;
int xMax, yMax, zMax;
int cIndex, index;
int x, y, z, xx, yy, zz;
Builder_Chunk = chunk;
Builder_Counts = counts;
Builder_BitFlags = bitFlags;
Builder_PreStretchTiles(x1, y1, z1); Builder_PreStretchTiles(x1, y1, z1);
Mem_Set(chunk, BLOCK_AIR, EXTCHUNK_SIZE_3 * sizeof(BlockID)); Mem_Set(chunk, BLOCK_AIR, EXTCHUNK_SIZE_3 * sizeof(BlockID));
bool allSolid;
Builder_ReadChunkData(x1, y1, z1, allAir, &allSolid); Builder_ReadChunkData(x1, y1, z1, allAir, &allSolid);
if (x1 == 0 || y1 == 0 || z1 == 0 || x1 + CHUNK_SIZE >= World_Width || if (x1 == 0 || y1 == 0 || z1 == 0 || x1 + CHUNK_SIZE >= World_Width ||
@ -304,24 +312,23 @@ static bool Builder_BuildChunk(int x1, int y1, int z1, bool* allAir) {
Lighting_LightHint(x1 - 1, z1 - 1); Lighting_LightHint(x1 - 1, z1 - 1);
Mem_Set(counts, 1, CHUNK_SIZE_3 * FACE_COUNT); Mem_Set(counts, 1, CHUNK_SIZE_3 * FACE_COUNT);
int xMax = min(World_Width, x1 + CHUNK_SIZE); xMax = min(World_Width, x1 + CHUNK_SIZE);
int yMax = min(World_Height, y1 + CHUNK_SIZE); yMax = min(World_Height, y1 + CHUNK_SIZE);
int zMax = min(World_Length, z1 + CHUNK_SIZE); zMax = min(World_Length, z1 + CHUNK_SIZE);
Builder_ChunkEndX = xMax; Builder_ChunkEndZ = zMax; Builder_ChunkEndX = xMax; Builder_ChunkEndZ = zMax;
Builder_Stretch(x1, y1, z1); Builder_Stretch(x1, y1, z1);
Builder_PostStretchTiles(x1, y1, z1); Builder_PostStretchTiles(x1, y1, z1);
int x, y, z, xx, yy, zz;
for (y = y1, yy = 0; y < yMax; y++, yy++) { for (y = y1, yy = 0; y < yMax; y++, yy++) {
for (z = z1, zz = 0; z < zMax; z++, zz++) { for (z = z1, zz = 0; z < zMax; z++, zz++) {
int cIndex = Builder_PackChunk(0, yy, zz); cIndex = Builder_PackChunk(0, yy, zz);
for (x = x1, xx = 0; x < xMax; x++, xx++, cIndex++) { for (x = x1, xx = 0; x < xMax; x++, xx++, cIndex++) {
Builder_Block = chunk[cIndex]; Builder_Block = chunk[cIndex];
if (Block_Draw[Builder_Block] == DRAW_GAS) continue; if (Block_Draw[Builder_Block] == DRAW_GAS) continue;
int index = Builder_PackCount(xx, yy, zz); index = Builder_PackCount(xx, yy, zz);
Builder_X = x; Builder_Y = y; Builder_Z = z; Builder_X = x; Builder_Y = y; Builder_Z = z;
Builder_ChunkIndex = cIndex; Builder_ChunkIndex = cIndex;
Builder_RenderBlock(index); Builder_RenderBlock(index);
@ -334,11 +341,13 @@ static bool Builder_BuildChunk(int x1, int y1, int z1, bool* allAir) {
void Builder_MakeChunk(struct ChunkInfo* info) { void Builder_MakeChunk(struct ChunkInfo* info) {
int x = info->CentreX - 8, y = info->CentreY - 8, z = info->CentreZ - 8; int x = info->CentreX - 8, y = info->CentreY - 8, z = info->CentreZ - 8;
bool allAir = false, hasMesh; bool allAir = false, hasMesh;
int totalVerts;
hasMesh = Builder_BuildChunk(x, y, z, &allAir); hasMesh = Builder_BuildChunk(x, y, z, &allAir);
info->AllAir = allAir; info->AllAir = allAir;
if (!hasMesh) return; if (!hasMesh) return;
int totalVerts = Builder_TotalVerticesCount(); totalVerts = Builder_TotalVerticesCount();
if (!totalVerts) return; if (!totalVerts) return;
#ifndef CC_BUILD_GL11 #ifndef CC_BUILD_GL11
/* add an extra element to fix crashing on some GPUs */ /* add an extra element to fix crashing on some GPUs */
@ -384,7 +393,7 @@ static void Builder_DefaultPreStretchTiles(int x1, int y1, int z1) {
} }
static void Builder_DefaultPostStretchTiles(int x1, int y1, int z1) { static void Builder_DefaultPostStretchTiles(int x1, int y1, int z1) {
int i, vertsCount = Builder_TotalVerticesCount(); int i, j, vertsCount = Builder_TotalVerticesCount();
if (vertsCount > Builder_VerticesElems) { if (vertsCount > Builder_VerticesElems) {
Mem_Free(Builder_Vertices); Mem_Free(Builder_Vertices);
/* ensure buffer can be accessed with 64 bytes alignment by putting 2 extra vertices at end. */ /* ensure buffer can be accessed with 64 bytes alignment by putting 2 extra vertices at end. */
@ -394,7 +403,8 @@ static void Builder_DefaultPostStretchTiles(int x1, int y1, int z1) {
vertsCount = 0; vertsCount = 0;
for (i = 0; i < ATLAS1D_MAX_ATLASES; i++) { for (i = 0; i < ATLAS1D_MAX_ATLASES; i++) {
int j = i + ATLAS1D_MAX_ATLASES; j = i + ATLAS1D_MAX_ATLASES;
Builder1DPart_CalcOffsets(&Builder_Parts[i], &vertsCount); Builder1DPart_CalcOffsets(&Builder_Parts[i], &vertsCount);
Builder1DPart_CalcOffsets(&Builder_Parts[j], &vertsCount); Builder1DPart_CalcOffsets(&Builder_Parts[j], &vertsCount);
} }
@ -561,26 +571,29 @@ static int NormalBuilder_StretchZ(int countIndex, int x, int y, int z, int chunk
} }
static void NormalBuilder_RenderBlock(int index) { static void NormalBuilder_RenderBlock(int index) {
TextureLoc texLoc; TextureLoc texLoc;
int offset;
struct Builder1DPart* part; struct Builder1DPart* part;
PackedCol col; PackedCol col;
int count_XMin, count_XMax, count_ZMin;
int count_ZMax, count_YMin, count_YMax;
int offset, count;
if (Block_Draw[Builder_Block] == DRAW_SPRITE) { if (Block_Draw[Builder_Block] == DRAW_SPRITE) {
Builder_FullBright = Block_FullBright[Builder_Block]; Builder_FullBright = Block_FullBright[Builder_Block];
Builder_Tinted = Block_Tinted[Builder_Block]; Builder_Tinted = Block_Tinted[Builder_Block];
int count = Builder_Counts[index + FACE_YMAX]; count = Builder_Counts[index + FACE_YMAX];
if (count) Builder_DrawSprite(count); if (count) Builder_DrawSprite(count);
return; return;
} }
int count_XMin = Builder_Counts[index + FACE_XMIN]; count_XMin = Builder_Counts[index + FACE_XMIN];
int count_XMax = Builder_Counts[index + FACE_XMAX]; count_XMax = Builder_Counts[index + FACE_XMAX];
int count_ZMin = Builder_Counts[index + FACE_ZMIN]; count_ZMin = Builder_Counts[index + FACE_ZMIN];
int count_ZMax = Builder_Counts[index + FACE_ZMAX]; count_ZMax = Builder_Counts[index + FACE_ZMAX];
int count_YMin = Builder_Counts[index + FACE_YMIN]; count_YMin = Builder_Counts[index + FACE_YMIN];
int count_YMax = Builder_Counts[index + FACE_YMAX]; count_YMax = Builder_Counts[index + FACE_YMAX];
if (count_XMin == 0 && count_XMax == 0 && count_ZMin == 0 && if (count_XMin == 0 && count_XMax == 0 && count_ZMin == 0 &&
count_ZMax == 0 && count_YMin == 0 && count_YMax == 0) return; count_ZMax == 0 && count_YMin == 0 && count_YMax == 0) return;
@ -1091,20 +1104,26 @@ static void Adv_DrawYMax(int count) {
} }
static void Adv_RenderBlock(int index) { static void Adv_RenderBlock(int index) {
Vector3 min, max;
int count_XMin, count_XMax, count_ZMin;
int count_ZMax, count_YMin, count_YMax;
int count;
if (Block_Draw[Builder_Block] == DRAW_SPRITE) { if (Block_Draw[Builder_Block] == DRAW_SPRITE) {
Builder_FullBright = Block_FullBright[Builder_Block]; Builder_FullBright = Block_FullBright[Builder_Block];
Builder_Tinted = Block_Tinted[Builder_Block]; Builder_Tinted = Block_Tinted[Builder_Block];
int count = Builder_Counts[index + FACE_YMAX];
count = Builder_Counts[index + FACE_YMAX];
if (count) Builder_DrawSprite(count); if (count) Builder_DrawSprite(count);
return; return;
} }
int count_XMin = Builder_Counts[index + FACE_XMIN]; count_XMin = Builder_Counts[index + FACE_XMIN];
int count_XMax = Builder_Counts[index + FACE_XMAX]; count_XMax = Builder_Counts[index + FACE_XMAX];
int count_ZMin = Builder_Counts[index + FACE_ZMIN]; count_ZMin = Builder_Counts[index + FACE_ZMIN];
int count_ZMax = Builder_Counts[index + FACE_ZMAX]; count_ZMax = Builder_Counts[index + FACE_ZMAX];
int count_YMin = Builder_Counts[index + FACE_YMIN]; count_YMin = Builder_Counts[index + FACE_YMIN];
int count_YMax = Builder_Counts[index + FACE_YMAX]; count_YMax = Builder_Counts[index + FACE_YMAX];
if (count_XMin == 0 && count_XMax == 0 && count_ZMin == 0 && if (count_XMin == 0 && count_XMax == 0 && count_ZMin == 0 &&
count_ZMax == 0 && count_YMin == 0 && count_YMax == 0) return; count_ZMax == 0 && count_YMin == 0 && count_YMax == 0) return;
@ -1114,7 +1133,7 @@ static void Adv_RenderBlock(int index) {
adv_lightFlags = Block_LightOffset[Builder_Block]; adv_lightFlags = Block_LightOffset[Builder_Block];
Builder_Tinted = Block_Tinted[Builder_Block]; Builder_Tinted = Block_Tinted[Builder_Block];
Vector3 min = Block_RenderMinBB[Builder_Block], max = Block_RenderMaxBB[Builder_Block]; min = Block_RenderMinBB[Builder_Block]; max = Block_RenderMaxBB[Builder_Block];
adv_x1 = Builder_X + min.X; adv_y1 = Builder_Y + min.Y; adv_z1 = Builder_Z + min.Z; adv_x1 = Builder_X + min.X; adv_y1 = Builder_Y + min.Y; adv_z1 = Builder_Z + min.Z;
adv_x2 = Builder_X + max.X; adv_y2 = Builder_Y + max.Y; adv_z2 = Builder_Z + max.Z; adv_x2 = Builder_X + max.X; adv_y2 = Builder_Y + max.Y; adv_z2 = Builder_Z + max.Z;

View File

@ -12,7 +12,7 @@
enum GZIP_STATE { enum GZIP_STATE {
GZIP_STATE_HEADER1, GZIP_STATE_HEADER2, GZIP_STATE_COMPRESSIONMETHOD, GZIP_STATE_FLAGS, GZIP_STATE_HEADER1, GZIP_STATE_HEADER2, GZIP_STATE_COMPRESSIONMETHOD, GZIP_STATE_FLAGS,
GZIP_STATE_LASTMODIFIED, GZIP_STATE_COMPRESSIONFLAGS, GZIP_STATE_OPERATINGSYSTEM, GZIP_STATE_LASTMODIFIED, GZIP_STATE_COMPRESSIONFLAGS, GZIP_STATE_OPERATINGSYSTEM,
GZIP_STATE_HEADERCHECKSUM, GZIP_STATE_FILENAME, GZIP_STATE_COMMENT, GZIP_STATE_DONE, GZIP_STATE_HEADERCHECKSUM, GZIP_STATE_FILENAME, GZIP_STATE_COMMENT, GZIP_STATE_DONE
}; };
void GZipHeader_Init(struct GZipHeader* header) { void GZipHeader_Init(struct GZipHeader* header) {
@ -134,7 +134,7 @@ enum INFLATE_STATE_ {
INFLATE_STATE_DYNAMIC_LITSDISTSREPEAT, INFLATE_STATE_COMPRESSED_LIT, INFLATE_STATE_DYNAMIC_LITSDISTSREPEAT, INFLATE_STATE_COMPRESSED_LIT,
INFLATE_STATE_COMPRESSED_LITREPEAT, INFLATE_STATE_COMPRESSED_DIST, INFLATE_STATE_COMPRESSED_LITREPEAT, INFLATE_STATE_COMPRESSED_DIST,
INFLATE_STATE_COMPRESSED_DISTREPEAT, INFLATE_STATE_COMPRESSED_DATA, INFLATE_STATE_COMPRESSED_DISTREPEAT, INFLATE_STATE_COMPRESSED_DATA,
INFLATE_STATE_FASTCOMPRESSED, INFLATE_STATE_DONE, INFLATE_STATE_FASTCOMPRESSED, INFLATE_STATE_DONE
}; };
/* Insert next byte into the bit buffer */ /* Insert next byte into the bit buffer */

View File

@ -109,10 +109,10 @@ void Entity_GetBounds(struct Entity* e, struct AABB* bb) {
} }
static void Entity_ParseScale(struct Entity* e, const String* scale) { static void Entity_ParseScale(struct Entity* e, const String* scale) {
float value; float value, maxScale;
if (!Convert_TryParseFloat(scale, &value)) return; if (!Convert_TryParseFloat(scale, &value)) return;
float maxScale = e->Model->MaxScale; maxScale = e->Model->MaxScale;
Math_Clamp(value, 0.01f, maxScale); Math_Clamp(value, 0.01f, maxScale);
e->ModelScale = Vector3_Create1(value); e->ModelScale = Vector3_Create1(value);
} }
@ -236,9 +236,10 @@ void Entities_Tick(struct ScheduledTask* task) {
} }
void Entities_RenderModels(double delta, float t) { void Entities_RenderModels(double delta, float t) {
int i;
Gfx_SetTexturing(true); Gfx_SetTexturing(true);
Gfx_SetAlphaTest(true); Gfx_SetAlphaTest(true);
int i;
for (i = 0; i < ENTITIES_MAX_COUNT; i++) { for (i = 0; i < ENTITIES_MAX_COUNT; i++) {
if (!Entities_List[i]) continue; if (!Entities_List[i]) continue;
Entities_List[i]->VTABLE->RenderModel(Entities_List[i], delta, t); Entities_List[i]->VTABLE->RenderModel(Entities_List[i], delta, t);
@ -249,17 +250,19 @@ void Entities_RenderModels(double delta, float t) {
void Entities_RenderNames(double delta) { void Entities_RenderNames(double delta) {
if (Entities_NameMode == NAME_MODE_NONE) return;
struct LocalPlayer* p = &LocalPlayer_Instance; struct LocalPlayer* p = &LocalPlayer_Instance;
bool hadFog;
int i;
if (Entities_NameMode == NAME_MODE_NONE) return;
entities_closestId = Entities_GetCloset(&p->Base); entities_closestId = Entities_GetCloset(&p->Base);
if (!p->Hacks.CanSeeAllNames || Entities_NameMode != NAME_MODE_ALL) return; if (!p->Hacks.CanSeeAllNames || Entities_NameMode != NAME_MODE_ALL) return;
Gfx_SetTexturing(true); Gfx_SetTexturing(true);
Gfx_SetAlphaTest(true); Gfx_SetAlphaTest(true);
bool hadFog = Gfx_GetFog(); hadFog = Gfx_GetFog();
if (hadFog) Gfx_SetFog(false); if (hadFog) Gfx_SetFog(false);
int i;
for (i = 0; i < ENTITIES_MAX_COUNT; i++) { for (i = 0; i < ENTITIES_MAX_COUNT; i++) {
if (!Entities_List[i]) continue; if (!Entities_List[i]) continue;
if (i != entities_closestId || i == ENTITIES_SELF_ID) { if (i != entities_closestId || i == ENTITIES_SELF_ID) {
@ -273,18 +276,20 @@ void Entities_RenderNames(double delta) {
} }
void Entities_RenderHoveredNames(double delta) { void Entities_RenderHoveredNames(double delta) {
if (Entities_NameMode == NAME_MODE_NONE) return;
struct LocalPlayer* p = &LocalPlayer_Instance; struct LocalPlayer* p = &LocalPlayer_Instance;
bool allNames = !(Entities_NameMode == NAME_MODE_HOVERED || Entities_NameMode == NAME_MODE_ALL) bool allNames, hadFog;
int i;
if (Entities_NameMode == NAME_MODE_NONE) return;
allNames = !(Entities_NameMode == NAME_MODE_HOVERED || Entities_NameMode == NAME_MODE_ALL)
&& p->Hacks.CanSeeAllNames; && p->Hacks.CanSeeAllNames;
Gfx_SetTexturing(true); Gfx_SetTexturing(true);
Gfx_SetAlphaTest(true); Gfx_SetAlphaTest(true);
Gfx_SetDepthTest(false); Gfx_SetDepthTest(false);
bool hadFog = Gfx_GetFog(); hadFog = Gfx_GetFog();
if (hadFog) Gfx_SetFog(false); if (hadFog) Gfx_SetFog(false);
int i;
for (i = 0; i < ENTITIES_MAX_COUNT; i++) { for (i = 0; i < ENTITIES_MAX_COUNT; i++) {
if (!Entities_List[i]) continue; if (!Entities_List[i]) continue;
if ((i == entities_closestId || allNames) && i != ENTITIES_SELF_ID) { if ((i == entities_closestId || allNames) && i != ENTITIES_SELF_ID) {
@ -366,12 +371,13 @@ EntityID Entities_GetCloset(struct Entity* src) {
float closestDist = MATH_POS_INF; float closestDist = MATH_POS_INF;
EntityID targetId = ENTITIES_SELF_ID; EntityID targetId = ENTITIES_SELF_ID;
float t0, t1;
int i; int i;
for (i = 0; i < ENTITIES_SELF_ID; i++) { /* because we don't want to pick against local player */ for (i = 0; i < ENTITIES_SELF_ID; i++) { /* because we don't want to pick against local player */
struct Entity* entity = Entities_List[i]; struct Entity* entity = Entities_List[i];
if (!entity) continue; if (!entity) continue;
float t0, t1;
if (Intersection_RayIntersectsRotatedBox(eyePos, dir, entity, &t0, &t1) && t0 < closestDist) { if (Intersection_RayIntersectsRotatedBox(eyePos, dir, entity, &t0, &t1) && t0 < closestDist) {
closestDist = t0; closestDist = t0;
targetId = (EntityID)i; targetId = (EntityID)i;
@ -684,10 +690,16 @@ static void Player_EnsurePow2(struct Player* player, Bitmap* bmp) {
static void Player_CheckSkin(struct Player* p) { static void Player_CheckSkin(struct Player* p) {
struct Entity* e = &p->Base; struct Entity* e = &p->Base;
String skin = String_FromRawArray(e->SkinNameRaw); struct Player* first;
String url, skin = String_FromRawArray(e->SkinNameRaw);
struct AsyncRequest item;
struct Stream mem;
Bitmap bmp;
ReturnCode res;
if (!p->FetchedSkin && e->Model->UsesSkin) { if (!p->FetchedSkin && e->Model->UsesSkin) {
struct Player* first = Player_FirstOtherWithSameSkinAndFetchedSkin(p); first = Player_FirstOtherWithSameSkinAndFetchedSkin(p);
if (!first) { if (!first) {
AsyncDownloader_GetSkin(&skin, &skin); AsyncDownloader_GetSkin(&skin, &skin);
} else { } else {
@ -695,17 +707,13 @@ static void Player_CheckSkin(struct Player* p) {
} }
p->FetchedSkin = true; p->FetchedSkin = true;
} }
struct AsyncRequest item;
if (!AsyncDownloader_Get(&skin, &item)) return; if (!AsyncDownloader_Get(&skin, &item)) return;
if (!item.ResultData) { Player_SetSkinAll(p, true); return; } if (!item.ResultData) { Player_SetSkinAll(p, true); return; }
String url = String_FromRawArray(item.URL);
struct Stream mem; Bitmap bmp;
Stream_ReadonlyMemory(&mem, item.ResultData, item.ResultSize); Stream_ReadonlyMemory(&mem, item.ResultData, item.ResultSize);
ReturnCode res = Png_Decode(&bmp, &mem); if ((res = Png_Decode(&bmp, &mem))) {
if (res) { url = String_FromRawArray(item.URL);
Chat_LogError2(res, "decoding", &url); Chat_LogError2(res, "decoding", &url);
Mem_Free(bmp.Scan0); return; Mem_Free(bmp.Scan0); return;
} }
@ -729,7 +737,8 @@ static void Player_CheckSkin(struct Player* p) {
static void Player_Despawn(struct Entity* e) { static void Player_Despawn(struct Entity* e) {
struct Player* player = (struct Player*)e; struct Player* player = (struct Player*)e;
struct Player* first = Player_FirstOtherWithSameSkin(player); struct Player* first = Player_FirstOtherWithSameSkin(player);
if (!first) { if (!first) {
Gfx_DeleteTexture(&e->TextureId); Gfx_DeleteTexture(&e->TextureId);
Player_ResetSkin(player); Player_ResetSkin(player);
@ -750,8 +759,9 @@ static void Player_ContextRecreated(struct Entity* e) {
void Player_SetName(struct Player* p, const String* name, const String* skin) { void Player_SetName(struct Player* p, const String* name, const String* skin) {
String p_name = String_ClearedArray(p->DisplayNameRaw); String p_name = String_ClearedArray(p->DisplayNameRaw);
String_AppendString(&p_name, name);
String p_skin = String_ClearedArray(p->Base.SkinNameRaw); String p_skin = String_ClearedArray(p->Base.SkinNameRaw);
String_AppendString(&p_name, name);
String_AppendString(&p_skin, skin); String_AppendString(&p_skin, skin);
} }
@ -809,7 +819,7 @@ static void LocalPlayer_HandleInput(float* xMoving, float* zMoving) {
hacks->FlyingDown = KeyBind_IsPressed(KeyBind_FlyDown); hacks->FlyingDown = KeyBind_IsPressed(KeyBind_FlyDown);
if (hacks->WOMStyleHacks && hacks->Enabled && hacks->CanNoclip) { if (hacks->WOMStyleHacks && hacks->Enabled && hacks->CanNoclip) {
if (hacks->Noclip) { Vector3 zero = Vector3_Zero; p->Base.Velocity = zero; } if (hacks->Noclip) p->Base.Velocity = Vector3_Zero;
hacks->Noclip = KeyBind_IsPressed(KeyBind_NoClip); hacks->Noclip = KeyBind_IsPressed(KeyBind_NoClip);
} }
} }
@ -837,7 +847,7 @@ void LocalPlayer_Tick(struct Entity* e, double delta) {
/* Immediate stop in noclip mode */ /* Immediate stop in noclip mode */
if (!hacks->NoclipSlide && (hacks->Noclip && xMoving == 0 && zMoving == 0)) { if (!hacks->NoclipSlide && (hacks->Noclip && xMoving == 0 && zMoving == 0)) {
Vector3 zero = Vector3_Zero; e->Velocity = zero; e->Velocity = Vector3_Zero;
} }
PhysicsComp_UpdateVelocityState(&p->Physics); PhysicsComp_UpdateVelocityState(&p->Physics);
@ -889,7 +899,7 @@ static void LocalPlayer_Init_(void) {
static void LocalPlayer_Reset(void) { static void LocalPlayer_Reset(void) {
struct LocalPlayer* p = &LocalPlayer_Instance; struct LocalPlayer* p = &LocalPlayer_Instance;
p->ReachDistance = 5.0f; p->ReachDistance = 5.0f;
Vector3 zero = Vector3_Zero; p->Base.Velocity = zero; p->Base.Velocity = Vector3_Zero;
p->Physics.JumpVel = 0.42f; p->Physics.JumpVel = 0.42f;
p->Physics.ServerJumpVel = 0.42f; p->Physics.ServerJumpVel = 0.42f;
/* p->Base.Health = 20; TODO: survival mode stuff */ /* p->Base.Health = 20; TODO: survival mode stuff */
@ -897,9 +907,8 @@ static void LocalPlayer_Reset(void) {
static void LocalPlayer_OnNewMap(void) { static void LocalPlayer_OnNewMap(void) {
struct LocalPlayer* p = &LocalPlayer_Instance; struct LocalPlayer* p = &LocalPlayer_Instance;
Vector3 zero = Vector3_Zero; p->Base.Velocity = Vector3_Zero;
p->Base.Velocity = zero; p->OldVelocity = Vector3_Zero;
p->OldVelocity = zero;
p->_WarnedRespawn = false; p->_WarnedRespawn = false;
p->_WarnedFly = false; p->_WarnedFly = false;
@ -961,7 +970,7 @@ static void LocalPlayer_DoRespawn(void) {
spawn.Y += 2.0f / 16.0f; spawn.Y += 2.0f / 16.0f;
struct LocationUpdate update; LocationUpdate_MakePosAndOri(&update, spawn, p->SpawnRotY, p->SpawnHeadX, false); struct LocationUpdate update; LocationUpdate_MakePosAndOri(&update, spawn, p->SpawnRotY, p->SpawnHeadX, false);
p->Base.VTABLE->SetLocation(&p->Base, &update, false); p->Base.VTABLE->SetLocation(&p->Base, &update, false);
Vector3 zero = Vector3_Zero; p->Base.Velocity = zero; p->Base.Velocity = Vector3_Zero;
/* Update onGround, otherwise if 'respawn' then 'space' is pressed, you still jump into the air if onGround was true before */ /* Update onGround, otherwise if 'respawn' then 'space' is pressed, you still jump into the air if onGround was true before */
Entity_GetBounds(&p->Base, &bb); Entity_GetBounds(&p->Base, &bb);
@ -1071,11 +1080,13 @@ static void NetPlayer_RenderModel(struct Entity* e, double deltaTime, float t) {
static void NetPlayer_RenderName(struct Entity* e) { static void NetPlayer_RenderName(struct Entity* e) {
struct NetPlayer* p = (struct NetPlayer*)e; struct NetPlayer* p = (struct NetPlayer*)e;
float distance;
int threshold;
if (!p->ShouldRender) return; if (!p->ShouldRender) return;
float dist = Model_RenderDistance(e); distance = Model_RenderDistance(e);
int threshold = Entities_NameMode == NAME_MODE_ALL_UNSCALED ? 8192 * 8192 : 32 * 32; threshold = Entities_NameMode == NAME_MODE_ALL_UNSCALED ? 8192 * 8192 : 32 * 32;
if (dist <= (float)threshold) Player_DrawName((struct Player*)p); if (distance <= (float)threshold) Player_DrawName((struct Player*)p);
} }
struct EntityVTABLE netPlayer_VTABLE = { struct EntityVTABLE netPlayer_VTABLE = {

View File

@ -695,14 +695,15 @@ static void Collisions_ClipZ(struct Entity* entity, Vector3* size, struct AABB*
} }
static bool Collisions_CanSlideThrough(struct AABB* adjFinalBB) { static bool Collisions_CanSlideThrough(struct AABB* adjFinalBB) {
Vector3I bbMin; Vector3I_Floor(&bbMin, &adjFinalBB->Min); Vector3I bbMin, bbMax;
Vector3I bbMax; Vector3I_Floor(&bbMax, &adjFinalBB->Max);
BlockID block; BlockID block;
struct AABB blockBB; struct AABB blockBB;
Vector3 v; Vector3 v;
int x, y, z; int x, y, z;
Vector3I_Floor(&bbMin, &adjFinalBB->Min);
Vector3I_Floor(&bbMax, &adjFinalBB->Max);
for (y = bbMin.Y; y <= bbMax.Y; y++) { v.Y = (float)y; for (y = bbMin.Y; y <= bbMax.Y; y++) { v.Y = (float)y;
for (z = bbMin.Z; z <= bbMax.Z; z++) { v.Z = (float)z; for (z = bbMin.Z; z <= bbMax.Z; z++) { v.Z = (float)z;
for (x = bbMin.X; x <= bbMax.X; x++) { v.X = (float)x; for (x = bbMin.X; x <= bbMax.X; x++) { v.X = (float)x;
@ -869,9 +870,8 @@ static void Collisions_CollideWithReachableBlocks(struct CollisionsComp* comp, i
/* TODO: test for corner cases, and refactor this */ /* TODO: test for corner cases, and refactor this */
void Collisions_MoveAndWallSlide(struct CollisionsComp* comp) { void Collisions_MoveAndWallSlide(struct CollisionsComp* comp) {
Vector3 zero = Vector3_Zero;
struct Entity* entity = comp->Entity; struct Entity* entity = comp->Entity;
if (Vector3_Equals(&entity->Velocity, &zero)) return; if (Vector3_Equals(&entity->Velocity, &Vector3_Zero)) return;
struct AABB entityBB, entityExtentBB; struct AABB entityBB, entityExtentBB;
int count = Searcher_FindReachableBlocks(entity, &entityBB, &entityExtentBB); int count = Searcher_FindReachableBlocks(entity, &entityBB, &entityExtentBB);
@ -893,7 +893,7 @@ void PhysicsComp_Init(struct PhysicsComp* comp, struct Entity* entity) {
static bool PhysicsComp_TouchesLiquid(BlockID block) { return Block_Collide[block] == COLLIDE_LIQUID; } static bool PhysicsComp_TouchesLiquid(BlockID block) { return Block_Collide[block] == COLLIDE_LIQUID; }
void PhysicsComp_UpdateVelocityState(struct PhysicsComp* comp) { void PhysicsComp_UpdateVelocityState(struct PhysicsComp* comp) {
struct Entity* entity = comp->Entity; struct Entity* entity = comp->Entity;
struct HacksComp* hacks = comp->Hacks; struct HacksComp* hacks = comp->Hacks;
if (hacks->Floating) { if (hacks->Floating) {

View File

@ -127,12 +127,16 @@ GfxResourceID clouds_vb, clouds_tex;
int clouds_vertices; int clouds_vertices;
void EnvRenderer_RenderClouds(double deltaTime) { void EnvRenderer_RenderClouds(double deltaTime) {
double time;
float offset;
struct Matrix m;
if (!clouds_vb || Env_CloudsHeight < -2000) return; if (!clouds_vb || Env_CloudsHeight < -2000) return;
double time = Game_Accumulator; time = Game_Accumulator;
float offset = (float)(time / 2048.0f * 0.6f * Env_CloudsSpeed); offset = (float)(time / 2048.0f * 0.6f * Env_CloudsSpeed);
Gfx_SetMatrixMode(MATRIX_TYPE_TEXTURE); Gfx_SetMatrixMode(MATRIX_TYPE_TEXTURE);
struct Matrix m = Matrix_Identity; m.Row3.X = offset; /* translate X axis */ m = Matrix_Identity; m.Row3.X = offset; /* translate X axis */
Gfx_LoadMatrix(&m); Gfx_LoadMatrix(&m);
Gfx_SetMatrixMode(MATRIX_TYPE_VIEW); Gfx_SetMatrixMode(MATRIX_TYPE_VIEW);
@ -178,17 +182,22 @@ static void EnvRenderer_DrawCloudsY(int x1, int z1, int x2, int z2, int y, Verte
} }
static void EnvRenderer_UpdateClouds(void) { static void EnvRenderer_UpdateClouds(void) {
int extent;
int x1, z1, x2, z2;
VertexP3fT2fC4b v[ENV_SMALL_VERTICES];
VertexP3fT2fC4b* ptr;
if (!World_Blocks || Gfx_LostContext) return; if (!World_Blocks || Gfx_LostContext) return;
Gfx_DeleteVb(&clouds_vb); Gfx_DeleteVb(&clouds_vb);
if (EnvRenderer_Minimal) return; if (EnvRenderer_Minimal) return;
int extent = Utils_AdjViewDist(Game_ViewDistance); extent = Utils_AdjViewDist(Game_ViewDistance);
int x1 = -extent, x2 = World_Width + extent; x1 = -extent; x2 = World_Width + extent;
int z1 = -extent, z2 = World_Length + extent; z1 = -extent; z2 = World_Length + extent;
clouds_vertices = EnvRenderer_Vertices(x2 - x1, z2 - z1); clouds_vertices = EnvRenderer_Vertices(x2 - x1, z2 - z1);
VertexP3fT2fC4b v[ENV_SMALL_VERTICES]; ptr = v;
VertexP3fT2fC4b* ptr = v;
if (clouds_vertices > ENV_SMALL_VERTICES) { if (clouds_vertices > ENV_SMALL_VERTICES) {
ptr = Mem_Alloc(clouds_vertices, sizeof(VertexP3fT2fC4b), "temp clouds vertices"); ptr = Mem_Alloc(clouds_vertices, sizeof(VertexP3fT2fC4b), "temp clouds vertices");
} }
@ -250,22 +259,27 @@ static void EnvRenderer_DrawSkyY(int x1, int z1, int x2, int z2, int y, VertexP3
} }
static void EnvRenderer_UpdateSky(void) { static void EnvRenderer_UpdateSky(void) {
int extent, height;
int x1, z1, x2, z2;
VertexP3fC4b v[ENV_SMALL_VERTICES];
VertexP3fC4b* ptr;
if (!World_Blocks || Gfx_LostContext) return; if (!World_Blocks || Gfx_LostContext) return;
Gfx_DeleteVb(&sky_vb); Gfx_DeleteVb(&sky_vb);
if (EnvRenderer_Minimal) return; if (EnvRenderer_Minimal) return;
int extent = Utils_AdjViewDist(Game_ViewDistance); extent = Utils_AdjViewDist(Game_ViewDistance);
int x1 = -extent, x2 = World_Width + extent; x1 = -extent; x2 = World_Width + extent;
int z1 = -extent, z2 = World_Length + extent; z1 = -extent; z2 = World_Length + extent;
sky_vertices = EnvRenderer_Vertices(x2 - x1, z2 - z1); sky_vertices = EnvRenderer_Vertices(x2 - x1, z2 - z1);
VertexP3fC4b v[ENV_SMALL_VERTICES]; ptr = v;
VertexP3fC4b* ptr = v;
if (sky_vertices > ENV_SMALL_VERTICES) { if (sky_vertices > ENV_SMALL_VERTICES) {
ptr = Mem_Alloc(sky_vertices, sizeof(VertexP3fC4b), "temp sky vertices"); ptr = Mem_Alloc(sky_vertices, sizeof(VertexP3fC4b), "temp sky vertices");
} }
int height = max((World_Height + 2) + 6, Env_CloudsHeight + 6); height = max((World_Height + 2), Env_CloudsHeight) + 6;
EnvRenderer_DrawSkyY(x1, z1, x2, z2, height, ptr); EnvRenderer_DrawSkyY(x1, z1, x2, z2, height, ptr);
sky_vb = Gfx_CreateVb(ptr, VERTEX_FORMAT_P3FC4B, sky_vertices); sky_vb = Gfx_CreateVb(ptr, VERTEX_FORMAT_P3FC4B, sky_vertices);
@ -296,8 +310,8 @@ void EnvRenderer_RenderSkybox(double deltaTime) {
Matrix_RotateX(&rotX, Env_SkyboxVerSpeed * rotTime); Matrix_MulBy(&m, &rotX); Matrix_RotateX(&rotX, Env_SkyboxVerSpeed * rotTime); Matrix_MulBy(&m, &rotX);
/* Rotate around camera */ /* Rotate around camera */
Vector3 pos = Camera_CurrentPos, zero = Vector3_Zero; Vector3 pos = Camera_CurrentPos;
Camera_CurrentPos = zero; Camera_CurrentPos = Vector3_Zero;
Camera_Active->GetView(&view); Matrix_MulBy(&m, &view); Camera_Active->GetView(&view); Matrix_MulBy(&m, &view);
Camera_CurrentPos = pos; Camera_CurrentPos = pos;
@ -364,7 +378,8 @@ static void EnvRenderer_InitWeatherHeightmap(void) {
#define EnvRenderer_RainCalcBody(get_block)\ #define EnvRenderer_RainCalcBody(get_block)\
for (y = maxY; y >= 0; y--, i -= World_OneY) {\ for (y = maxY; y >= 0; y--, i -= World_OneY) {\
uint8_t draw = Block_Draw[get_block];\ draw = Block_Draw[get_block];\
\
if (!(draw == DRAW_GAS || draw == DRAW_SPRITE)) {\ if (!(draw == DRAW_GAS || draw == DRAW_SPRITE)) {\
Weather_Heightmap[hIndex] = y;\ Weather_Heightmap[hIndex] = y;\
return y;\ return y;\
@ -373,6 +388,7 @@ for (y = maxY; y >= 0; y--, i -= World_OneY) {\
static int EnvRenderer_CalcRainHeightAt(int x, int maxY, int z, int hIndex) { static int EnvRenderer_CalcRainHeightAt(int x, int maxY, int z, int hIndex) {
int i = World_Pack(x, maxY, z), y; int i = World_Pack(x, maxY, z), y;
uint8_t draw;
#ifndef EXTENDED_BLOCKS #ifndef EXTENDED_BLOCKS
EnvRenderer_RainCalcBody(World_Blocks[i]); EnvRenderer_RainCalcBody(World_Blocks[i]);
@ -389,23 +405,25 @@ static int EnvRenderer_CalcRainHeightAt(int x, int maxY, int z, int hIndex) {
} }
static float EnvRenderer_RainHeight(int x, int z) { static float EnvRenderer_RainHeight(int x, int z) {
if (x < 0 || z < 0 || x >= World_Width || z >= World_Length) { int hIndex, height;
return (float)Env_EdgeHeight; int y;
} if (x < 0 || z < 0 || x >= World_Width || z >= World_Length) return (float)Env_EdgeHeight;
int hIndex = Weather_Pack(x, z);
int height = Weather_Heightmap[hIndex];
int y = height == Int16_MaxValue ? EnvRenderer_CalcRainHeightAt(x, World_MaxY, z, hIndex) : height; hIndex = Weather_Pack(x, z);
height = Weather_Heightmap[hIndex];
y = height == Int16_MaxValue ? EnvRenderer_CalcRainHeightAt(x, World_MaxY, z, hIndex) : height;
return y == -1 ? 0 : y + Block_MaxBB[World_GetBlock(x, y, z)].Y; return y == -1 ? 0 : y + Block_MaxBB[World_GetBlock(x, y, z)].Y;
} }
void EnvRenderer_OnBlockChanged(int x, int y, int z, BlockID oldBlock, BlockID newBlock) { void EnvRenderer_OnBlockChanged(int x, int y, int z, BlockID oldBlock, BlockID newBlock) {
bool didBlock = !(Block_Draw[oldBlock] == DRAW_GAS || Block_Draw[oldBlock] == DRAW_SPRITE); bool didBlock = !(Block_Draw[oldBlock] == DRAW_GAS || Block_Draw[oldBlock] == DRAW_SPRITE);
bool nowBlock = !(Block_Draw[newBlock] == DRAW_GAS || Block_Draw[newBlock] == DRAW_SPRITE); bool nowBlock = !(Block_Draw[newBlock] == DRAW_GAS || Block_Draw[newBlock] == DRAW_SPRITE);
int hIndex, height;
if (didBlock == nowBlock) return; if (didBlock == nowBlock) return;
int hIndex = Weather_Pack(x, z); hIndex = Weather_Pack(x, z);
int height = Weather_Heightmap[hIndex]; height = Weather_Heightmap[hIndex];
/* Two cases can be skipped here: */ /* Two cases can be skipped here: */
/* a) rain height was not calculated to begin with (height is short.MaxValue) */ /* a) rain height was not calculated to begin with (height is short.MaxValue) */
/* b) changed y is below current calculated rain height */ /* b) changed y is below current calculated rain height */
@ -666,6 +684,10 @@ static void EnvRenderer_UpdateMapSides(void) {
int y, y1, y2; int y, y1, y2;
int i; int i;
VertexP3fT2fC4b v[ENV_SMALL_VERTICES];
VertexP3fT2fC4b* ptr;
VertexP3fT2fC4b* cur;
if (!World_Blocks || Gfx_LostContext) return; if (!World_Blocks || Gfx_LostContext) return;
Gfx_DeleteVb(&sides_vb); Gfx_DeleteVb(&sides_vb);
block = Env_SidesBlock; block = Env_SidesBlock;
@ -675,7 +697,7 @@ static void EnvRenderer_UpdateMapSides(void) {
sides_vertices = 0; sides_vertices = 0;
for (i = 0; i < 4; i++) { for (i = 0; i < 4; i++) {
Rect2D r = rects[i]; r = rects[i];
sides_vertices += EnvRenderer_Vertices(r.Width, r.Height); /* YQuads outside */ sides_vertices += EnvRenderer_Vertices(r.Width, r.Height); /* YQuads outside */
} }
@ -684,12 +706,11 @@ static void EnvRenderer_UpdateMapSides(void) {
sides_vertices += 2 * EnvRenderer_Vertices(World_Width, Math_AbsI(y)); /* ZQuads */ sides_vertices += 2 * EnvRenderer_Vertices(World_Width, Math_AbsI(y)); /* ZQuads */
sides_vertices += 2 * EnvRenderer_Vertices(World_Length, Math_AbsI(y)); /* XQuads */ sides_vertices += 2 * EnvRenderer_Vertices(World_Length, Math_AbsI(y)); /* XQuads */
VertexP3fT2fC4b v[ENV_SMALL_VERTICES]; ptr = v;
VertexP3fT2fC4b* ptr = v;
if (sides_vertices > ENV_SMALL_VERTICES) { if (sides_vertices > ENV_SMALL_VERTICES) {
ptr = Mem_Alloc(sides_vertices, sizeof(VertexP3fT2fC4b), "temp sides vertices"); ptr = Mem_Alloc(sides_vertices, sizeof(VertexP3fT2fC4b), "temp sides vertices");
} }
VertexP3fT2fC4b* cur = ptr; cur = ptr;
sides_fullBright = Block_FullBright[block]; sides_fullBright = Block_FullBright[block];
col = sides_fullBright ? white : Env_ShadowCol; col = sides_fullBright ? white : Env_ShadowCol;
@ -722,6 +743,10 @@ static void EnvRenderer_UpdateMapEdges(void) {
float y; float y;
int i; int i;
VertexP3fT2fC4b v[ENV_SMALL_VERTICES];
VertexP3fT2fC4b* ptr;
VertexP3fT2fC4b* cur;
if (!World_Blocks || Gfx_LostContext) return; if (!World_Blocks || Gfx_LostContext) return;
Gfx_DeleteVb(&edges_vb); Gfx_DeleteVb(&edges_vb);
block = Env_EdgeBlock; block = Env_EdgeBlock;
@ -735,12 +760,11 @@ static void EnvRenderer_UpdateMapEdges(void) {
edges_vertices += EnvRenderer_Vertices(r.Width, r.Height); /* YPlanes outside */ edges_vertices += EnvRenderer_Vertices(r.Width, r.Height); /* YPlanes outside */
} }
VertexP3fT2fC4b v[ENV_SMALL_VERTICES]; ptr = v;
VertexP3fT2fC4b* ptr = v;
if (edges_vertices > ENV_SMALL_VERTICES) { if (edges_vertices > ENV_SMALL_VERTICES) {
ptr = Mem_Alloc(edges_vertices, sizeof(VertexP3fT2fC4b), "temp edge vertices"); ptr = Mem_Alloc(edges_vertices, sizeof(VertexP3fT2fC4b), "temp edge vertices");
} }
VertexP3fT2fC4b* cur = ptr; cur = ptr;
edges_fullBright = Block_FullBright[block]; edges_fullBright = Block_FullBright[block];
col = edges_fullBright ? white : Env_SunCol; col = edges_fullBright ? white : Env_SunCol;

View File

@ -25,7 +25,7 @@ bool Gfx_GetFog(void) { return gfx_fogEnabled; }
*--------------------------------------------------------Direct3D9--------------------------------------------------------* *--------------------------------------------------------Direct3D9--------------------------------------------------------*
*#########################################################################################################################*/ *#########################################################################################################################*/
#ifdef CC_BUILD_D3D9 #ifdef CC_BUILD_D3D9
//#define D3D_DISABLE_9EX causes compile errors /*#define D3D_DISABLE_9EX causes compile errors*/
#include <d3d9.h> #include <d3d9.h>
#include <d3d9caps.h> #include <d3d9caps.h>
#include <d3d9types.h> #include <d3d9types.h>
@ -202,6 +202,9 @@ static void D3D9_SetTexturePartData(IDirect3DTexture9* texture, int x, int y, Bi
static void D3D9_DoMipmaps(IDirect3DTexture9* texture, int x, int y, Bitmap* bmp, bool partial) { static void D3D9_DoMipmaps(IDirect3DTexture9* texture, int x, int y, Bitmap* bmp, bool partial) {
uint8_t* prev = bmp->Scan0; uint8_t* prev = bmp->Scan0;
uint8_t* cur;
Bitmap mipmap;
int lvls = GfxCommon_MipmapsLevels(bmp->Width, bmp->Height); int lvls = GfxCommon_MipmapsLevels(bmp->Width, bmp->Height);
int lvl, width = bmp->Width, height = bmp->Height; int lvl, width = bmp->Width, height = bmp->Height;
@ -210,10 +213,9 @@ static void D3D9_DoMipmaps(IDirect3DTexture9* texture, int x, int y, Bitmap* bmp
if (width > 1) width /= 2; if (width > 1) width /= 2;
if (height > 1) height /= 2; if (height > 1) height /= 2;
uint8_t* cur = Mem_Alloc(width * height, BITMAP_SIZEOF_PIXEL, "mipmaps"); cur = Mem_Alloc(width * height, BITMAP_SIZEOF_PIXEL, "mipmaps");
GfxCommon_GenMipmaps(width, height, cur, prev); GfxCommon_GenMipmaps(width, height, cur, prev);
Bitmap mipmap;
Bitmap_Create(&mipmap, width, height, cur); Bitmap_Create(&mipmap, width, height, cur);
if (partial) { if (partial) {
D3D9_SetTexturePartData(texture, x, y, &mipmap, lvl); D3D9_SetTexturePartData(texture, x, y, &mipmap, lvl);
@ -786,7 +788,6 @@ static void GL_CheckVboSupport(void) {
glGenBuffers = (FUNC_GLGENBUFFERS)GLContext_GetAddress("glGenBuffers"); glGenBuffers = (FUNC_GLGENBUFFERS)GLContext_GetAddress("glGenBuffers");
glBufferData = (FUNC_GLBUFFERDATA)GLContext_GetAddress("glBufferData"); glBufferData = (FUNC_GLBUFFERDATA)GLContext_GetAddress("glBufferData");
glBufferSubData = (FUNC_GLBUFFERSUBDATA)GLContext_GetAddress("glBufferSubData"); glBufferSubData = (FUNC_GLBUFFERSUBDATA)GLContext_GetAddress("glBufferSubData");
return;
} else if (String_CaselessContains(&extensions, &vboExt)) { } else if (String_CaselessContains(&extensions, &vboExt)) {
glBindBuffer = (FUNC_GLBINDBUFFER)GLContext_GetAddress("glBindBufferARB"); glBindBuffer = (FUNC_GLBINDBUFFER)GLContext_GetAddress("glBindBufferARB");
glDeleteBuffers = (FUNC_GLDELETEBUFFERS)GLContext_GetAddress("glDeleteBuffersARB"); glDeleteBuffers = (FUNC_GLDELETEBUFFERS)GLContext_GetAddress("glDeleteBuffersARB");
@ -833,6 +834,8 @@ void Gfx_Free(void) {
*#########################################################################################################################*/ *#########################################################################################################################*/
static void GL_DoMipmaps(GfxResourceID texId, int x, int y, Bitmap* bmp, bool partial) { static void GL_DoMipmaps(GfxResourceID texId, int x, int y, Bitmap* bmp, bool partial) {
uint8_t* prev = bmp->Scan0; uint8_t* prev = bmp->Scan0;
uint8_t* cur;
int lvls = GfxCommon_MipmapsLevels(bmp->Width, bmp->Height); int lvls = GfxCommon_MipmapsLevels(bmp->Width, bmp->Height);
int lvl, width = bmp->Width, height = bmp->Height; int lvl, width = bmp->Width, height = bmp->Height;
@ -841,7 +844,7 @@ static void GL_DoMipmaps(GfxResourceID texId, int x, int y, Bitmap* bmp, bool pa
if (width > 1) width /= 2; if (width > 1) width /= 2;
if (height > 1) height /= 2; if (height > 1) height /= 2;
uint8_t* cur = Mem_Alloc(width * height, BITMAP_SIZEOF_PIXEL, "mipmaps"); cur = Mem_Alloc(width * height, BITMAP_SIZEOF_PIXEL, "mipmaps");
GfxCommon_GenMipmaps(width, height, cur, prev); GfxCommon_GenMipmaps(width, height, cur, prev);
if (partial) { if (partial) {
@ -918,9 +921,13 @@ void Gfx_SetFog(bool enabled) {
} }
void Gfx_SetFogCol(PackedCol col) { void Gfx_SetFogCol(PackedCol col) {
float rgba[4];
if (PackedCol_Equals(col, gl_lastFogCol)) return; if (PackedCol_Equals(col, gl_lastFogCol)) return;
float colRGBA[4] = { col.R / 255.0f, col.G / 255.0f, col.B / 255.0f, col.A / 255.0f };
glFogfv(GL_FOG_COLOR, colRGBA); rgba[0] = col.R / 255.0f; rgba[1] = col.G / 255.0f;
rgba[2] = col.B / 255.0f; rgba[3] = col.A / 255.0f;
glFogfv(GL_FOG_COLOR, rgba);
gl_lastFogCol = col; gl_lastFogCol = col;
} }
@ -939,6 +946,7 @@ void Gfx_SetFogEnd(float value) {
void Gfx_SetFogMode(int mode) { void Gfx_SetFogMode(int mode) {
static GLint modes[3] = { GL_LINEAR, GL_EXP, GL_EXP2 }; static GLint modes[3] = { GL_LINEAR, GL_EXP, GL_EXP2 };
if (mode == gl_lastFogMode) return; if (mode == gl_lastFogMode) return;
glFogi(GL_FOG_MODE, modes[mode]); glFogi(GL_FOG_MODE, modes[mode]);
gl_lastFogMode = mode; gl_lastFogMode = mode;
} }
@ -989,22 +997,22 @@ static GfxResourceID GL_GenAndBind(GLenum target) {
GfxResourceID Gfx_CreateDynamicVb(int vertexFormat, int maxVertices) { GfxResourceID Gfx_CreateDynamicVb(int vertexFormat, int maxVertices) {
GfxResourceID id = GL_GenAndBind(GL_ARRAY_BUFFER); GfxResourceID id = GL_GenAndBind(GL_ARRAY_BUFFER);
uint32_t sizeInBytes = maxVertices * Gfx_strideSizes[vertexFormat]; uint32_t size = maxVertices * Gfx_strideSizes[vertexFormat];
glBufferData(GL_ARRAY_BUFFER, (void*)sizeInBytes, NULL, GL_DYNAMIC_DRAW); glBufferData(GL_ARRAY_BUFFER, (void*)size, NULL, GL_DYNAMIC_DRAW);
return id; return id;
} }
GfxResourceID Gfx_CreateVb(void* vertices, int vertexFormat, int count) { GfxResourceID Gfx_CreateVb(void* vertices, int vertexFormat, int count) {
GfxResourceID id = GL_GenAndBind(GL_ARRAY_BUFFER); GfxResourceID id = GL_GenAndBind(GL_ARRAY_BUFFER);
uint32_t sizeInBytes = count * Gfx_strideSizes[vertexFormat]; uint32_t size = count * Gfx_strideSizes[vertexFormat];
glBufferData(GL_ARRAY_BUFFER, (void*)sizeInBytes, vertices, GL_STATIC_DRAW); glBufferData(GL_ARRAY_BUFFER, (void*)size, vertices, GL_STATIC_DRAW);
return id; return id;
} }
GfxResourceID Gfx_CreateIb(void* indices, int indicesCount) { GfxResourceID Gfx_CreateIb(void* indices, int indicesCount) {
GfxResourceID id = GL_GenAndBind(GL_ELEMENT_ARRAY_BUFFER); GfxResourceID id = GL_GenAndBind(GL_ELEMENT_ARRAY_BUFFER);
uint32_t sizeInBytes = indicesCount * 2; uint32_t size = indicesCount * 2;
glBufferData(GL_ELEMENT_ARRAY_BUFFER, (void*)sizeInBytes, indices, GL_STATIC_DRAW); glBufferData(GL_ELEMENT_ARRAY_BUFFER, (void*)size, indices, GL_STATIC_DRAW);
return id; return id;
} }
@ -1026,16 +1034,17 @@ void Gfx_DeleteIb(GfxResourceID* ib) {
GfxResourceID Gfx_CreateDynamicVb(int vertexFormat, int maxVertices) { return gl_DYNAMICLISTID; } GfxResourceID Gfx_CreateDynamicVb(int vertexFormat, int maxVertices) { return gl_DYNAMICLISTID; }
GfxResourceID Gfx_CreateVb(void* vertices, int vertexFormat, int count) { GfxResourceID Gfx_CreateVb(void* vertices, int vertexFormat, int count) {
/* We need to setup client state properly when building the list */ /* We need to setup client state properly when building the list */
int curFormat = gfx_batchFormat; int curFormat = gfx_batchFormat, stride;
Gfx_SetBatchFormat(vertexFormat); Gfx_SetBatchFormat(vertexFormat);
GfxResourceID list = glGenLists(1); GfxResourceID list = glGenLists(1);
glNewList(list, GL_COMPILE); glNewList(list, GL_COMPILE);
count &= ~0x01; /* Need to get rid of the 1 extra element, see comment in chunk mesh builder for why */ count &= ~0x01; /* Need to get rid of the 1 extra element, see comment in chunk mesh builder for why */
uint16_t indices[GFX_MAX_INDICES]; uint16_t indices[GFX_MAX_INDICES];
GfxCommon_MakeIndices(indices, ICOUNT(count)); GfxCommon_MakeIndices(indices, ICOUNT(count));
stride = Gfx_strideSizes[vertexFormat];
int stride = vertexFormat == VERTEX_FORMAT_P3FT2FC4B ? sizeof(VertexP3fT2fC4b) : sizeof(VertexP3fC4b);
glVertexPointer(3, GL_FLOAT, stride, vertices); glVertexPointer(3, GL_FLOAT, stride, vertices);
glColorPointer(4, GL_UNSIGNED_BYTE, stride, (void*)((uint8_t*)vertices + 12)); glColorPointer(4, GL_UNSIGNED_BYTE, stride, (void*)((uint8_t*)vertices + 12));
if (vertexFormat == VERTEX_FORMAT_P3FT2FC4B) { if (vertexFormat == VERTEX_FORMAT_P3FT2FC4B) {
@ -1105,9 +1114,9 @@ void Gfx_SetBatchFormat(int vertexFormat) {
#ifndef CC_BUILD_GL11 #ifndef CC_BUILD_GL11
void Gfx_SetDynamicVbData(GfxResourceID vb, void* vertices, int vCount) { void Gfx_SetDynamicVbData(GfxResourceID vb, void* vertices, int vCount) {
uint32_t size = vCount * gfx_batchStride;
glBindBuffer(GL_ARRAY_BUFFER, vb); glBindBuffer(GL_ARRAY_BUFFER, vb);
uint32_t sizeInBytes = vCount * gfx_batchStride; glBufferSubData(GL_ARRAY_BUFFER, NULL, (void*)size, vertices);
glBufferSubData(GL_ARRAY_BUFFER, NULL, (void*)sizeInBytes, vertices);
} }
void Gfx_DrawVb_Lines(int verticesCount) { void Gfx_DrawVb_Lines(int verticesCount) {
@ -1150,8 +1159,9 @@ static void GL_V24(VertexP3fT2fC4b v) {
} }
static void GL_DrawDynamicTriangles(int verticesCount, int startVertex) { static void GL_DrawDynamicTriangles(int verticesCount, int startVertex) {
glBegin(GL_TRIANGLES);
int i; int i;
glBegin(GL_TRIANGLES);
if (gfx_batchFormat == VERTEX_FORMAT_P3FT2FC4B) { if (gfx_batchFormat == VERTEX_FORMAT_P3FT2FC4B) {
VertexP3fT2fC4b* ptr = (VertexP3fT2fC4b*)gl_dynamicListData; VertexP3fT2fC4b* ptr = (VertexP3fT2fC4b*)gl_dynamicListData;
for (i = startVertex; i < startVertex + verticesCount; i += 4) { for (i = startVertex; i < startVertex + verticesCount; i += 4) {
@ -1169,8 +1179,9 @@ static void GL_DrawDynamicTriangles(int verticesCount, int startVertex) {
} }
void Gfx_DrawVb_Lines(int verticesCount) { void Gfx_DrawVb_Lines(int verticesCount) {
glBegin(GL_LINES);
int i; int i;
glBegin(GL_LINES);
if (gfx_batchFormat == VERTEX_FORMAT_P3FT2FC4B) { if (gfx_batchFormat == VERTEX_FORMAT_P3FT2FC4B) {
VertexP3fT2fC4b* ptr = (VertexP3fT2fC4b*)gl_dynamicListData; VertexP3fT2fC4b* ptr = (VertexP3fT2fC4b*)gl_dynamicListData;
for (i = 0; i < verticesCount; i += 2) { GL_V24(ptr[i + 0]); GL_V24(ptr[i + 1]); } for (i = 0; i < verticesCount; i += 2) { GL_V24(ptr[i + 0]); GL_V24(ptr[i + 1]); }
@ -1207,10 +1218,11 @@ void Gfx_DrawIndexedVb_TrisT2fC4b(int verticesCount, int startVertex) {
int gl_lastMatrixType; int gl_lastMatrixType;
void Gfx_SetMatrixMode(int matrixType) { void Gfx_SetMatrixMode(int matrixType) {
static GLenum modes[3] = { GL_PROJECTION, GL_MODELVIEW, GL_TEXTURE };
if (matrixType == gl_lastMatrixType) return; if (matrixType == gl_lastMatrixType) return;
gl_lastMatrixType = matrixType; gl_lastMatrixType = matrixType;
static GLenum matrixModes[3] = { GL_PROJECTION, GL_MODELVIEW, GL_TEXTURE }; glMatrixMode(modes[matrixType]);
glMatrixMode(matrixModes[matrixType]);
} }
void Gfx_LoadMatrix(struct Matrix* matrix) { glLoadMatrixf((float*)matrix); } void Gfx_LoadMatrix(struct Matrix* matrix) { glLoadMatrixf((float*)matrix); }
@ -1229,53 +1241,58 @@ void Gfx_CalcPerspectiveMatrix(float fov, float aspect, float zNear, float zFar,
*#########################################################################################################################*/ *#########################################################################################################################*/
static int GL_SelectRow(Bitmap* bmp, int y) { return (bmp->Height - 1) - y; } static int GL_SelectRow(Bitmap* bmp, int y) { return (bmp->Height - 1) - y; }
ReturnCode Gfx_TakeScreenshot(struct Stream* output, int width, int height) { ReturnCode Gfx_TakeScreenshot(struct Stream* output, int width, int height) {
Bitmap bmp; Bitmap_Allocate(&bmp, width, height); Bitmap bmp;
ReturnCode res;
Bitmap_Allocate(&bmp, width, height);
glReadPixels(0, 0, width, height, GL_BGRA_EXT, GL_UNSIGNED_BYTE, bmp.Scan0); glReadPixels(0, 0, width, height, GL_BGRA_EXT, GL_UNSIGNED_BYTE, bmp.Scan0);
ReturnCode res = Png_Encode(&bmp, output, GL_SelectRow); res = Png_Encode(&bmp, output, GL_SelectRow);
Mem_Free(bmp.Scan0); Mem_Free(bmp.Scan0);
return res; return res;
} }
bool nv_mem; bool nv_mem;
void Gfx_MakeApiInfo(void) { void Gfx_MakeApiInfo(void) {
int depthBits = 0; static String memExt = String_FromConst("GL_NVX_gpu_memory_info");
String extensions = String_FromReadonly(glGetString(GL_EXTENSIONS));
int depthBits;
nv_mem = String_CaselessContains(&extensions, &memExt);
glGetIntegerv(GL_DEPTH_BITS, &depthBits); glGetIntegerv(GL_DEPTH_BITS, &depthBits);
String_AppendConst(&Gfx_ApiInfo[0],"-- Using OpenGL --"); String_AppendConst(&Gfx_ApiInfo[0],"-- Using OpenGL --");
String_Format1(&Gfx_ApiInfo[1], "Vendor: %c", glGetString(GL_VENDOR)); String_Format1(&Gfx_ApiInfo[1], "Vendor: %c", glGetString(GL_VENDOR));
String_Format1(&Gfx_ApiInfo[2], "Renderer: %c", glGetString(GL_RENDERER)); String_Format1(&Gfx_ApiInfo[2], "Renderer: %c", glGetString(GL_RENDERER));
String_Format1(&Gfx_ApiInfo[3], "GL version: %c", glGetString(GL_VERSION)); String_Format1(&Gfx_ApiInfo[3], "GL version: %c", glGetString(GL_VERSION));
/* Memory usage goes here */ /* Memory usage line goes here */
String_Format2(&Gfx_ApiInfo[5], "Max texture size: (%i, %i)", &Gfx_MaxTexWidth, &Gfx_MaxTexHeight); String_Format2(&Gfx_ApiInfo[5], "Max texture size: (%i, %i)", &Gfx_MaxTexWidth, &Gfx_MaxTexHeight);
String_Format1(&Gfx_ApiInfo[6], "Depth buffer bits: %i", &depthBits); String_Format1(&Gfx_ApiInfo[6], "Depth buffer bits: %i", &depthBits);
String extensions = String_FromReadonly(glGetString(GL_EXTENSIONS));
String memExt = String_FromConst("GL_NVX_gpu_memory_info");
nv_mem = String_CaselessContains(&extensions, &memExt);
} }
void Gfx_UpdateApiInfo(void) { void Gfx_UpdateApiInfo(void) {
if (!nv_mem) return;
int totalKb = 0, curKb = 0; int totalKb = 0, curKb = 0;
float total, cur;
if (!nv_mem) return;
glGetIntegerv(0x9048, &totalKb); glGetIntegerv(0x9048, &totalKb);
glGetIntegerv(0x9049, &curKb); glGetIntegerv(0x9049, &curKb);
if (totalKb <= 0 || curKb <= 0) return; if (totalKb <= 0 || curKb <= 0) return;
total = totalKb / 1024.0f; cur = curKb / 1024.0f;
Gfx_ApiInfo[4].length = 0; Gfx_ApiInfo[4].length = 0;
float total = totalKb / 1024.0f, cur = curKb / 1024.0f;
String_Format2(&Gfx_ApiInfo[4], "Video memory: %f2 MB total, %f2 free", &total, &cur); String_Format2(&Gfx_ApiInfo[4], "Video memory: %f2 MB total, %f2 free", &total, &cur);
} }
bool Gfx_WarnIfNecessary(void) { bool Gfx_WarnIfNecessary(void) {
static String intel = String_FromConst("Intel");
String renderer = String_FromReadonly(glGetString(GL_RENDERER));
#ifdef CC_BUILD_GL11 #ifdef CC_BUILD_GL11
Chat_AddRaw("&cYou are using the very outdated OpenGL backend."); Chat_AddRaw("&cYou are using the very outdated OpenGL backend.");
Chat_AddRaw("&cAs such you may experience poor performance."); Chat_AddRaw("&cAs such you may experience poor performance.");
Chat_AddRaw("&cIt is likely you need to install video card drivers."); Chat_AddRaw("&cIt is likely you need to install video card drivers.");
#endif #endif
String renderer = String_FromReadonly(glGetString(GL_RENDERER));
String intel = String_FromConst("Intel");
if (!String_ContainsString(&renderer, &intel)) return false; if (!String_ContainsString(&renderer, &intel)) return false;
Chat_AddRaw("&cIntel graphics cards are known to have issues with the OpenGL build."); Chat_AddRaw("&cIntel graphics cards are known to have issues with the OpenGL build.");

View File

@ -399,6 +399,7 @@ void InputHandler_PickBlocks(bool cooldown, bool left, bool middle, bool right)
static void InputHandler_MouseWheel(void* obj, float delta) { static void InputHandler_MouseWheel(void* obj, float delta) {
struct Screen* active = Gui_GetActiveScreen(); struct Screen* active = Gui_GetActiveScreen();
struct Widget* widget;
bool hotbar; bool hotbar;
if (Elem_HandlesMouseScroll(active, delta)) return; if (Elem_HandlesMouseScroll(active, delta)) return;
@ -406,8 +407,8 @@ static void InputHandler_MouseWheel(void* obj, float delta) {
if (!hotbar && Camera_Active->Zoom(delta)) return; if (!hotbar && Camera_Active->Zoom(delta)) return;
if (InputHandler_DoFovZoom(delta) || !Inventory_CanChangeHeldBlock) return; if (InputHandler_DoFovZoom(delta) || !Inventory_CanChangeHeldBlock) return;
struct Widget* hotbarW = HUDScreen_GetHotbar(Gui_HUD); widget = HUDScreen_GetHotbar(Gui_HUD);
Elem_HandlesMouseScroll(hotbarW, delta); Elem_HandlesMouseScroll(widget, delta);
} }
static void InputHandler_MouseMove(void* obj, int xDelta, int yDelta) { static void InputHandler_MouseMove(void* obj, int xDelta, int yDelta) {

View File

@ -1158,8 +1158,8 @@ static void BlockModel_RecalcProperties(struct Entity* p) {
float height; float height;
if (Block_Draw[block] == DRAW_GAS) { if (Block_Draw[block] == DRAW_GAS) {
Vector3 zero = Vector3_Zero; BlockModel_minBB = zero; BlockModel_minBB = Vector3_Zero;
Vector3 one = Vector3_One; BlockModel_maxBB = one; BlockModel_maxBB = Vector3_One;
height = 1.0f; height = 1.0f;
} else { } else {
BlockModel_minBB = Block_MinBB[block]; BlockModel_minBB = Block_MinBB[block];

View File

@ -163,8 +163,10 @@ static void Window_RefreshBorders(void) {
static void Window_RefreshBounds(XEvent* e) { static void Window_RefreshBounds(XEvent* e) {
Window_RefreshBorders(); Window_RefreshBorders();
Point2D loc;
loc.X = e->xconfigure.x - borderLeft;
loc.Y = e->xconfigure.y - borderTop;
Point2D loc = { e->xconfigure.x - borderLeft, e->xconfigure.y - borderTop };
if (loc.X != Window_Bounds.X || loc.Y != Window_Bounds.Y) { if (loc.X != Window_Bounds.X || loc.Y != Window_Bounds.Y) {
Window_Bounds.X = loc.X; Window_Bounds.Y = loc.Y; Window_Bounds.X = loc.X; Window_Bounds.Y = loc.Y;
Event_RaiseVoid(&WindowEvents_Moved); Event_RaiseVoid(&WindowEvents_Moved);
@ -172,10 +174,9 @@ static void Window_RefreshBounds(XEvent* e) {
/* Note: width and height denote the internal (client) size. /* Note: width and height denote the internal (client) size.
To get the external (window) size, we need to add the border size. */ To get the external (window) size, we need to add the border size. */
Size2D size = { Size2D size;
e->xconfigure.width + borderLeft + borderRight, size.Width = e->xconfigure.width + borderLeft + borderRight;
e->xconfigure.height + borderTop + borderBottom size.Height = e->xconfigure.height + borderTop + borderBottom;
};
if (size.Width != Window_Bounds.Width || size.Height != Window_Bounds.Height) { if (size.Width != Window_Bounds.Width || size.Height != Window_Bounds.Height) {
Window_ClientSize.Width = e->xconfigure.width; Window_Bounds.Width = size.Width; Window_ClientSize.Width = e->xconfigure.width; Window_Bounds.Width = size.Width;

View File

@ -216,16 +216,18 @@ static void WoM_UpdateIdentifier(void) {
} }
static void WoM_CheckMotd(void) { static void WoM_CheckMotd(void) {
String motd = ServerConnection_ServerMOTD; static String cfg = String_FromConst("cfg=");
if (!motd.length) return; String motd = ServerConnection_ServerMOTD, host;
int index;
String cfg = String_FromConst("cfg=");
int index = String_IndexOfString(&motd, &cfg);
if (Game_PureClassic || index == -1) return;
char urlBuffer[STRING_SIZE]; char urlBuffer[STRING_SIZE];
String url = String_FromArray(urlBuffer); String url = String_FromArray(urlBuffer);
String host = String_UNSAFE_SubstringAt(&motd, index + cfg.length);
if (!motd.length) return;
index = String_IndexOfString(&motd, &cfg);
if (Game_PureClassic || index == -1) return;
host = String_UNSAFE_SubstringAt(&motd, index + cfg.length);
String_Format1(&url, "http://%s", &host); String_Format1(&url, "http://%s", &host);
/* TODO: Replace $U with username */ /* TODO: Replace $U with username */
/*url = url.Replace("$U", game.Username); */ /*url = url.Replace("$U", game.Username); */
@ -259,10 +261,11 @@ static PackedCol WoM_ParseCol(const String* value, PackedCol defaultCol) {
static bool WoM_ReadLine(STRING_REF const String* page, int* start, String* line) { static bool WoM_ReadLine(STRING_REF const String* page, int* start, String* line) {
int i, offset = *start; int i, offset = *start;
char c;
if (offset == -1) return false; if (offset == -1) return false;
for (i = offset; i < page->length; i++) { for (i = offset; i < page->length; i++) {
char c = page->buffer[i]; c = page->buffer[i];
if (c != '\r' && c != '\n') continue; if (c != '\r' && c != '\n') continue;
*line = String_UNSAFE_Substring(page, offset, i - offset); *line = String_UNSAFE_Substring(page, offset, i - offset);
@ -282,23 +285,23 @@ static bool WoM_ReadLine(STRING_REF const String* page, int* start, String* line
static void WoM_ParseConfig(const String* page) { static void WoM_ParseConfig(const String* page) {
String line, key, value; String line, key, value;
int start = 0; int start = 0, waterLevel;
PackedCol col;
while (WoM_ReadLine(page, &start, &line)) { while (WoM_ReadLine(page, &start, &line)) {
Platform_Log(&line); Platform_Log(&line);
if (!String_UNSAFE_Separate(&line, '=', &key, &value)) continue; if (!String_UNSAFE_Separate(&line, '=', &key, &value)) continue;
if (String_CaselessEqualsConst(&key, "environment.cloud")) { if (String_CaselessEqualsConst(&key, "environment.cloud")) {
PackedCol col = WoM_ParseCol(&value, Env_DefaultCloudsCol); col = WoM_ParseCol(&value, Env_DefaultCloudsCol);
Env_SetCloudsCol(col); Env_SetCloudsCol(col);
} else if (String_CaselessEqualsConst(&key, "environment.sky")) { } else if (String_CaselessEqualsConst(&key, "environment.sky")) {
PackedCol col = WoM_ParseCol(&value, Env_DefaultSkyCol); col = WoM_ParseCol(&value, Env_DefaultSkyCol);
Env_SetSkyCol(col); Env_SetSkyCol(col);
} else if (String_CaselessEqualsConst(&key, "environment.fog")) { } else if (String_CaselessEqualsConst(&key, "environment.fog")) {
PackedCol col = WoM_ParseCol(&value, Env_DefaultFogCol); col = WoM_ParseCol(&value, Env_DefaultFogCol);
Env_SetFogCol(col); Env_SetFogCol(col);
} else if (String_CaselessEqualsConst(&key, "environment.level")) { } else if (String_CaselessEqualsConst(&key, "environment.level")) {
int waterLevel;
if (Convert_TryParseInt(&value, &waterLevel)) { if (Convert_TryParseInt(&value, &waterLevel)) {
Env_SetEdgeHeight(waterLevel); Env_SetEdgeHeight(waterLevel);
} }
@ -456,10 +459,13 @@ static void Classic_LevelInit(uint8_t* data) {
} }
static void Classic_LevelDataChunk(uint8_t* data) { static void Classic_LevelDataChunk(uint8_t* data) {
int usedLength;
float progress;
/* Workaround for some servers that send LevelDataChunk before LevelInit due to their async sending behaviour */ /* Workaround for some servers that send LevelDataChunk before LevelInit due to their async sending behaviour */
if (!map_begunLoading) Classic_StartLoading(); if (!map_begunLoading) Classic_StartLoading();
usedLength = Stream_GetU16_BE(data); data += 2;
int usedLength = Stream_GetU16_BE(data); data += 2;
map_part.Meta.Mem.Cur = data; map_part.Meta.Mem.Cur = data;
map_part.Meta.Mem.Base = data; map_part.Meta.Mem.Base = data;
map_part.Meta.Mem.Left = usedLength; map_part.Meta.Mem.Left = usedLength;
@ -503,21 +509,24 @@ static void Classic_LevelDataChunk(uint8_t* data) {
} }
} }
float progress = !map_blocks ? 0.0f : (float)map_index / map_volume; progress = !map_blocks ? 0.0f : (float)map_index / map_volume;
Event_RaiseFloat(&WorldEvents_Loading, progress); Event_RaiseFloat(&WorldEvents_Loading, progress);
} }
static void Classic_LevelFinalise(uint8_t* data) { static void Classic_LevelFinalise(uint8_t* data) {
int width, height, length;
int loadingMs;
Gui_CloseActive(); Gui_CloseActive();
Gui_Active = classic_prevScreen; Gui_Active = classic_prevScreen;
classic_prevScreen = NULL; classic_prevScreen = NULL;
Gui_CalcCursorVisible(); Gui_CalcCursorVisible();
int width = Stream_GetU16_BE(&data[0]); width = Stream_GetU16_BE(&data[0]);
int height = Stream_GetU16_BE(&data[2]); height = Stream_GetU16_BE(&data[2]);
int length = Stream_GetU16_BE(&data[4]); length = Stream_GetU16_BE(&data[4]);
int loadingMs = (int)(DateTime_CurrentUTC_MS() - map_receiveStart); loadingMs = (int)(DateTime_CurrentUTC_MS() - map_receiveStart);
Platform_Log1("map loading took: %i", &loadingMs); Platform_Log1("map loading took: %i", &loadingMs);
World_SetNewMap(map_blocks, map_volume, width, height, length); World_SetNewMap(map_blocks, map_volume, width, height, length);
@ -540,12 +549,15 @@ static void Classic_LevelFinalise(uint8_t* data) {
} }
static void Classic_SetBlock(uint8_t* data) { static void Classic_SetBlock(uint8_t* data) {
int x = Stream_GetU16_BE(&data[0]); int x, y, z;
int y = Stream_GetU16_BE(&data[2]); BlockID block;
int z = Stream_GetU16_BE(&data[4]);
x = Stream_GetU16_BE(&data[0]);
y = Stream_GetU16_BE(&data[2]);
z = Stream_GetU16_BE(&data[4]);
data += 6; data += 6;
BlockID block; Handlers_ReadBlock(data, block);
Handlers_ReadBlock(data, block);
if (World_IsValidPos(x, y, z)) { if (World_IsValidPos(x, y, z)) {
Game_UpdateBlock(x, y, z, block); Game_UpdateBlock(x, y, z, block);
} }
@ -574,33 +586,43 @@ static void Classic_EntityTeleport(uint8_t* data) {
} }
static void Classic_RelPosAndOrientationUpdate(uint8_t* data) { static void Classic_RelPosAndOrientationUpdate(uint8_t* data) {
EntityID id = *data++; Vector3 pos; EntityID id = *data++;
Vector3 pos;
float rotY, headX;
struct LocationUpdate update;
pos.X = (int8_t)(*data++) / 32.0f; pos.X = (int8_t)(*data++) / 32.0f;
pos.Y = (int8_t)(*data++) / 32.0f; pos.Y = (int8_t)(*data++) / 32.0f;
pos.Z = (int8_t)(*data++) / 32.0f; pos.Z = (int8_t)(*data++) / 32.0f;
rotY = Math_Packed2Deg(*data++);
headX = Math_Packed2Deg(*data++);
float rotY = Math_Packed2Deg(*data++); LocationUpdate_MakePosAndOri(&update, pos, rotY, headX, true);
float headX = Math_Packed2Deg(*data++);
struct LocationUpdate update; LocationUpdate_MakePosAndOri(&update, pos, rotY, headX, true);
Handlers_UpdateLocation(id, &update, true); Handlers_UpdateLocation(id, &update, true);
} }
static void Classic_RelPositionUpdate(uint8_t* data) { static void Classic_RelPositionUpdate(uint8_t* data) {
EntityID id = *data++; Vector3 pos; EntityID id = *data++;
Vector3 pos;
struct LocationUpdate update;
pos.X = (int8_t)(*data++) / 32.0f; pos.X = (int8_t)(*data++) / 32.0f;
pos.Y = (int8_t)(*data++) / 32.0f; pos.Y = (int8_t)(*data++) / 32.0f;
pos.Z = (int8_t)(*data++) / 32.0f; pos.Z = (int8_t)(*data++) / 32.0f;
struct LocationUpdate update; LocationUpdate_MakePos(&update, pos, true); LocationUpdate_MakePos(&update, pos, true);
Handlers_UpdateLocation(id, &update, true); Handlers_UpdateLocation(id, &update, true);
} }
static void Classic_OrientationUpdate(uint8_t* data) { static void Classic_OrientationUpdate(uint8_t* data) {
EntityID id = *data++; EntityID id = *data++;
float rotY = Math_Packed2Deg(*data++); float rotY, headX;
float headX = Math_Packed2Deg(*data++); struct LocationUpdate update;
struct LocationUpdate update; LocationUpdate_MakeOri(&update, rotY, headX); rotY = Math_Packed2Deg(*data++);
headX = Math_Packed2Deg(*data++);
LocationUpdate_MakeOri(&update, rotY, headX);
Handlers_UpdateLocation(id, &update, true); Handlers_UpdateLocation(id, &update, true);
} }
@ -610,6 +632,9 @@ static void Classic_RemoveEntity(uint8_t* data) {
} }
static void Classic_Message(uint8_t* data) { static void Classic_Message(uint8_t* data) {
static String detailMsg = String_FromConst("^detail.user=");
static String detailUser = String_FromConst("^detail.user");
char textBuffer[STRING_SIZE + 2]; char textBuffer[STRING_SIZE + 2];
String text = String_FromArray(textBuffer); String text = String_FromArray(textBuffer);
uint8_t type = *data++; uint8_t type = *data++;
@ -621,23 +646,22 @@ static void Classic_Message(uint8_t* data) {
if (!cpe_useMessageTypes) type = MSG_TYPE_NORMAL; if (!cpe_useMessageTypes) type = MSG_TYPE_NORMAL;
/* WoM detail messages (used e.g. for fCraft server compass) */ /* WoM detail messages (used e.g. for fCraft server compass) */
String detailMsg = String_FromConst("^detail.user=");
if (String_CaselessStarts(&text, &detailMsg)) { if (String_CaselessStarts(&text, &detailMsg)) {
text = String_UNSAFE_SubstringAt(&text, detailMsg.length); text = String_UNSAFE_SubstringAt(&text, detailMsg.length);
type = MSG_TYPE_STATUS_3; type = MSG_TYPE_STATUS_3;
} }
/* Ignore ^detail.user.joined etc */ /* Ignore ^detail.user.joined etc */
String detailUser = String_FromConst("^detail.user");
if (!String_CaselessStarts(&text, &detailUser)) { if (!String_CaselessStarts(&text, &detailUser)) {
Chat_AddOf(&text, type); Chat_AddOf(&text, type);
} }
} }
static void Classic_Kick(uint8_t* data) { static void Classic_Kick(uint8_t* data) {
static String title = String_FromConst("&eLost connection to the server");
char reasonBuffer[STRING_SIZE]; char reasonBuffer[STRING_SIZE];
String reason = String_FromArray(reasonBuffer); String reason = String_FromArray(reasonBuffer);
String title = String_FromConst("&eLost connection to the server");
Handlers_ReadString(&data, &reason); Handlers_ReadString(&data, &reason);
Game_Disconnect(&title, &reason); Game_Disconnect(&title, &reason);
@ -1012,20 +1036,23 @@ static void CPE_ExtRemovePlayerName(uint8_t* data) {
} }
static void CPE_MakeSelection(uint8_t* data) { static void CPE_MakeSelection(uint8_t* data) {
uint8_t selectionId = *data++; uint8_t selectionId;
Vector3I p1, p2;
PackedCol c;
selectionId = *data++;
data += STRING_SIZE; /* label */ data += STRING_SIZE; /* label */
Vector3I p1;
p1.X = (int16_t)Stream_GetU16_BE(&data[0]); p1.X = (int16_t)Stream_GetU16_BE(&data[0]);
p1.Y = (int16_t)Stream_GetU16_BE(&data[2]); p1.Y = (int16_t)Stream_GetU16_BE(&data[2]);
p1.Z = (int16_t)Stream_GetU16_BE(&data[4]); p1.Z = (int16_t)Stream_GetU16_BE(&data[4]);
data += 6;
Vector3I p2; data += 6;
p2.X = (int16_t)Stream_GetU16_BE(&data[0]); p2.X = (int16_t)Stream_GetU16_BE(&data[0]);
p2.Y = (int16_t)Stream_GetU16_BE(&data[2]); p2.Y = (int16_t)Stream_GetU16_BE(&data[2]);
p2.Z = (int16_t)Stream_GetU16_BE(&data[4]); p2.Z = (int16_t)Stream_GetU16_BE(&data[4]);
data += 6;
PackedCol c; data += 6;
/* R,G,B,A are actually 16 bit unsigned integers */ /* R,G,B,A are actually 16 bit unsigned integers */
c.R = data[1]; c.G = data[3]; c.B = data[5]; c.A = data[7]; c.R = data[1]; c.G = data[3]; c.B = data[5]; c.A = data[7];
Selections_Add(selectionId, p1, p2, c); Selections_Add(selectionId, p1, p2, c);
@ -1197,14 +1224,13 @@ static void CPE_SetMapEnvProperty(uint8_t* data) {
uint8_t type = *data++; uint8_t type = *data++;
int value = (int)Stream_GetU32_BE(data); int value = (int)Stream_GetU32_BE(data);
Math_Clamp(value, -0xFFFFFF, 0xFFFFFF); Math_Clamp(value, -0xFFFFFF, 0xFFFFFF);
int maxBlock = BLOCK_COUNT - 1;
switch (type) { switch (type) {
case 0: case 0:
Math_Clamp(value, 0, maxBlock); Math_Clamp(value, 0, BLOCK_MAX_DEFINED);
Env_SetSidesBlock((BlockID)value); break; Env_SetSidesBlock((BlockID)value); break;
case 1: case 1:
Math_Clamp(value, 0, maxBlock); Math_Clamp(value, 0, BLOCK_MAX_DEFINED);
Env_SetEdgeBlock((BlockID)value); break; Env_SetEdgeBlock((BlockID)value); break;
case 2: case 2:
Env_SetEdgeHeight(value); break; Env_SetEdgeHeight(value); break;
@ -1281,8 +1307,9 @@ static void CPE_TwoWayPing(uint8_t* data) {
} }
static void CPE_SetInventoryOrder(uint8_t* data) { static void CPE_SetInventoryOrder(uint8_t* data) {
BlockID block; Handlers_ReadBlock(data, block); BlockID block, order;
BlockID order; Handlers_ReadBlock(data, order); Handlers_ReadBlock(data, block);
Handlers_ReadBlock(data, order);
Inventory_Remove(block); Inventory_Remove(block);
if (order) { Inventory_Map[order - 1] = block; } if (order) { Inventory_Map[order - 1] = block; }
@ -1358,12 +1385,15 @@ static TextureLoc BlockDefs_Tex(uint8_t** ptr) {
} }
static BlockID BlockDefs_DefineBlockCommonStart(uint8_t** ptr, bool uniqueSideTexs) { static BlockID BlockDefs_DefineBlockCommonStart(uint8_t** ptr, bool uniqueSideTexs) {
BlockID block;
bool didBlockLight = Block_BlocksLight[block];
uint8_t sound;
uint8_t* data = *ptr; uint8_t* data = *ptr;
char nameBuffer[STRING_SIZE]; char nameBuffer[STRING_SIZE];
String name = String_FromArray(nameBuffer); String name = String_FromArray(nameBuffer);
BlockID block; Handlers_ReadBlock(data, block); Handlers_ReadBlock(data, block);
bool didBlockLight = Block_BlocksLight[block];
Block_ResetProps(block); Block_ResetProps(block);
Handlers_ReadString(&data, &name); Handlers_ReadString(&data, &name);
@ -1388,9 +1418,9 @@ static BlockID BlockDefs_DefineBlockCommonStart(uint8_t** ptr, bool uniqueSideTe
Block_BlocksLight[block] = *data++ == 0; Block_BlocksLight[block] = *data++ == 0;
BlockDefs_OnBlockUpdated(block, didBlockLight); BlockDefs_OnBlockUpdated(block, didBlockLight);
uint8_t sound = *data++; sound = *data++;
Block_StepSounds[block] = sound; Block_StepSounds[block] = sound;
Block_DigSounds[block] = sound; Block_DigSounds[block] = sound;
if (sound == SOUND_GLASS) Block_StepSounds[block] = SOUND_STONE; if (sound == SOUND_GLASS) Block_StepSounds[block] = SOUND_STONE;
Block_FullBright[block] = *data++ != 0; Block_FullBright[block] = *data++ != 0;
@ -1399,17 +1429,20 @@ static BlockID BlockDefs_DefineBlockCommonStart(uint8_t** ptr, bool uniqueSideTe
} }
static void BlockDefs_DefineBlockCommonEnd(uint8_t* data, uint8_t shape, BlockID block) { static void BlockDefs_DefineBlockCommonEnd(uint8_t* data, uint8_t shape, BlockID block) {
uint8_t blockDraw = *data++; uint8_t blockDraw;
uint8_t density;
PackedCol c;
blockDraw = *data++;
if (shape == 0) { if (shape == 0) {
Block_SpriteOffset[block] = blockDraw; Block_SpriteOffset[block] = blockDraw;
blockDraw = DRAW_SPRITE; blockDraw = DRAW_SPRITE;
} }
Block_Draw[block] = blockDraw; Block_Draw[block] = blockDraw;
uint8_t density = *data++; density = *data++;
Block_FogDensity[block] = density == 0 ? 0.0f : (density + 1) / 128.0f; Block_FogDensity[block] = density == 0 ? 0.0f : (density + 1) / 128.0f;
PackedCol c;
c.R = *data++; c.G = *data++; c.B = *data++; c.A = 255; c.R = *data++; c.G = *data++; c.B = *data++; c.A = 255;
Block_FogCol[block] = c; Block_FogCol[block] = c;
Block_DefineCustom(block); Block_DefineCustom(block);
@ -1431,8 +1464,9 @@ static void BlockDefs_DefineBlock(uint8_t* data) {
} }
static void BlockDefs_UndefineBlock(uint8_t* data) { static void BlockDefs_UndefineBlock(uint8_t* data) {
BlockID block; Handlers_ReadBlock(data, block); BlockID block;
bool didBlockLight = Block_BlocksLight[block]; bool didBlockLight = Block_BlocksLight[block];
Handlers_ReadBlock(data, block);
Block_ResetProps(block); Block_ResetProps(block);
BlockDefs_OnBlockUpdated(block, didBlockLight); BlockDefs_OnBlockUpdated(block, didBlockLight);

View File

@ -74,7 +74,7 @@ static BlockID Particle_GetBlock(int x, int y, int z) {
static bool Particle_TestY(struct Particle* p, int y, bool topFace, bool throughLiquids) { static bool Particle_TestY(struct Particle* p, int y, bool topFace, bool throughLiquids) {
if (y < 0) { if (y < 0) {
p->NextPos.Y = ENTITY_ADJUSTMENT; p->LastPos.Y = ENTITY_ADJUSTMENT; p->NextPos.Y = ENTITY_ADJUSTMENT; p->LastPos.Y = ENTITY_ADJUSTMENT;
Vector3 zero = Vector3_Zero; p->Velocity = zero; p->Velocity = Vector3_Zero;
particle_hitTerrain = true; particle_hitTerrain = true;
return false; return false;
} }
@ -90,7 +90,7 @@ static bool Particle_TestY(struct Particle* p, int y, bool topFace, bool through
float adjust = topFace ? ENTITY_ADJUSTMENT : -ENTITY_ADJUSTMENT; float adjust = topFace ? ENTITY_ADJUSTMENT : -ENTITY_ADJUSTMENT;
p->LastPos.Y = collideY + adjust; p->LastPos.Y = collideY + adjust;
p->NextPos.Y = p->LastPos.Y; p->NextPos.Y = p->LastPos.Y;
Vector3 zero = Vector3_Zero; p->Velocity = zero; p->Velocity = Vector3_Zero;
particle_hitTerrain = true; particle_hitTerrain = true;
return false; return false;
} }

View File

@ -45,7 +45,31 @@ void PickedPosRenderer_Render(double delta) {
Gfx_SetAlphaBlending(false); Gfx_SetAlphaBlending(false);
} }
#define PickedPos_Y(y)\
0,y,1, 0,y,2, 1,y,2, 1,y,1,\
3,y,1, 3,y,2, 2,y,2, 2,y,1,\
0,y,0, 0,y,1, 3,y,1, 3,y,0,\
0,y,3, 0,y,2, 3,y,2, 3,y,3,
#define PickedPos_X(x)\
x,1,0, x,2,0, x,2,1, x,1,1,\
x,1,3, x,2,3, x,2,2, x,1,2,\
x,0,0, x,1,0, x,1,3, x,0,3,\
x,3,0, x,2,0, x,2,3, x,3,3,
#define PickedPos_Z(z)\
0,1,z, 0,2,z, 1,2,z, 1,1,z,\
3,1,z, 3,2,z, 2,2,z, 2,1,z,\
0,0,z, 0,1,z, 3,1,z, 3,0,z,\
0,3,z, 0,2,z, 3,2,z, 3,3,z,
void PickedPosRenderer_Update(struct PickedPos* selected) { void PickedPosRenderer_Update(struct PickedPos* selected) {
static uint8_t indices[288] = {
PickedPos_Y(0) PickedPos_Y(3) /* YMin, YMax */
PickedPos_X(0) PickedPos_X(3) /* XMin, XMax */
PickedPos_Z(0) PickedPos_Z(3) /* ZMin, ZMax */
};
Vector3 delta; Vector3 delta;
float dist, offset, size; float dist, offset, size;
Vector3 coords[4]; Vector3 coords[4];
@ -82,30 +106,7 @@ void PickedPosRenderer_Update(struct PickedPos* selected) {
Vector3_Add1(&coords[1], &coords[0], size); Vector3_Add1(&coords[1], &coords[0], size);
Vector3_Add1(&coords[3], &selected->Max, offset); Vector3_Add1(&coords[3], &selected->Max, offset);
Vector3_Add1(&coords[2], &coords[3], -size); Vector3_Add1(&coords[2], &coords[3], -size);
#define PickedPos_Y(y)\
0,y,1, 0,y,2, 1,y,2, 1,y,1,\
3,y,1, 3,y,2, 2,y,2, 2,y,1,\
0,y,0, 0,y,1, 3,y,1, 3,y,0,\
0,y,3, 0,y,2, 3,y,2, 3,y,3,
#define PickedPos_X(x)\
x,1,0, x,2,0, x,2,1, x,1,1,\
x,1,3, x,2,3, x,2,2, x,1,2,\
x,0,0, x,1,0, x,1,3, x,0,3,\
x,3,0, x,2,0, x,2,3, x,3,3,
#define PickedPos_Z(z)\
0,1,z, 0,2,z, 1,2,z, 1,1,z,\
3,1,z, 3,2,z, 2,2,z, 2,1,z,\
0,0,z, 0,1,z, 3,1,z, 3,0,z,\
0,3,z, 0,2,z, 3,2,z, 3,3,z,
static uint8_t indices[288] = {
PickedPos_Y(0) PickedPos_Y(3) /* YMin, YMax */
PickedPos_X(0) PickedPos_X(3) /* XMin, XMax */
PickedPos_Z(0) PickedPos_Z(3) /* ZMin, ZMax */
};
PackedCol col = PACKEDCOL_CONST(0, 0, 0, 102); PackedCol col = PACKEDCOL_CONST(0, 0, 0, 102);
VertexP3fC4b* ptr = pickedPos_vertices; VertexP3fC4b* ptr = pickedPos_vertices;
int i; int i;

View File

@ -59,9 +59,10 @@ static float RayTracer_Div(float a, float b) {
} }
void RayTracer_SetVectors(struct RayTracer* t, Vector3 origin, Vector3 dir) { void RayTracer_SetVectors(struct RayTracer* t, Vector3 origin, Vector3 dir) {
Vector3I start, cellBoundary;
t->Origin = origin; t->Dir = dir; t->Origin = origin; t->Dir = dir;
/* Rounds the position's X, Y and Z down to the nearest integer values. */ /* Rounds the position's X, Y and Z down to the nearest integer values. */
Vector3I start;
Vector3I_Floor(&start, &origin); Vector3I_Floor(&start, &origin);
/* The cell in which the ray starts. */ /* The cell in which the ray starts. */
t->X = start.X; t->Y = start.Y; t->Z = start.Z; t->X = start.X; t->Y = start.Y; t->Z = start.Z;
@ -71,7 +72,6 @@ void RayTracer_SetVectors(struct RayTracer* t, Vector3 origin, Vector3 dir) {
/* Calculate cell boundaries. When the step (i.e. direction sign) is positive, /* Calculate cell boundaries. When the step (i.e. direction sign) is positive,
the next boundary is AFTER our current position, meaning that we have to add 1. the next boundary is AFTER our current position, meaning that we have to add 1.
Otherwise, it is BEFORE our current position, in which case we add nothing. */ Otherwise, it is BEFORE our current position, in which case we add nothing. */
Vector3I cellBoundary;
cellBoundary.X = start.X + (t->step.X > 0 ? 1 : 0); cellBoundary.X = start.X + (t->step.X > 0 ? 1 : 0);
cellBoundary.Y = start.Y + (t->step.Y > 0 ? 1 : 0); cellBoundary.Y = start.Y + (t->step.Y > 0 ? 1 : 0);
cellBoundary.Z = start.Z + (t->step.Z > 0 ? 1 : 0); cellBoundary.Z = start.Z + (t->step.Z > 0 ? 1 : 0);
@ -186,7 +186,8 @@ static bool Picking_ClipBlock(struct PickedPos* pos) {
Vector3 scaledDir, intersect; Vector3 scaledDir, intersect;
Vector3_Mul1(&scaledDir, &tracer.Dir, t0); /* scaledDir = dir * t0 */ Vector3_Mul1(&scaledDir, &tracer.Dir, t0); /* scaledDir = dir * t0 */
Vector3_Add(&intersect, &tracer.Origin, &scaledDir); /* intersect = origin + scaledDir */ Vector3_Add(&intersect, &tracer.Origin, &scaledDir); /* intersect = origin + scaledDir */
/* Only pick the block if the block is precisely within reach distance. */
/* Only pick the block if the block is precisely within reach distance. */
float lenSq = Vector3_LengthSquared(&scaledDir); float lenSq = Vector3_LengthSquared(&scaledDir);
float reach = LocalPlayer_Instance.ReachDistance; float reach = LocalPlayer_Instance.ReachDistance;

View File

@ -849,9 +849,9 @@ static void ChatScreen_UpdateChatYOffset(struct ChatScreen* s, bool force) {
} }
static void ChatElem_Recreate(struct TextGroupWidget* group, char code) { static void ChatElem_Recreate(struct TextGroupWidget* group, char code) {
int i, j;
char lineBuffer[TEXTGROUPWIDGET_LEN]; char lineBuffer[TEXTGROUPWIDGET_LEN];
String line = String_FromArray(lineBuffer); String line = String_FromArray(lineBuffer);
int i, j;
for (i = 0; i < group->LinesCount; i++) { for (i = 0; i < group->LinesCount; i++) {
TextGroupWidget_GetText(group, i, &line); TextGroupWidget_GetText(group, i, &line);
@ -1465,13 +1465,14 @@ static bool DisconnectScreen_KeyPress(void* s, char keyChar) { return true; }
static bool DisconnectScreen_KeyUp(void* s, Key key) { return true; } static bool DisconnectScreen_KeyUp(void* s, Key key) { return true; }
static bool DisconnectScreen_MouseDown(void* screen, int x, int y, MouseButton btn) { static bool DisconnectScreen_MouseDown(void* screen, int x, int y, MouseButton btn) {
struct DisconnectScreen* s = screen; char titleBuffer[STRING_SIZE];
struct ButtonWidget* w = &s->Reconnect; String title = String_FromArray(titleBuffer);
if (btn != MouseButton_Left) return true;
if (!w->Disabled && Widget_Contains(w, x, y)) { struct DisconnectScreen* s = screen;
char titleBuffer[STRING_SIZE]; struct ButtonWidget* w = &s->Reconnect;
String title = String_FromArray(titleBuffer);
if (btn != MouseButton_Left) return true;
if (!w->Disabled && Widget_Contains(w, x, y)) {
String_Format2(&title, "Connecting to %s:%i..", &Game_IPAddress, &Game_Port); String_Format2(&title, "Connecting to %s:%i..", &Game_IPAddress, &Game_Port);
Gui_FreeActive(); Gui_FreeActive();
@ -1483,7 +1484,8 @@ static bool DisconnectScreen_MouseDown(void* screen, int x, int y, MouseButton b
static bool DisconnectScreen_MouseMove(void* screen, int x, int y) { static bool DisconnectScreen_MouseMove(void* screen, int x, int y) {
struct DisconnectScreen* s = screen; struct DisconnectScreen* s = screen;
struct ButtonWidget* w = &s->Reconnect; struct ButtonWidget* w = &s->Reconnect;
w->Active = !w->Disabled && Widget_Contains(w, x, y); w->Active = !w->Disabled && Widget_Contains(w, x, y);
return true; return true;
} }
@ -1498,7 +1500,10 @@ struct ScreenVTABLE DisconnectScreen_VTABLE = {
DisconnectScreen_OnResize, DisconnectScreen_ContextLost, DisconnectScreen_ContextRecreated DisconnectScreen_OnResize, DisconnectScreen_ContextLost, DisconnectScreen_ContextRecreated
}; };
struct Screen* DisconnectScreen_MakeInstance(const String* title, const String* message) { struct Screen* DisconnectScreen_MakeInstance(const String* title, const String* message) {
static String kick = String_FromConst("Kicked ");
static String ban = String_FromConst("Banned ");
struct DisconnectScreen* s = &DisconnectScreen_Instance; struct DisconnectScreen* s = &DisconnectScreen_Instance;
s->HandlesAllInput = true; s->HandlesAllInput = true;
s->BlocksWorld = true; s->BlocksWorld = true;
s->HidesHUD = true; s->HidesHUD = true;
@ -1514,12 +1519,8 @@ struct Screen* DisconnectScreen_MakeInstance(const String* title, const String*
char whyBuffer[STRING_SIZE]; char whyBuffer[STRING_SIZE];
String why = String_FromArray(whyBuffer); String why = String_FromArray(whyBuffer);
String_AppendColorless(&why, message); String_AppendColorless(&why, message);
String kick = String_FromConst("Kicked "); s->CanReconnect = !(String_CaselessStarts(&why, &kick) || String_CaselessStarts(&why, &ban));
String ban = String_FromConst("Banned ");
s->CanReconnect =
!(String_CaselessStarts(&why, &kick) || String_CaselessStarts(&why, &ban));
s->VTABLE = &DisconnectScreen_VTABLE; s->VTABLE = &DisconnectScreen_VTABLE;
return (struct Screen*)s; return (struct Screen*)s;
} }

View File

@ -3,6 +3,9 @@
#include "Funcs.h" #include "Funcs.h"
#include "Constants.h" #include "Constants.h"
const Vector3 Vector3_Zero = { 0.0f, 0.0f, 0.0f };
const Vector3 Vector3_One = { 1.0f, 1.0f, 1.0f };
Vector3 Vector3_Create1(float value) { Vector3 Vector3_Create1(float value) {
Vector3 v; v.X = value; v.Y = value; v.Z = value; return v; Vector3 v; v.X = value; v.Y = value; v.Z = value; return v;
} }

View File

@ -20,12 +20,12 @@ Vector3 Vector3_BigPos(void);
float Vector3_LengthSquared(const Vector3* v); float Vector3_LengthSquared(const Vector3* v);
#define VECTOR3_CONST(x, y, z) { x, y, z }; #define VECTOR3_CONST(x, y, z) { x, y, z };
#define Vector3_Zero VECTOR3_CONST(0.0f, 0.0f, 0.0f) extern const Vector3 Vector3_Zero;
#define Vector3_One VECTOR3_CONST(1.0f, 1.0f, 1.0f) extern const Vector3 Vector3_One;
void Vector3_Add(Vector3* result, Vector3* a, Vector3* b); void Vector3_Add(Vector3* result, Vector3* a, Vector3* b);
void Vector3_Add1(Vector3* result, Vector3* a, float b); void Vector3_Add1(Vector3* result, Vector3* a, float b);
void Vector3_Sub(Vector3* result, Vector3* a, Vector3* b); void Vector3_Sub(Vector3* result, Vector3* a, Vector3* b);
void Vector3_Mul1(Vector3* result, Vector3* a, float scale); void Vector3_Mul1(Vector3* result, Vector3* a, float scale);
void Vector3_Mul3(Vector3* result, Vector3* a, Vector3* scale); void Vector3_Mul3(Vector3* result, Vector3* a, Vector3* scale);
void Vector3_Negate(Vector3* result, Vector3* a); void Vector3_Negate(Vector3* result, Vector3* a);

View File

@ -2488,7 +2488,7 @@ void TextGroupWidget_SetText(struct TextGroupWidget* w, int index, const String*
text.length = min(text.length, TEXTGROUPWIDGET_LEN); text.length = min(text.length, TEXTGROUPWIDGET_LEN);
Mem_Copy(TextGroupWidget_LineBuffer(w, index), text.buffer, text.length); Mem_Copy(TextGroupWidget_LineBuffer(w, index), text.buffer, text.length);
w->LineLengths[index] = text.length; w->LineLengths[index] = (uint8_t)text.length;
if (!Drawer2D_IsEmptyText(&text)) { if (!Drawer2D_IsEmptyText(&text)) {
DrawTextArgs_Make(&args, &text, &w->Font, true); DrawTextArgs_Make(&args, &text, &w->Font, true);