DEV Community

JoeStrout
JoeStrout

Posted on

How displays work in Mini Micro

I've written here before about Mini Micro's 8-layer display system. Each layer can be configured to any of several types, including PixelDisplay, SpriteDisplay, TileDisplay, and TextDisplay. The default configuration looks like this:

Default display layout in Mini Micro

Layer 0 is in the front, and you can see that the first three display layers are off by default (as is layer 6). Then we have a text layer, a sprite layer, a graphics layer, and finally a solid color layer in the back.

In my previous post, I talked about how you can create additional off-screen displays, entirely separate from the above 8 layers, and then install them later. But that's the atypical case.

The far more typical usage is to just change the display type for one of the above 8 layers, and go about your business. You never have to explicitly create a new display object. But how does this work?

Display mode-switching magic

To review the typical usage, if you wanted to change layer 4 (by default, a sprite display) to pixel mode, and then draw something in it, you'd do it like this:

display(4).mode = displayMode.pixel
g = display(4)
g.fillEllipse 500,80, 300,200, color.pink
Enter fullscreen mode Exit fullscreen mode

I encourage you to fire up Mini Micro and try it yourself. You can type or paste those commands right on the command line.

Screen shot: change display 4 to pixel mode, then draw a pink ellipse in it

Easy enough, until you start thinking about it too deeply. Then it begins to seem mysterious. display(4) returns a Display object — by default, specifically a SpriteDisplay object. Then we assign a different value to the mode property. And now suddenly it's an entirely different kind of object (PixelDisplay in this example)? How can that be?

The magic trick revealed

Built-in classes like Display can do a special trick that ordinary MiniScript code can't do: they can intercept assignments to certain properties. You'll see this in some other places in the Mini Micro API, where you simply aren't allowed to alter certain maps. Image is an example of this; if you try to change (say) the width of an image, you simply get an error.

Screen shot of attempt to assign to Image.width

Display uses this trick differently; it catches the assignment and does something else with it. When you assign to the mode property of a Display, it just notifies an internal "display manager" responsible for the 8-layer display system. And the display manager says "oh, I see you want a different display type at this index," and it detaches the previous display object there, attaching one of the appropriate type.

That's why you always need to get a reference to your display after changing the type. If you tried to do something like

g = display(4)
g.mode = displayMode.pixel
g.fillEllipse 500,80, 300,200, color.pink
Enter fullscreen mode Exit fullscreen mode

...it would not work (unless display(4) was already in pixel mode). The first line would make g refer to whatever display was already in slot 4; after any reset, that's a SpriteDisplay. The second line would detach that and install a pixel display in slot 4, but g would continue to refer to the detached display. So, the third line would fail; SpriteDisplay does not have a fillEllipse method.

Screen shot showing incorrect attempt at handling a display

But where does it come from?

You might wonder where the display manager gets a display of the requested type. Well, at bootup, it actually prepares a display of each type for every slot. So in any given slot, there are solid-color, pixel, text, tile, and sprite displays just waiting to be used. The display manager keeps references to these five displays per slot, 40 displays total, ready for your use! When you change the mode at a given display index, the display manager just swaps in the prepared display it already has on hand.

If you manually install a display, as discussed in the previous post, then the newly installed display replaces the previous display of that type in its list of 5 ready displays for that slot. Your display becomes the one "on hand" for the display manager to use again if the user simply changes the mode on that display index. The previous one of that type gets detached — and like any MiniScript object, if there are no more references to it, then it is destroyed.

Now you know!

To recap:

  • Behind the scenes, a display manager keeps a display of each type on hand for each of the 8 display layers.
  • When you assign to the .mode of a display, that assignment is intercepted and sent as a request to the display manager.
  • The display manager swaps in the display of the appropriate type, keeping one previously there in reserve for future use.
  • If you install a display yourself, it replaces the one the display manager uses for that slot and type.

So now you know what's happening! Beginners generally don't need to understand how things work in this much detail; it's fine to just remember "assign the mode you want, then get a reference to the display." But now that you know what that actually does, you can have a deeper understanding of what's going on.

Top comments (0)