v1.1.0
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Modules Pages
video.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/cube.h>
33 #include <sifteo/math.h>
34 #include <sifteo/video/color.h>
35 #include <sifteo/video/sprite.h>
36 #include <sifteo/video/framebuffer.h>
37 #include <sifteo/video/bg0rom.h>
38 #include <sifteo/video/bg0.h>
39 #include <sifteo/video/bg1.h>
40 #include <sifteo/video/bg2.h>
41 #include <sifteo/video/tilebuffer.h>
42 
43 namespace Sifteo {
44 
53 static const unsigned LCD_width = 128;
54 static const unsigned LCD_height = 128;
55 static const unsigned TILE = 8;
56 
58 static const Int2 LCD_size = { LCD_width, LCD_height };
59 
61 static const Int2 LCD_center = { LCD_width / 2, LCD_height / 2 };
62 
63 
79 enum VideoMode {
80  POWERDOWN_MODE = _SYS_VM_POWERDOWN,
81  BG0_ROM = _SYS_VM_BG0_ROM,
82  SOLID_MODE = _SYS_VM_SOLID,
83  FB32 = _SYS_VM_FB32,
84  FB64 = _SYS_VM_FB64,
85  FB128 = _SYS_VM_FB128,
86  BG0 = _SYS_VM_BG0,
87  BG0_BG1 = _SYS_VM_BG0_BG1,
88  BG0_SPR_BG1 = _SYS_VM_BG0_SPR_BG1,
89  BG2 = _SYS_VM_BG2,
90  STAMP = _SYS_VM_STAMP,
91 };
92 
93 
103 enum Rotation {
104  ROT_NORMAL = 0,
105  ROT_LEFT_90_MIRROR = _SYS_VF_XY_SWAP,
106  ROT_MIRROR = _SYS_VF_X_FLIP,
107  ROT_LEFT_90 = _SYS_VF_XY_SWAP | _SYS_VF_Y_FLIP,
108  ROT_180_MIRROR = _SYS_VF_Y_FLIP,
109  ROT_RIGHT_90 = _SYS_VF_XY_SWAP | _SYS_VF_X_FLIP,
110  ROT_180 = _SYS_VF_X_FLIP | _SYS_VF_Y_FLIP,
111  ROT_RIGHT_90_MIRROR = _SYS_VF_XY_SWAP | _SYS_VF_X_FLIP | _SYS_VF_Y_FLIP
112 };
113 
114 
145 struct VideoBuffer {
147  union {
148  _SYSAttachedVideoBuffer sys;
159  };
160 
161  // Implicit conversions
162  operator _SYSVideoBuffer* () { return &sys.vbuf; }
163  operator const _SYSVideoBuffer* () const { return &sys.vbuf; }
164  operator _SYSAttachedVideoBuffer* () { return &sys; }
165  operator const _SYSAttachedVideoBuffer* () const { return &sys; }
166 
174  operator _SYSCubeID () const {
175  return sys.cube;
176  }
177 
181  CubeID cube() const {
182  return sys.cube;
183  }
184 
201  void setWindow(uint8_t firstLine, uint8_t numLines) {
202  poke(offsetof(_SYSVideoRAM, first_line) / 2, firstLine | (numLines << 8));
203  }
204 
209  setWindow(0, LCD_height);
210  }
211 
215  void setWindowFirstLine(uint8_t firstLine) {
216  pokeb(offsetof(_SYSVideoRAM, first_line), firstLine);
217  }
218 
222  void setWindowNumLines(uint8_t numLines) {
223  pokeb(offsetof(_SYSVideoRAM, num_lines), numLines);
224  }
225 
230  uint8_t windowFirstLine() const {
231  return peekb(offsetof(_SYSVideoRAM, first_line));
232  }
233 
238  uint8_t windowNumLines() const {
239  return peekb(offsetof(_SYSVideoRAM, num_lines));
240  }
241 
246  const uint8_t mask = _SYS_VF_XY_SWAP | _SYS_VF_X_FLIP | _SYS_VF_Y_FLIP;
247  uint8_t flags = peekb(offsetof(_SYSVideoRAM, flags));
248 
249  // Must do this atomically; the asynchronous paint controller can
250  // modify other bits within this flags byte.
251  xorb(offsetof(_SYSVideoRAM, flags), (r ^ flags) & mask);
252  }
253 
257  Rotation rotation() const {
258  const uint8_t mask = _SYS_VF_XY_SWAP | _SYS_VF_X_FLIP | _SYS_VF_Y_FLIP;
259  uint8_t flags = peekb(offsetof(_SYSVideoRAM, flags));
260  return Rotation(mask & flags);
261  }
262 
267  Side orientation() const {
268  switch (rotation()) {
269  case ROT_NORMAL: return TOP;
270  case ROT_LEFT_90: return LEFT;
271  case ROT_180: return BOTTOM;
272  case ROT_RIGHT_90: return RIGHT;
273  default: return NO_SIDE;
274  }
275  }
276 
283  void setOrientation(Side topSide) {
284  // Tiny lookup table in a uint32
285  const uint32_t sideToRotation =
286  (ROT_NORMAL << 0) |
287  (ROT_LEFT_90 << 8) |
288  (ROT_180 << 16) |
289  (ROT_RIGHT_90 << 24) ;
290 
291  ASSERT(topSide >= 0 && topSide < 4);
292  uint8_t r = sideToRotation >> (topSide * 8);
293  setRotation(Rotation(r));
294  }
295 
309  void orientTo(const Neighborhood &thisN, const VideoBuffer &src, const Neighborhood &srcN) {
310  int srcSide = srcN.sideOf(cube());
311  int dstSide = thisN.sideOf(src.cube());
312  if(srcSide != NO_SIDE && dstSide != NO_SIDE) {
313  setOrientation(Side(umod(2 + dstSide - srcSide + src.orientation(), NUM_SIDES)));
314  }
315 
316  }
317 
327  void orientTo(const VideoBuffer &src) {
328  orientTo(Neighborhood(cube()), src, Neighborhood(src.cube()));
329  }
330 
335  static Side physicalToVirtual(Side side, Side rot) {
336  if (side == NO_SIDE) { return NO_SIDE; }
337  ASSERT(side >= 0 && side < 4 && rot != NO_SIDE);
338  return Side(umod(side - rot, NUM_SIDES));
339  }
340 
345  static Side virtualToPhysical(Side side, Side rot) {
346  if (side == NO_SIDE) { return NO_SIDE; }
347  ASSERT(side >= 0 && side < 4 && rot != NO_SIDE);
348  return Side(umod(side + rot, NUM_SIDES));
349  }
350 
356  return physicalToVirtual(side, orientation());
357  }
358 
364  return virtualToPhysical(side, orientation());
365  }
366 
378  Neighborhood result;
379  result.sys.sides[0] = nb.sys.sides[virtualToPhysical(Side(0), rot)];
380  result.sys.sides[1] = nb.sys.sides[virtualToPhysical(Side(1), rot)];
381  result.sys.sides[2] = nb.sys.sides[virtualToPhysical(Side(2), rot)];
382  result.sys.sides[3] = nb.sys.sides[virtualToPhysical(Side(3), rot)];
383  return result;
384  }
385 
397  Neighborhood result;
398  result.sys.sides[0] = nb.sys.sides[physicalToVirtual(Side(0), rot)];
399  result.sys.sides[1] = nb.sys.sides[physicalToVirtual(Side(1), rot)];
400  result.sys.sides[2] = nb.sys.sides[physicalToVirtual(Side(2), rot)];
401  result.sys.sides[3] = nb.sys.sides[physicalToVirtual(Side(3), rot)];
402  return result;
403  }
404 
416  return physicalToVirtual(nb, orientation());
417  }
418 
430  return virtualToPhysical(nb, orientation());
431  }
432 
442  return Neighborhood(cube());
443  }
444 
454  }
455 
464  return cube().accel();
465  }
466 
473  Byte3 virtualAccel() const {
474  return cube().accel().zRotateI(orientation());
475  }
476 
486  void setMode(VideoMode m) {
487  pokeb(offsetof(_SYSVideoRAM, mode), m);
488  }
489 
493  VideoMode mode() const {
494  return VideoMode(peekb(offsetof(_SYSVideoRAM, mode)));
495  }
496 
504  void erase() {
505  _SYS_vbuf_fill(*this, 0, 0, _SYS_VA_FIRST_LINE / 2);
506  }
507 
527  void initMode(VideoMode m, unsigned firstLine = 0, unsigned numLines = LCD_height) {
528  _SYS_finish();
529  erase();
530  setWindow(firstLine, numLines);
531  setRotation(ROT_NORMAL);
532  setMode(m);
533  }
534 
556  void attach(_SYSCubeID id) {
557  _SYS_finish();
558  sys.cube = id;
559  _SYS_vbuf_init(*this);
560  _SYS_setVideoBuffer(*this, *this);
561  }
562 
573  void lock(uint16_t addr) {
574  _SYS_vbuf_lock(*this, addr);
575  }
576 
584  void unlock() {
585  _SYS_vbuf_unlock(*this);
586  }
587 
595  void touch() {
596  lock(_SYS_VA_FLAGS);
597  }
598 
606  void poke(uint16_t addr, uint16_t word) {
607  _SYS_vbuf_poke(*this, addr, word);
608  }
609 
614  void pokeb(uint16_t addr, uint8_t byte) {
615  _SYS_vbuf_pokeb(*this, addr, byte);
616  }
617 
621  void pokei(uint16_t addr, uint16_t index) {
622  _SYS_vbuf_poke(*this, addr, _SYS_TILE77(index));
623  }
624 
629  void xorb(uint16_t addr, uint8_t byte) {
630  _SYS_vbuf_xorb(*this, addr, byte);
631  }
632 
636  uint16_t peek(uint16_t addr) const {
637  return _SYS_vbuf_peek(*this, addr);
638  }
639 
643  uint8_t peekb(uint16_t addr) const {
644  return _SYS_vbuf_peekb(*this, addr);
645  }
646 };
647 
652 }; // namespace Sifteo
SpriteLayer sprites
Drawable for the sprite layer in BG0_SPR_BG1 mode.
Definition: video.h:149
Neighborhood virtualToPhysical(Neighborhood nb) const
Convert a Neighborhood from virtual to physical orientation.
Definition: video.h:429
128x48 pixel 2-color framebuffer
Definition: video.h:85
static Side physicalToVirtual(Side side, Side rot)
Convert a physical side (relative to the hardware itself) to a virtual side (relative to the specifie...
Definition: video.h:335
#define offsetof(t, m)
Definition: macros.h:368
uint8_t windowFirstLine() const
Retrieve the most recent 'firstLine' value, set with setWindow() or setWindowFirstLine() ...
Definition: video.h:230
StampDrawable stamp
Drawable for the STAMP framebuffer mode.
Definition: video.h:158
Byte3 accel() const
Return the physical accelerometer state, as a signed byte-vector.
Definition: cube.h:144
void setRotation(Rotation r)
Set the display rotation to use in subsequent rendering.
Definition: video.h:245
void erase()
Zero all mode-specific video memory.
Definition: video.h:504
BG2Drawable bg2
Drawable for the BG2 tiled mode.
Definition: video.h:157
void setWindow(uint8_t firstLine, uint8_t numLines)
Change the current drawing window.
Definition: video.h:201
#define ASSERT(_x)
Runtime debug assertion.
Definition: macros.h:205
void touch()
Mark the VideoBuffer as having changed, without actually modifying any memory.
Definition: video.h:595
void lock(uint16_t addr)
Prepare to modify a particular address.
Definition: video.h:573
Reconfigurable 16-color framebuffer with transparency.
Definition: video.h:90
Side
An enumeration which names the four sides of a Sifteo cube.
Definition: cube.h:54
void orientTo(const Neighborhood &thisN, const VideoBuffer &src, const Neighborhood &srcN)
Set this VideoBuffer's cube orientation to be consistent with the orientation of another "source" Vid...
Definition: video.h:309
BG0ROMDrawable bg0rom
Drawable for the BG0_ROM tiled mode.
Definition: video.h:154
A VRAM accessor for the STAMP mode, a special purpose 16-color framebuffer mode which supports color-...
Definition: framebuffer.h:340
A VRAM accessor for drawing graphics in the BG2 mode.
Definition: bg2.h:61
Side orientation() const
Map the LCD rotation mask to screen orientation. This is the side which maps to the physical "top" of...
Definition: video.h:267
Side sideOf(CubeID cube) const
Search for a CubeID in this Neighborhood.
Definition: cube.h:442
A VRAM accessor for drawing graphics in the BG0_ROM mode.
Definition: bg0rom.h:53
Vector2< int > Int2
Typedef for a 2-vector of ints.
Definition: math.h:641
BG0Drawable bg0
Drawable for the BG0 layer, as used in BG0, BG0_BG1, and BG0_SPR_BG1 modes.
Definition: video.h:155
void attach(_SYSCubeID id)
Attach this VideoBuffer to a cube.
Definition: video.h:556
uint16_t peek(uint16_t addr) const
Read one word of VRAM.
Definition: video.h:636
BG0 background layer.
Definition: video.h:86
FB64Drawable fb64
Drawable for the FB64 framebuffer mode.
Definition: video.h:152
VideoMode
Supported video modes.
Definition: video.h:79
A VRAM accessor for drawing graphics in the BG1 mode.
Definition: bg1.h:285
A VRAM accessor for drawing graphics in the BG0 mode.
Definition: bg0.h:48
FB128Drawable fb128
Drawable for the FB128 framebuffer mode.
Definition: video.h:153
Nil value (-1)
Definition: cube.h:60
Bottom side (Y+)
Definition: cube.h:57
Side physicalToVirtual(Side side) const
Convert a physical side (relative to the hardware itself) to a virtual side (relative to the current ...
Definition: video.h:355
A lightweight identifier for one Sifteo cube.
Definition: cube.h:85
void unlock()
End a sequence of modifications to VRAM.
Definition: video.h:584
FB32Drawable fb32
Drawable for the FB32 framebuffer mode.
Definition: video.h:151
static Side virtualToPhysical(Side side, Side rot)
Convert a virtual side (relative to the specified screen orientation) to a physical side (relative to...
Definition: video.h:345
void xorb(uint16_t addr, uint8_t byte)
Like pokeb(), but atomically XORs a value with the byte. This is a no-op if and only if byte==0...
Definition: video.h:629
void setWindowFirstLine(uint8_t firstLine)
Like setWindow(), but change only the first line.
Definition: video.h:215
static Neighborhood physicalToVirtual(Neighborhood nb, Side rot)
Convert a Neighborhood from physical to virtual orientation.
Definition: video.h:377
VideoMode mode() const
Retrieve the last video mode set by setMode()
Definition: video.h:493
Byte3 virtualAccel() const
Return the virtual accelerometer reading for this cube.
Definition: video.h:473
Neighborhood virtualNeighbors() const
Return the current virtual neighbors for the cube attached to this VideoBuffer.
Definition: video.h:452
A Neighborhood is a description of all neighbors for a single cube, packed into a small value...
Definition: cube.h:368
uint8_t windowNumLines() const
Retrieve the most recent 'numLines' value, set with setWindow() or setWindowNumLines() ...
Definition: video.h:238
static Neighborhood virtualToPhysical(Neighborhood nb, Side rot)
Convert a Neighborhood from virtual to physical orientation.
Definition: video.h:396
64x64 pixel 2-color framebuffer
Definition: video.h:84
void orientTo(const VideoBuffer &src)
Variant of orientTo() without explicitly specified Neighborhoods.
Definition: video.h:327
A memory buffer which holds graphics data.
Definition: video.h:145
Definition: array.h:34
Left side (X-)
Definition: cube.h:56
Colormap colormap
Colormap accessor, for framebuffer modes.
Definition: video.h:150
Right side (X+)
Definition: cube.h:58
Side virtualToPhysical(Side side) const
Convert a virtual side (relative to the current screen orientation) to a physical side (relative to t...
Definition: video.h:363
Vector3< T > zRotateI(int angle) const
Rotate this vector about the Z axis counterclockwise by an integer multiple of 90 degrees...
Definition: math.h:800
unsigned umod(int a, int b)
Compute the unsigned remainder from dividing two signed integers.
Definition: math.h:208
BG0 background, 8 sprites, BG1 overlay.
Definition: video.h:88
Total number of sides (4)
Definition: cube.h:59
void pokeb(uint16_t addr, uint8_t byte)
Like poke(), but modifies a single byte. Less efficient, but sometimes you really do just want to mod...
Definition: video.h:614
Rotation rotation() const
Look up the last display rotation set by setRotation().
Definition: video.h:257
Solid color, from colormap[0].
Definition: video.h:82
Byte3 physicalAccel() const
Return the physical accelerometer reading for this cube.
Definition: video.h:463
void setOrientation(Side topSide)
Set the LCD rotation such that the top of the framebuffer is at the physical side 'topSide'...
Definition: video.h:283
An accessor for the colormap, with up to 16 colors.
Definition: color.h:264
BG0, with tile data from internal ROM.
Definition: video.h:81
void setMode(VideoMode m)
Change the video mode.
Definition: video.h:486
Top side (Y-)
Definition: cube.h:55
void setWindowNumLines(uint8_t numLines)
Like setWindow(), but change only the number of lines.
Definition: video.h:222
uint8_t peekb(uint16_t addr) const
Read one byte of VRAM.
Definition: video.h:643
Neighborhood physicalNeighbors() const
Return the current physical neighbors for the cube attached to this VideoBuffer.
Definition: video.h:441
BG1Drawable bg1
Drawable for the BG1 layer, as used in BG0_BG1 and BG0_SPR_BG1 modes.
Definition: video.h:156
void poke(uint16_t addr, uint16_t word)
Modify a word of VRAM, automatically locking it and marking the change only if that word has actually...
Definition: video.h:606
void pokei(uint16_t addr, uint16_t index)
Poke a 14-bit tile index into a particular VRAM word.
Definition: video.h:621
CubeID cube() const
Get the CubeID that this buffer is currently attached to.
Definition: video.h:181
Rotation
Rotation and mirroring modes, for setRotation().
Definition: video.h:103
void initMode(VideoMode m, unsigned firstLine=0, unsigned numLines=LCD_height)
Initialize the video buffer and change modes.
Definition: video.h:527
Neighborhood physicalToVirtual(Neighborhood nb) const
Convert a Neighborhood from physical to virtual orientation.
Definition: video.h:415
Power saving mode, LCD is off.
Definition: video.h:80
16x16 tiled mode with affine transform
Definition: video.h:89
void setDefaultWindow()
Restore the default full-screen drawing window.
Definition: video.h:208
A SpriteLayer represents the VRAM attributes for the sprite rendering layer in BG0_SPR_BG1 mode...
Definition: sprite.h:278
32x32 pixel 16-color framebuffer
Definition: video.h:83
BG0 background plus BG1 overlay.
Definition: video.h:87