Skip to content

BOBEmitter

Matthias Grimm edited this page Aug 16, 2026 · 6 revisions

Particles and Particle Emitter

Introduction

Particle Engines are facinating. It is a quite simply concept which enourmous potential and power. It enables you to simulated fluids and gases, can break solid objects apart or create realistic views of an explosion. The posibilities are endless and todays computer graphics cannot work without them.

This is reason enough to experiment with particle emitters on the CMM2.

How it works

A particle engine consists out of two components: The Emitter and the Particle.

The Particle is the basic element. It has certain properties like a position, a life time, a color and maybe more. It will be moved over the screen according to movement rules and may change its visual depending on the life time or other properties. The particle will be removed from screen, when its life time expires.

The Emitter is responsible to create particles, move them and destroy them at the end of their life time. To do this, the emitter keeps track of all its particles in a list which is worked though and upodated on a regular basis.

A Simple Example: Starfield.

The Particle is just a pixel with X and Y property for position, dX and dY property for movement and live for life time.

The Emitter creates a new particle at it's position and adds it to the list. Next round it updates the position of each particle by X=X+dX and Y=Y+dY and draws the pixel on the screen as long as life > 0.

As soon as a particle reaches its end of life a new particle is created to replace it.

The result is a starfield effect where pixel are moving from a center to the screen edges while the pixel size scaled with the age of the particle.

Starfield animation

Creating such a particle engine in modern programming languages with objects and dynamic memory management is easy. It is a little more challenging to implement it in Basic, where you don't have this comfort.

Objective

I started with a simple starfield simulation as described above but the effects just build with pixels is rather limited. I wanted more.

  1. Use an image as particle with a reasonable number of shapes
  2. Run fast
  3. More than one emitter possible
  4. Unlimited number of particles (yes, I know .. performance is limited)

The result is the GEM bobemitter.inc and its siblings. But before we come to it, let's talk about the CMM2 and MMBasic.

CMM2 and Particle Emitter

The CMMS supports different APIs which can be used for a particle engine:

  1. BLIT, which is a highly optimized memory copy function,
  2. BLIT read and BLIT write, which stores images in special buffers and
  3. SPRITE, the API to handle game objects

For a clear language I will use BOB (Blitter OBject) for particles in this article to make clear that we use images here and not pixels or other graphical elements and to have a clear differentiation from Sprites.

I didn't know which method would be the most flexible and fastest, so I created a particle engine for each of them

  1. bobemitter.inc with the example SmokeEffectDirect.bas,
  2. bobemitter_buffered.inc with the example SmokeEffectBuffered.bas and
  3. bobemitter_sprites.inc with the example SmokeEffectSprites.bas

The direct method with BLIT

For this method the BOB images will be loaded into a free video buffer and copied from there on the screen. Due to the big video memory of the CMM2, there is almost no limit in number of BOB images. For example: If your BOB is 16x16 pixels in size, you could store 1000 of them on a 640x400 video page.

This method is very fast bus has two drawbacks:

  1. The position of your BOB image has to calculate each time before drawing and
  2. it does not support transparency.

The second point can be overcome by clever image design, which is used in the example code.

The buffered method with BLIT read/write

For this method the BOB images will also be loaded into a free video buffer but then each image is copied into a special buffer with BLIT read. From here the images will be written to the screen with BLIT write. Becasue CMM2 has only 64 of these buffers, the number of BOB images, that can be handled at the same time, is limited to 64

This method is even faster because the image positions do not have to be calculated each time. A reference to the buffer will do the trick. And, real transparency is supported, at least for the 12 bit color modes with SPRITE transparency. We will see in a moment why this works.

The method using sprites

This method can copy the sprite image from a video buffer like the others with SPRITE read or the sprite images could be loaded from disk with SPRITE load. The sprites will be written to the screen with SPRITE write. The CMM2 supports 64 sprites to the number of BOB images at the same time are limited to 64, as with the BLIT read/write.

Sprites will be addressed with sprite numbers, so they don't need address calculations, and they support real transparency with SPRITE transparency. Unfortunately, this works only in the 12 bit color modes.

Behind the scenes, SPRITE uses the same image buffers as BLIT read/write. In fact, BLIT read/write is the foundatrion layer of SPRITE. That is also the reason why SPRITE transparency works on a BLIT read buffer even though the sprite was never created.

If you read the full sprite API, you might find functions like SPRITE show and SPRITE hide, which take also care about restoring the background of a sprite. This sounds really clever. It should be faster because only small portions of the background must be restored and maybe clearing the screen can be skipped, too?

Unfortunately, there is a flaw in this concept of restoring the background automatically. The background is read at the time the sprite is drawn. If another sprite is drawn later and partially overlap the already drawn sprite, the old sprite is part of the background of the new one. What would happen, if we remove sprites again?

After removing the first sprite the blank background would be restored. So far so good. Now we remove the second one and suddely the first sprite is partly back on screen because it was saved as background when the second sprite was drawn and it is now restored.

Particle emitters use a lot of overlapping images to create the desired effect. Drawing images with SPRITE show/hide would create a lot of artifacts that destroys the effect. Maybe there is a way of controlling the showing and hiding sequence to avoid artifacts, but I haven't found an efficient method.

But hey, what do I know. If you think you can handle this problem with sprites in an efficient way, please let me know. Create an example based on my SmokeEffectSprites.bas and see if it can compete.

Performance

Now let's compare the performance of the three methds. The conditions are always the same: resolution 640x400, 64 BOBs, 16 BOB images, the code is optimized for each color mode and the 12 bit color mode uses real transparency, if available.

PerformanceTable

Buffered BLIT and SPRITES reach the same performance. This is expected after what we have learned about the relation between BLIT read/write and SPRITE. The performance drop in color mode 12 is caused by the transparency, which must be calculated and set.

A fun fact: Drawing pixels instead of blitting images is not faster. That shows how good the BLIT command really is. :-)

So, from my point of view the buffered BLIT is the best method for a particle emitter with images. Unless someone takes the SPRITE challenge and breaks all records.

GEM BOBEmitter

Below you will find the outputs of the example programs showing the particle emitters in action.

How to use it: API of BOB Emitter

Output of the example code BOBEmitter.bas

StarfieldEffect

Output of the examples SmokeEffect<>.bas

SmokeEffect2_animated

Clone this wiki locally