v1.1.0
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Modules Pages
color.h
1 /* -*- mode: C; c-basic-offset: 4; intent-tabs-mode: nil -*-
2  *
3  * Sifteo SDK
4  *
5  * Copyright <c> 2012 Sifteo, Inc.
6  *
7  * Permission is hereby granted, free of charge, to any person obtaining a copy
8  * of this software and associated documentation files (the "Software"), to deal
9  * in the Software without restriction, including without limitation the rights
10  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11  * copies of the Software, and to permit persons to whom the Software is
12  * furnished to do so, subject to the following conditions:
13  *
14  * The above copyright notice and this permission notice shall be included in
15  * all copies or substantial portions of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23  * THE SOFTWARE.
24  */
25 
26 #pragma once
27 #ifdef NOT_USERSPACE
28 # error This is a userspace-only header, not allowed by the current build.
29 #endif
30 
31 #include <sifteo/abi.h>
32 #include <sifteo/macros.h>
33 #include <sifteo/math.h>
34 
35 namespace Sifteo {
36 
50 struct RGB565 {
52  uint16_t value;
53 
58  static RGB565 from565(uint8_t r, uint8_t g, uint8_t b) {
59  RGB565 result = { (r << 11) | (g << 5) | b };
60  return result;
61  }
62 
67  static RGB565 fromRGB(uint8_t r, uint8_t g, uint8_t b) {
68  /*
69  * Round to the nearest 5/6 bit color. Note that simple
70  * bit truncation does NOT produce the best result!
71  */
72  return from565( ((unsigned)r * 31 + 128) / 255,
73  ((unsigned)g * 63 + 128) / 255,
74  ((unsigned)b * 31 + 128) / 255 );
75  }
76 
81  static RGB565 fromRGB(float r, float g, float b) {
82  return from565( r * 31.f + 0.5f,
83  g * 63.f + 0.5f,
84  b * 31.f + 0.5f );
85  }
86 
93  static RGB565 fromRGB(uint32_t rgb) {
94  return fromRGB((uint8_t)(rgb >> 16), (uint8_t)(rgb >> 8), (uint8_t)rgb);
95  }
96 
100  uint8_t red5() const {
101  return (value >> 11) & 0x1F;
102  }
103 
107  uint8_t green6() const {
108  return (value >> 5) & 0x3F;
109  }
110 
114  uint8_t blue5() const {
115  return value & 0x1F;
116  }
117 
121  uint8_t red() const {
122  /*
123  * A good approximation is `(r5 << 3) | (r5 >> 2)`, but this
124  * is still not quite as accurate as the implementation here.
125  */
126  return red5() * 255 / 31;
127  }
128 
132  uint8_t green() const {
133  return green6() * 255 / 63;
134  }
135 
139  uint8_t blue() const {
140  return blue5() * 255 / 31;
141  }
142 
149  uint32_t packedRGB() const {
150  return blue() | (green() << 8) | (red() << 16);
151  }
152 
160  RGB565 lerp(RGB565 other, uint8_t alpha) const {
161  unsigned A = alpha;
162  unsigned invA = 0xff - A;
163  return from565( (red5() * invA + other.red5() * A) / 0xff,
164  (green6() * invA + other.green6() * A) / 0xff,
165  (blue5() * invA + other.blue5() * A) / 0xff );
166  }
167 
169  bool operator== (const RGB565 &other) const { return value == other.value; }
170 
172  bool operator!= (const RGB565 &other) const { return value != other.value; }
173 };
174 
175 
187 struct ColormapSlot {
188  _SYSAttachedVideoBuffer *sys;
189  unsigned index;
190 
194  void set(RGB565 color) const {
195  _SYS_vbuf_poke(&sys->vbuf, _SYS_VA_COLORMAP / 2 + index, color.value);
196  }
197 
201  void set(uint8_t r, uint8_t g, uint8_t b) const {
202  set(RGB565::fromRGB(r, g, b));
203  }
204 
208  void set(float r, float g, float b) const {
209  set(RGB565::fromRGB(r, g, b));
210  }
211 
218  void set(uint32_t rgb) const {
219  set(RGB565::fromRGB(rgb));
220  }
221 
225  const ColormapSlot& operator= (RGB565 color) const {
226  set(color);
227  return *this;
228  }
229 
236  const ColormapSlot& operator= (uint32_t color) const {
237  set(color);
238  return *this;
239  }
240 
244  RGB565 get() const {
245  RGB565 result = { _SYS_vbuf_peek(&sys->vbuf, _SYS_VA_COLORMAP / 2 + index) };
246  return result;
247  }
248 };
249 
250 
264 struct Colormap {
265  _SYSAttachedVideoBuffer sys;
266 
268  static const unsigned NUM_COLORS = 16;
269 
278  ColormapSlot operator[](unsigned index) {
279  ASSERT(index < NUM_COLORS);
280  ColormapSlot result = { &sys, index };
281  return result;
282  }
283 
287  void erase() {
288  _SYS_vbuf_fill(&sys.vbuf, _SYS_VA_COLORMAP / 2, 0, NUM_COLORS);
289  }
290 
294  void fill(RGB565 color) {
295  _SYS_vbuf_fill(&sys.vbuf, _SYS_VA_COLORMAP / 2, color.value, NUM_COLORS);
296  }
297 
301  void setRange(const RGB565 *colors, unsigned firstColor, unsigned numColors) {
302  ASSERT(firstColor <= NUM_COLORS && numColors <= NUM_COLORS
303  && (firstColor + numColors) <= NUM_COLORS);
304  _SYS_vbuf_write(&sys.vbuf, _SYS_VA_COLORMAP / 2 + firstColor,
305  &colors[0].value, numColors);
306  }
307 
311  void set(const RGB565 *colors) {
312  setRange(colors, 0, NUM_COLORS);
313  }
314 
320  void setEGA() {
321  static const RGB565 colors[] = {
322  /* 0 */ { 0x0000 },
323  /* 1 */ { 0x0015 },
324  /* 2 */ { 0x0540 },
325  /* 3 */ { 0x0555 },
326  /* 4 */ { 0xa800 },
327  /* 5 */ { 0xa815 },
328  /* 6 */ { 0xaaa0 },
329  /* 7 */ { 0xad55 },
330  /* 8 */ { 0x52aa },
331  /* 9 */ { 0x52bf },
332  /* 10 */ { 0x57ea },
333  /* 11 */ { 0x57ff },
334  /* 12 */ { 0xfaaa },
335  /* 13 */ { 0xfabf },
336  /* 14 */ { 0xffea },
337  /* 15 */ { 0xffff },
338  };
339  set(colors);
340  }
341 
347  void setMono(RGB565 color0, RGB565 color1) {
348  (*this)[0].set(color0);
349  (*this)[1].set(color1);
350  }
351 
359  void setMono(uint32_t color0, uint32_t color1) {
360  (*this)[0].set(color0);
361  (*this)[1].set(color1);
362  }
363 
367  _SYSVideoBuffer &videoBuffer() {
368  return sys.vbuf;
369  }
370 
374  CubeID cube() const {
375  return sys.cube;
376  }
377 };
378 
383 }; // namespace Sifteo
void setMono(RGB565 color0, RGB565 color1)
Set a monochrome palette, in entries [0] and [1].
Definition: color.h:347
uint8_t blue() const
Return the color's blue component, extended to 8 bits.
Definition: color.h:139
void set(const RGB565 *colors)
Set the entire palette, given an array of exactly 16 RGB565 values.
Definition: color.h:311
bool operator!=(const RGB565 &other) const
Exact inequality test.
Definition: color.h:172
static const unsigned NUM_COLORS
Maximum number of colors in the colormap.
Definition: color.h:268
void set(uint32_t rgb) const
Set the color in this slot to the specified packed RGB color.
Definition: color.h:218
static RGB565 fromRGB(uint32_t rgb)
Create an RGB565 color from a packed-pixel 24-bit RGB color.
Definition: color.h:93
void setMono(uint32_t color0, uint32_t color1)
Set a monochrome palette, in entries [0] and [1].
Definition: color.h:359
uint8_t green6() const
Return the color's green component, as a 6-bit value.
Definition: color.h:107
#define ASSERT(_x)
Runtime debug assertion.
Definition: macros.h:205
static RGB565 from565(uint8_t r, uint8_t g, uint8_t b)
Create an RGB565 color from a 5-6-5-bit RGB color, with each component specified separately.
Definition: color.h:58
void setEGA()
Set the entire palette to the traditional EGA 16-color palette.
Definition: color.h:320
void fill(RGB565 color)
Splat the given color across all colormap slots.
Definition: color.h:294
void set(float r, float g, float b) const
Set the color in this slot to the specified floating point RGB value.
Definition: color.h:208
uint8_t green() const
Return the color's green component, extended to 8 bits.
Definition: color.h:132
void set(RGB565 color) const
Set the color in this colormap slot to the specified RGB565 value.
Definition: color.h:194
A ColormapSlot refers to a single colormap index on a single cube.
Definition: color.h:187
A lightweight identifier for one Sifteo cube.
Definition: cube.h:85
static RGB565 fromRGB(uint8_t r, uint8_t g, uint8_t b)
Create an RGB565 color from an 8-bit RGB color. We accurately round to the nearest representable 16-b...
Definition: color.h:67
ColormapSlot operator[](unsigned index)
Return a ColormapSlot which references a single colormap entry on a single VideoBuffer.
Definition: color.h:278
uint8_t red5() const
Return the color's red component, as a 5-bit value.
Definition: color.h:100
const ColormapSlot & operator=(RGB565 color) const
Set the color in this slot to a specifc RGB565 value.
Definition: color.h:225
uint32_t packedRGB() const
Return the color as a packed 24-bit RGB value.
Definition: color.h:149
uint8_t blue5() const
Return the color's blue component, as a 5-bit value.
Definition: color.h:114
Definition: array.h:34
void set(uint8_t r, uint8_t g, uint8_t b) const
Set the color in this slot to the specified 8-bit RGB value.
Definition: color.h:201
static RGB565 fromRGB(float r, float g, float b)
Create an RGB565 color from a floating point RGB color. We accurately round to the nearest representa...
Definition: color.h:81
uint8_t red() const
Return the color's red component, extended to 8 bits.
Definition: color.h:121
An accessor for the colormap, with up to 16 colors.
Definition: color.h:264
CubeID cube() const
Return the CubeID associated with this drawable.
Definition: color.h:374
bool operator==(const RGB565 &other) const
Exact equality test.
Definition: color.h:169
Represents a 16-bit 5:6:5 color, the native format used by our display.
Definition: color.h:50
void setRange(const RGB565 *colors, unsigned firstColor, unsigned numColors)
Set a range of colormap values, given an array of RGB565 values.
Definition: color.h:301
void erase()
Clear the palette to black.
Definition: color.h:287
uint16_t value
The raw color value, as a 16-bit integer.
Definition: color.h:52
_SYSVideoBuffer & videoBuffer()
Return the VideoBuffer associated with this drawable.
Definition: color.h:367
RGB565 lerp(RGB565 other, uint8_t alpha) const
Linear interpolation between this color and another color.
Definition: color.h:160