PPU: Implemented color window
This commit is contained in:
parent
c809f096f5
commit
dbfed2bb46
3 changed files with 62 additions and 7 deletions
54
Core/Ppu.cpp
54
Core/Ppu.cpp
|
@ -564,10 +564,57 @@ void Ppu::ApplyColorMath()
|
||||||
return;
|
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++) {
|
for(int x = 0; x < 256; x++) {
|
||||||
if(_rowPixelFlags[x] & PixelFlags::AllowColorMath) {
|
if(_rowPixelFlags[x] & PixelFlags::AllowColorMath) {
|
||||||
uint16_t otherPixel;
|
|
||||||
uint8_t halfShift = _colorMathHalveResult ? 1 : 0;
|
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(_colorMathAddSubscreen) {
|
||||||
if(_subScreenFilled[x]) {
|
if(_subScreenFilled[x]) {
|
||||||
otherPixel = _subScreenBuffer[x];
|
otherPixel = _subScreenBuffer[x];
|
||||||
|
@ -580,7 +627,6 @@ void Ppu::ApplyColorMath()
|
||||||
otherPixel = _fixedColor;
|
otherPixel = _fixedColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t &mainPixel = _currentBuffer[(_scanline << 8) | x];
|
|
||||||
|
|
||||||
if(_colorMathSubstractMode) {
|
if(_colorMathSubstractMode) {
|
||||||
uint16_t r = std::max((mainPixel & 0x001F) - (otherPixel & 0x001F), 0) >> halfShift;
|
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:
|
case 0x2130:
|
||||||
//CGWSEL - Color Addition Select
|
//CGWSEL - Color Addition Select
|
||||||
_colorMathClipMode = (value >> 6) & 0x03; //TODO
|
_colorMathClipMode = (ColorWindowMode)((value >> 6) & 0x03);
|
||||||
_colorMathPreventMode = (value >> 4) & 0x03; //TODO
|
_colorMathPreventMode = (ColorWindowMode)((value >> 4) & 0x03);
|
||||||
_colorMathAddSubscreen = (value & 0x02) != 0;
|
_colorMathAddSubscreen = (value & 0x02) != 0;
|
||||||
_directColorMode = (value & 0x01) != 0; //TODO
|
_directColorMode = (value & 0x01) != 0; //TODO
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -28,6 +28,7 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
constexpr static int SpriteLayerIndex = 4;
|
constexpr static int SpriteLayerIndex = 4;
|
||||||
|
constexpr static int ColorWindowIndex = 5;
|
||||||
|
|
||||||
constexpr static const uint8_t _oamSizes[8][2][2] = {
|
constexpr static const uint8_t _oamSizes[8][2][2] = {
|
||||||
{ { 1, 1 }, { 2, 2 } }, //8x8 + 16x16
|
{ { 1, 1 }, { 2, 2 } }, //8x8 + 16x16
|
||||||
|
@ -110,8 +111,8 @@ private:
|
||||||
|
|
||||||
bool _directColorMode = false;
|
bool _directColorMode = false;
|
||||||
|
|
||||||
uint8_t _colorMathClipMode = 0;
|
ColorWindowMode _colorMathClipMode = ColorWindowMode::Never;
|
||||||
uint8_t _colorMathPreventMode = 0;
|
ColorWindowMode _colorMathPreventMode = ColorWindowMode::Never;
|
||||||
bool _colorMathAddSubscreen = false;
|
bool _colorMathAddSubscreen = false;
|
||||||
uint8_t _colorMathEnabled = 0;
|
uint8_t _colorMathEnabled = 0;
|
||||||
bool _colorMathSubstractMode = false;
|
bool _colorMathSubstractMode = false;
|
||||||
|
|
|
@ -54,4 +54,12 @@ enum class WindowMaskLogic
|
||||||
And = 1,
|
And = 1,
|
||||||
Xor = 2,
|
Xor = 2,
|
||||||
Xnor = 3
|
Xnor = 3
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class ColorWindowMode
|
||||||
|
{
|
||||||
|
Never = 0,
|
||||||
|
OutsideWindow = 1,
|
||||||
|
InsideWindow = 2,
|
||||||
|
Always = 3
|
||||||
|
};
|
||||||
|
|
Loading…
Add table
Reference in a new issue