Skip to content

Commit 3527144

Browse files
committed
Fixed another memory / pointer bug, but there is still one left...
-also some minor fixes
1 parent 06ae14c commit 3527144

File tree

2 files changed

+55
-28
lines changed

2 files changed

+55
-28
lines changed

wled00/FX.cpp

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8078,9 +8078,9 @@ uint16_t mode_particlefireworks(void)
80788078
numRockets = min(PartSys->numSources, (uint8_t)NUMBEROFSOURCES);
80798079
for (j = 0; j < numRockets; j++)
80808080
{
8081-
PartSys->sources[j].source.ttl = 500 * j; // first rocket starts immediately, others follow soon
8082-
PartSys->sources[j].source.vy = -1; // at negative speed, no particles are emitted and if rocket dies, it will be relaunched
8083-
}
8081+
PartSys->sources[j].source.ttl = 500 * j; // first rocket starts immediately, others follow soon
8082+
PartSys->sources[j].source.vy = -1; // at negative speed, no particles are emitted and if rocket dies, it will be relaunched
8083+
}
80848084
}
80858085
else
80868086
PartSys = reinterpret_cast<ParticleSystem *>(SEGMENT.data); // if not first call, just set the pointer to the PS
@@ -8167,6 +8167,14 @@ uint16_t mode_particlefireworks(void)
81678167
}
81688168
else
81698169
{
8170+
/*
8171+
if( PartSys->sources[j].source.vy < 0) //explosion is ongoing
8172+
{
8173+
if(i < (emitparticles>>2)) //set 1/4 of particles to larger size
8174+
PartSys->sources[j].size = 50+random16(140);
8175+
else
8176+
PartSys->sources[j].size = 0;
8177+
}*/
81708178
PartSys->sprayEmit(PartSys->sources[j]);
81718179
if ((j % 3) == 0)
81728180
{
@@ -8353,7 +8361,7 @@ uint16_t mode_particlefire(void)
83538361
}
83548362

83558363
uint32_t spread = (PartSys->maxX >> 5) * (SEGMENT.custom3 + 1); //fire around segment center (in subpixel points)
8356-
numFlames = min((uint32_t)PartSys->numSources, (1 + ((spread / PS_P_RADIUS) << 1))); // number of flames used depends on spread with, good value is (fire width in pixel) * 2
8364+
numFlames = min((uint32_t)PartSys->numSources, (2 + ((spread / PS_P_RADIUS) << 1))); // number of flames used depends on spread with, good value is (fire width in pixel) * 2
83578365
uint32_t percycle = numFlames*2/3;// / 2; // maximum number of particles emitted per cycle (TODO: for ESP826 maybe use flames/2)
83588366
// percycle = map(SEGMENT.intensity,0,255, 2, (numFlames*3) / 2); //TODO: does this give better flames or worse?
83598367

@@ -8420,7 +8428,7 @@ uint16_t mode_particlefire(void)
84208428

84218429
return FRAMETIME;
84228430
}
8423-
static const char _data_FX_MODE_PARTICLEFIRE[] PROGMEM = "PS Fire@Speed,Intensity,Base Heat,Wind,Spread,Smooth,Cylinder,Turbulence;;!;2;pal=35,sx=110,c1=110,c2=50,o1=1";
8431+
static const char _data_FX_MODE_PARTICLEFIRE[] PROGMEM = "PS Fire@Speed,Intensity,Base Heat,Wind,Spread,Smooth,Cylinder,Turbulence;;!;2;pal=35,sx=110,c1=110,c2=50,c3=31,o1=1";
84248432

