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) {
if (draw == DRAW_OPAQUE && Block_Collide[block] != COLLIDE_SOLID) {
draw = DRAW_TRANSPARENT;
}
if (draw == DRAW_OPAQUE && Block_Collide[block] != COLLIDE_SOLID) draw = DRAW_TRANSPARENT;
Block_Draw[block] = draw;
Block_RecalcIsLiquid(block);
Vector3 zero = Vector3_Zero; Vector3 one = Vector3_One;
Block_FullOpaque[block] = draw == DRAW_OPAQUE
&& Vector3_Equals(&Block_MinBB[block], &zero)
&& Vector3_Equals(&Block_MaxBB[block], &one);
&& Vector3_Equals(&Block_MinBB[block], &Vector3_Zero)
&& 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_MaxBB[block] = Vector3_Create3(13.5f / 16.0f, 1.0f, 13.5f / 16.0f);
} else {
Vector3 zero = Vector3_Zero; Block_MinBB[block] = zero;
Vector3 one = Vector3_One; Block_MaxBB[block] = one;
Block_MinBB[block] = Vector3_Zero;
Block_MaxBB[block] = Vector3_One;
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) {
BlockID chunk[EXTCHUNK_SIZE_3]; Builder_Chunk = chunk;
uint8_t counts[CHUNK_SIZE_3 * FACE_COUNT]; Builder_Counts = counts;
int bitFlags[EXTCHUNK_SIZE_3]; Builder_BitFlags = bitFlags;
BlockID chunk[EXTCHUNK_SIZE_3];
uint8_t counts[CHUNK_SIZE_3 * FACE_COUNT];
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);
Mem_Set(chunk, BLOCK_AIR, EXTCHUNK_SIZE_3 * sizeof(BlockID));
bool allSolid;
Builder_ReadChunkData(x1, y1, z1, allAir, &allSolid);
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);
Mem_Set(counts, 1, CHUNK_SIZE_3 * FACE_COUNT);
int xMax = min(World_Width, x1 + CHUNK_SIZE);
int yMax = min(World_Height, y1 + CHUNK_SIZE);
int zMax = min(World_Length, z1 + CHUNK_SIZE);
xMax = min(World_Width, x1 + CHUNK_SIZE);
yMax = min(World_Height, y1 + CHUNK_SIZE);
zMax = min(World_Length, z1 + CHUNK_SIZE);
Builder_ChunkEndX = xMax; Builder_ChunkEndZ = zMax;
Builder_Stretch(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 (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++) {
Builder_Block = chunk[cIndex];
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_ChunkIndex = cIndex;
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) {
int x = info->CentreX - 8, y = info->CentreY - 8, z = info->CentreZ - 8;
bool allAir = false, hasMesh;
int totalVerts;
hasMesh = Builder_BuildChunk(x, y, z, &allAir);
info->AllAir = allAir;
if (!hasMesh) return;
int totalVerts = Builder_TotalVerticesCount();
totalVerts = Builder_TotalVerticesCount();
if (!totalVerts) return;
#ifndef CC_BUILD_GL11
/* 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) {
int i, vertsCount = Builder_TotalVerticesCount();
int i, j, vertsCount = Builder_TotalVerticesCount();
if (vertsCount > Builder_VerticesElems) {
Mem_Free(Builder_Vertices);
/* 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;
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[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) {
TextureLoc texLoc;
int offset;
TextureLoc texLoc;
struct Builder1DPart* part;
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) {
Builder_FullBright = Block_FullBright[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);
return;
}
int count_XMin = Builder_Counts[index + FACE_XMIN];
int count_XMax = Builder_Counts[index + FACE_XMAX];
int count_ZMin = Builder_Counts[index + FACE_ZMIN];
int count_ZMax = Builder_Counts[index + FACE_ZMAX];
int count_YMin = Builder_Counts[index + FACE_YMIN];
int count_YMax = Builder_Counts[index + FACE_YMAX];
count_XMin = Builder_Counts[index + FACE_XMIN];
count_XMax = Builder_Counts[index + FACE_XMAX];
count_ZMin = Builder_Counts[index + FACE_ZMIN];
count_ZMax = Builder_Counts[index + FACE_ZMAX];
count_YMin = Builder_Counts[index + FACE_YMIN];
count_YMax = Builder_Counts[index + FACE_YMAX];
if (count_XMin == 0 && count_XMax == 0 && count_ZMin == 0 &&
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) {
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) {
Builder_FullBright = Block_FullBright[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);
return;
}
int count_XMin = Builder_Counts[index + FACE_XMIN];
int count_XMax = Builder_Counts[index + FACE_XMAX];
int count_ZMin = Builder_Counts[index + FACE_ZMIN];
int count_ZMax = Builder_Counts[index + FACE_ZMAX];
int count_YMin = Builder_Counts[index + FACE_YMIN];
int count_YMax = Builder_Counts[index + FACE_YMAX];
count_XMin = Builder_Counts[index + FACE_XMIN];
count_XMax = Builder_Counts[index + FACE_XMAX];
count_ZMin = Builder_Counts[index + FACE_ZMIN];
count_ZMax = Builder_Counts[index + FACE_ZMAX];
count_YMin = Builder_Counts[index + FACE_YMIN];
count_YMax = Builder_Counts[index + FACE_YMAX];
if (count_XMin == 0 && count_XMax == 0 && count_ZMin == 0 &&
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];
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_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 {
GZIP_STATE_HEADER1, GZIP_STATE_HEADER2, GZIP_STATE_COMPRESSIONMETHOD, GZIP_STATE_FLAGS,
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) {
@ -134,7 +134,7 @@ enum INFLATE_STATE_ {
INFLATE_STATE_DYNAMIC_LITSDISTSREPEAT, INFLATE_STATE_COMPRESSED_LIT,
INFLATE_STATE_COMPRESSED_LITREPEAT, INFLATE_STATE_COMPRESSED_DIST,
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 */

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) {
float value;
float value, maxScale;
if (!Convert_TryParseFloat(scale, &value)) return;
float maxScale = e->Model->MaxScale;
maxScale = e->Model->MaxScale;
Math_Clamp(value, 0.01f, maxScale);
e->ModelScale = Vector3_Create1(value);
}
@ -236,9 +236,10 @@ void Entities_Tick(struct ScheduledTask* task) {
}
void Entities_RenderModels(double delta, float t) {
int i;
Gfx_SetTexturing(true);
Gfx_SetAlphaTest(true);
int i;
for (i = 0; i < ENTITIES_MAX_COUNT; i++) {
if (!Entities_List[i]) continue;
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) {
if (Entities_NameMode == NAME_MODE_NONE) return;
struct LocalPlayer* p = &LocalPlayer_Instance;
bool hadFog;
int i;
if (Entities_NameMode == NAME_MODE_NONE) return;
entities_closestId = Entities_GetCloset(&p->Base);
if (!p->Hacks.CanSeeAllNames || Entities_NameMode != NAME_MODE_ALL) return;
Gfx_SetTexturing(true);
Gfx_SetAlphaTest(true);
bool hadFog = Gfx_GetFog();
hadFog = Gfx_GetFog();
if (hadFog) Gfx_SetFog(false);
int i;
for (i = 0; i < ENTITIES_MAX_COUNT; i++) {
if (!Entities_List[i]) continue;
if (i != entities_closestId || i == ENTITIES_SELF_ID) {
@ -273,18 +276,20 @@ void Entities_RenderNames(double delta) {
}
void Entities_RenderHoveredNames(double delta) {
if (Entities_NameMode == NAME_MODE_NONE) return;
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;
Gfx_SetTexturing(true);
Gfx_SetAlphaTest(true);
Gfx_SetDepthTest(false);
bool hadFog = Gfx_GetFog();
hadFog = Gfx_GetFog();
if (hadFog) Gfx_SetFog(false);
int i;
for (i = 0; i < ENTITIES_MAX_COUNT; i++) {
if (!Entities_List[i]) continue;
if ((i == entities_closestId || allNames) && i != ENTITIES_SELF_ID) {
@ -366,12 +371,13 @@ EntityID Entities_GetCloset(struct Entity* src) {
float closestDist = MATH_POS_INF;
EntityID targetId = ENTITIES_SELF_ID;
float t0, t1;
int i;
for (i = 0; i < ENTITIES_SELF_ID; i++) { /* because we don't want to pick against local player */
struct Entity* entity = Entities_List[i];
if (!entity) continue;
float t0, t1;
if (Intersection_RayIntersectsRotatedBox(eyePos, dir, entity, &t0, &t1) && t0 < closestDist) {
closestDist = t0;
targetId = (EntityID)i;
@ -684,10 +690,16 @@ static void Player_EnsurePow2(struct Player* player, Bitmap* bmp) {
static void Player_CheckSkin(struct Player* p) {
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) {
struct Player* first = Player_FirstOtherWithSameSkinAndFetchedSkin(p);
first = Player_FirstOtherWithSameSkinAndFetchedSkin(p);
if (!first) {
AsyncDownloader_GetSkin(&skin, &skin);
} else {
@ -695,17 +707,13 @@ static void Player_CheckSkin(struct Player* p) {
}
p->FetchedSkin = true;
}
struct AsyncRequest item;
if (!AsyncDownloader_Get(&skin, &item)) 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);
ReturnCode res = Png_Decode(&bmp, &mem);
if (res) {
if ((res = Png_Decode(&bmp, &mem))) {
url = String_FromRawArray(item.URL);
Chat_LogError2(res, "decoding", &url);
Mem_Free(bmp.Scan0); return;
}
@ -729,7 +737,8 @@ static void Player_CheckSkin(struct Player* p) {
static void Player_Despawn(struct Entity* e) {
struct Player* player = (struct Player*)e;
struct Player* first = Player_FirstOtherWithSameSkin(player);
struct Player* first = Player_FirstOtherWithSameSkin(player);
if (!first) {
Gfx_DeleteTexture(&e->TextureId);
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) {
String p_name = String_ClearedArray(p->DisplayNameRaw);
String_AppendString(&p_name, name);
String p_skin = String_ClearedArray(p->Base.SkinNameRaw);
String_AppendString(&p_name, name);
String_AppendString(&p_skin, skin);
}
@ -809,7 +819,7 @@ static void LocalPlayer_HandleInput(float* xMoving, float* zMoving) {
hacks->FlyingDown = KeyBind_IsPressed(KeyBind_FlyDown);
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);
}
}
@ -837,7 +847,7 @@ void LocalPlayer_Tick(struct Entity* e, double delta) {
/* Immediate stop in noclip mode */
if (!hacks->NoclipSlide && (hacks->Noclip && xMoving == 0 && zMoving == 0)) {
Vector3 zero = Vector3_Zero; e->Velocity = zero;
e->Velocity = Vector3_Zero;
}
PhysicsComp_UpdateVelocityState(&p->Physics);
@ -889,7 +899,7 @@ static void LocalPlayer_Init_(void) {
static void LocalPlayer_Reset(void) {
struct LocalPlayer* p = &LocalPlayer_Instance;
p->ReachDistance = 5.0f;
Vector3 zero = Vector3_Zero; p->Base.Velocity = zero;
p->Base.Velocity = Vector3_Zero;
p->Physics.JumpVel = 0.42f;
p->Physics.ServerJumpVel = 0.42f;
/* p->Base.Health = 20; TODO: survival mode stuff */
@ -897,9 +907,8 @@ static void LocalPlayer_Reset(void) {
static void LocalPlayer_OnNewMap(void) {
struct LocalPlayer* p = &LocalPlayer_Instance;
Vector3 zero = Vector3_Zero;
p->Base.Velocity = zero;
p->OldVelocity = zero;
p->Base.Velocity = Vector3_Zero;
p->OldVelocity = Vector3_Zero;
p->_WarnedRespawn = false;
p->_WarnedFly = false;
@ -961,7 +970,7 @@ static void LocalPlayer_DoRespawn(void) {
spawn.Y += 2.0f / 16.0f;
struct LocationUpdate update; LocationUpdate_MakePosAndOri(&update, spawn, p->SpawnRotY, p->SpawnHeadX, 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 */
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) {
struct NetPlayer* p = (struct NetPlayer*)e;
float distance;
int threshold;
if (!p->ShouldRender) return;
float dist = Model_RenderDistance(e);
int threshold = Entities_NameMode == NAME_MODE_ALL_UNSCALED ? 8192 * 8192 : 32 * 32;
if (dist <= (float)threshold) Player_DrawName((struct Player*)p);
distance = Model_RenderDistance(e);
threshold = Entities_NameMode == NAME_MODE_ALL_UNSCALED ? 8192 * 8192 : 32 * 32;
if (distance <= (float)threshold) Player_DrawName((struct Player*)p);
}
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) {
Vector3I bbMin; Vector3I_Floor(&bbMin, &adjFinalBB->Min);
Vector3I bbMax; Vector3I_Floor(&bbMax, &adjFinalBB->Max);
Vector3I bbMin, bbMax;
BlockID block;
struct AABB blockBB;
Vector3 v;
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 (z = bbMin.Z; z <= bbMax.Z; z++) { v.Z = (float)z;
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 */
void Collisions_MoveAndWallSlide(struct CollisionsComp* comp) {
Vector3 zero = Vector3_Zero;
struct Entity* entity = comp->Entity;
if (Vector3_Equals(&entity->Velocity, &zero)) return;
if (Vector3_Equals(&entity->Velocity, &Vector3_Zero)) return;
struct AABB 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; }
void PhysicsComp_UpdateVelocityState(struct PhysicsComp* comp) {
struct Entity* entity = comp->Entity;
struct Entity* entity = comp->Entity;
struct HacksComp* hacks = comp->Hacks;
if (hacks->Floating) {

View File

@ -127,12 +127,16 @@ GfxResourceID clouds_vb, clouds_tex;
int clouds_vertices;
void EnvRenderer_RenderClouds(double deltaTime) {
double time;
float offset;
struct Matrix m;
if (!clouds_vb || Env_CloudsHeight < -2000) return;
double time = Game_Accumulator;
float offset = (float)(time / 2048.0f * 0.6f * Env_CloudsSpeed);
time = Game_Accumulator;
offset = (float)(time / 2048.0f * 0.6f * Env_CloudsSpeed);
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_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) {
int extent;
int x1, z1, x2, z2;
VertexP3fT2fC4b v[ENV_SMALL_VERTICES];
VertexP3fT2fC4b* ptr;
if (!World_Blocks || Gfx_LostContext) return;
Gfx_DeleteVb(&clouds_vb);
if (EnvRenderer_Minimal) return;
int extent = Utils_AdjViewDist(Game_ViewDistance);
int x1 = -extent, x2 = World_Width + extent;
int z1 = -extent, z2 = World_Length + extent;
extent = Utils_AdjViewDist(Game_ViewDistance);
x1 = -extent; x2 = World_Width + extent;
z1 = -extent; z2 = World_Length + extent;
clouds_vertices = EnvRenderer_Vertices(x2 - x1, z2 - z1);
VertexP3fT2fC4b v[ENV_SMALL_VERTICES];
VertexP3fT2fC4b* ptr = v;
ptr = v;
if (clouds_vertices > ENV_SMALL_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) {
int extent, height;
int x1, z1, x2, z2;
VertexP3fC4b v[ENV_SMALL_VERTICES];
VertexP3fC4b* ptr;
if (!World_Blocks || Gfx_LostContext) return;
Gfx_DeleteVb(&sky_vb);
if (EnvRenderer_Minimal) return;
int extent = Utils_AdjViewDist(Game_ViewDistance);
int x1 = -extent, x2 = World_Width + extent;
int z1 = -extent, z2 = World_Length + extent;
extent = Utils_AdjViewDist(Game_ViewDistance);
x1 = -extent; x2 = World_Width + extent;
z1 = -extent; z2 = World_Length + extent;
sky_vertices = EnvRenderer_Vertices(x2 - x1, z2 - z1);
VertexP3fC4b v[ENV_SMALL_VERTICES];
VertexP3fC4b* ptr = v;
ptr = v;
if (sky_vertices > ENV_SMALL_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);
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);
/* Rotate around camera */
Vector3 pos = Camera_CurrentPos, zero = Vector3_Zero;
Camera_CurrentPos = zero;
Vector3 pos = Camera_CurrentPos;
Camera_CurrentPos = Vector3_Zero;
Camera_Active->GetView(&view); Matrix_MulBy(&m, &view);
Camera_CurrentPos = pos;
@ -364,7 +378,8 @@ static void EnvRenderer_InitWeatherHeightmap(void) {
#define EnvRenderer_RainCalcBody(get_block)\
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)) {\
Weather_Heightmap[hIndex] = 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) {
int i = World_Pack(x, maxY, z), y;
uint8_t draw;
#ifndef EXTENDED_BLOCKS
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) {
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 hIndex, height;
int y;
if (x < 0 || z < 0 || x >= World_Width || z >= World_Length) return (float)Env_EdgeHeight;
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;
}
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 nowBlock = !(Block_Draw[newBlock] == DRAW_GAS || Block_Draw[newBlock] == DRAW_SPRITE);
int hIndex, height;
if (didBlock == nowBlock) return;
int hIndex = Weather_Pack(x, z);
int height = Weather_Heightmap[hIndex];
hIndex = Weather_Pack(x, z);
height = Weather_Heightmap[hIndex];
/* Two cases can be skipped here: */
/* a) rain height was not calculated to begin with (height is short.MaxValue) */
/* b) changed y is below current calculated rain height */
@ -666,6 +684,10 @@ static void EnvRenderer_UpdateMapSides(void) {
int y, y1, y2;
int i;
VertexP3fT2fC4b v[ENV_SMALL_VERTICES];
VertexP3fT2fC4b* ptr;
VertexP3fT2fC4b* cur;
if (!World_Blocks || Gfx_LostContext) return;
Gfx_DeleteVb(&sides_vb);
block = Env_SidesBlock;
@ -675,7 +697,7 @@ static void EnvRenderer_UpdateMapSides(void) {
sides_vertices = 0;
for (i = 0; i < 4; i++) {
Rect2D r = rects[i];
r = rects[i];
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_Length, Math_AbsI(y)); /* XQuads */
VertexP3fT2fC4b v[ENV_SMALL_VERTICES];
VertexP3fT2fC4b* ptr = v;
ptr = v;
if (sides_vertices > ENV_SMALL_VERTICES) {
ptr = Mem_Alloc(sides_vertices, sizeof(VertexP3fT2fC4b), "temp sides vertices");
}
VertexP3fT2fC4b* cur = ptr;
cur = ptr;
sides_fullBright = Block_FullBright[block];
col = sides_fullBright ? white : Env_ShadowCol;
@ -722,6 +743,10 @@ static void EnvRenderer_UpdateMapEdges(void) {
float y;
int i;
VertexP3fT2fC4b v[ENV_SMALL_VERTICES];
VertexP3fT2fC4b* ptr;
VertexP3fT2fC4b* cur;
if (!World_Blocks || Gfx_LostContext) return;
Gfx_DeleteVb(&edges_vb);
block = Env_EdgeBlock;
@ -735,12 +760,11 @@ static void EnvRenderer_UpdateMapEdges(void) {
edges_vertices += EnvRenderer_Vertices(r.Width, r.Height); /* YPlanes outside */
}
VertexP3fT2fC4b v[ENV_SMALL_VERTICES];
VertexP3fT2fC4b* ptr = v;
ptr = v;
if (edges_vertices > ENV_SMALL_VERTICES) {
ptr = Mem_Alloc(edges_vertices, sizeof(VertexP3fT2fC4b), "temp edge vertices");
}
VertexP3fT2fC4b* cur = ptr;
cur = ptr;
edges_fullBright = Block_FullBright[block];
col = edges_fullBright ? white : Env_SunCol;

View File

@ -25,7 +25,7 @@ bool Gfx_GetFog(void) { return gfx_fogEnabled; }
*--------------------------------------------------------Direct3D9--------------------------------------------------------*
*#########################################################################################################################*/
#ifdef CC_BUILD_D3D9
//#define D3D_DISABLE_9EX causes compile errors
/*#define D3D_DISABLE_9EX causes compile errors*/
#include <d3d9.h>
#include <d3d9caps.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) {
uint8_t* prev = bmp->Scan0;
uint8_t* cur;
Bitmap mipmap;
int lvls = GfxCommon_MipmapsLevels(bmp->Width, 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 (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);
Bitmap mipmap;
Bitmap_Create(&mipmap, width, height, cur);
if (partial) {
D3D9_SetTexturePartData(texture, x, y, &mipmap, lvl);
@ -786,7 +788,6 @@ static void GL_CheckVboSupport(void) {
glGenBuffers = (FUNC_GLGENBUFFERS)GLContext_GetAddress("glGenBuffers");
glBufferData = (FUNC_GLBUFFERDATA)GLContext_GetAddress("glBufferData");
glBufferSubData = (FUNC_GLBUFFERSUBDATA)GLContext_GetAddress("glBufferSubData");
return;
} else if (String_CaselessContains(&extensions, &vboExt)) {
glBindBuffer = (FUNC_GLBINDBUFFER)GLContext_GetAddress("glBindBufferARB");
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) {
uint8_t* prev = bmp->Scan0;
uint8_t* cur;
int lvls = GfxCommon_MipmapsLevels(bmp->Width, 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 (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);
if (partial) {
@ -918,9 +921,13 @@ void Gfx_SetFog(bool enabled) {
}
void Gfx_SetFogCol(PackedCol col) {
float rgba[4];
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;
}
@ -939,6 +946,7 @@ void Gfx_SetFogEnd(float value) {
void Gfx_SetFogMode(int mode) {
static GLint modes[3] = { GL_LINEAR, GL_EXP, GL_EXP2 };
if (mode == gl_lastFogMode) return;
glFogi(GL_FOG_MODE, modes[mode]);
gl_lastFogMode = mode;
}
@ -989,22 +997,22 @@ static GfxResourceID GL_GenAndBind(GLenum target) {
GfxResourceID Gfx_CreateDynamicVb(int vertexFormat, int maxVertices) {
GfxResourceID id = GL_GenAndBind(GL_ARRAY_BUFFER);
uint32_t sizeInBytes = maxVertices * Gfx_strideSizes[vertexFormat];
glBufferData(GL_ARRAY_BUFFER, (void*)sizeInBytes, NULL, GL_DYNAMIC_DRAW);
uint32_t size = maxVertices * Gfx_strideSizes[vertexFormat];
glBufferData(GL_ARRAY_BUFFER, (void*)size, NULL, GL_DYNAMIC_DRAW);
return id;
}
GfxResourceID Gfx_CreateVb(void* vertices, int vertexFormat, int count) {
GfxResourceID id = GL_GenAndBind(GL_ARRAY_BUFFER);
uint32_t sizeInBytes = count * Gfx_strideSizes[vertexFormat];
glBufferData(GL_ARRAY_BUFFER, (void*)sizeInBytes, vertices, GL_STATIC_DRAW);
uint32_t size = count * Gfx_strideSizes[vertexFormat];
glBufferData(GL_ARRAY_BUFFER, (void*)size, vertices, GL_STATIC_DRAW);
return id;
}
GfxResourceID Gfx_CreateIb(void* indices, int indicesCount) {
GfxResourceID id = GL_GenAndBind(GL_ELEMENT_ARRAY_BUFFER);
uint32_t sizeInBytes = indicesCount * 2;
glBufferData(GL_ELEMENT_ARRAY_BUFFER, (void*)sizeInBytes, indices, GL_STATIC_DRAW);
uint32_t size = indicesCount * 2;
glBufferData(GL_ELEMENT_ARRAY_BUFFER, (void*)size, indices, GL_STATIC_DRAW);
return id;
}
@ -1026,16 +1034,17 @@ void Gfx_DeleteIb(GfxResourceID* ib) {
GfxResourceID Gfx_CreateDynamicVb(int vertexFormat, int maxVertices) { return gl_DYNAMICLISTID; }
GfxResourceID Gfx_CreateVb(void* vertices, int vertexFormat, int count) {
/* We need to setup client state properly when building the list */
int curFormat = gfx_batchFormat;
int curFormat = gfx_batchFormat, stride;
Gfx_SetBatchFormat(vertexFormat);
GfxResourceID list = glGenLists(1);
glNewList(list, GL_COMPILE);
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];
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);
glColorPointer(4, GL_UNSIGNED_BYTE, stride, (void*)((uint8_t*)vertices + 12));
if (vertexFormat == VERTEX_FORMAT_P3FT2FC4B) {
@ -1105,9 +1114,9 @@ void Gfx_SetBatchFormat(int vertexFormat) {
#ifndef CC_BUILD_GL11
void Gfx_SetDynamicVbData(GfxResourceID vb, void* vertices, int vCount) {
uint32_t size = vCount * gfx_batchStride;
glBindBuffer(GL_ARRAY_BUFFER, vb);
uint32_t sizeInBytes = vCount * gfx_batchStride;
glBufferSubData(GL_ARRAY_BUFFER, NULL, (void*)sizeInBytes, vertices);
glBufferSubData(GL_ARRAY_BUFFER, NULL, (void*)size, vertices);
}
void Gfx_DrawVb_Lines(int verticesCount) {
@ -1150,8 +1159,9 @@ static void GL_V24(VertexP3fT2fC4b v) {
}
static void GL_DrawDynamicTriangles(int verticesCount, int startVertex) {
glBegin(GL_TRIANGLES);
int i;
glBegin(GL_TRIANGLES);
if (gfx_batchFormat == VERTEX_FORMAT_P3FT2FC4B) {
VertexP3fT2fC4b* ptr = (VertexP3fT2fC4b*)gl_dynamicListData;
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) {
glBegin(GL_LINES);
int i;
glBegin(GL_LINES);
if (gfx_batchFormat == VERTEX_FORMAT_P3FT2FC4B) {
VertexP3fT2fC4b* ptr = (VertexP3fT2fC4b*)gl_dynamicListData;
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;
void Gfx_SetMatrixMode(int matrixType) {
static GLenum modes[3] = { GL_PROJECTION, GL_MODELVIEW, GL_TEXTURE };
if (matrixType == gl_lastMatrixType) return;
gl_lastMatrixType = matrixType;
static GLenum matrixModes[3] = { GL_PROJECTION, GL_MODELVIEW, GL_TEXTURE };
glMatrixMode(matrixModes[matrixType]);
glMatrixMode(modes[matrixType]);
}
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; }
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);
ReturnCode res = Png_Encode(&bmp, output, GL_SelectRow);
res = Png_Encode(&bmp, output, GL_SelectRow);
Mem_Free(bmp.Scan0);
return res;
}
bool nv_mem;
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);
String_AppendConst(&Gfx_ApiInfo[0],"-- Using OpenGL --");
String_Format1(&Gfx_ApiInfo[1], "Vendor: %c", glGetString(GL_VENDOR));
String_Format1(&Gfx_ApiInfo[2], "Renderer: %c", glGetString(GL_RENDERER));
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_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) {
if (!nv_mem) return;
int totalKb = 0, curKb = 0;
float total, cur;
if (!nv_mem) return;
glGetIntegerv(0x9048, &totalKb);
glGetIntegerv(0x9049, &curKb);
if (totalKb <= 0 || curKb <= 0) return;
total = totalKb / 1024.0f; cur = curKb / 1024.0f;
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);
}
bool Gfx_WarnIfNecessary(void) {
static String intel = String_FromConst("Intel");
String renderer = String_FromReadonly(glGetString(GL_RENDERER));
#ifdef CC_BUILD_GL11
Chat_AddRaw("&cYou are using the very outdated OpenGL backend.");
Chat_AddRaw("&cAs such you may experience poor performance.");
Chat_AddRaw("&cIt is likely you need to install video card drivers.");
#endif
String renderer = String_FromReadonly(glGetString(GL_RENDERER));
String intel = String_FromConst("Intel");
if (!String_ContainsString(&renderer, &intel)) return false;
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) {
struct Screen* active = Gui_GetActiveScreen();
struct Widget* widget;
bool hotbar;
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 (InputHandler_DoFovZoom(delta) || !Inventory_CanChangeHeldBlock) return;
struct Widget* hotbarW = HUDScreen_GetHotbar(Gui_HUD);
Elem_HandlesMouseScroll(hotbarW, delta);
widget = HUDScreen_GetHotbar(Gui_HUD);
Elem_HandlesMouseScroll(widget, delta);
}
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;
if (Block_Draw[block] == DRAW_GAS) {
Vector3 zero = Vector3_Zero; BlockModel_minBB = zero;
Vector3 one = Vector3_One; BlockModel_maxBB = one;
BlockModel_minBB = Vector3_Zero;
BlockModel_maxBB = Vector3_One;
height = 1.0f;
} else {
BlockModel_minBB = Block_MinBB[block];

View File

@ -163,8 +163,10 @@ static void Window_RefreshBorders(void) {
static void Window_RefreshBounds(XEvent* e) {
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) {
Window_Bounds.X = loc.X; Window_Bounds.Y = loc.Y;
Event_RaiseVoid(&WindowEvents_Moved);
@ -172,10 +174,9 @@ static void Window_RefreshBounds(XEvent* e) {
/* Note: width and height denote the internal (client) size.
To get the external (window) size, we need to add the border size. */
Size2D size = {
e->xconfigure.width + borderLeft + borderRight,
e->xconfigure.height + borderTop + borderBottom
};
Size2D size;
size.Width = e->xconfigure.width + borderLeft + borderRight;
size.Height = e->xconfigure.height + borderTop + borderBottom;
if (size.Width != Window_Bounds.Width || size.Height != Window_Bounds.Height) {
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) {
String motd = ServerConnection_ServerMOTD;
if (!motd.length) return;
String cfg = String_FromConst("cfg=");
int index = String_IndexOfString(&motd, &cfg);
if (Game_PureClassic || index == -1) return;
static String cfg = String_FromConst("cfg=");
String motd = ServerConnection_ServerMOTD, host;
int index;
char urlBuffer[STRING_SIZE];
String url = String_FromArray(urlBuffer);
String host = String_UNSAFE_SubstringAt(&motd, index + cfg.length);
String url = String_FromArray(urlBuffer);
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);
/* TODO: Replace $U with 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) {
int i, offset = *start;
char c;
if (offset == -1) return false;
for (i = offset; i < page->length; i++) {
char c = page->buffer[i];
c = page->buffer[i];
if (c != '\r' && c != '\n') continue;
*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) {
String line, key, value;
int start = 0;
int start = 0, waterLevel;
PackedCol col;
while (WoM_ReadLine(page, &start, &line)) {
Platform_Log(&line);
if (!String_UNSAFE_Separate(&line, '=', &key, &value)) continue;
if (String_CaselessEqualsConst(&key, "environment.cloud")) {
PackedCol col = WoM_ParseCol(&value, Env_DefaultCloudsCol);
col = WoM_ParseCol(&value, Env_DefaultCloudsCol);
Env_SetCloudsCol(col);
} else if (String_CaselessEqualsConst(&key, "environment.sky")) {
PackedCol col = WoM_ParseCol(&value, Env_DefaultSkyCol);
col = WoM_ParseCol(&value, Env_DefaultSkyCol);
Env_SetSkyCol(col);
} else if (String_CaselessEqualsConst(&key, "environment.fog")) {
PackedCol col = WoM_ParseCol(&value, Env_DefaultFogCol);
col = WoM_ParseCol(&value, Env_DefaultFogCol);
Env_SetFogCol(col);
} else if (String_CaselessEqualsConst(&key, "environment.level")) {
int waterLevel;
if (Convert_TryParseInt(&value, &waterLevel)) {
Env_SetEdgeHeight(waterLevel);
}
@ -456,10 +459,13 @@ static void Classic_LevelInit(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 */
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.Base = data;
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);
}
static void Classic_LevelFinalise(uint8_t* data) {
int width, height, length;
int loadingMs;
Gui_CloseActive();
Gui_Active = classic_prevScreen;
classic_prevScreen = NULL;
Gui_CalcCursorVisible();
int width = Stream_GetU16_BE(&data[0]);
int height = Stream_GetU16_BE(&data[2]);
int length = Stream_GetU16_BE(&data[4]);
width = Stream_GetU16_BE(&data[0]);
height = Stream_GetU16_BE(&data[2]);
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);
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) {
int x = Stream_GetU16_BE(&data[0]);
int y = Stream_GetU16_BE(&data[2]);
int z = Stream_GetU16_BE(&data[4]);
int x, y, z;
BlockID block;
x = Stream_GetU16_BE(&data[0]);
y = Stream_GetU16_BE(&data[2]);
z = Stream_GetU16_BE(&data[4]);
data += 6;
BlockID block; Handlers_ReadBlock(data, block);
Handlers_ReadBlock(data, block);
if (World_IsValidPos(x, y, z)) {
Game_UpdateBlock(x, y, z, block);
}
@ -574,33 +586,43 @@ static void Classic_EntityTeleport(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.Y = (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++);
float headX = Math_Packed2Deg(*data++);
struct LocationUpdate update; LocationUpdate_MakePosAndOri(&update, pos, rotY, headX, true);
LocationUpdate_MakePosAndOri(&update, pos, rotY, headX, true);
Handlers_UpdateLocation(id, &update, true);
}
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.Y = (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);
}
static void Classic_OrientationUpdate(uint8_t* data) {
EntityID id = *data++;
float rotY = Math_Packed2Deg(*data++);
float headX = Math_Packed2Deg(*data++);
float rotY, headX;
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);
}
@ -610,6 +632,9 @@ static void Classic_RemoveEntity(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];
String text = String_FromArray(textBuffer);
uint8_t type = *data++;
@ -621,23 +646,22 @@ static void Classic_Message(uint8_t* data) {
if (!cpe_useMessageTypes) type = MSG_TYPE_NORMAL;
/* WoM detail messages (used e.g. for fCraft server compass) */
String detailMsg = String_FromConst("^detail.user=");
if (String_CaselessStarts(&text, &detailMsg)) {
text = String_UNSAFE_SubstringAt(&text, detailMsg.length);
type = MSG_TYPE_STATUS_3;
}
/* Ignore ^detail.user.joined etc */
String detailUser = String_FromConst("^detail.user");
if (!String_CaselessStarts(&text, &detailUser)) {
Chat_AddOf(&text, type);
}
}
static void Classic_Kick(uint8_t* data) {
static String title = String_FromConst("&eLost connection to the server");
char reasonBuffer[STRING_SIZE];
String reason = String_FromArray(reasonBuffer);
String title = String_FromConst("&eLost connection to the server");
String reason = String_FromArray(reasonBuffer);
Handlers_ReadString(&data, &reason);
Game_Disconnect(&title, &reason);
@ -1012,20 +1036,23 @@ static void CPE_ExtRemovePlayerName(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 */
Vector3I p1;
p1.X = (int16_t)Stream_GetU16_BE(&data[0]);
p1.Y = (int16_t)Stream_GetU16_BE(&data[2]);
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.Y = (int16_t)Stream_GetU16_BE(&data[2]);
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 */
c.R = data[1]; c.G = data[3]; c.B = data[5]; c.A = data[7];
Selections_Add(selectionId, p1, p2, c);
@ -1197,14 +1224,13 @@ static void CPE_SetMapEnvProperty(uint8_t* data) {
uint8_t type = *data++;
int value = (int)Stream_GetU32_BE(data);
Math_Clamp(value, -0xFFFFFF, 0xFFFFFF);
int maxBlock = BLOCK_COUNT - 1;
switch (type) {
case 0:
Math_Clamp(value, 0, maxBlock);
Math_Clamp(value, 0, BLOCK_MAX_DEFINED);
Env_SetSidesBlock((BlockID)value); break;
case 1:
Math_Clamp(value, 0, maxBlock);
Math_Clamp(value, 0, BLOCK_MAX_DEFINED);
Env_SetEdgeBlock((BlockID)value); break;
case 2:
Env_SetEdgeHeight(value); break;
@ -1281,8 +1307,9 @@ static void CPE_TwoWayPing(uint8_t* data) {
}
static void CPE_SetInventoryOrder(uint8_t* data) {
BlockID block; Handlers_ReadBlock(data, block);
BlockID order; Handlers_ReadBlock(data, order);
BlockID block, order;
Handlers_ReadBlock(data, block);
Handlers_ReadBlock(data, order);
Inventory_Remove(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) {
BlockID block;
bool didBlockLight = Block_BlocksLight[block];
uint8_t sound;
uint8_t* data = *ptr;
char nameBuffer[STRING_SIZE];
String name = String_FromArray(nameBuffer);
BlockID block; Handlers_ReadBlock(data, block);
bool didBlockLight = Block_BlocksLight[block];
Handlers_ReadBlock(data, block);
Block_ResetProps(block);
Handlers_ReadString(&data, &name);
@ -1388,9 +1418,9 @@ static BlockID BlockDefs_DefineBlockCommonStart(uint8_t** ptr, bool uniqueSideTe
Block_BlocksLight[block] = *data++ == 0;
BlockDefs_OnBlockUpdated(block, didBlockLight);
uint8_t sound = *data++;
sound = *data++;
Block_StepSounds[block] = sound;
Block_DigSounds[block] = sound;
Block_DigSounds[block] = sound;
if (sound == SOUND_GLASS) Block_StepSounds[block] = SOUND_STONE;
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) {
uint8_t blockDraw = *data++;
uint8_t blockDraw;
uint8_t density;
PackedCol c;
blockDraw = *data++;
if (shape == 0) {
Block_SpriteOffset[block] = blockDraw;
blockDraw = DRAW_SPRITE;
}
Block_Draw[block] = blockDraw;
uint8_t density = *data++;
density = *data++;
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;
Block_FogCol[block] = c;
Block_DefineCustom(block);
@ -1431,8 +1464,9 @@ static void BlockDefs_DefineBlock(uint8_t* data) {
}
static void BlockDefs_UndefineBlock(uint8_t* data) {
BlockID block; Handlers_ReadBlock(data, block);
BlockID block;
bool didBlockLight = Block_BlocksLight[block];
Handlers_ReadBlock(data, block);
Block_ResetProps(block);
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) {
if (y < 0) {
p->NextPos.Y = ENTITY_ADJUSTMENT; p->LastPos.Y = ENTITY_ADJUSTMENT;
Vector3 zero = Vector3_Zero; p->Velocity = zero;
p->Velocity = Vector3_Zero;
particle_hitTerrain = true;
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;
p->LastPos.Y = collideY + adjust;
p->NextPos.Y = p->LastPos.Y;
Vector3 zero = Vector3_Zero; p->Velocity = zero;
p->Velocity = Vector3_Zero;
particle_hitTerrain = true;
return false;
}

View File

@ -45,7 +45,31 @@ void PickedPosRenderer_Render(double delta) {
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) {
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;
float dist, offset, size;
Vector3 coords[4];
@ -82,30 +106,7 @@ void PickedPosRenderer_Update(struct PickedPos* selected) {
Vector3_Add1(&coords[1], &coords[0], size);
Vector3_Add1(&coords[3], &selected->Max, offset);
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);
VertexP3fC4b* ptr = pickedPos_vertices;
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) {
Vector3I start, cellBoundary;
t->Origin = origin; t->Dir = dir;
/* Rounds the position's X, Y and Z down to the nearest integer values. */
Vector3I start;
Vector3I_Floor(&start, &origin);
/* The cell in which the ray starts. */
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,
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. */
Vector3I cellBoundary;
cellBoundary.X = start.X + (t->step.X > 0 ? 1 : 0);
cellBoundary.Y = start.Y + (t->step.Y > 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_Mul1(&scaledDir, &tracer.Dir, t0); /* scaledDir = dir * t0 */
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 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) {
int i, j;
char lineBuffer[TEXTGROUPWIDGET_LEN];
String line = String_FromArray(lineBuffer);
int i, j;
for (i = 0; i < group->LinesCount; i++) {
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_MouseDown(void* screen, int x, int y, MouseButton btn) {
struct DisconnectScreen* s = screen;
struct ButtonWidget* w = &s->Reconnect;
if (btn != MouseButton_Left) return true;
char titleBuffer[STRING_SIZE];
String title = String_FromArray(titleBuffer);
if (!w->Disabled && Widget_Contains(w, x, y)) {
char titleBuffer[STRING_SIZE];
String title = String_FromArray(titleBuffer);
struct DisconnectScreen* s = screen;
struct ButtonWidget* w = &s->Reconnect;
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);
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) {
struct DisconnectScreen* s = screen;
struct ButtonWidget* w = &s->Reconnect;
struct ButtonWidget* w = &s->Reconnect;
w->Active = !w->Disabled && Widget_Contains(w, x, y);
return true;
}
@ -1498,7 +1500,10 @@ struct ScreenVTABLE DisconnectScreen_VTABLE = {
DisconnectScreen_OnResize, DisconnectScreen_ContextLost, DisconnectScreen_ContextRecreated
};
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;
s->HandlesAllInput = true;
s->BlocksWorld = true;
s->HidesHUD = true;
@ -1514,12 +1519,8 @@ struct Screen* DisconnectScreen_MakeInstance(const String* title, const String*
char whyBuffer[STRING_SIZE];
String why = String_FromArray(whyBuffer);
String_AppendColorless(&why, message);
String kick = String_FromConst("Kicked ");
String ban = String_FromConst("Banned ");
s->CanReconnect =
!(String_CaselessStarts(&why, &kick) || String_CaselessStarts(&why, &ban));
s->CanReconnect = !(String_CaselessStarts(&why, &kick) || String_CaselessStarts(&why, &ban));
s->VTABLE = &DisconnectScreen_VTABLE;
return (struct Screen*)s;
}

View File

@ -3,6 +3,9 @@
#include "Funcs.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 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);
#define VECTOR3_CONST(x, y, z) { x, y, z };
#define Vector3_Zero VECTOR3_CONST(0.0f, 0.0f, 0.0f)
#define Vector3_One VECTOR3_CONST(1.0f, 1.0f, 1.0f)
extern const Vector3 Vector3_Zero;
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_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_Mul3(Vector3* result, Vector3* a, Vector3* scale);
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);
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)) {
DrawTextArgs_Make(&args, &text, &w->Font, true);