Shift all those uint_least32 to a custom, variable typedef. Still tries rendering 32bpp to a 16bpp buffer, though.

This commit is contained in:
Alcaro 2013-11-22 22:01:44 +01:00
parent 255e0f7af5
commit 434ea5dfab
13 changed files with 99 additions and 64 deletions

View File

@ -1,4 +1,4 @@
DEBUG = 0
DEBUG = 1
ifeq ($(platform),)
platform = unix
@ -146,7 +146,7 @@ CXXOBJ := $(CXXSRCS:.cpp=.o)
OBJS := $(CXXOBJ)
DEFINES := -D__LIBRETRO__ $(PLATFORM_DEFINES) -DHAVE_STDINT_H -DHAVE_INTTYPES_H -DINLINE=inline
DEFINES := -D__LIBRETRO__ $(PLATFORM_DEFINES) -DHAVE_STDINT_H -DHAVE_INTTYPES_H -DINLINE=inline -DVIDEO_RGB565
ifeq ($(platform), sncps3)
CODE_DEFINES =

View File

@ -25,6 +25,11 @@
#include <stddef.h>
namespace gambatte {
#ifdef VIDEO_RGB565
typedef uint16_t video_pixel_t;
#else
typedef uint_least32_t video_pixel_t;
#endif
enum { BG_PALETTE = 0, SP1_PALETTE = 1, SP2_PALETTE = 2 };
class GB {
@ -60,7 +65,7 @@ public:
* @param samples in: number of stereo samples to produce, out: actual number of samples produced
* @return sample number at which the video frame was produced. -1 means no frame was produced.
*/
long runFor(gambatte::uint_least32_t *videoBuf, int pitch,
long runFor(gambatte::video_pixel_t *videoBuf, int pitch,
gambatte::uint_least32_t *soundBuf, unsigned &samples);
/** Reset to initial state.

View File

@ -345,12 +345,21 @@ bool retro_load_game(const struct retro_game_info *info)
return false;
}
#ifdef VIDEO_RGB565
enum retro_pixel_format fmt = RETRO_PIXEL_FORMAT_RGB565;
if (!environ_cb(RETRO_ENVIRONMENT_SET_PIXEL_FORMAT, &fmt))
{
fprintf(stderr, "[Gambatte]: RGB565 is not supported.\n");
return false;
}
#else
enum retro_pixel_format fmt = RETRO_PIXEL_FORMAT_XRGB8888;
if (!environ_cb(RETRO_ENVIRONMENT_SET_PIXEL_FORMAT, &fmt))
{
fprintf(stderr, "[Gambatte]: XRGB8888 is not supported.\n");
return false;
}
#endif
if (gb.load(info->data, info->size))
return false;
@ -416,7 +425,11 @@ void retro_run()
uint64_t expected_frames = samples_count / 35112;
if (frames_count < expected_frames) // Detect frame dupes.
{
#ifdef VIDEO_RGB565
video_cb(0, 160, 144, 512);
#else
video_cb(0, 160, 144, 1024);
#endif
frames_count++;
return;
}
@ -428,7 +441,7 @@ void retro_run()
} static sound_buf;
unsigned samples = 2064;
static gambatte::uint_least32_t video_buf[256 * 144];
static gambatte::video_pixel_t video_buf[256 * 144];
gambatte::uint_least32_t video_pitch = 256;
while (gb.runFor(video_buf, video_pitch, sound_buf.u32, samples) == -1)
{
@ -440,7 +453,11 @@ void retro_run()
samples_count += samples;
output_audio(sound_buf.i16, samples);
#ifdef VIDEO_RGB565
video_cb(video_buf, 160, 144, 512);
#else
video_cb(video_buf, 160, 144, 1024);
#endif
frames_count++;

View File

@ -19,6 +19,7 @@
#ifndef BITMAP_FONT_H
#define BITMAP_FONT_H
#include "gambatte.h"
#include "gbint.h"
namespace bitmapfont {
@ -42,7 +43,7 @@ unsigned getWidth(const char *chars);
template<class RandomAccessIterator, class Fill>
void print(RandomAccessIterator dest, unsigned pitch, Fill fill, const char *chars);
void print(gambatte::uint_least32_t *dest, unsigned pitch, unsigned long color, const char *chars);
void print(gambatte::video_pixel_t *dest, unsigned pitch, unsigned long color, const char *chars);
void utoa(unsigned u, char *a);
// --- INTERFACE END ---

View File

@ -56,7 +56,7 @@ public:
void *rtcdata_ptr() { return memory.rtcdata_ptr(); }
unsigned rtcdata_size() { return memory.rtcdata_size(); }
void setVideoBuffer(uint_least32_t *const videoBuf, const int pitch) {
void setVideoBuffer(video_pixel_t *const videoBuf, const int pitch) {
memory.setVideoBuffer(videoBuf, pitch);
}

View File

@ -140,7 +140,7 @@ public:
void setSoundBuffer(uint_least32_t *const buf) { sound.setBuffer(buf); }
unsigned fillSoundBuffer(unsigned long cc);
void setVideoBuffer(uint_least32_t *const videoBuf, const int pitch) {
void setVideoBuffer(video_pixel_t *const videoBuf, const int pitch) {
display.setVideoBuffer(videoBuf, pitch);
}

View File

@ -41,7 +41,7 @@ GB::~GB() {
delete p_;
}
long GB::runFor(gambatte::uint_least32_t *const videoBuf, const int pitch,
long GB::runFor(gambatte::video_pixel_t *const videoBuf, const int pitch,
gambatte::uint_least32_t *const soundBuf, unsigned &samples) {
p_->cpu.setVideoBuffer(videoBuf, pitch);

View File

@ -60,7 +60,7 @@ public:
unsigned h() const { return h_; }
Opacity opacity() const { return opacity_; }
virtual const uint_least32_t* update() = 0;
virtual const gambatte::video_pixel_t* update() = 0;
};
}

View File

@ -16,6 +16,7 @@
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#include "gambatte.h"
#include "state_osd_elements.h"
#include "bitmap_font.h"
#include "statesaver.h"
@ -34,7 +35,7 @@ static const unsigned stateSavedTxtWidth = getWidth(stateSavedTxt);
class ShadedTextOsdElment : public OsdElement {
struct ShadeFill {
void operator()(uint_least32_t *dest, const unsigned pitch) const {
void operator()(video_pixel_t *dest, const unsigned pitch) const {
dest[2] = dest[1] = dest[0] = 0x000000ul;
dest += pitch;
dest[2] = dest[0] = 0x000000ul;
@ -43,7 +44,7 @@ class ShadedTextOsdElment : public OsdElement {
}
};
uint_least32_t *const pixels;
video_pixel_t *const pixels;
unsigned life;
ShadedTextOsdElment(const ShadedTextOsdElment&);
@ -51,14 +52,14 @@ class ShadedTextOsdElment : public OsdElement {
public:
ShadedTextOsdElment(unsigned w, const char *txt);
~ShadedTextOsdElment();
const uint_least32_t* update();
const gambatte::video_pixel_t* update();
};
ShadedTextOsdElment::ShadedTextOsdElment(unsigned width, const char *txt) :
OsdElement(MAX_WIDTH, 144 - HEIGHT - HEIGHT, width + 2, HEIGHT + 2, THREE_FOURTHS),
pixels(new uint_least32_t[w() * h()]),
pixels(new video_pixel_t[w() * h()]),
life(4 * 60) {
std::memset(pixels, 0xFF, w() * h() * sizeof(uint_least32_t));
std::memset(pixels, 0xFF, w() * h() * sizeof(video_pixel_t));
/*print(pixels + 0 * w() + 0, w(), 0x000000ul, txt);
print(pixels + 0 * w() + 1, w(), 0x000000ul, txt);
@ -78,7 +79,7 @@ ShadedTextOsdElment::~ShadedTextOsdElment() {
delete []pixels;
}
const uint_least32_t* ShadedTextOsdElment::update() {
const video_pixel_t* ShadedTextOsdElment::update() {
if (life--)
return pixels;
@ -86,7 +87,7 @@ const uint_least32_t* ShadedTextOsdElment::update() {
}
/*class FramedTextOsdElment : public OsdElement {
uint_least32_t *const pixels;
video_pixel_t *const pixels;
unsigned life;
FramedTextOsdElment(const FramedTextOsdElment&);
@ -94,14 +95,14 @@ const uint_least32_t* ShadedTextOsdElment::update() {
public:
FramedTextOsdElment(unsigned w, const char *txt);
~FramedTextOsdElment();
const uint_least32_t* update();
const video_pixel_t* update();
};
FramedTextOsdElment::FramedTextOsdElment(unsigned width, const char *txt) :
OsdElement(NUMBER_WIDTH, 144 - HEIGHT * 2 - HEIGHT / 2, width + NUMBER_WIDTH * 2, HEIGHT * 2),
pixels(new uint_least32_t[w() * h()]),
pixels(new video_pixel_t[w() * h()]),
life(4 * 60) {
std::memset(pixels, 0x00, w() * h() * sizeof(uint_least32_t));
std::memset(pixels, 0x00, w() * h() * sizeof(video_pixel_t));
print(pixels + (w() - width) / 2 + ((h() - HEIGHT) / 2) * w(), w(), 0xA0A0A0ul, txt);
}
@ -109,7 +110,7 @@ FramedTextOsdElment::~FramedTextOsdElment() {
delete []pixels;
}
const uint_least32_t* FramedTextOsdElment::update() {
const video_pixel_t* FramedTextOsdElment::update() {
if (life--)
return pixels;
@ -117,12 +118,12 @@ const uint_least32_t* FramedTextOsdElment::update() {
}*/
class SaveStateOsdElement : public OsdElement {
uint_least32_t pixels[StateSaver::SS_WIDTH * StateSaver::SS_HEIGHT];
video_pixel_t pixels[StateSaver::SS_WIDTH * StateSaver::SS_HEIGHT];
unsigned life;
public:
SaveStateOsdElement(const std::string &fileName, unsigned stateNo);
const uint_least32_t* update();
const video_pixel_t* update();
};
SaveStateOsdElement::SaveStateOsdElement(const std::string &fileName, unsigned stateNo) :
@ -147,7 +148,7 @@ life(4 * 60) {
}
}
const uint_least32_t* SaveStateOsdElement::update() {
const video_pixel_t* SaveStateOsdElement::update() {
if (life--)
return pixels;

View File

@ -23,7 +23,7 @@
namespace gambatte {
void LCD::setDmgPalette(unsigned long *const palette, const unsigned long *const dmgColors, const unsigned data) {
void LCD::setDmgPalette(video_pixel_t *const palette, const video_pixel_t *const dmgColors, const unsigned data) {
palette[0] = dmgColors[data & 3];
palette[1] = dmgColors[data >> 2 & 3];
palette[2] = dmgColors[data >> 4 & 3];
@ -77,7 +77,17 @@ LCD::LCD(const unsigned char *const oamram, const unsigned char *const vram, con
std::memset(objpData, 0, sizeof objpData);
for (std::size_t i = 0; i < sizeof(dmgColorsRgb32) / sizeof(dmgColorsRgb32[0]); ++i)
{
#ifdef VIDEO_RGB565
uint16_t dmgColors[4]={0xFFFF, //11111 111111 11111
0xAD55, //10101 101010 10101
0x52AA, //01010 010101 01010
0x0000};//00000 000000 00000
setDmgPaletteColor(i, dmgColors[i]);
#else
setDmgPaletteColor(i, (3 - (i & 3)) * 85 * 0x010101);
#endif
}
reset(oamram, false);
setVideoBuffer(0, 160);
@ -186,8 +196,8 @@ void LCD::refreshPalettes() {
namespace {
template<class Blend>
static void blitOsdElement(uint_least32_t *d,
const uint_least32_t *s, const unsigned width, unsigned h, const int dpitch, Blend blend)
static void blitOsdElement(video_pixel_t *d,
const video_pixel_t *s, const unsigned width, unsigned h, const int dpitch, Blend blend)
{
while (h--) {
for (unsigned w = width; w--;) {
@ -206,7 +216,7 @@ template<unsigned weight>
struct Blend {
enum { SW = weight - 1 };
enum { LOWMASK = SW * 0x010101ul };
uint_least32_t operator()(const uint_least32_t s, const uint_least32_t d) const {
video_pixel_t operator()(const video_pixel_t s, const video_pixel_t d) const {
return (s * SW + d - (((s & LOWMASK) * SW + (d & LOWMASK)) & LOWMASK)) / weight;
}
};
@ -227,13 +237,13 @@ void LCD::updateScreen(const bool blanklcd, const unsigned long cycleCounter) {
update(cycleCounter);
if (blanklcd && ppu.frameBuf().fb()) {
const unsigned long color = ppu.cgb() ? gbcToRgb32(0xFFFF) : dmgColorsRgb32[0];
const video_pixel_t color = ppu.cgb() ? gbcToRgb32(0xFFFF) : dmgColorsRgb32[0];
clear(ppu.frameBuf().fb(), color, ppu.frameBuf().pitch());
}
if (ppu.frameBuf().fb() && osdElement.get()) {
if (const uint_least32_t *const s = osdElement->update()) {
uint_least32_t *const d = ppu.frameBuf().fb()
if (const video_pixel_t *const s = osdElement->update()) {
video_pixel_t *const d = ppu.frameBuf().fb()
+ static_cast<long>(osdElement->y()) * ppu.frameBuf().pitch() + osdElement->x();
switch (osdElement->opacity()) {
@ -356,7 +366,7 @@ bool LCD::cgbpAccessible(const unsigned long cycleCounter) {
}
static void doCgbColorChange(unsigned char *const pdata,
unsigned long *const palette, unsigned index, const unsigned data) {
video_pixel_t *const palette, unsigned index, const unsigned data) {
pdata[index] = data;
index >>= 1;
palette[index] = gbcToRgb32(pdata[index << 1] | pdata[(index << 1) + 1] << 8);
@ -762,15 +772,15 @@ void LCD::update(const unsigned long cycleCounter) {
ppu.update(cycleCounter);
}
void LCD::setVideoBuffer(uint_least32_t *const videoBuf, const int pitch) {
void LCD::setVideoBuffer(video_pixel_t *const videoBuf, const int pitch) {
ppu.setFrameBuf(videoBuf, pitch);
}
void LCD::setDmgPaletteColor(const unsigned index, const unsigned long rgb32) {
void LCD::setDmgPaletteColor(const unsigned index, const video_pixel_t rgb32) {
dmgColorsRgb32[index] = rgb32;
}
void LCD::setDmgPaletteColor(const unsigned palNum, const unsigned colorNum, const unsigned long rgb32) {
void LCD::setDmgPaletteColor(const unsigned palNum, const unsigned colorNum, const video_pixel_t rgb32) {
if (palNum > 2 || colorNum > 3)
return;

View File

@ -119,7 +119,7 @@ class LCD {
};
PPU ppu;
unsigned long dmgColorsRgb32[3 * 4];
video_pixel_t dmgColorsRgb32[3 * 4];
unsigned char bgpData[8 * 8];
unsigned char objpData[8 * 8];
@ -134,8 +134,8 @@ class LCD {
unsigned char m2IrqStatReg_;
unsigned char m1IrqStatReg_;
static void setDmgPalette(unsigned long *palette, const unsigned long *dmgColors, unsigned data);
void setDmgPaletteColor(unsigned index, unsigned long rgb32);
static void setDmgPalette(video_pixel_t *palette, const video_pixel_t *dmgColors, unsigned data);
void setDmgPaletteColor(unsigned index, video_pixel_t rgb32);
void refreshPalettes();
void setDBuffer();
@ -156,8 +156,8 @@ public:
void setStatePtrs(SaveState &state);
void saveState(SaveState &state) const;
void loadState(const SaveState &state, const unsigned char *oamram);
void setDmgPaletteColor(unsigned palNum, unsigned colorNum, unsigned long rgb32);
void setVideoBuffer(uint_least32_t *videoBuf, int pitch);
void setDmgPaletteColor(unsigned palNum, unsigned colorNum, video_pixel_t rgb32);
void setVideoBuffer(video_pixel_t *videoBuf, int pitch);
void setOsdElement(std::auto_ptr<OsdElement> osdElement) { this->osdElement = osdElement; }

View File

@ -293,7 +293,7 @@ namespace M3Start {
}
namespace M3Loop {
static void doFullTilesUnrolledDmg(PPUPriv &p, const int xend, uint_least32_t *const dbufline,
static void doFullTilesUnrolledDmg(PPUPriv &p, const int xend, video_pixel_t *const dbufline,
const unsigned char *const tileMapLine, const unsigned tileline, unsigned tileMapXpos) {
const unsigned tileIndexSign = ~p.lcdc << 3 & 0x80;
const unsigned char *const tileDataLine = p.vram + tileIndexSign * 32 + tileline * 2;
@ -354,7 +354,7 @@ namespace M3Loop {
n = static_cast<unsigned>(p.cycles) >> 3 < n ? static_cast<unsigned>(p.cycles) >> 3 : n;
unsigned ntileword = p.ntileword;
uint_least32_t *dst = dbufline + xpos - 8;
video_pixel_t *dst = dbufline + xpos - 8;
p.cycles -= n * 8;
xpos += n * 8;
@ -393,7 +393,7 @@ namespace M3Loop {
}
{
uint_least32_t *const dst = dbufline + (xpos - 8);
video_pixel_t *const dst = dbufline + (xpos - 8);
const unsigned tileword = p.ntileword;
dst[0] = p.bgPalette[tileword & twmask];
@ -426,7 +426,7 @@ namespace M3Loop {
const unsigned attrib = p.spriteList[i].attrib;
unsigned spword = p.spwordList[i];
const unsigned long *const spPalette = p.spPalette + (attrib >> 2 & 4);
const video_pixel_t *const spPalette = p.spPalette + (attrib >> 2 & 4);
if (!(attrib & 0x80)) {
switch (n) {
@ -487,7 +487,7 @@ namespace M3Loop {
p.xpos = xpos;
}
static void doFullTilesUnrolledCgb(PPUPriv &p, const int xend, uint_least32_t *const dbufline,
static void doFullTilesUnrolledCgb(PPUPriv &p, const int xend, video_pixel_t *const dbufline,
const unsigned char *const tileMapLine, const unsigned tileline, unsigned tileMapXpos) {
int xpos = p.xpos;
const unsigned tileIndexSign = ~p.lcdc << 3 & 0x80;
@ -538,7 +538,7 @@ namespace M3Loop {
unsigned ntileword = p.ntileword;
unsigned nattrib = p.nattrib;
uint_least32_t *dst = dbufline + xpos - 8;
video_pixel_t *dst = dbufline + xpos - 8;
p.cycles -= n * 8;
xpos += n * 8;
@ -585,10 +585,10 @@ namespace M3Loop {
}
{
uint_least32_t *const dst = dbufline + (xpos - 8);
video_pixel_t *const dst = dbufline + (xpos - 8);
const unsigned tileword = p.ntileword;
const unsigned attrib = p.nattrib;
const unsigned long *const bgPalette = p.bgPalette + (attrib & 7) * 4;
const video_pixel_t *const bgPalette = p.bgPalette + (attrib & 7) * 4;
dst[0] = bgPalette[tileword & 3];
dst[1] = bgPalette[tileword >> 2 & 3];
@ -624,7 +624,7 @@ namespace M3Loop {
const unsigned id = p.spriteList[i].oampos;
const unsigned sattrib = p.spriteList[i].attrib;
unsigned spword = p.spwordList[i];
const unsigned long *const spPalette = p.spPalette + (sattrib & 7) * 4;
const video_pixel_t *const spPalette = p.spPalette + (sattrib & 7) * 4;
if (!((attrib | sattrib) & bgenmask)) {
switch (n) {
@ -725,7 +725,7 @@ namespace M3Loop {
if (xpos >= xend)
return;
uint_least32_t *const dbufline = p.framebuf.fbline();
video_pixel_t *const dbufline = p.framebuf.fbline();
const unsigned char *tileMapLine;
unsigned tileline;
unsigned tileMapXpos;
@ -741,7 +741,7 @@ namespace M3Loop {
}
if (xpos < 8) {
uint_least32_t prebuf[16];
video_pixel_t prebuf[16];
if (p.cgb) {
doFullTilesUnrolledCgb(p, xend < 8 ? xend : 8, prebuf + (8 - xpos), tileMapLine, tileline, tileMapXpos);
@ -751,7 +751,7 @@ namespace M3Loop {
const int newxpos = p.xpos;
if (newxpos > 8) {
std::memcpy(dbufline, prebuf + (8 - xpos), (newxpos - 8) * sizeof(uint_least32_t));
std::memcpy(dbufline, prebuf + (8 - xpos), (newxpos - 8) * sizeof(video_pixel_t));
} else if (newxpos < 8)
return;
@ -770,7 +770,7 @@ namespace M3Loop {
static void plotPixel(PPUPriv &p) {
const int xpos = p.xpos;
const unsigned tileword = p.tileword;
uint_least32_t *const fbline = p.framebuf.fbline();
video_pixel_t *const fbline = p.framebuf.fbline();
if (static_cast<int>(p.wx) == xpos && (p.weMaster || (p.wy2 == p.lyCounter.ly() && (p.lcdc & 0x20))) && xpos < 167) {
if (p.winDrawState == 0 && (p.lcdc & 0x20)) {
@ -781,7 +781,7 @@ namespace M3Loop {
}
const unsigned twdata = tileword & ((p.lcdc & 1) | p.cgb) * 3;
unsigned long pixel = p.bgPalette[twdata + (p.attrib & 7) * 4];
video_pixel_t pixel = p.bgPalette[twdata + (p.attrib & 7) * 4];
int i = static_cast<int>(p.nextSprite) - 1;
if (i >= 0 && static_cast<int>(p.spriteList[i].spx) > xpos - 8) {

View File

@ -22,22 +22,23 @@
#include "video/ly_counter.h"
#include "video/sprite_mapper.h"
#include "gbint.h"
#include "gambatte.h"
namespace gambatte {
class PPUFrameBuf {
uint_least32_t *buf_;
uint_least32_t *fbline_;
video_pixel_t *buf_;
video_pixel_t *fbline_;
int pitch_;
static uint_least32_t * nullfbline() { static uint_least32_t nullfbline_[160]; return nullfbline_; }
static video_pixel_t * nullfbline() { static video_pixel_t nullfbline_[160]; return nullfbline_; }
public:
PPUFrameBuf() : buf_(0), fbline_(nullfbline()), pitch_(0) {}
uint_least32_t * fb() const { return buf_; }
uint_least32_t * fbline() const { return fbline_; }
video_pixel_t * fb() const { return buf_; }
video_pixel_t * fbline() const { return fbline_; }
int pitch() const { return pitch_; }
void setBuf(uint_least32_t *const buf, const int pitch) { buf_ = buf; pitch_ = pitch; fbline_ = nullfbline(); }
void setBuf(video_pixel_t *const buf, const int pitch) { buf_ = buf; pitch_ = pitch; fbline_ = nullfbline(); }
void setFbline(const unsigned ly) { fbline_ = buf_ ? buf_ + static_cast<long>(ly) * static_cast<long>(pitch_) : nullfbline(); }
};
@ -49,8 +50,8 @@ struct PPUState {
// The PPU loop accesses a lot of state at once, so it's difficult to split this up much beyond grouping stuff into smaller structs.
struct PPUPriv {
unsigned long bgPalette[8 * 4];
unsigned long spPalette[8 * 4];
video_pixel_t bgPalette[8 * 4];
video_pixel_t spPalette[8 * 4];
const unsigned char *const vram;
const PPUState *nextCallPtr;
@ -101,7 +102,7 @@ public:
{
}
unsigned long * bgPalette() { return p_.bgPalette; }
video_pixel_t * bgPalette() { return p_.bgPalette; }
bool cgb() const { return p_.cgb; }
void doLyCountEvent() { p_.lyCounter.doEvent(); }
unsigned long doSpriteMapEvent(unsigned long time) { return p_.spriteMapper.doEvent(time); }
@ -118,7 +119,7 @@ public:
void reset(const unsigned char *oamram, bool cgb);
void resetCc(unsigned long oldCc, unsigned long newCc);
void saveState(SaveState &ss) const;
void setFrameBuf(uint_least32_t *buf, unsigned pitch) { p_.framebuf.setBuf(buf, pitch); }
void setFrameBuf(video_pixel_t *buf, unsigned pitch) { p_.framebuf.setBuf(buf, pitch); }
void setLcdc(unsigned lcdc, unsigned long cc);
void setScx(const unsigned scx) { p_.scx = scx; }
void setScy(const unsigned scy) { p_.scy = scy; }
@ -127,7 +128,7 @@ public:
void setWy(const unsigned wy) { p_.wy = wy; }
void updateWy2() { p_.wy2 = p_.wy; }
void speedChange(unsigned long cycleCounter);
unsigned long * spPalette() { return p_.spPalette; }
video_pixel_t * spPalette() { return p_.spPalette; }
void update(unsigned long cc);
};