Introduce comet effect usermod with fire particle system#5347
Introduce comet effect usermod with fire particle system#5347gustebeast wants to merge 1 commit intowled:mainfrom
Conversation
WalkthroughIntroduces a new PS Comet usermod that implements a falling comet particle effect using 2D particle systems. The implementation includes initialization, per-frame updates, spawning logic, and particle lifecycle management with configurable parameters via UI sliders and palette selection. Includes documentation and library manifest. Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Suggested reviewers
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Fix all issues with AI agents
In `@usermods/PS_Comet/PS_Comet.cpp`:
- Around line 23-60: Guard against division-by-zero when computing pixel mapping
and vertical shifts by using a safe denominator (e.g., uint32_t denomW = max(1u,
SEGMENT.vWidth() - 1) and uint32_t denomH = max(1u, SEGMENT.vHeight() - 1)) and
replace any uses of (SEGMENT.vWidth() - 1) / (SEGMENT.vHeight() - 1) with those
safe denominators; fix the 3x->column mapping in mode_pscomet by computing
baseCol = i / 3, offset = (int)(i % 3) - 1 (so center = 0, left = -1, right =
+1), then targetCol = clamp(baseCol + offset, 0u, SEGMENT.vWidth() - 1) and set
sourceParticle.x = targetCol * PartSys->maxX / denomW; similarly compute
sideCometVerticalShift using denomH (uint32_t sideCometVerticalShift = 2 *
PartSys->maxY / denomH) and ensure all divisions use the safe denominators and
clamp results to valid ranges to avoid out-of-bounds writes.
In `@usermods/PS_Comet/README.md`:
- Line 3: Fix the spelling mistake "palletes" to "palettes" in the README
sentence describing color support (the phrase "Works with custom color palletes,
defaulting to "Fire""). Update that phrase to read "Works with custom color
palettes, defaulting to 'Fire'".
🧹 Nitpick comments (1)
usermods/PS_Comet/PS_Comet.cpp (1)
4-4: Avoid global spawn timer to prevent cross‑segment coupling.
nextCometCreationTimeis global, so multiple segments running PS Comet will share a single spawn cadence. Consider storing this per segment (e.g., in SEGENV.aux0/aux1 or a small state struct tied to SEGENV.data) to keep animations independent.
| uint16_t mode_pscomet(void) { | ||
| ParticleSystem2D *PartSys = nullptr; | ||
| uint32_t i; | ||
| // Allocate three comets for every column to allow for large comets with side emitters | ||
| uint32_t numComets = SEGMENT.vWidth() * 3; | ||
|
|
||
| if (SEGMENT.call == 0) { // Initialization | ||
| if (!initParticleSystem2D(PartSys, numComets)) { | ||
| return mode_static(); // Allocation failed or not 2D | ||
| } | ||
| PartSys->setMotionBlur(170); // Enable motion blur | ||
| PartSys->setParticleSize(0); // Allow small comets to be a single pixel wide | ||
| } | ||
| else { | ||
| PartSys = reinterpret_cast<ParticleSystem2D *>(SEGENV.data); // If not first call, use existing data | ||
| } | ||
| if (PartSys == nullptr) { | ||
| return mode_static(); // Something went wrong, no data! | ||
| } | ||
|
|
||
| PartSys->updateSystem(); // Update system properties (dimensions and data pointers) | ||
|
|
||
| uint32_t sideCometVerticalShift = 2 * PartSys->maxY / (SEGMENT.vHeight() - 1); // Shift emitters on left and right of comet up by 1 pixel | ||
| uint32_t chosenIndex = hw_random(numComets); // Only allow one column to spawn a comet each frame | ||
| uint8_t fallingSpeed = 1 + (SEGMENT.speed >> 2); | ||
| uint16_t cometFrequencyDelay = 2040 - (SEGMENT.intensity << 3); | ||
|
|
||
| // Update the comets | ||
| for (i = 0; i < numComets; i++) { | ||
| auto& source = PartSys->sources[i]; | ||
| auto& sourceParticle = source.source; | ||
| // Large comets use three particle sources, with i indicating left, center or right: | ||
| // 0: left, 1: center, 2: right, 3: left, 4: center, 5: right, ... | ||
| // Small comets leave the left and right indices unused | ||
| bool isCometCenter = (i % 3) == 1; | ||
|
|
||
| // Map the 3x comet index into an output pixel index | ||
| sourceParticle.x = ((i / 3) + (i % 3)) * PartSys->maxX / (SEGMENT.vWidth() - 1); |
There was a problem hiding this comment.
Guard 1‑pixel dimensions and fix column mapping.
When vWidth or vHeight is 1, (vWidth - 1) / (vHeight - 1) becomes zero and will crash. Also ((i / 3) + (i % 3)) shifts center columns right and can exceed the last column, so some columns never receive center comets and x can go out of range.
🛠️ Proposed fix
uint16_t mode_pscomet(void) {
ParticleSystem2D *PartSys = nullptr;
uint32_t i;
- // Allocate three comets for every column to allow for large comets with side emitters
- uint32_t numComets = SEGMENT.vWidth() * 3;
+ const uint32_t vWidth = SEGMENT.vWidth();
+ const uint32_t vHeight = SEGMENT.vHeight();
+ if (vWidth < 2 || vHeight < 2) {
+ return mode_static();
+ }
+ // Allocate three comets for every column to allow for large comets with side emitters
+ uint32_t numComets = vWidth * 3;
@@
- uint32_t sideCometVerticalShift = 2 * PartSys->maxY / (SEGMENT.vHeight() - 1); // Shift emitters on left and right of comet up by 1 pixel
+ uint32_t sideCometVerticalShift = 2 * PartSys->maxY / (vHeight - 1); // Shift emitters on left and right of comet up by 1 pixel
@@
- sourceParticle.x = ((i / 3) + (i % 3)) * PartSys->maxX / (SEGMENT.vWidth() - 1);
+ const uint32_t baseCol = i / 3;
+ const int8_t offset = (int8_t)(i % 3) - 1; // left, center, right
+ const int32_t col = constrain((int32_t)baseCol + offset, 0, (int32_t)vWidth - 1);
+ sourceParticle.x = (uint32_t)col * PartSys->maxX / (vWidth - 1);🤖 Prompt for AI Agents
In `@usermods/PS_Comet/PS_Comet.cpp` around lines 23 - 60, Guard against
division-by-zero when computing pixel mapping and vertical shifts by using a
safe denominator (e.g., uint32_t denomW = max(1u, SEGMENT.vWidth() - 1) and
uint32_t denomH = max(1u, SEGMENT.vHeight() - 1)) and replace any uses of
(SEGMENT.vWidth() - 1) / (SEGMENT.vHeight() - 1) with those safe denominators;
fix the 3x->column mapping in mode_pscomet by computing baseCol = i / 3, offset
= (int)(i % 3) - 1 (so center = 0, left = -1, right = +1), then targetCol =
clamp(baseCol + offset, 0u, SEGMENT.vWidth() - 1) and set sourceParticle.x =
targetCol * PartSys->maxX / denomW; similarly compute sideCometVerticalShift
using denomH (uint32_t sideCometVerticalShift = 2 * PartSys->maxY / denomH) and
ensure all divisions use the safe denominators and clamp results to valid ranges
to avoid out-of-bounds writes.
| @@ -0,0 +1,25 @@ | |||
| ## Description | |||
|
|
|||
| A 2D falling comet effect similar to "Matrix" but with a fire particle simulation to enhance the comet trail visuals. Works with custom color palletes, defaulting to "Fire". Supports "small" and "large" comets which are 1px and 3px wide respectively. | |||
There was a problem hiding this comment.
Fix spelling: “palettes”.
User-facing docs should avoid typos.
📝 Proposed fix
-A 2D falling comet effect similar to "Matrix" but with a fire particle simulation to enhance the comet trail visuals. Works with custom color palletes, defaulting to "Fire". Supports "small" and "large" comets which are 1px and 3px wide respectively.
+A 2D falling comet effect similar to "Matrix" but with a fire particle simulation to enhance the comet trail visuals. Works with custom color palettes, defaulting to "Fire". Supports "small" and "large" comets which are 1px and 3px wide respectively.📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| A 2D falling comet effect similar to "Matrix" but with a fire particle simulation to enhance the comet trail visuals. Works with custom color palletes, defaulting to "Fire". Supports "small" and "large" comets which are 1px and 3px wide respectively. | |
| A 2D falling comet effect similar to "Matrix" but with a fire particle simulation to enhance the comet trail visuals. Works with custom color palettes, defaulting to "Fire". Supports "small" and "large" comets which are 1px and 3px wide respectively. |
🧰 Tools
🪛 LanguageTool
[grammar] ~3-~3: Ensure spelling is correct
Context: ... trail visuals. Works with custom color palletes, defaulting to "Fire". Supports "small"...
(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)
🤖 Prompt for AI Agents
In `@usermods/PS_Comet/README.md` at line 3, Fix the spelling mistake "palletes"
to "palettes" in the README sentence describing color support (the phrase "Works
with custom color palletes, defaulting to "Fire""). Update that phrase to read
"Works with custom color palettes, defaulting to 'Fire'".
A 2D falling comet effect similar to "Matrix" but with a fire particle simulation to enhance the comet trail visuals. Works with custom color palletes, defaulting to "Fire". Supports "small" and "large" comets which are 1px and 3px wide respectively.
Demo: https://imgur.com/a/i1v5WAy
Summary by CodeRabbit