84258433
/*
84268434
PS Ballpit: particles falling down, user can enable these three options: X-wraparound, side bounce, ground bounce
@@ -8791,8 +8799,8 @@ uint16_t mode_particlebox(void)
87918799
xgravity = ((int16_t)inoise8(SEGMENT.aux0) - 127);
87928800
ygravity = ((int16_t)inoise8(SEGMENT.aux0 + 10000) - 127);
87938801
// scale the gravity force
8794-
xgravity = (xgravity * SEGMENT.custom1) / 50;
8795-
ygravity = (ygravity * SEGMENT.custom1) / 50;
8802+
xgravity = (xgravity * SEGMENT.custom1) / 128;
8803+
ygravity = (ygravity * SEGMENT.custom1) / 128;
87968804
}
87978805
else //go in a circle
87988806
{

wled00/FXparticleSystem.cpp

Lines changed: 40 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,7 @@ void ParticleSystem::particleMoveUpdate(PSparticle &part, PSsettings &options, P
320320
{
321321
if(advancedproperties->size > 0)
322322
usesize = true; //note: variable eases out of frame checking below
323-
particleHardRadius = max(PS_P_MINHARDRADIUS, (int)particlesize + advancedproperties->size);
323+
particleHardRadius = max(PS_P_MINHARDRADIUS, (int)particlesize + (advancedproperties->size));
324324
}
325325
//if wall collisions are enabled, bounce them before they reach the edge, it looks much nicer if the particle is not half out of view
326326
if (options.bounceX)
@@ -340,7 +340,7 @@ void ParticleSystem::particleMoveUpdate(PSparticle &part, PSsettings &options, P
340340
bool isleaving = true;
341341
if(usesize) //using individual particle size
342342
{
343-
if (((newX > -particleHardRadius) || (newX < maxX + particleHardRadius))) // large particle is not yet leaving the view - note: this is not pixel perfect but good enough
343+
if (((newX > -particleHardRadius) && (newX < maxX + particleHardRadius))) // large particle is not yet leaving the view - note: this is not pixel perfect but good enough
344344
isleaving = false;
345345
}
346346

@@ -719,14 +719,8 @@ void ParticleSystem::ParticleSys_render(bool firemode, uint32_t fireintensity)
719719
baseRGB = (CRGB)baseHSV; //convert back to RGB
720720
}
721721
}
722-
723-
if(renderbuffer) //set buffer to zero if it exists
724-
{
725-
memset(renderbuffer[0], 0, 100 * sizeof(CRGB)); // renderbuffer is 10x10 pixels. note: passing the buffer and setting it zero here is faster than creating a new buffer for every particle
726-
}
727-
728-
renderParticle(framebuffer, i, brightness, baseRGB, renderbuffer);
729722

723+
renderParticle(framebuffer, i, brightness, baseRGB, renderbuffer);
730724
}
731725

732726
if(particlesize > 0)
@@ -793,7 +787,27 @@ void ParticleSystem::renderParticle(CRGB **framebuffer, uint32_t particleindex,
793787
if(advPartProps[particleindex].size > 0)
794788
{
795789
if(renderbuffer)
796-
advancedrender = true;
790+
{
791+
advancedrender = true;
792+
//memset(renderbuffer[0], 0, 100 * sizeof(CRGB)); //clear the buffer, renderbuffer is 10x10 pixels
793+
//memset seems to do something bad... trying to set it manually -> was probably a bug in the access below... TODO: remove this
794+
795+
for(int i = 0; i<10;i++) //this works fine but is slower
796+
{
797+
for(int j = 0; j<10;j++)
798+
{
799+
renderbuffer[i][j] = BLACK; //note: this is way slower than memset (but safer)
800+
}
801+
}
802+
803+
//faster: the memory block is 300bytes, or 75*32bit
804+
/*
805+
uint32_t* datablock = reinterpret_cast<uint32_t *>(renderbuffer[0]);
806+
for(int i = 0; i<75;i++)
807+
{
808+
datablock[i] = 0; //note: this is almost as fast as memset but also not safe(?)
809+
}*/
810+
}
797811
else
798812
return; //cannot render without buffer, advanced size particles are allowed out of frame
799813
}
@@ -871,8 +885,6 @@ void ParticleSystem::renderParticle(CRGB **framebuffer, uint32_t particleindex,
871885
if (pxlbrightness[3] >= 0)
872886
pxlbrightness[3] = (precal1 * precal3) >> PS_P_SURFACE; // top left value equal to ((PS_P_RADIUS-dx) * dy * brightess) >> PS_P_SURFACE
873887

874-
875-
876888
if(advancedrender)
877889
{
878890
//render particle to a bigger size
@@ -885,6 +897,7 @@ void ParticleSystem::renderParticle(CRGB **framebuffer, uint32_t particleindex,
885897
fast_color_add(renderbuffer[4][5], color, pxlbrightness[3]); //TODO: make this a loop somehow? needs better coordinate handling...
886898
uint32_t rendersize = 4;
887899
uint32_t offset = 3; //offset to zero coordinate to write/read data in renderbuffer
900+
//TODO: add asymmetrical size support
888901
blur2D(renderbuffer, rendersize, rendersize, advPartProps[particleindex].size, advPartProps[particleindex].size, true, offset, offset, true); //blur to 4x4
889902
if (advPartProps[particleindex].size > 64)
890903
{
@@ -915,20 +928,26 @@ void ParticleSystem::renderParticle(CRGB **framebuffer, uint32_t particleindex,
915928
{
916929
xfb = xfb_orig + xrb;
917930
if(xfb > maxXpixel)
931+
{
918932
if (particlesettings.wrapX) // wrap x to the other side if required
919933
xfb = xfb % (maxXpixel + 1);
920934
else
921935
continue;
936+
}
937+
922938
for(uint32_t yrb = offset; yrb < rendersize+offset; yrb++)
923939
{
924940
yfb = yfb_orig + yrb;
925941
if(yfb > maxYpixel)
926-
if (particlesettings.wrapY) // wrap y to the other side if required
927-
yfb = yfb % (maxYpixel + 1);
928-
else
929-
continue;
942+
{
943+
if (particlesettings.wrapY) // wrap y to the other side if required
944+
yfb = yfb % (maxYpixel + 1);
945+
else
946+
continue;
947+
}
948+
930949
//if(xfb < maxXpixel +1 && yfb < maxYpixel +1)
931-
fast_color_add(framebuffer[xfb][yfb], renderbuffer[xrb][yrb]); //TODO: this is just a test, need to render to correct coordinates with out of frame checking
950+
fast_color_add(framebuffer[xfb][yfb], renderbuffer[xrb][yrb]);
932951
}
933952
}
934953
}
@@ -1364,7 +1383,7 @@ int32_t ParticleSystem::limitSpeed(int32_t speed)
13641383
// allocate memory for the 2D array in one contiguous block and set values to zero
13651384
CRGB **ParticleSystem::allocate2Dbuffer(uint32_t cols, uint32_t rows)
13661385
{
1367-
CRGB ** array2D = (CRGB **)malloc(cols * sizeof(CRGB *) + cols * rows * sizeof(CRGB));
1386+
CRGB ** array2D = (CRGB **)calloc(cols, sizeof(CRGB *) + rows * sizeof(CRGB));
13681387
if (array2D == NULL)
13691388
DEBUG_PRINT(F("PS buffer alloc failed"));
13701389
else
@@ -1375,7 +1394,7 @@ CRGB **ParticleSystem::allocate2Dbuffer(uint32_t cols, uint32_t rows)
13751394
{
13761395
array2D[i] = start + i * rows;
13771396
}
1378-
memset(start, 0, cols * rows * sizeof(CRGB)); // set all values to zero
1397+
//memset(start, 0, cols * rows * sizeof(CRGB)); // set all values to zero (TODO: remove, not needed if calloc is used)
13791398
}
13801399
return array2D;
13811400
}
@@ -1405,8 +1424,8 @@ void ParticleSystem::updatePSpointers(bool isadvanced)
14051424
particles = reinterpret_cast<PSparticle *>(this + 1); // pointer to particle array at data+sizeof(ParticleSystem)
14061425
if(isadvanced)
14071426
{
1408-
sources = reinterpret_cast<PSsource *>(particles + numParticles); // pointer to source(s)
1409-
advPartProps = reinterpret_cast<PSadvancedParticle *>(sources + numParticles);
1427+
sources = reinterpret_cast<PSsource *>(particles + numParticles); // pointer to source(s)
1428+
advPartProps = reinterpret_cast<PSadvancedParticle *>(sources + numParticles);
14101429
}
14111430
else
14121431
{

0 commit comments

Comments
 (0)