From c925f31445662d46a208fde5762b83cd9fe8911f Mon Sep 17 00:00:00 2001 From: Goodlyay Date: Fri, 21 Feb 2020 16:53:23 -0800 Subject: [PATCH 01/11] Initial commit of CustomParticles And changed size in struct Particle to be a float instead of cc_uint8 --- src/Particle.c | 184 +++++++++++++++++++++++++++++++++++++++++++++++-- src/Particle.h | 20 +++++- 2 files changed, 197 insertions(+), 7 deletions(-) diff --git a/src/Particle.c b/src/Particle.c index bb7b47a1c..cdc721f65 100644 --- a/src/Particle.c +++ b/src/Particle.c @@ -148,7 +148,7 @@ static void RainParticle_Render(struct Particle* p, float t, VertexP3fT2fC4b* ve int x, y, z; Vec3_Lerp(&pos, &p->lastPos, &p->nextPos, t); - size.X = (float)p->size * 0.015625f; size.Y = size.X; + size.X = p->size * 0.015625f; size.Y = size.X; x = Math_Floor(pos.X); y = Math_Floor(pos.Y); z = Math_Floor(pos.Z); col = World_Contains(x, y, z) ? Lighting_Col(x, y, z) : Env.SunCol; @@ -218,7 +218,7 @@ static void TerrainParticle_Render(struct TerrainParticle* p, float t, VertexP3f int x, y, z; Vec3_Lerp(&pos, &p->base.lastPos, &p->base.nextPos, t); - size.X = (float)p->base.size * 0.015625f; size.Y = size.X; + size.X = p->base.size * 0.015625f; size.Y = size.X; if (!Blocks.FullBright[p->block]) { x = Math_Floor(pos.X); y = Math_Floor(pos.Y); z = Math_Floor(pos.Z); @@ -293,12 +293,90 @@ static void Terrain_Tick(double delta) { } } +/*########################################################################################################################* +*-------------------------------------------------------Custom particle---------------------------------------------------* +*#########################################################################################################################*/ +struct CustomParticle { + struct Particle base; + struct CustomParticleProperty* prop; + float totalLifespan; +}; + +static struct CustomParticle customParticle_particles[PARTICLES_MAX]; +static int customParticle_count; +static TextureRec defaultCustomParticle_rec = { 0.0f / 128.0f, 24.0f / 128.0f, 16.0f / 128.0f, 40.0f / 128.0f }; + +static cc_bool CustomParticle_Tick(struct CustomParticle* p, double delta) { + particle_hitTerrain = false; + return Particle_PhysicsTick(&p->base, p->prop->gravity, false, delta) || particle_hitTerrain; +} + +static void CustomParticle_Render(struct CustomParticle* p, float t, VertexP3fT2fC4b* vertices) { + Vec3 pos; + Vec2 size; + PackedCol col; + TextureRec rec = p->prop->rec; + + float frame_time = p->totalLifespan / p->prop->frameCount; + float inverted_lifetime = Math_AbsF(p->base.lifetime - p->totalLifespan); + int curFrame = Math_Floor(inverted_lifetime / frame_time); + float shiftU = curFrame * (rec.U2 - rec.U1); + + rec.U1 += shiftU;// * 0.0078125f; + rec.U2 += shiftU;// * 0.0078125f; + int x, y, z; + + Vec3_Lerp(&pos, &p->base.lastPos, &p->base.nextPos, t); + size.X = p->base.size; size.Y = size.X; + + x = Math_Floor(pos.X); y = Math_Floor(pos.Y); z = Math_Floor(pos.Z); + col = p->prop->fullBright ? PACKEDCOL_WHITE : (World_Contains(x, y, z) ? Lighting_Col(x, y, z) : Env.SunCol); + + Particle_DoRender(&size, &pos, &rec, col, vertices); +} + +static void Custom_Render(float t) { + VertexP3fT2fC4b* data; + int i; + if (!customParticle_count) return; + + data = (VertexP3fT2fC4b*)Gfx_LockDynamicVb(Particles_VB, VERTEX_FORMAT_P3FT2FC4B, customParticle_count * 4); + for (i = 0; i < customParticle_count; i++) { + CustomParticle_Render(&customParticle_particles[i], t, data); + data += 4; + } + + Gfx_BindTexture(Particles_TexId); + Gfx_UnlockDynamicVb(Particles_VB); + Gfx_DrawVb_IndexedTris(customParticle_count * 4); +} + +static void Custom_RemoveAt(int index) { + struct CustomParticle removed = customParticle_particles[index]; + int i; + + for (i = index; i < customParticle_count - 1; i++) { + customParticle_particles[i] = customParticle_particles[i + 1]; + } + customParticle_particles[customParticle_count - 1] = removed; + customParticle_count--; +} + +static void Custom_Tick(double delta) { + int i; + for (i = 0; i < customParticle_count; i++) { + if (CustomParticle_Tick(&customParticle_particles[i], delta)) { + Custom_RemoveAt(i); i--; + } + } +} + /*########################################################################################################################* *--------------------------------------------------------Particles--------------------------------------------------------* *#########################################################################################################################*/ void Particles_Render(float t) { - if (!terrain_count && !rain_count) return; + if (!terrain_count && !rain_count && !customParticle_count) return; if (Gfx.LostContext) return; Gfx_SetTexturing(true); @@ -307,6 +385,7 @@ void Particles_Render(float t) { Gfx_SetVertexFormat(VERTEX_FORMAT_P3FT2FC4B); Terrain_Render(t); Rain_Render(t); + Custom_Render(t); Gfx_SetAlphaTest(false); Gfx_SetTexturing(false); @@ -315,6 +394,7 @@ void Particles_Render(float t) { void Particles_Tick(struct ScheduledTask* task) { Terrain_Tick(task->Interval); Rain_Tick(task->Interval); + Custom_Tick(task->Interval); } void Particles_BreakBlockEffect(IVec3 coords, BlockID old, BlockID now) { @@ -392,7 +472,7 @@ void Particles_BreakBlockEffect(IVec3 coords, BlockID old, BlockID now) { p->texLoc = loc; p->block = old; type = Random_Next(&rnd, 30); - p->base.size = (cc_uint8)(type >= 28 ? 12 : (type >= 25 ? 10 : 8)); + p->base.size = type >= 28 ? 12 : (type >= 25 ? 10 : 8); } } } @@ -418,7 +498,63 @@ void Particles_RainSnowEffect(float x, float y, float z) { p->lifetime = 40.0f; type = Random_Next(&rnd, 30); - p->size = (cc_uint8)(type >= 28 ? 2 : (type >= 25 ? 4 : 3)); + p->size = type >= 28 ? 2 : (type >= 25 ? 4 : 3); + } +} + +//Vec3 GetRandomSpherePoint() { +// float u = Random_Float(&rnd); +// float v = Random_Float(&rnd); +// float theta = u * 2.0 * MATH_PI; +// float phi = Math.acos(2.0 * v - 1.0); +// float r = Math.cbrt(Random_Float(&rnd)); +// float sinTheta = Math.sin(theta); +// float cosTheta = Math.cos(theta); +// float sinPhi = Math.sin(phi); +// float cosPhi = Math.cos(phi); +// float x = r * sinPhi * cosTheta; +// float y = r * sinPhi * sinTheta; +// float z = r * cosPhi; +// return { x: x, y : y, z : z }; +//} + + +void Particles_CustomEffect(float x, float y, float z, int propertyID) { + struct CustomParticle* p; + struct CustomParticleProperty* prop = &customParticle_properties[propertyID]; + int i; + int count = prop->particleCount; + + for (i = 0; i < count; i++) { + if (customParticle_count == PARTICLES_MAX) Custom_RemoveAt(0); + p = &customParticle_particles[customParticle_count++]; + + p->prop = prop; + + //TODO: Add prop speed and origin working here + p->base.velocity.X = 0; + p->base.velocity.Z = 0; + p->base.velocity.Y = 0; + + Vec3 offset = { Random_Float(&rnd) - 0.5f, Random_Float(&rnd) - 0.5f, Random_Float(&rnd) - 0.5f }; + Vec3_Normalize(&offset, &offset); + float d = Random_Float(&rnd); + + d = Math_Exp(Math_Log(d) / 3.0); + Vec3_Mul1By(&offset, d); + Vec3_Mul1By(&offset, p->prop->spread*0.03125f); + + p->base.lastPos.X = x + (offset.X); + p->base.lastPos.Y = y + (offset.Y); + p->base.lastPos.Z = z + (offset.Z); + + + p->base.nextPos = p->base.lastPos; + p->base.lifetime = p->prop->baseLifetime + ( (p->prop->baseLifetime * p->prop->lifetimeVariation) * ((Random_Float(&rnd) - 0.5f) * 2)); + p->totalLifespan = p->base.lifetime; + + p->base.size = p->prop->size + ( (p->prop->size * p->prop->sizeVariation) * ((Random_Float(&rnd) - 0.5f) * 2) ) ; + } } @@ -434,6 +570,7 @@ static void OnContextRecreated(void* obj) { } static void OnBreakBlockEffect_Handler(void* obj, IVec3 coords, BlockID old, BlockID now) { Particles_BreakBlockEffect(coords, old, now); + Particles_CustomEffect(coords.X+0.5f, coords.Y+2.5f, coords.Z+0.5f, 0); } static void OnFileChanged(void* obj, struct Stream* stream, const String* name) { @@ -443,6 +580,41 @@ static void OnFileChanged(void* obj, struct Stream* stream, const String* name) } static void Particles_Init(void) { + + + //struct CustomParticleProperty { + // TextureRec rec; + // int frameCount; + // int amount; //how many of this particle are spawned per spawn-packet + // float size; //size of the particle in fixed-point world units (e.g. 32 is a full block's size) + // float sizeVariation; + // float spread; //how far from the spawnpoint their location can vary (in fixed-point world units) + // float speed; //how fast they move away/towards the origin + // float gravity; + // float baseLifetime; + // float lifetimeVariation; + // cc_bool fullBright; + // cc_bool converge; ////true means the particles move toward the origin. False means they move away from the origin + //}; + + //TEMP CODE IN LIEU OF ANY DEFINING PACKETS + struct CustomParticleProperty* prop; + prop = &customParticle_properties[0]; + + prop->rec = defaultCustomParticle_rec; + prop->frameCount = 8; + prop->particleCount = 50; + prop->size = 32 * 0.03125f; + prop->sizeVariation = 0.5f; + prop->spread = 96; + prop->speed = 2; + prop->gravity = 0.0f; + prop->baseLifetime = 0.7f; + prop->lifetimeVariation = 0.25f; + prop->fullBright = true; + prop->converge = false; + //END TEMP CODE + ScheduledTask_Add(GAME_DEF_TICKS, Particles_Tick); Random_SeedFromCurrentTime(&rnd); OnContextRecreated(NULL); @@ -463,7 +635,7 @@ static void Particles_Free(void) { Event_UnregisterVoid(&GfxEvents.ContextRecreated, NULL, OnContextRecreated); } -static void Particles_Reset(void) { rain_count = 0; terrain_count = 0; } +static void Particles_Reset(void) { rain_count = 0; terrain_count = 0; customParticle_count = 0; } struct IGameComponent Particles_Component = { Particles_Init, /* Init */ diff --git a/src/Particle.h b/src/Particle.h index 318569db4..f974b406d 100644 --- a/src/Particle.h +++ b/src/Particle.h @@ -14,13 +14,31 @@ struct Particle { Vec3 velocity; float lifetime; Vec3 lastPos, nextPos; - cc_uint8 size; + float size; }; +struct CustomParticleProperty { + TextureRec rec; + int frameCount; + int particleCount; //how many of this particle are spawned per spawn-packet + float size; //size of the particle in fixed-point world units (e.g. 32 is a full block's size) + float sizeVariation; + float spread; //how far from the spawnpoint their location can vary (in fixed-point world units) + float speed; //how fast they move away/towards the origin + float gravity; + float baseLifetime; + float lifetimeVariation; + cc_bool fullBright; + cc_bool converge; ////true means the particles move toward the origin. False means they move away from the origin +}; + +static struct CustomParticleProperty customParticle_properties[256]; + /* http://www.opengl-tutorial.org/intermediate-tutorials/billboards-particles/billboards/ */ void Particle_DoRender(const Vec2* size, const Vec3* pos, const TextureRec* rec, PackedCol col, VertexP3fT2fC4b* vertices); void Particles_Render(float t); void Particles_Tick(struct ScheduledTask* task); void Particles_BreakBlockEffect(IVec3 coords, BlockID oldBlock, BlockID block); void Particles_RainSnowEffect(float x, float y, float z); +void Particles_CustomEffect(float x, float y, float z, int propertyID); #endif From b4f166381fc8ab204c7e98a9e222e013f4d174c5 Mon Sep 17 00:00:00 2001 From: Goodlyay Date: Fri, 21 Feb 2020 19:00:20 -0800 Subject: [PATCH 02/11] Fix customParticle_properties issue Implement/Add "expireUponTouchingGround" property Implement velocity based on origin and speed Implement/Add "converge" property that makes it implode toward origin instead of explode away --- src/Particle.c | 68 +++++++++++++++++++++++++------------------------- src/Particle.h | 3 ++- 2 files changed, 36 insertions(+), 35 deletions(-) diff --git a/src/Particle.c b/src/Particle.c index cdc721f65..5b721b7df 100644 --- a/src/Particle.c +++ b/src/Particle.c @@ -302,13 +302,14 @@ struct CustomParticle { float totalLifespan; }; +struct CustomParticleProperty customParticle_properties[256]; static struct CustomParticle customParticle_particles[PARTICLES_MAX]; static int customParticle_count; static TextureRec defaultCustomParticle_rec = { 0.0f / 128.0f, 24.0f / 128.0f, 16.0f / 128.0f, 40.0f / 128.0f }; static cc_bool CustomParticle_Tick(struct CustomParticle* p, double delta) { particle_hitTerrain = false; - return Particle_PhysicsTick(&p->base, p->prop->gravity, false, delta) || particle_hitTerrain; + return Particle_PhysicsTick(&p->base, p->prop->gravity, false, delta) || (particle_hitTerrain && p->prop->expireUponTouchingGround); } static void CustomParticle_Render(struct CustomParticle* p, float t, VertexP3fT2fC4b* vertices) { @@ -502,24 +503,7 @@ void Particles_RainSnowEffect(float x, float y, float z) { } } -//Vec3 GetRandomSpherePoint() { -// float u = Random_Float(&rnd); -// float v = Random_Float(&rnd); -// float theta = u * 2.0 * MATH_PI; -// float phi = Math.acos(2.0 * v - 1.0); -// float r = Math.cbrt(Random_Float(&rnd)); -// float sinTheta = Math.sin(theta); -// float cosTheta = Math.cos(theta); -// float sinPhi = Math.sin(phi); -// float cosPhi = Math.cos(phi); -// float x = r * sinPhi * cosTheta; -// float y = r * sinPhi * sinTheta; -// float z = r * cosPhi; -// return { x: x, y : y, z : z }; -//} - - -void Particles_CustomEffect(float x, float y, float z, int propertyID) { +void Particles_CustomEffect(float x, float y, float z, int propertyID, float originX, float originY, float originZ) { struct CustomParticle* p; struct CustomParticleProperty* prop = &customParticle_properties[propertyID]; int i; @@ -528,27 +512,42 @@ void Particles_CustomEffect(float x, float y, float z, int propertyID) { for (i = 0; i < count; i++) { if (customParticle_count == PARTICLES_MAX) Custom_RemoveAt(0); p = &customParticle_particles[customParticle_count++]; - p->prop = prop; - //TODO: Add prop speed and origin working here - p->base.velocity.X = 0; - p->base.velocity.Z = 0; - p->base.velocity.Y = 0; - Vec3 offset = { Random_Float(&rnd) - 0.5f, Random_Float(&rnd) - 0.5f, Random_Float(&rnd) - 0.5f }; Vec3_Normalize(&offset, &offset); float d = Random_Float(&rnd); - d = Math_Exp(Math_Log(d) / 3.0); Vec3_Mul1By(&offset, d); Vec3_Mul1By(&offset, p->prop->spread*0.03125f); - p->base.lastPos.X = x + (offset.X); p->base.lastPos.Y = y + (offset.Y); p->base.lastPos.Z = z + (offset.Z); - + Vec3 origin = { originX, originY, originZ }; + if (Vec3_Equals(&origin, &p->base.lastPos)) { + p->base.velocity.X = 0; + p->base.velocity.Y = 0; + p->base.velocity.Z = 0; + } + else { + Vec3 diff; + Vec3_Sub(&diff, &p->base.lastPos, &origin); + Vec3_Normalize(&diff, &diff); + + if (p->prop->converge) { + p->base.velocity.X = (-diff.X) * p->prop->speed; + p->base.velocity.Y = (-diff.Y) * p->prop->speed; + p->base.velocity.Z = (-diff.Z) * p->prop->speed; + } + else { + p->base.velocity.X = diff.X * p->prop->speed; + p->base.velocity.Y = diff.Y * p->prop->speed; + p->base.velocity.Z = diff.Z * p->prop->speed; + } + + } + p->base.nextPos = p->base.lastPos; p->base.lifetime = p->prop->baseLifetime + ( (p->prop->baseLifetime * p->prop->lifetimeVariation) * ((Random_Float(&rnd) - 0.5f) * 2)); p->totalLifespan = p->base.lifetime; @@ -570,7 +569,7 @@ static void OnContextRecreated(void* obj) { } static void OnBreakBlockEffect_Handler(void* obj, IVec3 coords, BlockID old, BlockID now) { Particles_BreakBlockEffect(coords, old, now); - Particles_CustomEffect(coords.X+0.5f, coords.Y+2.5f, coords.Z+0.5f, 0); + Particles_CustomEffect(coords.X+0.5f, coords.Y+0.5f, coords.Z+0.5f, 0, coords.X+0.5f, coords.Y + 0.5f, coords.Z + 0.5f); } static void OnFileChanged(void* obj, struct Stream* stream, const String* name) { @@ -604,15 +603,16 @@ static void Particles_Init(void) { prop->rec = defaultCustomParticle_rec; prop->frameCount = 8; prop->particleCount = 50; - prop->size = 32 * 0.03125f; + prop->size = 64 * 0.03125f; prop->sizeVariation = 0.5f; prop->spread = 96; - prop->speed = 2; - prop->gravity = 0.0f; + prop->speed = 0.5; + prop->gravity = -0.5f; prop->baseLifetime = 0.7f; - prop->lifetimeVariation = 0.25f; + prop->lifetimeVariation = 0.5f; prop->fullBright = true; - prop->converge = false; + prop->converge = true; + prop->expireUponTouchingGround = true; //END TEMP CODE ScheduledTask_Add(GAME_DEF_TICKS, Particles_Tick); diff --git a/src/Particle.h b/src/Particle.h index f974b406d..684590906 100644 --- a/src/Particle.h +++ b/src/Particle.h @@ -28,11 +28,12 @@ struct CustomParticleProperty { float gravity; float baseLifetime; float lifetimeVariation; + cc_bool expireUponTouchingGround; cc_bool fullBright; cc_bool converge; ////true means the particles move toward the origin. False means they move away from the origin }; -static struct CustomParticleProperty customParticle_properties[256]; +extern struct CustomParticleProperty customParticle_properties[256]; /* http://www.opengl-tutorial.org/intermediate-tutorials/billboards-particles/billboards/ */ void Particle_DoRender(const Vec2* size, const Vec3* pos, const TextureRec* rec, PackedCol col, VertexP3fT2fC4b* vertices); From dcc256c15d26e1891f312ca4bd02519bbdc85707 Mon Sep 17 00:00:00 2001 From: Goodlyay Date: Fri, 21 Feb 2020 19:49:37 -0800 Subject: [PATCH 03/11] Remove converge property It's pointless since the same can be achieved by making speed negative --- src/Particle.c | 16 +++------------- src/Particle.h | 1 - 2 files changed, 3 insertions(+), 14 deletions(-) diff --git a/src/Particle.c b/src/Particle.c index 5b721b7df..f8c42bace 100644 --- a/src/Particle.c +++ b/src/Particle.c @@ -534,18 +534,9 @@ void Particles_CustomEffect(float x, float y, float z, int propertyID, float ori Vec3 diff; Vec3_Sub(&diff, &p->base.lastPos, &origin); Vec3_Normalize(&diff, &diff); - - if (p->prop->converge) { - p->base.velocity.X = (-diff.X) * p->prop->speed; - p->base.velocity.Y = (-diff.Y) * p->prop->speed; - p->base.velocity.Z = (-diff.Z) * p->prop->speed; - } - else { - p->base.velocity.X = diff.X * p->prop->speed; - p->base.velocity.Y = diff.Y * p->prop->speed; - p->base.velocity.Z = diff.Z * p->prop->speed; - } - + p->base.velocity.X = diff.X * p->prop->speed; + p->base.velocity.Y = diff.Y * p->prop->speed; + p->base.velocity.Z = diff.Z * p->prop->speed; } p->base.nextPos = p->base.lastPos; @@ -611,7 +602,6 @@ static void Particles_Init(void) { prop->baseLifetime = 0.7f; prop->lifetimeVariation = 0.5f; prop->fullBright = true; - prop->converge = true; prop->expireUponTouchingGround = true; //END TEMP CODE diff --git a/src/Particle.h b/src/Particle.h index 684590906..2a1079cd9 100644 --- a/src/Particle.h +++ b/src/Particle.h @@ -30,7 +30,6 @@ struct CustomParticleProperty { float lifetimeVariation; cc_bool expireUponTouchingGround; cc_bool fullBright; - cc_bool converge; ////true means the particles move toward the origin. False means they move away from the origin }; extern struct CustomParticleProperty customParticle_properties[256]; From 94bc9b02b1833248826e9e85f8491542075018cb Mon Sep 17 00:00:00 2001 From: Goodlyay Date: Fri, 21 Feb 2020 23:53:00 -0800 Subject: [PATCH 04/11] Add DefineParticle and SpawnParticle packets Remove test code from Particle.c --- src/Particle.c | 38 +-------------------------------- src/Particle.h | 6 +++--- src/Protocol.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/Protocol.h | 1 + 4 files changed, 62 insertions(+), 40 deletions(-) diff --git a/src/Particle.c b/src/Particle.c index f8c42bace..48474957c 100644 --- a/src/Particle.c +++ b/src/Particle.c @@ -503,7 +503,7 @@ void Particles_RainSnowEffect(float x, float y, float z) { } } -void Particles_CustomEffect(float x, float y, float z, int propertyID, float originX, float originY, float originZ) { +void Particles_CustomEffect(int propertyID, float x, float y, float z, float originX, float originY, float originZ) { struct CustomParticle* p; struct CustomParticleProperty* prop = &customParticle_properties[propertyID]; int i; @@ -560,7 +560,6 @@ static void OnContextRecreated(void* obj) { } static void OnBreakBlockEffect_Handler(void* obj, IVec3 coords, BlockID old, BlockID now) { Particles_BreakBlockEffect(coords, old, now); - Particles_CustomEffect(coords.X+0.5f, coords.Y+0.5f, coords.Z+0.5f, 0, coords.X+0.5f, coords.Y + 0.5f, coords.Z + 0.5f); } static void OnFileChanged(void* obj, struct Stream* stream, const String* name) { @@ -570,41 +569,6 @@ static void OnFileChanged(void* obj, struct Stream* stream, const String* name) } static void Particles_Init(void) { - - - //struct CustomParticleProperty { - // TextureRec rec; - // int frameCount; - // int amount; //how many of this particle are spawned per spawn-packet - // float size; //size of the particle in fixed-point world units (e.g. 32 is a full block's size) - // float sizeVariation; - // float spread; //how far from the spawnpoint their location can vary (in fixed-point world units) - // float speed; //how fast they move away/towards the origin - // float gravity; - // float baseLifetime; - // float lifetimeVariation; - // cc_bool fullBright; - // cc_bool converge; ////true means the particles move toward the origin. False means they move away from the origin - //}; - - //TEMP CODE IN LIEU OF ANY DEFINING PACKETS - struct CustomParticleProperty* prop; - prop = &customParticle_properties[0]; - - prop->rec = defaultCustomParticle_rec; - prop->frameCount = 8; - prop->particleCount = 50; - prop->size = 64 * 0.03125f; - prop->sizeVariation = 0.5f; - prop->spread = 96; - prop->speed = 0.5; - prop->gravity = -0.5f; - prop->baseLifetime = 0.7f; - prop->lifetimeVariation = 0.5f; - prop->fullBright = true; - prop->expireUponTouchingGround = true; - //END TEMP CODE - ScheduledTask_Add(GAME_DEF_TICKS, Particles_Tick); Random_SeedFromCurrentTime(&rnd); OnContextRecreated(NULL); diff --git a/src/Particle.h b/src/Particle.h index 2a1079cd9..40a187765 100644 --- a/src/Particle.h +++ b/src/Particle.h @@ -21,12 +21,12 @@ struct CustomParticleProperty { TextureRec rec; int frameCount; int particleCount; //how many of this particle are spawned per spawn-packet - float size; //size of the particle in fixed-point world units (e.g. 32 is a full block's size) + float size; //size of the particle in fixed-point world units (e.g. 32 is a full block's length) float sizeVariation; float spread; //how far from the spawnpoint their location can vary (in fixed-point world units) float speed; //how fast they move away/towards the origin float gravity; - float baseLifetime; + float baseLifetime; //how long (in seconds) the particle lives for float lifetimeVariation; cc_bool expireUponTouchingGround; cc_bool fullBright; @@ -40,5 +40,5 @@ void Particles_Render(float t); void Particles_Tick(struct ScheduledTask* task); void Particles_BreakBlockEffect(IVec3 coords, BlockID oldBlock, BlockID block); void Particles_RainSnowEffect(float x, float y, float z); -void Particles_CustomEffect(float x, float y, float z, int propertyID); +void Particles_CustomEffect(int propertyID, float x, float y, float z, float originX, float originY, float originZ); #endif diff --git a/src/Protocol.c b/src/Protocol.c index 822596e26..251d181b9 100644 --- a/src/Protocol.c +++ b/src/Protocol.c @@ -24,6 +24,7 @@ #include "Errors.h" #include "Camera.h" #include "Window.h" +#include "Particle.h" cc_uint16 Net_PacketSizes[OPCODE_COUNT]; Net_Handler Net_Handlers[OPCODE_COUNT]; @@ -1339,6 +1340,60 @@ static void CPE_VelocityControl(cc_uint8* data) { CalcVelocity(&p->Base.Velocity.Z, data + 8, data[14]); } +static void CPE_DefineParticle(cc_uint8* data) { + cc_uint8 particleID = data[0]; + cc_uint8 U1 = data[1]; + cc_uint8 V1 = data[2]; + cc_uint8 U2 = data[3]; + cc_uint8 V2 = data[4]; + cc_uint8 frameCount = data[5]; + cc_uint8 particleCount = data[6]; + cc_uint8 size = data[7]; + data += 8; + int sizeVariation = (int)Stream_GetU32_BE(&data[0]); + int spread = (int)Stream_GetU32_BE(&data[4]); + int speed = (int)Stream_GetU32_BE(&data[8]); + int gravity = (int)Stream_GetU32_BE(&data[12]); + int baseLifetime = (int)Stream_GetU32_BE(&data[16]); + int lifetimeVariation = (int)Stream_GetU32_BE(&data[20]); + data += 24; + cc_uint8 expireUponTouchingGround = data[0]; + cc_uint8 fullBright = data[1]; + data += 2; + + struct CustomParticleProperty* prop; + prop = &customParticle_properties[particleID]; + //e.g. bounds of 0 0, 16 16 makes an 8x8 icon in the default 128x128 particles.png + TextureRec rec = { U1/256, V1/256, U2/256, V2/256 }; + prop->rec = rec; + prop->frameCount = frameCount; + prop->particleCount = particleCount; + prop->size = size; + prop->sizeVariation = sizeVariation / 10000.0f; + prop->spread = spread; + prop->speed = speed / 10000.0f; + prop->gravity = gravity / 10000.0f; + prop->baseLifetime = baseLifetime / 10000.0f; + prop->lifetimeVariation = lifetimeVariation / 10000.0f; + prop->expireUponTouchingGround = expireUponTouchingGround; + prop->fullBright = fullBright; +} + +static void CPE_SpawnParticle(cc_uint8* data) { + cc_uint8 particleID = data[0]; + data++; + int x, y, z, originX, originY, originZ; + + x = (int)Stream_GetU32_BE(&data[0]); + y = (int)Stream_GetU32_BE(&data[4]); + z = (int)Stream_GetU32_BE(&data[8]); + originX = (int)Stream_GetU32_BE(&data[12]); + originY = (int)Stream_GetU32_BE(&data[16]); + originZ = (int)Stream_GetU32_BE(&data[20]); + data += 24; + Particles_CustomEffect(particleID, x / 32.0f, y / 32.0f, z / 32.0f, originX / 32.0f, originY / 32.0f, originZ / 32.0f); +} + static void CPE_Reset(void) { cpe_serverExtensionsCount = 0; cpe_pingTicks = 0; cpe_sendHeldBlock = false; cpe_useMessageTypes = false; @@ -1379,6 +1434,8 @@ static void CPE_Reset(void) { Net_Set(OPCODE_SET_HOTBAR, CPE_SetHotbar, 3); Net_Set(OPCODE_SET_SPAWNPOINT, CPE_SetSpawnPoint, 9); Net_Set(OPCODE_VELOCITY_CONTROL, CPE_VelocityControl, 16); + Net_Set(OPCODE_DEFINE_PARTICLE, CPE_DefineParticle, 35); + Net_Set(OPCODE_SPAWN_PARTICLE, CPE_SpawnParticle, 26); } static void CPE_Tick(void) { diff --git a/src/Protocol.h b/src/Protocol.h index 1a6760785..1758e2443 100644 --- a/src/Protocol.h +++ b/src/Protocol.h @@ -33,6 +33,7 @@ enum OPCODE_ { OPCODE_SET_ENTITY_PROPERTY, OPCODE_TWO_WAY_PING, OPCODE_SET_INVENTORY_ORDER, OPCODE_SET_HOTBAR, OPCODE_SET_SPAWNPOINT, OPCODE_VELOCITY_CONTROL, + OPCODE_DEFINE_PARTICLE, OPCODE_SPAWN_PARTICLE, OPCODE_COUNT }; From 8bdce1122031d18e1c77cf6852be3a60fc7fc7ab Mon Sep 17 00:00:00 2001 From: Goodlyay Date: Sat, 22 Feb 2020 00:25:22 -0800 Subject: [PATCH 05/11] Add tint and fixed size to be divided by 32 --- src/Particle.c | 1 + src/Particle.h | 1 + src/Protocol.c | 17 +++++++++++------ 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/src/Particle.c b/src/Particle.c index 48474957c..a458b0ab1 100644 --- a/src/Particle.c +++ b/src/Particle.c @@ -332,6 +332,7 @@ static void CustomParticle_Render(struct CustomParticle* p, float t, VertexP3fT2 x = Math_Floor(pos.X); y = Math_Floor(pos.Y); z = Math_Floor(pos.Z); col = p->prop->fullBright ? PACKEDCOL_WHITE : (World_Contains(x, y, z) ? Lighting_Col(x, y, z) : Env.SunCol); + col = PackedCol_Tint(col, p->prop->tint); Particle_DoRender(&size, &pos, &rec, col, vertices); } diff --git a/src/Particle.h b/src/Particle.h index 40a187765..05432e846 100644 --- a/src/Particle.h +++ b/src/Particle.h @@ -19,6 +19,7 @@ struct Particle { struct CustomParticleProperty { TextureRec rec; + PackedCol tint; int frameCount; int particleCount; //how many of this particle are spawned per spawn-packet float size; //size of the particle in fixed-point world units (e.g. 32 is a full block's length) diff --git a/src/Protocol.c b/src/Protocol.c index 251d181b9..e09c8e911 100644 --- a/src/Protocol.c +++ b/src/Protocol.c @@ -1346,10 +1346,13 @@ static void CPE_DefineParticle(cc_uint8* data) { cc_uint8 V1 = data[2]; cc_uint8 U2 = data[3]; cc_uint8 V2 = data[4]; - cc_uint8 frameCount = data[5]; - cc_uint8 particleCount = data[6]; - cc_uint8 size = data[7]; - data += 8; + cc_uint8 tintRed = data[5]; + cc_uint8 tintGreen = data[6]; + cc_uint8 tintBlue = data[7]; + cc_uint8 frameCount = data[8]; + cc_uint8 particleCount = data[9]; + cc_uint8 size = data[10]; + data += 11; int sizeVariation = (int)Stream_GetU32_BE(&data[0]); int spread = (int)Stream_GetU32_BE(&data[4]); int speed = (int)Stream_GetU32_BE(&data[8]); @@ -1366,9 +1369,11 @@ static void CPE_DefineParticle(cc_uint8* data) { //e.g. bounds of 0 0, 16 16 makes an 8x8 icon in the default 128x128 particles.png TextureRec rec = { U1/256, V1/256, U2/256, V2/256 }; prop->rec = rec; + PackedCol tint = PackedCol_Make(tintRed, tintGreen, tintBlue, 255); + prop->tint = tint; prop->frameCount = frameCount; prop->particleCount = particleCount; - prop->size = size; + prop->size = size * 0.03125; //divided by 32 to turn it into world units prop->sizeVariation = sizeVariation / 10000.0f; prop->spread = spread; prop->speed = speed / 10000.0f; @@ -1434,7 +1439,7 @@ static void CPE_Reset(void) { Net_Set(OPCODE_SET_HOTBAR, CPE_SetHotbar, 3); Net_Set(OPCODE_SET_SPAWNPOINT, CPE_SetSpawnPoint, 9); Net_Set(OPCODE_VELOCITY_CONTROL, CPE_VelocityControl, 16); - Net_Set(OPCODE_DEFINE_PARTICLE, CPE_DefineParticle, 35); + Net_Set(OPCODE_DEFINE_PARTICLE, CPE_DefineParticle, 38); Net_Set(OPCODE_SPAWN_PARTICLE, CPE_SpawnParticle, 26); } From 5e45c0214d8b080b32bdccdaab46ed6c6e360265 Mon Sep 17 00:00:00 2001 From: Goodlyay Date: Sat, 22 Feb 2020 01:34:06 -0800 Subject: [PATCH 06/11] Fix declaring support for custom particles --- src/Protocol.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Protocol.c b/src/Protocol.c index e09c8e911..3fc7c9012 100644 --- a/src/Protocol.c +++ b/src/Protocol.c @@ -727,13 +727,13 @@ static void Classic_Tick(void) { /*########################################################################################################################* *------------------------------------------------------CPE protocol-------------------------------------------------------* *#########################################################################################################################*/ -static const char* cpe_clientExtensions[33] = { +static const char* cpe_clientExtensions[35] = { "ClickDistance", "CustomBlocks", "HeldBlock", "EmoteFix", "TextHotKey", "ExtPlayerList", "EnvColors", "SelectionCuboid", "BlockPermissions", "ChangeModel", "EnvMapAppearance", "EnvWeatherType", "MessageTypes", "HackControl", "PlayerClick", "FullCP437", "LongerMessages", "BlockDefinitions", "BlockDefinitionsExt", "BulkBlockUpdate", "TextColors", "EnvMapAspect", "EntityProperty", "ExtEntityPositions", "TwoWayPing", "InventoryOrder", "InstantMOTD", "FastMap", "SetHotbar", - "SetSpawnpoint", "VelocityControl", + "SetSpawnpoint", "VelocityControl", "DefineParticle", "SpawnParticle", /* NOTE: These must be placed last for when EXTENDED_TEXTURES or EXTENDED_BLOCKS are not defined */ "ExtendedTextures", "ExtendedBlocks" }; From be400a0e0290ed750224e3ad9cc35c68af00a3a2 Mon Sep 17 00:00:00 2001 From: UnknownShadow200 Date: Sat, 22 Feb 2020 22:29:38 +1100 Subject: [PATCH 07/11] Fix particles being 0 sized --- src/Protocol.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Protocol.c b/src/Protocol.c index 3fc7c9012..d6d1d606d 100644 --- a/src/Protocol.c +++ b/src/Protocol.c @@ -727,13 +727,13 @@ static void Classic_Tick(void) { /*########################################################################################################################* *------------------------------------------------------CPE protocol-------------------------------------------------------* *#########################################################################################################################*/ -static const char* cpe_clientExtensions[35] = { +static const char* cpe_clientExtensions[34] = { "ClickDistance", "CustomBlocks", "HeldBlock", "EmoteFix", "TextHotKey", "ExtPlayerList", "EnvColors", "SelectionCuboid", "BlockPermissions", "ChangeModel", "EnvMapAppearance", "EnvWeatherType", "MessageTypes", "HackControl", "PlayerClick", "FullCP437", "LongerMessages", "BlockDefinitions", "BlockDefinitionsExt", "BulkBlockUpdate", "TextColors", "EnvMapAspect", "EntityProperty", "ExtEntityPositions", "TwoWayPing", "InventoryOrder", "InstantMOTD", "FastMap", "SetHotbar", - "SetSpawnpoint", "VelocityControl", "DefineParticle", "SpawnParticle", + "SetSpawnpoint", "VelocityControl", "CustomParticles", /* NOTE: These must be placed last for when EXTENDED_TEXTURES or EXTENDED_BLOCKS are not defined */ "ExtendedTextures", "ExtendedBlocks" }; @@ -1367,7 +1367,7 @@ static void CPE_DefineParticle(cc_uint8* data) { struct CustomParticleProperty* prop; prop = &customParticle_properties[particleID]; //e.g. bounds of 0 0, 16 16 makes an 8x8 icon in the default 128x128 particles.png - TextureRec rec = { U1/256, V1/256, U2/256, V2/256 }; + TextureRec rec = { U1/256.0f, V1/256.0f, U2/256.0f, V2/256.0f }; prop->rec = rec; PackedCol tint = PackedCol_Make(tintRed, tintGreen, tintBlue, 255); prop->tint = tint; From 523462d829aa442a0c5176b5e4a98fd7441d5b17 Mon Sep 17 00:00:00 2001 From: UnknownShadow200 Date: Sat, 22 Feb 2020 23:00:16 +1100 Subject: [PATCH 08/11] cleanup code a bit --- src/Particle.c | 52 ++++++++++++++--------------- src/Particle.h | 12 +++---- src/Program.c | 4 +-- src/Protocol.c | 89 +++++++++++++++++++------------------------------- src/Protocol.h | 2 +- 5 files changed, 67 insertions(+), 92 deletions(-) diff --git a/src/Particle.c b/src/Particle.c index a458b0ab1..db253e12c 100644 --- a/src/Particle.c +++ b/src/Particle.c @@ -302,14 +302,14 @@ struct CustomParticle { float totalLifespan; }; -struct CustomParticleProperty customParticle_properties[256]; -static struct CustomParticle customParticle_particles[PARTICLES_MAX]; -static int customParticle_count; -static TextureRec defaultCustomParticle_rec = { 0.0f / 128.0f, 24.0f / 128.0f, 16.0f / 128.0f, 40.0f / 128.0f }; +struct CustomParticleProperty Particles_CustomEffects[256]; +static struct CustomParticle custom_particles[PARTICLES_MAX]; +static int custom_count; static cc_bool CustomParticle_Tick(struct CustomParticle* p, double delta) { particle_hitTerrain = false; - return Particle_PhysicsTick(&p->base, p->prop->gravity, false, delta) || (particle_hitTerrain && p->prop->expireUponTouchingGround); + return Particle_PhysicsTick(&p->base, p->prop->gravity, false, delta) + || (particle_hitTerrain && p->prop->expireUponTouchingGround); } static void CustomParticle_Render(struct CustomParticle* p, float t, VertexP3fT2fC4b* vertices) { @@ -317,6 +317,7 @@ static void CustomParticle_Render(struct CustomParticle* p, float t, VertexP3fT2 Vec2 size; PackedCol col; TextureRec rec = p->prop->rec; + int x, y, z; float frame_time = p->totalLifespan / p->prop->frameCount; float inverted_lifetime = Math_AbsF(p->base.lifetime - p->totalLifespan); @@ -325,7 +326,6 @@ static void CustomParticle_Render(struct CustomParticle* p, float t, VertexP3fT2 rec.U1 += shiftU;// * 0.0078125f; rec.U2 += shiftU;// * 0.0078125f; - int x, y, z; Vec3_Lerp(&pos, &p->base.lastPos, &p->base.nextPos, t); size.X = p->base.size; size.Y = size.X; @@ -340,34 +340,30 @@ static void CustomParticle_Render(struct CustomParticle* p, float t, VertexP3fT2 static void Custom_Render(float t) { VertexP3fT2fC4b* data; int i; - if (!customParticle_count) return; + if (!custom_count) return; - data = (VertexP3fT2fC4b*)Gfx_LockDynamicVb(Particles_VB, VERTEX_FORMAT_P3FT2FC4B, customParticle_count * 4); - for (i = 0; i < customParticle_count; i++) { - CustomParticle_Render(&customParticle_particles[i], t, data); + data = (VertexP3fT2fC4b*)Gfx_LockDynamicVb(Particles_VB, VERTEX_FORMAT_P3FT2FC4B, custom_count * 4); + for (i = 0; i < custom_count; i++) { + CustomParticle_Render(&custom_particles[i], t, data); data += 4; } Gfx_BindTexture(Particles_TexId); Gfx_UnlockDynamicVb(Particles_VB); - Gfx_DrawVb_IndexedTris(customParticle_count * 4); + Gfx_DrawVb_IndexedTris(custom_count * 4); } -static void Custom_RemoveAt(int index) { - struct CustomParticle removed = customParticle_particles[index]; - int i; - - for (i = index; i < customParticle_count - 1; i++) { - customParticle_particles[i] = customParticle_particles[i + 1]; +static void Custom_RemoveAt(int i) { + for (; i < custom_count - 1; i++) { + custom_particles[i] = custom_particles[i + 1]; } - customParticle_particles[customParticle_count - 1] = removed; - customParticle_count--; + custom_count--; } static void Custom_Tick(double delta) { int i; - for (i = 0; i < customParticle_count; i++) { - if (CustomParticle_Tick(&customParticle_particles[i], delta)) { + for (i = 0; i < custom_count; i++) { + if (CustomParticle_Tick(&custom_particles[i], delta)) { Custom_RemoveAt(i); i--; } } @@ -378,7 +374,7 @@ static void Custom_Tick(double delta) { *--------------------------------------------------------Particles--------------------------------------------------------* *#########################################################################################################################*/ void Particles_Render(float t) { - if (!terrain_count && !rain_count && !customParticle_count) return; + if (!terrain_count && !rain_count && !custom_count) return; if (Gfx.LostContext) return; Gfx_SetTexturing(true); @@ -504,15 +500,15 @@ void Particles_RainSnowEffect(float x, float y, float z) { } } -void Particles_CustomEffect(int propertyID, float x, float y, float z, float originX, float originY, float originZ) { +void Particles_CustomEffect(int effectID, float x, float y, float z, float originX, float originY, float originZ) { struct CustomParticle* p; - struct CustomParticleProperty* prop = &customParticle_properties[propertyID]; + struct CustomParticleProperty* prop = &Particles_CustomEffects[effectID]; int i; int count = prop->particleCount; for (i = 0; i < count; i++) { - if (customParticle_count == PARTICLES_MAX) Custom_RemoveAt(0); - p = &customParticle_particles[customParticle_count++]; + if (custom_count == PARTICLES_MAX) Custom_RemoveAt(0); + p = &custom_particles[custom_count++]; p->prop = prop; Vec3 offset = { Random_Float(&rnd) - 0.5f, Random_Float(&rnd) - 0.5f, Random_Float(&rnd) - 0.5f }; @@ -520,7 +516,7 @@ void Particles_CustomEffect(int propertyID, float x, float y, float z, float ori float d = Random_Float(&rnd); d = Math_Exp(Math_Log(d) / 3.0); Vec3_Mul1By(&offset, d); - Vec3_Mul1By(&offset, p->prop->spread*0.03125f); + Vec3_Mul1By(&offset, p->prop->spread); p->base.lastPos.X = x + (offset.X); p->base.lastPos.Y = y + (offset.Y); p->base.lastPos.Z = z + (offset.Z); @@ -590,7 +586,7 @@ static void Particles_Free(void) { Event_UnregisterVoid(&GfxEvents.ContextRecreated, NULL, OnContextRecreated); } -static void Particles_Reset(void) { rain_count = 0; terrain_count = 0; customParticle_count = 0; } +static void Particles_Reset(void) { rain_count = 0; terrain_count = 0; custom_count = 0; } struct IGameComponent Particles_Component = { Particles_Init, /* Init */ diff --git a/src/Particle.h b/src/Particle.h index 05432e846..e6d2c0fab 100644 --- a/src/Particle.h +++ b/src/Particle.h @@ -17,14 +17,14 @@ struct Particle { float size; }; -struct CustomParticleProperty { +struct CustomParticleEffect { TextureRec rec; PackedCol tint; int frameCount; - int particleCount; //how many of this particle are spawned per spawn-packet - float size; //size of the particle in fixed-point world units (e.g. 32 is a full block's length) + int particleCount; + float size; float sizeVariation; - float spread; //how far from the spawnpoint their location can vary (in fixed-point world units) + float spread; //how far from the spawnpoint their location can vary float speed; //how fast they move away/towards the origin float gravity; float baseLifetime; //how long (in seconds) the particle lives for @@ -33,7 +33,7 @@ struct CustomParticleProperty { cc_bool fullBright; }; -extern struct CustomParticleProperty customParticle_properties[256]; +extern struct CustomParticleEffect Particles_CustomEffects[256]; /* http://www.opengl-tutorial.org/intermediate-tutorials/billboards-particles/billboards/ */ void Particle_DoRender(const Vec2* size, const Vec3* pos, const TextureRec* rec, PackedCol col, VertexP3fT2fC4b* vertices); @@ -41,5 +41,5 @@ void Particles_Render(float t); void Particles_Tick(struct ScheduledTask* task); void Particles_BreakBlockEffect(IVec3 coords, BlockID oldBlock, BlockID block); void Particles_RainSnowEffect(float x, float y, float z); -void Particles_CustomEffect(int propertyID, float x, float y, float z, float originX, float originY, float originZ); +void Particles_CustomEffect(int effectID, float x, float y, float z, float originX, float originY, float originZ); #endif diff --git a/src/Program.c b/src/Program.c index 1554d92da..ee48a7a6e 100644 --- a/src/Program.c +++ b/src/Program.c @@ -107,9 +107,9 @@ static int Program_Run(int argc, char** argv) { int argsCount = Platform_GetCommandLineArgs(argc, argv, args); #ifdef _MSC_VER /* NOTE: Make sure to comment this out before pushing a commit */ - //String rawArgs = String_FromConst("UnknownShadow200 fffff 127.0.0.1 25565"); + String rawArgs = String_FromConst("UnknownShadow200 fffff 127.0.0.1 25565"); //String rawArgs = String_FromConst("UnknownShadow200"); - //argsCount = String_UNSAFE_Split(&rawArgs, ' ', args, 4); + argsCount = String_UNSAFE_Split(&rawArgs, ' ', args, 4); #endif if (argsCount == 0) { diff --git a/src/Protocol.c b/src/Protocol.c index d6d1d606d..7929dc31a 100644 --- a/src/Protocol.c +++ b/src/Protocol.c @@ -1340,63 +1340,42 @@ static void CPE_VelocityControl(cc_uint8* data) { CalcVelocity(&p->Base.Velocity.Z, data + 8, data[14]); } -static void CPE_DefineParticle(cc_uint8* data) { - cc_uint8 particleID = data[0]; - cc_uint8 U1 = data[1]; - cc_uint8 V1 = data[2]; - cc_uint8 U2 = data[3]; - cc_uint8 V2 = data[4]; - cc_uint8 tintRed = data[5]; - cc_uint8 tintGreen = data[6]; - cc_uint8 tintBlue = data[7]; - cc_uint8 frameCount = data[8]; - cc_uint8 particleCount = data[9]; - cc_uint8 size = data[10]; - data += 11; - int sizeVariation = (int)Stream_GetU32_BE(&data[0]); - int spread = (int)Stream_GetU32_BE(&data[4]); - int speed = (int)Stream_GetU32_BE(&data[8]); - int gravity = (int)Stream_GetU32_BE(&data[12]); - int baseLifetime = (int)Stream_GetU32_BE(&data[16]); - int lifetimeVariation = (int)Stream_GetU32_BE(&data[20]); - data += 24; - cc_uint8 expireUponTouchingGround = data[0]; - cc_uint8 fullBright = data[1]; - data += 2; +static void CPE_DefineEffect(cc_uint8* data) { + struct CustomParticleProperty* effect = &Particles_CustomEffects[data[0]]; - struct CustomParticleProperty* prop; - prop = &customParticle_properties[particleID]; - //e.g. bounds of 0 0, 16 16 makes an 8x8 icon in the default 128x128 particles.png - TextureRec rec = { U1/256.0f, V1/256.0f, U2/256.0f, V2/256.0f }; - prop->rec = rec; - PackedCol tint = PackedCol_Make(tintRed, tintGreen, tintBlue, 255); - prop->tint = tint; - prop->frameCount = frameCount; - prop->particleCount = particleCount; - prop->size = size * 0.03125; //divided by 32 to turn it into world units - prop->sizeVariation = sizeVariation / 10000.0f; - prop->spread = spread; - prop->speed = speed / 10000.0f; - prop->gravity = gravity / 10000.0f; - prop->baseLifetime = baseLifetime / 10000.0f; - prop->lifetimeVariation = lifetimeVariation / 10000.0f; - prop->expireUponTouchingGround = expireUponTouchingGround; - prop->fullBright = fullBright; + /* e.g. bounds of 0,0, 15,15 gives an 8x8 icon in the default 128x128 particles.png */ + effect->rec.U1 = data[1] / 256.0f; + effect->rec.V1 = data[2] / 256.0f; + effect->rec.U2 = (data[3] + 1) / 256.0f; + effect->rec.V2 = (data[4] + 1) / 256.0f; + + effect->tint = PackedCol_Make(data[5], data[6], data[7], 255); + effect->frameCount = data[8]; + effect->particleCount = data[9]; + effect->size = data[10] / 32.0f; /* 32 units per block */ + + effect->sizeVariation = (int)Stream_GetU32_BE(data + 11) / 10000.0f; + effect->spread = (int)Stream_GetU32_BE(data + 15) / 32.0f; /* TODO: should be 10000? */ + effect->speed = (int)Stream_GetU32_BE(data + 19) / 10000.0f; + effect->gravity = (int)Stream_GetU32_BE(data + 23) / 10000.0f; + effect->baseLifetime = (int)Stream_GetU32_BE(data + 27) / 10000.0f; + effect->lifetimeVariation = (int)Stream_GetU32_BE(data + 31) / 10000.0f; + + effect->expireUponTouchingGround = data[35]; + effect->fullBright = data[36]; } -static void CPE_SpawnParticle(cc_uint8* data) { - cc_uint8 particleID = data[0]; - data++; - int x, y, z, originX, originY, originZ; +static void CPE_SpawnEffect(cc_uint8* data) { + float x, y, z, originX, originY, originZ; - x = (int)Stream_GetU32_BE(&data[0]); - y = (int)Stream_GetU32_BE(&data[4]); - z = (int)Stream_GetU32_BE(&data[8]); - originX = (int)Stream_GetU32_BE(&data[12]); - originY = (int)Stream_GetU32_BE(&data[16]); - originZ = (int)Stream_GetU32_BE(&data[20]); - data += 24; - Particles_CustomEffect(particleID, x / 32.0f, y / 32.0f, z / 32.0f, originX / 32.0f, originY / 32.0f, originZ / 32.0f); + x = (int)Stream_GetU32_BE(data + 1) / 32.0f; + y = (int)Stream_GetU32_BE(data + 5) / 32.0f; + z = (int)Stream_GetU32_BE(data + 9) / 32.0f; + originX = (int)Stream_GetU32_BE(data + 13) / 32.0f; + originY = (int)Stream_GetU32_BE(data + 17) / 32.0f; + originZ = (int)Stream_GetU32_BE(data + 21) / 32.0f; + + Particles_CustomEffect(data[0], x, y, z, originX, originY, originZ); } static void CPE_Reset(void) { @@ -1439,8 +1418,8 @@ static void CPE_Reset(void) { Net_Set(OPCODE_SET_HOTBAR, CPE_SetHotbar, 3); Net_Set(OPCODE_SET_SPAWNPOINT, CPE_SetSpawnPoint, 9); Net_Set(OPCODE_VELOCITY_CONTROL, CPE_VelocityControl, 16); - Net_Set(OPCODE_DEFINE_PARTICLE, CPE_DefineParticle, 38); - Net_Set(OPCODE_SPAWN_PARTICLE, CPE_SpawnParticle, 26); + Net_Set(OPCODE_DEFINE_EFFECT, CPE_DefineEffect, 38); + Net_Set(OPCODE_SPAWN_EFFECT, CPE_SpawnEffect, 26); } static void CPE_Tick(void) { diff --git a/src/Protocol.h b/src/Protocol.h index 1758e2443..95f3b239b 100644 --- a/src/Protocol.h +++ b/src/Protocol.h @@ -33,7 +33,7 @@ enum OPCODE_ { OPCODE_SET_ENTITY_PROPERTY, OPCODE_TWO_WAY_PING, OPCODE_SET_INVENTORY_ORDER, OPCODE_SET_HOTBAR, OPCODE_SET_SPAWNPOINT, OPCODE_VELOCITY_CONTROL, - OPCODE_DEFINE_PARTICLE, OPCODE_SPAWN_PARTICLE, + OPCODE_DEFINE_EFFECT, OPCODE_SPAWN_EFFECT, OPCODE_COUNT }; From a5c3e296e9546b5acabfc71cd5ffba64657ed7d9 Mon Sep 17 00:00:00 2001 From: UnknownShadow200 Date: Sat, 22 Feb 2020 23:39:30 +1100 Subject: [PATCH 09/11] reduce custom particles memory usage by 2kb on 32 bit, 9kb on 64 bit --- src/Particle.c | 59 ++++++++++++++++++++++++++++---------------------- src/Particle.h | 10 ++++----- src/Program.c | 4 ++-- src/Protocol.c | 34 ++++++++++++++--------------- 4 files changed, 57 insertions(+), 50 deletions(-) diff --git a/src/Particle.c b/src/Particle.c index db253e12c..428d5b297 100644 --- a/src/Particle.c +++ b/src/Particle.c @@ -298,28 +298,31 @@ static void Terrain_Tick(double delta) { *#########################################################################################################################*/ struct CustomParticle { struct Particle base; - struct CustomParticleProperty* prop; + int effectId; float totalLifespan; }; -struct CustomParticleProperty Particles_CustomEffects[256]; +struct CustomParticleEffect Particles_CustomEffects[256]; static struct CustomParticle custom_particles[PARTICLES_MAX]; static int custom_count; static cc_bool CustomParticle_Tick(struct CustomParticle* p, double delta) { + struct CustomParticleEffect* e = &Particles_CustomEffects[p->effectId]; particle_hitTerrain = false; - return Particle_PhysicsTick(&p->base, p->prop->gravity, false, delta) - || (particle_hitTerrain && p->prop->expireUponTouchingGround); + + return Particle_PhysicsTick(&p->base, e->gravity, false, delta) + || (particle_hitTerrain && e->expireUponTouchingGround); } static void CustomParticle_Render(struct CustomParticle* p, float t, VertexP3fT2fC4b* vertices) { + struct CustomParticleEffect* e = &Particles_CustomEffects[p->effectId]; Vec3 pos; Vec2 size; PackedCol col; - TextureRec rec = p->prop->rec; + TextureRec rec = e->rec; int x, y, z; - float frame_time = p->totalLifespan / p->prop->frameCount; + float frame_time = p->totalLifespan / e->frameCount; float inverted_lifetime = Math_AbsF(p->base.lifetime - p->totalLifespan); int curFrame = Math_Floor(inverted_lifetime / frame_time); float shiftU = curFrame * (rec.U2 - rec.U1); @@ -331,8 +334,8 @@ static void CustomParticle_Render(struct CustomParticle* p, float t, VertexP3fT2 size.X = p->base.size; size.Y = size.X; x = Math_Floor(pos.X); y = Math_Floor(pos.Y); z = Math_Floor(pos.Z); - col = p->prop->fullBright ? PACKEDCOL_WHITE : (World_Contains(x, y, z) ? Lighting_Col(x, y, z) : Env.SunCol); - col = PackedCol_Tint(col, p->prop->tint); + col = e->fullBright ? PACKEDCOL_WHITE : (World_Contains(x, y, z) ? Lighting_Col(x, y, z) : Env.SunCol); + col = PackedCol_Tint(col, e->tintCol); Particle_DoRender(&size, &pos, &rec, col, vertices); } @@ -502,24 +505,28 @@ void Particles_RainSnowEffect(float x, float y, float z) { void Particles_CustomEffect(int effectID, float x, float y, float z, float originX, float originY, float originZ) { struct CustomParticle* p; - struct CustomParticleProperty* prop = &Particles_CustomEffects[effectID]; - int i; - int count = prop->particleCount; + struct CustomParticleEffect* e = &Particles_CustomEffects[effectID]; + int i, count = e->particleCount; + Vec3 offset; + float d; for (i = 0; i < count; i++) { if (custom_count == PARTICLES_MAX) Custom_RemoveAt(0); p = &custom_particles[custom_count++]; - p->prop = prop; + p->effectId = effectID; - Vec3 offset = { Random_Float(&rnd) - 0.5f, Random_Float(&rnd) - 0.5f, Random_Float(&rnd) - 0.5f }; + offset.X = Random_Float(&rnd) - 0.5f; + offset.Y = Random_Float(&rnd) - 0.5f; + offset.Z = Random_Float(&rnd) - 0.5f; Vec3_Normalize(&offset, &offset); - float d = Random_Float(&rnd); - d = Math_Exp(Math_Log(d) / 3.0); - Vec3_Mul1By(&offset, d); - Vec3_Mul1By(&offset, p->prop->spread); - p->base.lastPos.X = x + (offset.X); - p->base.lastPos.Y = y + (offset.Y); - p->base.lastPos.Z = z + (offset.Z); + + d = Random_Float(&rnd); + d = Math_Exp(Math_Log(d) / 3.0); /* d^1/3 for better distribution */ + d *= e->spread; + + p->base.lastPos.X = x + offset.X * d; + p->base.lastPos.Y = y + offset.Y * d; + p->base.lastPos.Z = z + offset.Z * d; Vec3 origin = { originX, originY, originZ }; if (Vec3_Equals(&origin, &p->base.lastPos)) { @@ -531,16 +538,16 @@ void Particles_CustomEffect(int effectID, float x, float y, float z, float origi Vec3 diff; Vec3_Sub(&diff, &p->base.lastPos, &origin); Vec3_Normalize(&diff, &diff); - p->base.velocity.X = diff.X * p->prop->speed; - p->base.velocity.Y = diff.Y * p->prop->speed; - p->base.velocity.Z = diff.Z * p->prop->speed; + p->base.velocity.X = diff.X * e->speed; + p->base.velocity.Y = diff.Y * e->speed; + p->base.velocity.Z = diff.Z * e->speed; } - p->base.nextPos = p->base.lastPos; - p->base.lifetime = p->prop->baseLifetime + ( (p->prop->baseLifetime * p->prop->lifetimeVariation) * ((Random_Float(&rnd) - 0.5f) * 2)); + p->base.nextPos = p->base.lastPos; + p->base.lifetime = e->baseLifetime + (e->baseLifetime * e->lifetimeVariation) * ((Random_Float(&rnd) - 0.5f) * 2); p->totalLifespan = p->base.lifetime; - p->base.size = p->prop->size + ( (p->prop->size * p->prop->sizeVariation) * ((Random_Float(&rnd) - 0.5f) * 2) ) ; + p->base.size = e->size + (e->size * e->sizeVariation) * ((Random_Float(&rnd) - 0.5f) * 2); } } diff --git a/src/Particle.h b/src/Particle.h index e6d2c0fab..1d5dad4e8 100644 --- a/src/Particle.h +++ b/src/Particle.h @@ -19,9 +19,11 @@ struct Particle { struct CustomParticleEffect { TextureRec rec; - PackedCol tint; - int frameCount; - int particleCount; + PackedCol tintCol; + cc_uint8 frameCount; + cc_uint8 particleCount; + cc_bool expireUponTouchingGround; + cc_bool fullBright; float size; float sizeVariation; float spread; //how far from the spawnpoint their location can vary @@ -29,8 +31,6 @@ struct CustomParticleEffect { float gravity; float baseLifetime; //how long (in seconds) the particle lives for float lifetimeVariation; - cc_bool expireUponTouchingGround; - cc_bool fullBright; }; extern struct CustomParticleEffect Particles_CustomEffects[256]; diff --git a/src/Program.c b/src/Program.c index ee48a7a6e..1554d92da 100644 --- a/src/Program.c +++ b/src/Program.c @@ -107,9 +107,9 @@ static int Program_Run(int argc, char** argv) { int argsCount = Platform_GetCommandLineArgs(argc, argv, args); #ifdef _MSC_VER /* NOTE: Make sure to comment this out before pushing a commit */ - String rawArgs = String_FromConst("UnknownShadow200 fffff 127.0.0.1 25565"); + //String rawArgs = String_FromConst("UnknownShadow200 fffff 127.0.0.1 25565"); //String rawArgs = String_FromConst("UnknownShadow200"); - argsCount = String_UNSAFE_Split(&rawArgs, ' ', args, 4); + //argsCount = String_UNSAFE_Split(&rawArgs, ' ', args, 4); #endif if (argsCount == 0) { diff --git a/src/Protocol.c b/src/Protocol.c index 7929dc31a..69f55cfe8 100644 --- a/src/Protocol.c +++ b/src/Protocol.c @@ -1341,28 +1341,28 @@ static void CPE_VelocityControl(cc_uint8* data) { } static void CPE_DefineEffect(cc_uint8* data) { - struct CustomParticleProperty* effect = &Particles_CustomEffects[data[0]]; + struct CustomParticleEffect* e = &Particles_CustomEffects[data[0]]; /* e.g. bounds of 0,0, 15,15 gives an 8x8 icon in the default 128x128 particles.png */ - effect->rec.U1 = data[1] / 256.0f; - effect->rec.V1 = data[2] / 256.0f; - effect->rec.U2 = (data[3] + 1) / 256.0f; - effect->rec.V2 = (data[4] + 1) / 256.0f; + e->rec.U1 = data[1] / 256.0f; + e->rec.V1 = data[2] / 256.0f; + e->rec.U2 = (data[3] + 1) / 256.0f; + e->rec.V2 = (data[4] + 1) / 256.0f; - effect->tint = PackedCol_Make(data[5], data[6], data[7], 255); - effect->frameCount = data[8]; - effect->particleCount = data[9]; - effect->size = data[10] / 32.0f; /* 32 units per block */ + e->tintCol = PackedCol_Make(data[5], data[6], data[7], 255); + e->frameCount = data[8]; + e->particleCount = data[9]; + e->size = data[10] / 32.0f; /* 32 units per block */ - effect->sizeVariation = (int)Stream_GetU32_BE(data + 11) / 10000.0f; - effect->spread = (int)Stream_GetU32_BE(data + 15) / 32.0f; /* TODO: should be 10000? */ - effect->speed = (int)Stream_GetU32_BE(data + 19) / 10000.0f; - effect->gravity = (int)Stream_GetU32_BE(data + 23) / 10000.0f; - effect->baseLifetime = (int)Stream_GetU32_BE(data + 27) / 10000.0f; - effect->lifetimeVariation = (int)Stream_GetU32_BE(data + 31) / 10000.0f; + e->sizeVariation = (int)Stream_GetU32_BE(data + 11) / 10000.0f; + e->spread = (int)Stream_GetU32_BE(data + 15) / 32.0f; /* TODO: should be 10000? */ + e->speed = (int)Stream_GetU32_BE(data + 19) / 10000.0f; + e->gravity = (int)Stream_GetU32_BE(data + 23) / 10000.0f; + e->baseLifetime = (int)Stream_GetU32_BE(data + 27) / 10000.0f; + e->lifetimeVariation = (int)Stream_GetU32_BE(data + 31) / 10000.0f; - effect->expireUponTouchingGround = data[35]; - effect->fullBright = data[36]; + e->expireUponTouchingGround = data[35]; + e->fullBright = data[36]; } static void CPE_SpawnEffect(cc_uint8* data) { From 68639f9772032f2859db00eef1a3012482807c5e Mon Sep 17 00:00:00 2001 From: UnknownShadow200 Date: Sun, 23 Feb 2020 00:24:12 +1100 Subject: [PATCH 10/11] Make CustomParticle_Render slightly faster --- src/Particle.c | 5 ++--- src/Particle.h | 6 +++--- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/Particle.c b/src/Particle.c index 428d5b297..f1217acc3 100644 --- a/src/Particle.c +++ b/src/Particle.c @@ -322,9 +322,8 @@ static void CustomParticle_Render(struct CustomParticle* p, float t, VertexP3fT2 TextureRec rec = e->rec; int x, y, z; - float frame_time = p->totalLifespan / e->frameCount; - float inverted_lifetime = Math_AbsF(p->base.lifetime - p->totalLifespan); - int curFrame = Math_Floor(inverted_lifetime / frame_time); + float time_lived = p->totalLifespan - p->base.lifetime; + int curFrame = Math_Floor(e->frameCount * (time_lived / p->totalLifespan)); float shiftU = curFrame * (rec.U2 - rec.U1); rec.U1 += shiftU;// * 0.0078125f; diff --git a/src/Particle.h b/src/Particle.h index 1d5dad4e8..93e4fd6af 100644 --- a/src/Particle.h +++ b/src/Particle.h @@ -26,10 +26,10 @@ struct CustomParticleEffect { cc_bool fullBright; float size; float sizeVariation; - float spread; //how far from the spawnpoint their location can vary - float speed; //how fast they move away/towards the origin + float spread; /* how far from the spawnpoint their location can vary */ + float speed; /* how fast they move away/towards the origin */ float gravity; - float baseLifetime; //how long (in seconds) the particle lives for + float baseLifetime; /* how long (in seconds) the particle lives for */ float lifetimeVariation; }; From 40cbde4c8e77368a7121fd5f9101f9f4320b2cca Mon Sep 17 00:00:00 2001 From: UnknownShadow200 Date: Sun, 23 Feb 2020 10:30:10 +1100 Subject: [PATCH 11/11] Make spread 16 bit unsigned integer instead --- src/Protocol.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/Protocol.c b/src/Protocol.c index 69f55cfe8..5b09148de 100644 --- a/src/Protocol.c +++ b/src/Protocol.c @@ -1355,14 +1355,14 @@ static void CPE_DefineEffect(cc_uint8* data) { e->size = data[10] / 32.0f; /* 32 units per block */ e->sizeVariation = (int)Stream_GetU32_BE(data + 11) / 10000.0f; - e->spread = (int)Stream_GetU32_BE(data + 15) / 32.0f; /* TODO: should be 10000? */ - e->speed = (int)Stream_GetU32_BE(data + 19) / 10000.0f; - e->gravity = (int)Stream_GetU32_BE(data + 23) / 10000.0f; - e->baseLifetime = (int)Stream_GetU32_BE(data + 27) / 10000.0f; - e->lifetimeVariation = (int)Stream_GetU32_BE(data + 31) / 10000.0f; + e->spread = Stream_GetU16_BE(data + 15) / 32.0f; + e->speed = (int)Stream_GetU32_BE(data + 17) / 10000.0f; + e->gravity = (int)Stream_GetU32_BE(data + 21) / 10000.0f; + e->baseLifetime = (int)Stream_GetU32_BE(data + 25) / 10000.0f; + e->lifetimeVariation = (int)Stream_GetU32_BE(data + 29) / 10000.0f; - e->expireUponTouchingGround = data[35]; - e->fullBright = data[36]; + e->expireUponTouchingGround = data[33]; + e->fullBright = data[34]; } static void CPE_SpawnEffect(cc_uint8* data) { @@ -1418,7 +1418,7 @@ static void CPE_Reset(void) { Net_Set(OPCODE_SET_HOTBAR, CPE_SetHotbar, 3); Net_Set(OPCODE_SET_SPAWNPOINT, CPE_SetSpawnPoint, 9); Net_Set(OPCODE_VELOCITY_CONTROL, CPE_VelocityControl, 16); - Net_Set(OPCODE_DEFINE_EFFECT, CPE_DefineEffect, 38); + Net_Set(OPCODE_DEFINE_EFFECT, CPE_DefineEffect, 36); Net_Set(OPCODE_SPAWN_EFFECT, CPE_SpawnEffect, 26); }