PPU: Implemented color window

This commit is contained in:
Sour 2019-02-22 22:19:20 -05:00
parent c809f096f5
commit dbfed2bb46
3 changed files with 62 additions and 7 deletions

View file

@ -564,10 +564,57 @@ void Ppu::ApplyColorMath()
return;
}
uint8_t activeWindowCount = (uint8_t)_window[0].ActiveLayers[Ppu::ColorWindowIndex] + (uint8_t)_window[1].ActiveLayers[Ppu::ColorWindowIndex];
for(int x = 0; x < 256; x++) {
if(_rowPixelFlags[x] & PixelFlags::AllowColorMath) {
uint16_t otherPixel;
uint8_t halfShift = _colorMathHalveResult ? 1 : 0;
uint16_t &mainPixel = _currentBuffer[(_scanline << 8) | x];
bool isInsideWindow = activeWindowCount && ProcessMaskWindow<Ppu::ColorWindowIndex>(activeWindowCount, x);
//Set color to black as needed based on clip mode
switch(_colorMathClipMode) {
default:
case ColorWindowMode::Never: break;
case ColorWindowMode::OutsideWindow:
if(!isInsideWindow) {
mainPixel = 0;
halfShift = 0;
}
break;
case ColorWindowMode::InsideWindow:
if(isInsideWindow) {
mainPixel = 0;
halfShift = 0;
}
break;
case ColorWindowMode::Always: mainPixel = 0; break;
}
//Prevent color math as needed based on mode
switch(_colorMathPreventMode) {
default:
case ColorWindowMode::Never: break;
case ColorWindowMode::OutsideWindow:
if(!isInsideWindow) {
continue;
}
break;
case ColorWindowMode::InsideWindow:
if(isInsideWindow) {
continue;
}
break;
case ColorWindowMode::Always: continue;
}
uint16_t otherPixel;
if(_colorMathAddSubscreen) {
if(_subScreenFilled[x]) {
otherPixel = _subScreenBuffer[x];
@ -580,7 +627,6 @@ void Ppu::ApplyColorMath()
otherPixel = _fixedColor;
}
uint16_t &mainPixel = _currentBuffer[(_scanline << 8) | x];
if(_colorMathSubstractMode) {
uint16_t r = std::max((mainPixel & 0x001F) - (otherPixel & 0x001F), 0) >> halfShift;
@ -1014,8 +1060,8 @@ void Ppu::Write(uint32_t addr, uint8_t value)
case 0x2130:
//CGWSEL - Color Addition Select
_colorMathClipMode = (value >> 6) & 0x03; //TODO
_colorMathPreventMode = (value >> 4) & 0x03; //TODO
_colorMathClipMode = (ColorWindowMode)((value >> 6) & 0x03);
_colorMathPreventMode = (ColorWindowMode)((value >> 4) & 0x03);
_colorMathAddSubscreen = (value & 0x02) != 0;
_directColorMode = (value & 0x01) != 0; //TODO
break;

View file

@ -28,6 +28,7 @@ public:
private:
constexpr static int SpriteLayerIndex = 4;
constexpr static int ColorWindowIndex = 5;
constexpr static const uint8_t _oamSizes[8][2][2] = {
{ { 1, 1 }, { 2, 2 } }, //8x8 + 16x16
@ -110,8 +111,8 @@ private:
bool _directColorMode = false;
uint8_t _colorMathClipMode = 0;
uint8_t _colorMathPreventMode = 0;
ColorWindowMode _colorMathClipMode = ColorWindowMode::Never;
ColorWindowMode _colorMathPreventMode = ColorWindowMode::Never;
bool _colorMathAddSubscreen = false;
uint8_t _colorMathEnabled = 0;
bool _colorMathSubstractMode = false;

View file

@ -54,4 +54,12 @@ enum class WindowMaskLogic
And = 1,
Xor = 2,
Xnor = 3
};
};
enum class ColorWindowMode
{
Never = 0,
OutsideWindow = 1,
InsideWindow = 2,
Always = 3
};