mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-09-15 10:35:11 -04:00
and even more
This commit is contained in:
parent
d098e7731c
commit
0a51bfaa1e
13
src/Block.c
13
src/Block.c
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
@ -562,25 +572,28 @@ static int NormalBuilder_StretchZ(int countIndex, int x, int y, int z, int chunk
|
||||
|
||||
static void NormalBuilder_RenderBlock(int index) {
|
||||
TextureLoc texLoc;
|
||||
int offset;
|
||||
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;
|
||||
|
||||
|
@ -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 */
|
||||
|
73
src/Entity.c
73
src/Entity.c
@ -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 {
|
||||
@ -696,16 +708,12 @@ 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 = {
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
@ -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.");
|
||||
|
@ -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) {
|
||||
|
@ -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];
|
||||
|
@ -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;
|
||||
|
@ -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");
|
||||
|
||||
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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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];
|
||||
@ -83,29 +107,6 @@ void PickedPosRenderer_Update(struct PickedPos* selected) {
|
||||
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;
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
||||
struct DisconnectScreen* s = screen;
|
||||
struct ButtonWidget* w = &s->Reconnect;
|
||||
|
||||
if (btn != MouseButton_Left) return true;
|
||||
if (!w->Disabled && Widget_Contains(w, x, y)) {
|
||||
char titleBuffer[STRING_SIZE];
|
||||
String title = String_FromArray(titleBuffer);
|
||||
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;
|
||||
@ -1515,11 +1520,7 @@ struct Screen* DisconnectScreen_MakeInstance(const String* title, const String*
|
||||
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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user