During the process of creating and manipulating SBM files we soon started talking about things like lines, pixel sequences, pixels, colors, and so on. What is more, very naturally we started thinking in terms of these entities: let’s drop this or that line, or let’s change the green component of this pixel.
Consider for example RGB colors. We know that each color is defined by three levels of light: red, green and blue. These components are also called color beams. Since each color beam has a range of 0 to 255, many formats, like SBM, use bytes to encode them.
Therefore, in the previous sections we used the type specifier
byte
when we needed to map RGB color beams, like in:
(poke) byte[3] @ 5#B
Recall that the mapping operation above means “map three bytes at the offset 5 bytes in the current IO space”. But what we really want is to map color beams, not bytes!
Poke provides a way to assign names to type specifiers:
(poke) type RGB_Color_Beam = byte
The definition above tells poke that a RGB color beam is composed of a byte, i.e. an unsigned 8-bit integer. Any type specifier can be used at the right side of the assignment sign, and also names of already defined types. From this point on, we can map in terms of color beams:
(poke) RGB_Color_Beam[3] @ 5#B
Meaning “map three RGB color beams at the offset 5 in the current IO space”.
Once a type is defined, the name can be used anywhere where a type specifier is expected.
By the way, we mentioned many times how byte
is a synonym for
uint<8>
, int
is a synonym for int<32>
and so on.
These synonyms are actually result of type definitions that are in the
poke standard library. This library is loaded by poke at
startup time.
Since we didn’t know better, during our work with SBM images we had to remember how these entities were constructed from more simple entities such as bits and bytes, every time we needed to map them, or to poke them. For example, if we wanted to map a pixel at some particular offset, we had to issue the following command:
(poke) var pixel = byte[3] @ 5#B
Now that we made poke aware of what a RGB color beam is, we can rewrite the above as:
(poke) var pixel = RGB_Color_Beam[3] @ 5#B
This is better, but still adoleces from a big problem: what if at some point the SBM pixels get expanded to also have a transparency index, stored in a fourth byte? If that ever happens (and will happen later in this book) then we would need to remember it before issuing commands like:
(poke) var image_data = RGB_Color_Beam[4][ppl][lines] @ 5#B
To avoid this problem, we define yet another type, this time describing the structure of a SBM pixel:
(poke) type SBM_Pixel = RGB_Color_Beam[3]
And then we can define image_data
as a table of SBM pixels,
instead of as a table of triplets of RGB color beams:
(poke) var image_data = SBM_Pixel[ppl][lines] @ 5#B
This later definition doesn’t need to be changed if we change the definition of what a SBM pixel is. This is called encapsulation and is a very useful abstraction in computing.