Skip to content

Commit f7eba55

Browse files
committed
Bugfixes in PS, improvements to PS Fireworks 1D (wled#4673)
- fixed inconsitencies in size rendering - fixed palette being wrapped in color by position and color by age modes - Fixed bug in memory layout: for some unknown reason, if flags come before particles, last flag is sometimes overwritten, changing memory laout seems to fix that - New color modes in PS Fireworks 1D: - custom3 slider < 16: lower saturation (check1: single color or multi-color explosions) - custom3 slider <= 23: full saturation (check1: single color or multi-color explosions) - custom3 slider > 23: color by speed (check 1 has not effect here) - custom slider = max: color by age or color by position (depends on check1)
1 parent 1cb2a66 commit f7eba55

3 files changed

Lines changed: 72 additions & 47 deletions

File tree

wled00/FX.cpp

Lines changed: 29 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -9467,7 +9467,7 @@ uint16_t mode_particlepit(void) {
94679467
PartSys->particles[i].sat = ((SEGMENT.custom3) << 3) + 7;
94689468
// set particle size
94699469
if (SEGMENT.custom1 == 255) {
9470-
PartSys->setParticleSize(1); // set global size to 1 for advanced rendering
9470+
PartSys->setParticleSize(1); // set global size to 1 for advanced rendering (no single pixel particles)
94719471
PartSys->advPartProps[i].size = hw_random16(SEGMENT.custom1); // set each particle to random size
94729472
} else {
94739473
PartSys->setParticleSize(SEGMENT.custom1); // set global size
@@ -10425,7 +10425,6 @@ uint16_t mode_particlePinball(void) {
1042510425
PartSys->sources[0].sourceFlags.collide = true; // seeded particles will collide (if enabled)
1042610426
PartSys->sources[0].source.x = PS_P_RADIUS_1D; //emit at bottom
1042710427
PartSys->setKillOutOfBounds(true); // out of bounds particles dont return
10428-
PartSys->setUsedParticles(255); // use all available particles for init
1042910428
SEGENV.aux0 = 1;
1043010429
SEGENV.aux1 = 5000; //set out of range to ensure uptate on first call
1043110430
}
@@ -10648,6 +10647,7 @@ uint16_t mode_particleFireworks1D(void) {
1064810647
uint8_t *forcecounter;
1064910648

1065010649
if (SEGMENT.call == 0) { // initialization
10650+
if (!initParticleSystem1D(PartSys, 4, 150, 4, true)) // init advanced particle system
1065110651
if (!initParticleSystem1D(PartSys, 4, 150, 4, true)) // init advanced particle system
1065210652
return mode_static(); // allocation failed or is single pixel
1065310653
PartSys->setKillOutOfBounds(true);
@@ -10661,9 +10661,7 @@ uint16_t mode_particleFireworks1D(void) {
1066110661
// Particle System settings
1066210662
PartSys->updateSystem(); // update system properties (dimensions and data pointers)
1066310663
forcecounter = PartSys->PSdataEnd;
10664-
PartSys->setParticleSize(SEGMENT.check3); // 1 or 2 pixel rendering
1066510664
PartSys->setMotionBlur(SEGMENT.custom2); // anable motion blur
10666-
1066710665
int32_t gravity = (1 + (SEGMENT.speed >> 3)); // gravity value used for rocket speed calculation
1066810666
PartSys->setGravity(SEGMENT.speed ? gravity : 0); // set gravity
1066910667

@@ -10677,17 +10675,17 @@ uint16_t mode_particleFireworks1D(void) {
1067710675
SEGENV.aux0 = 0;
1067810676

1067910677
PartSys->sources[0].sourceFlags.custom1 = 0; //flag used for rocket state
10680-
PartSys->sources[0].source.hue = hw_random16();
10678+
PartSys->sources[0].source.hue = hw_random16(); // different color for each launch
1068110679
PartSys->sources[0].var = 10; // emit variation
1068210680
PartSys->sources[0].v = -10; // emit speed
1068310681
PartSys->sources[0].minLife = 30;
10684-
PartSys->sources[0].maxLife = SEGMENT.check2 ? 400 : 40;
10682+
PartSys->sources[0].maxLife = SEGMENT.check2 ? 400 : 60;
1068510683
PartSys->sources[0].source.x = 0; // start from bottom
1068610684
uint32_t speed = sqrt((gravity * ((PartSys->maxX >> 2) + hw_random16(PartSys->maxX >> 1))) >> 4); // set speed such that rocket explods in frame
1068710685
PartSys->sources[0].source.vx = min(speed, (uint32_t)127);
1068810686
PartSys->sources[0].source.ttl = 4000;
1068910687
PartSys->sources[0].sat = 30; // low saturation exhaust
10690-
PartSys->sources[0].size = 0; // default size
10688+
PartSys->sources[0].size = SEGMENT.check3; // single or double pixel rendering
1069110689
PartSys->sources[0].sourceFlags.reversegrav = false ; // normal gravity
1069210690

1069310691
if (SEGENV.aux0) { // inverted rockets launch from end
@@ -10700,17 +10698,17 @@ uint16_t mode_particleFireworks1D(void) {
1070010698
}
1070110699
else { // rocket is launched
1070210700
int32_t rocketgravity = -gravity;
10703-
int32_t speed = PartSys->sources[0].source.vx;
10701+
int32_t currentspeed = PartSys->sources[0].source.vx;
1070410702
if (SEGENV.aux0) { // negative speed rocket
1070510703
rocketgravity = -rocketgravity;
10706-
speed = -speed;
10704+
currentspeed = -currentspeed;
1070710705
}
1070810706
PartSys->applyForce(PartSys->sources[0].source, rocketgravity, forcecounter[0]);
1070910707
PartSys->particleMoveUpdate(PartSys->sources[0].source, PartSys->sources[0].sourceFlags);
10710-
PartSys->particleMoveUpdate(PartSys->sources[0].source, PartSys->sources[0].sourceFlags); // increase speed by calling the move function twice, also ages twice
10708+
PartSys->particleMoveUpdate(PartSys->sources[0].source, PartSys->sources[0].sourceFlags); // increase rocket speed by calling the move function twice, also ages twice
1071110709
uint32_t rocketheight = SEGENV.aux0 ? PartSys->maxX - PartSys->sources[0].source.x : PartSys->sources[0].source.x;
1071210710

10713-
if (speed < 0 && PartSys->sources[0].source.ttl > 50) // reached apogee
10711+
if (currentspeed < 0 && PartSys->sources[0].source.ttl > 50) // reached apogee
1071410712
PartSys->sources[0].source.ttl = min((uint32_t)50, rocketheight >> (PS_P_RADIUS_SHIFT_1D + 3)); // alive for a few more frames
1071510713

1071610714
if (PartSys->sources[0].source.ttl < 2) { // explode
@@ -10719,19 +10717,32 @@ uint16_t mode_particleFireworks1D(void) {
1071910717
PartSys->sources[0].minLife = 600;
1072010718
PartSys->sources[0].maxLife = 1300;
1072110719
PartSys->sources[0].source.ttl = 100 + hw_random16(64 - (SEGMENT.speed >> 2)); // standby time til next launch
10722-
PartSys->sources[0].sat = 7 + (SEGMENT.custom3 << 3); //color saturation TODO: replace saturation with something more useful?
10723-
PartSys->sources[0].size = hw_random16(SEGMENT.intensity); // random particle size in explosion
10720+
PartSys->sources[0].sat = SEGMENT.custom3 < 16 ? 10 + (SEGMENT.custom3 << 4) : 255; //color saturation
10721+
PartSys->sources[0].size = SEGMENT.check3 ? hw_random16(SEGMENT.intensity) : 0; // random particle size in explosion
1072410722
uint32_t explosionsize = 8 + (PartSys->maxXpixel >> 2) + (PartSys->sources[0].source.x >> (PS_P_RADIUS_SHIFT_1D - 1));
1072510723
explosionsize += hw_random16((explosionsize * SEGMENT.intensity) >> 8);
1072610724
for (uint32_t e = 0; e < explosionsize; e++) { // emit explosion particles
10727-
if (SEGMENT.check1) // colorful mode
10728-
PartSys->sources[0].source.hue = hw_random16(); //random color for each particle
10729-
PartSys->sprayEmit(PartSys->sources[0]); // emit a particle
10725+
int idx = PartSys->sprayEmit(PartSys->sources[0]); // emit a particle
10726+
if(SEGMENT.custom3 > 23) {
10727+
if(SEGMENT.custom3 == 31) { // highest slider value
10728+
PartSys->setColorByAge(SEGMENT.check1); // color by age if colorful mode is enabled
10729+
PartSys->setColorByPosition(!SEGMENT.check1); // color by position otherwise
10730+
}
10731+
else { // if custom3 is set to high value (but not highest), set particle color by initial speed
10732+
PartSys->particles[idx].hue = map(abs(PartSys->particles[idx].vx), 0, PartSys->sources[0].var, 0, 16 + hw_random16(200)); // set hue according to speed, use random amount of palette width
10733+
PartSys->particles[idx].hue += PartSys->sources[0].source.hue; // add hue offset of the rocket (random starting color)
10734+
}
10735+
}
10736+
else {
10737+
if (SEGMENT.check1) // colorful mode
10738+
PartSys->sources[0].source.hue = hw_random16(); //random color for each particle
10739+
}
1073010740
}
1073110741
}
1073210742
}
10733-
if ((SEGMENT.call & 0x01) == 0 && PartSys->sources[0].sourceFlags.custom1 == false) // every second frame and not in standby
10743+
if ((SEGMENT.call & 0x01) == 0 && PartSys->sources[0].sourceFlags.custom1 == false && PartSys->sources[0].source.ttl > 50) // every second frame and not in standby and not about to explode
1073410744
PartSys->sprayEmit(PartSys->sources[0]); // emit exhaust particle
10745+
1073510746
if ((SEGMENT.call & 0x03) == 0) // every fourth frame
1073610747
PartSys->applyFriction(1); // apply friction to all particles
1073710748

@@ -10741,10 +10752,9 @@ uint16_t mode_particleFireworks1D(void) {
1074110752
if (PartSys->particles[i].ttl > 10) PartSys->particles[i].ttl -= 10; //ttl is linked to brightness, this allows to use higher brightness but still a short spark lifespan
1074210753
else PartSys->particles[i].ttl = 0;
1074310754
}
10744-
1074510755
return FRAMETIME;
1074610756
}
10747-
static const char _data_FX_MODE_PS_FIREWORKS1D[] PROGMEM = "PS Fireworks 1D@Gravity,Explosion,Firing side,Blur,Saturation,Colorful,Trail,Smooth;,!;!;1;sx=150,c2=30,c3=31,o1=1,o2=1";
10757+
static const char _data_FX_MODE_PS_FIREWORKS1D[] PROGMEM = "PS Fireworks 1D@Gravity,Explosion,Firing side,Blur,Color,Colorful,Trail,Smooth;,!;!;1;c2=30,o1=1";
1074810758

1074910759
/*
1075010760
Particle based Sparkle effect
@@ -11265,7 +11275,6 @@ uint16_t mode_particle1DGEQ(void) {
1126511275
PartSys->sources[i].maxLife = 240 + SEGMENT.intensity;
1126611276
PartSys->sources[i].sat = 255;
1126711277
PartSys->sources[i].size = SEGMENT.custom1;
11268-
PartSys->setParticleSize(SEGMENT.custom1);
1126911278
PartSys->sources[i].source.x = (spacing >> 1) + spacing * i; //distribute evenly
1127011279
}
1127111280

wled00/FXparticleSystem.cpp

Lines changed: 37 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ ParticleSystem2D::ParticleSystem2D(uint32_t width, uint32_t height, uint32_t num
4848
for (uint32_t i = 0; i < numSources; i++) {
4949
sources[i].source.sat = 255; //set saturation to max by default
5050
sources[i].source.ttl = 1; //set source alive
51+
sources[i].sourceFlags.asByte = 0; // all flags disabled
5152
}
5253

5354
}
@@ -559,6 +560,10 @@ void ParticleSystem2D::pointAttractor(const uint32_t particleindex, PSparticle &
559560
void ParticleSystem2D::render() {
560561
CRGB baseRGB;
561562
uint32_t brightness; // particle brightness, fades if dying
563+
TBlendType blend = LINEARBLEND; // default color rendering: wrap palette
564+
if (particlesettings.colorByAge) {
565+
blend = LINEARBLEND_NOWRAP;
566+
}
562567

563568
if (motionBlur) { // motion-blurring active
564569
for (int32_t y = 0; y <= maxYpixel; y++) {
@@ -581,11 +586,11 @@ void ParticleSystem2D::render() {
581586
if (fireIntesity) { // fire mode
582587
brightness = (uint32_t)particles[i].ttl * (3 + (fireIntesity >> 5)) + 20;
583588
brightness = min(brightness, (uint32_t)255);
584-
baseRGB = ColorFromPalette(SEGPALETTE, brightness, 255);
589+
baseRGB = ColorFromPalette(SEGPALETTE, brightness, 255, LINEARBLEND_NOWRAP);
585590
}
586591
else {
587592
brightness = min((particles[i].ttl << 1), (int)255);
588-
baseRGB = ColorFromPalette(SEGPALETTE, particles[i].hue);
593+
baseRGB = ColorFromPalette(SEGPALETTE, particles[i].hue, blend);
589594
if (particles[i].sat < 255) {
590595
CHSV baseHSV = rgb2hsv_approximate(baseRGB); // convert to HSV
591596
baseHSV.s = particles[i].sat; // set the saturation
@@ -595,14 +600,15 @@ void ParticleSystem2D::render() {
595600
renderParticle(i, brightness, baseRGB, particlesettings.wrapX, particlesettings.wrapY);
596601
}
597602

603+
// apply global size rendering
598604
if (particlesize > 1) {
599605
uint32_t passes = particlesize / 64 + 1; // number of blur passes, four passes max
600606
uint32_t bluramount = particlesize;
601607
uint32_t bitshift = 0;
602608
for (uint32_t i = 0; i < passes; i++) {
603609
if (i == 2) // for the last two passes, use higher amount of blur (results in a nicer brightness gradient with soft edges)
604610
bitshift = 1;
605-
blur2D(framebuffer, maxXpixel + 1, maxYpixel + 1, bluramount << bitshift, bluramount << bitshift);
611+
blur2D(framebuffer, maxXpixel + 1, maxYpixel + 1, bluramount << bitshift, bluramount << bitshift);
606612
bluramount -= 64;
607613
}
608614
}
@@ -623,7 +629,11 @@ void ParticleSystem2D::render() {
623629

624630
// calculate pixel positions and brightness distribution and render the particle to local buffer or global buffer
625631
__attribute__((optimize("O2"))) void ParticleSystem2D::renderParticle(const uint32_t particleindex, const uint8_t brightness, const CRGB& color, const bool wrapX, const bool wrapY) {
626-
if (particlesize == 0) { // single pixel rendering
632+
uint32_t size = particlesize;
633+
if (advPartProps && advPartProps[particleindex].size > 0) // use advanced size properties (0 means use global size including single pixel rendering)
634+
size = advPartProps[particleindex].size;
635+
636+
if (size == 0) { // single pixel rendering
627637
uint32_t x = particles[particleindex].x >> PS_P_RADIUS_SHIFT;
628638
uint32_t y = particles[particleindex].y >> PS_P_RADIUS_SHIFT;
629639
if (x <= (uint32_t)maxXpixel && y <= (uint32_t)maxYpixel) {
@@ -664,7 +674,7 @@ __attribute__((optimize("O2"))) void ParticleSystem2D::renderParticle(const uint
664674
pxlbrightness[2] = (dx * precal3) >> PS_P_SURFACE; // top right value equal to (dx * dy * brightness) >> PS_P_SURFACE
665675
pxlbrightness[3] = (precal1 * precal3) >> PS_P_SURFACE; // top left value equal to ((PS_P_RADIUS-dx) * dy * brightness) >> PS_P_SURFACE
666676

667-
if (advPartProps && advPartProps[particleindex].size > 0) { //render particle to a bigger size
677+
if (advPartProps && advPartProps[particleindex].size > 1) { //render particle to a bigger size
668678
CRGB renderbuffer[100]; // 10x10 pixel buffer
669679
memset(renderbuffer, 0, sizeof(renderbuffer)); // clear buffer
670680
//particle size to pixels: < 64 is 4x4, < 128 is 6x6, < 192 is 8x8, bigger is 10x10
@@ -959,15 +969,13 @@ void ParticleSystem2D::updateSystem(void) {
959969
// FX handles the PSsources, need to tell this function how many there are
960970
void ParticleSystem2D::updatePSpointers(bool isadvanced, bool sizecontrol) {
961971
PSPRINTLN("updatePSpointers");
962-
// DEBUG_PRINT(F("*** PS pointers ***"));
963-
// DEBUG_PRINTF_P(PSTR("this PS %p "), this);
964972
// Note on memory alignment:
965973
// a pointer MUST be 4 byte aligned. sizeof() in a struct/class is always aligned to the largest element. if it contains a 32bit, it will be padded to 4 bytes, 16bit is padded to 2byte alignment.
966974
// The PS is aligned to 4 bytes, a PSparticle is aligned to 2 and a struct containing only byte sized variables is not aligned at all and may need to be padded when dividing the memoryblock.
967975
// by making sure that the number of sources and particles is a multiple of 4, padding can be skipped here as alignent is ensured, independent of struct sizes.
968-
particleFlags = reinterpret_cast<PSparticleFlags *>(this + 1); // pointer to particle flags
969-
particles = reinterpret_cast<PSparticle *>(particleFlags + numParticles); // pointer to particles
970-
sources = reinterpret_cast<PSsource *>(particles + numParticles); // pointer to source(s) at data+sizeof(ParticleSystem2D)
976+
particles = reinterpret_cast<PSparticle *>(this + 1); // pointer to particles
977+
particleFlags = reinterpret_cast<PSparticleFlags *>(particles + numParticles); // pointer to particle flags
978+
sources = reinterpret_cast<PSsource *>(particleFlags + numParticles); // pointer to source(s) at data+sizeof(ParticleSystem2D)
971979
framebuffer = reinterpret_cast<CRGB *>(sources + numSources); // pointer to framebuffer
972980
// align pointer after framebuffer
973981
uintptr_t p = reinterpret_cast<uintptr_t>(framebuffer + (maxXpixel+1)*(maxYpixel+1));
@@ -1152,6 +1160,7 @@ ParticleSystem1D::ParticleSystem1D(uint32_t length, uint32_t numberofparticles,
11521160
// initialize some default non-zero values most FX use
11531161
for (uint32_t i = 0; i < numSources; i++) {
11541162
sources[i].source.ttl = 1; //set source alive
1163+
sources[i].sourceFlags.asByte = 0; // all flags disabled
11551164
}
11561165

11571166
if (isadvanced) {
@@ -1266,7 +1275,7 @@ int32_t ParticleSystem1D::sprayEmit(const PSsource1D &emitter) {
12661275
particles[emitIndex].x = emitter.source.x;
12671276
particles[emitIndex].hue = emitter.source.hue;
12681277
particles[emitIndex].ttl = hw_random16(emitter.minLife, emitter.maxLife);
1269-
particleFlags[emitIndex].collide = emitter.sourceFlags.collide;
1278+
particleFlags[emitIndex].collide = emitter.sourceFlags.collide; // TODO: could just set all flags (asByte) but need to check if that breaks any of the FX
12701279
particleFlags[emitIndex].reversegrav = emitter.sourceFlags.reversegrav;
12711280
particleFlags[emitIndex].perpetual = emitter.sourceFlags.perpetual;
12721281
if (advPartProps) {
@@ -1416,6 +1425,10 @@ void ParticleSystem1D::applyFriction(int32_t coefficient) {
14161425
void ParticleSystem1D::render() {
14171426
CRGB baseRGB;
14181427
uint32_t brightness; // particle brightness, fades if dying
1428+
TBlendType blend = LINEARBLEND; // default color rendering: wrap palette
1429+
if (particlesettings.colorByAge || particlesettings.colorByPosition) {
1430+
blend = LINEARBLEND_NOWRAP;
1431+
}
14191432

14201433
#ifdef ESP8266 // no local buffer on ESP8266
14211434
if (motionBlur)
@@ -1439,7 +1452,7 @@ void ParticleSystem1D::render() {
14391452

14401453
// generate RGB values for particle
14411454
brightness = min(particles[i].ttl << 1, (int)255);
1442-
baseRGB = ColorFromPalette(SEGPALETTE, particles[i].hue);
1455+
baseRGB = ColorFromPalette(SEGPALETTE, particles[i].hue, blend);
14431456

14441457
if (advPartProps) { //saturation is advanced property in 1D system
14451458
if (advPartProps[i].sat < 255) {
@@ -1483,9 +1496,9 @@ void ParticleSystem1D::render() {
14831496
// calculate pixel positions and brightness distribution and render the particle to local buffer or global buffer
14841497
__attribute__((optimize("O2"))) void ParticleSystem1D::renderParticle(const uint32_t particleindex, const uint8_t brightness, const CRGB &color, const bool wrap) {
14851498
uint32_t size = particlesize;
1486-
if (advPartProps) { // use advanced size properties
1499+
if (advPartProps) // use advanced size properties (1D system has no large size global rendering TODO: add large global rendering?)
14871500
size = advPartProps[particleindex].size;
1488-
}
1501+
14891502
if (size == 0) { //single pixel particle, can be out of bounds as oob checking is made for 2-pixel particles (and updating it uses more code)
14901503
uint32_t x = particles[particleindex].x >> PS_P_RADIUS_SHIFT_1D;
14911504
if (x <= (uint32_t)maxXpixel) { //by making x unsigned there is no need to check < 0 as it will overflow
@@ -1730,30 +1743,32 @@ void ParticleSystem1D::updatePSpointers(bool isadvanced) {
17301743
// a pointer MUST be 4 byte aligned. sizeof() in a struct/class is always aligned to the largest element. if it contains a 32bit, it will be padded to 4 bytes, 16bit is padded to 2byte alignment.
17311744
// The PS is aligned to 4 bytes, a PSparticle is aligned to 2 and a struct containing only byte sized variables is not aligned at all and may need to be padded when dividing the memoryblock.
17321745
// by making sure that the number of sources and particles is a multiple of 4, padding can be skipped here as alignent is ensured, independent of struct sizes.
1733-
particleFlags = reinterpret_cast<PSparticleFlags1D *>(this + 1); // pointer to particle flags
1734-
particles = reinterpret_cast<PSparticle1D *>(particleFlags + numParticles); // pointer to particles
1735-
sources = reinterpret_cast<PSsource1D *>(particles + numParticles); // pointer to source(s)
1746+
particles = reinterpret_cast<PSparticle1D *>(this + 1); // pointer to particles
1747+
particleFlags = reinterpret_cast<PSparticleFlags1D *>(particles + numParticles); // pointer to particle flags
1748+
sources = reinterpret_cast<PSsource1D *>(particleFlags + numParticles); // pointer to source(s)
17361749
#ifdef ESP8266 // no local buffer on ESP8266
17371750
PSdataEnd = reinterpret_cast<uint8_t *>(sources + numSources);
17381751
#else
17391752
framebuffer = reinterpret_cast<CRGB *>(sources + numSources); // pointer to framebuffer
17401753
// align pointer after framebuffer to 4bytes
1741-
uintptr_t p = reinterpret_cast<uintptr_t>(framebuffer + (maxXpixel+1));
1754+
uintptr_t p = reinterpret_cast<uintptr_t>(framebuffer + (maxXpixel+1)); // maxXpixel is SEGMENT.virtualLength() - 1
17421755
p = (p + 3) & ~0x03; // align to 4-byte boundary
17431756
PSdataEnd = reinterpret_cast<uint8_t *>(p); // pointer to first available byte after the PS for FX additional data
17441757
#endif
17451758
if (isadvanced) {
17461759
advPartProps = reinterpret_cast<PSadvancedParticle1D *>(PSdataEnd);
1747-
PSdataEnd = reinterpret_cast<uint8_t *>(advPartProps + numParticles);
1760+
PSdataEnd = reinterpret_cast<uint8_t *>(advPartProps + numParticles); // since numParticles is a multiple of 4, this is always aligned to 4 bytes. No need to add padding bytes here
17481761
}
17491762
#ifdef WLED_DEBUG_PS
17501763
PSPRINTLN(" PS Pointers: ");
17511764
PSPRINT(" PS : 0x");
17521765
Serial.println((uintptr_t)this, HEX);
1753-
PSPRINT(" Sources : 0x");
1754-
Serial.println((uintptr_t)sources, HEX);
1766+
PSPRINT(" Particleflags : 0x");
1767+
Serial.println((uintptr_t)particleFlags, HEX);
17551768
PSPRINT(" Particles : 0x");
17561769
Serial.println((uintptr_t)particles, HEX);
1770+
PSPRINT(" Sources : 0x");
1771+
Serial.println((uintptr_t)sources, HEX);
17571772
#endif
17581773
}
17591774

@@ -1774,6 +1789,7 @@ uint32_t calculateNumberOfParticles1D(const uint32_t fraction, const bool isadva
17741789
numberofParticles = numberofParticles < 20 ? 20 : numberofParticles; // 20 minimum
17751790
//make sure it is a multiple of 4 for proper memory alignment (easier than using padding bytes)
17761791
numberofParticles = (numberofParticles+3) & ~0x03; // note: with a separate particle buffer, this is probably unnecessary
1792+
PSPRINTLN(" calc numparticles:" + String(numberofParticles))
17771793
return numberofParticles;
17781794
}
17791795

0 commit comments

Comments
 (0)