mirror of
https://github.com/devinacker/bsnes-plus.git
synced 2025-04-02 10:52:46 -04:00
145 lines
3.8 KiB
C++
145 lines
3.8 KiB
C++
|
|
BaseRenderer::BaseRenderer()
|
|
{
|
|
customBackgroundColor = 0;
|
|
bitDepth = BitDepth::NONE;
|
|
overrideBackgroundColor = false;
|
|
}
|
|
|
|
BaseRenderer::BitDepth BaseRenderer::bitDepthForLayer(unsigned screenMode, unsigned layer) {
|
|
static const BitDepth map[8][4] = {
|
|
{ BPP2, BPP2, BPP2, BPP2},
|
|
{ BPP4, BPP4, BPP2, NONE},
|
|
{ BPP4, BPP4, NONE, NONE},
|
|
{ BPP8, BPP4, NONE, NONE},
|
|
{ BPP8, BPP2, NONE, NONE},
|
|
{ BPP4, BPP2, NONE, NONE},
|
|
{ BPP4, NONE, NONE, NONE},
|
|
{ MODE7, MODE7_EXTBG, NONE, NONE}
|
|
};
|
|
|
|
return map[screenMode & 7][layer & 3];
|
|
}
|
|
|
|
bool BaseRenderer::isMode7() const {
|
|
return bitDepth == BitDepth::MODE7 || bitDepth == BitDepth::MODE7_EXTBG;
|
|
}
|
|
|
|
unsigned BaseRenderer::bytesInbetweenTiles() const {
|
|
switch (bitDepth) {
|
|
case BitDepth::BPP8: return 64;
|
|
case BitDepth::BPP4: return 32;
|
|
case BitDepth::BPP2: return 16;
|
|
case BitDepth::MODE7: return 128;
|
|
case BitDepth::MODE7_EXTBG: return 128;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
unsigned BaseRenderer::colorsPerTile() const {
|
|
switch (bitDepth) {
|
|
case BitDepth::BPP8: return 256;
|
|
case BitDepth::BPP4: return 16;
|
|
case BitDepth::BPP2: return 4;
|
|
case BitDepth::MODE7: return 256;
|
|
case BitDepth::MODE7_EXTBG: return 256;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
void BaseRenderer::buildPalette() {
|
|
if(SNES::cartridge.loaded()) {
|
|
for(unsigned i = 0; i < 256; i++) {
|
|
palette[i] = rgbFromCgram(i);
|
|
}
|
|
}
|
|
}
|
|
|
|
void BaseRenderer::initImage(unsigned width, unsigned height)
|
|
{
|
|
QImage::Format format = QImage::Format_RGB32;
|
|
if(overrideBackgroundColor) {
|
|
if(qAlpha(customBackgroundColor) != 0xff) format = QImage::Format_ARGB32;
|
|
if(customBackgroundColor == 0) format = QImage::Format_ARGB32_Premultiplied;
|
|
}
|
|
|
|
if(image.width() != width || image.height() != height || image.format() != format) {
|
|
image = QImage(width, height, format);
|
|
}
|
|
|
|
if(overrideBackgroundColor) {
|
|
image.fill(customBackgroundColor);
|
|
} else {
|
|
image.fill(palette[0]);
|
|
}
|
|
}
|
|
|
|
void BaseRenderer::invalidateImage()
|
|
{
|
|
image = QImage();
|
|
}
|
|
|
|
void BaseRenderer::draw8pxTile(QRgb* imgBits, const unsigned wordsPerScanline, const uint8_t* tile, unsigned palOffset, bool hFlip, bool vFlip) {
|
|
uint8_t data[8];
|
|
|
|
for(unsigned py = 0; py < 8; py++) {
|
|
unsigned fpy = (vFlip == false) ? py : 7 - py;
|
|
const uint8_t *sliver = tile + fpy * 2;
|
|
|
|
switch(bitDepth) {
|
|
case BitDepth::BPP8:
|
|
data[4] = sliver[32];
|
|
data[5] = sliver[33];
|
|
data[6] = sliver[48];
|
|
data[7] = sliver[49];
|
|
//fall through
|
|
case BitDepth::BPP4:
|
|
data[2] = sliver[16];
|
|
data[3] = sliver[17];
|
|
//fall through
|
|
case BitDepth::BPP2:
|
|
data[0] = sliver[ 0];
|
|
data[1] = sliver[ 1];
|
|
}
|
|
|
|
for(unsigned px = 0; px < 8; px++) {
|
|
unsigned fpx = hFlip == false ? px : 7 - px;
|
|
|
|
uint8_t pixel = 0;
|
|
switch(bitDepth) {
|
|
case BitDepth::BPP8:
|
|
pixel |= (data[7] & (0x80 >> px)) ? 0x80 : 0;
|
|
pixel |= (data[6] & (0x80 >> px)) ? 0x40 : 0;
|
|
pixel |= (data[5] & (0x80 >> px)) ? 0x20 : 0;
|
|
pixel |= (data[4] & (0x80 >> px)) ? 0x10 : 0;
|
|
//fall through
|
|
case BitDepth::BPP4:
|
|
pixel |= (data[3] & (0x80 >> px)) ? 0x08 : 0;
|
|
pixel |= (data[2] & (0x80 >> px)) ? 0x04 : 0;
|
|
//fall through
|
|
case BitDepth::BPP2:
|
|
pixel |= (data[1] & (0x80 >> px)) ? 0x02 : 0;
|
|
pixel |= (data[0] & (0x80 >> px)) ? 0x01 : 0;
|
|
}
|
|
|
|
if (pixel != 0) {
|
|
imgBits[fpx] = palette[(palOffset + pixel) & 0xff];
|
|
}
|
|
}
|
|
|
|
imgBits += wordsPerScanline;
|
|
}
|
|
}
|
|
|
|
void BaseRenderer::drawMode7Tile(QRgb* imgBits, const unsigned wordsPerScanline, const uint8_t* tile) {
|
|
for(unsigned py = 0; py < 8; py++) {
|
|
for(unsigned px = 0; px < 8; px++) {
|
|
uint8_t pixel = *tile;
|
|
if(bitDepth == MODE7_EXTBG) pixel &= 0x7f;
|
|
|
|
if(pixel != 0) imgBits[px] = palette[pixel];
|
|
tile +=2;
|
|
}
|
|
imgBits += wordsPerScanline;
|
|
}
|
|
}
|