summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/video/ppu2c0x_vt.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/video/ppu2c0x_vt.cpp')
-rw-r--r--src/devices/video/ppu2c0x_vt.cpp190
1 files changed, 97 insertions, 93 deletions
diff --git a/src/devices/video/ppu2c0x_vt.cpp b/src/devices/video/ppu2c0x_vt.cpp
index bfd18d3d68a..e396999a950 100644
--- a/src/devices/video/ppu2c0x_vt.cpp
+++ b/src/devices/video/ppu2c0x_vt.cpp
@@ -24,6 +24,8 @@ ppu_vt03_device::ppu_vt03_device(const machine_config &mconfig, const char *tag,
m_read_bg(*this),
m_read_sp(*this)
{
+ for(int i = 0; i < 6; i++)
+ m_2012_2017_descramble[i] = 2 + i;
}
READ8_MEMBER(ppu_vt03_device::palette_read)
@@ -40,90 +42,75 @@ READ8_MEMBER(ppu_vt03_device::palette_read)
void ppu_vt03_device::set_new_pen(int i)
{
- if(m_pal_mode == PAL_MODE_NEW_RGB) {
- uint16_t rgbval = (m_newpal[i&0x7f] & 0xff) | ((m_newpal[(i&0x7f)+0x80] & 0xff)<<8);
- uint8_t blue = (rgbval & 0x001f) << 3;
- uint8_t green = (rgbval & 0x3e0) >> 2;
- uint8_t red = (rgbval & 0x7C00) >> 7;
- m_palette->set_pen_color(i & 0x7f, rgb_t(red, green, blue));
+ if((i < 0x20) && ((i & 0x3) == 0)) {
+ m_palette->set_pen_color(i & 0x7f, rgb_t(0, 0, 0));
} else {
- // TODO: should this be tidied up?
- uint16_t palval = (m_newpal[i&0x7f] & 0x3f) | ((m_newpal[(i&0x7f)+0x80] & 0x3f)<<6);
-
- uint8_t rhue = palval & 0x0F;
- uint8_t rlum = (palval >> 4) & 0x0F;
- uint8_t rsat = (palval >> 8) & 0x0F;
- //See http://wiki.nesdev.com/w/index.php/VT03%2B_Enhanced_Palette#Inverted_extended_color_numbers
- bool inverted = (rlum < ((rsat + 1) >> 1) || rlum > (15 - (rsat >>1)));
- if(inverted && (m_pal_mode != PAL_MODE_NEW_VG)) {
- rsat = 16 - rsat;
- rlum = (rlum - 8) & 0x0F;
- uint8_t hue_lut[16] = {0xD, 0x7, 0x8, 0x9, 0xA, 0xB, 0xC, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x0, 0xE, 0xF};
- rhue = hue_lut[rhue];
- }
-
- // Get base color
- double hue = 287.0;
-
- double Kr = 0.2989;
- double Kb = 0.1145;
- double Ku = 2.029;
- double Kv = 1.140;
-
- double sat;
- double y, u, v;
- double rad;
- int R, G, B;
- switch (rhue)
- {
- case 0:
- sat = 0; rad = 0;
- y = 1.0;
- break;
-
- case 13:
- sat = 0; rad = 0;
- y = 0.77;
- break;
-
- case 14:
- case 15:
- sat = 0; rad = 0; y = 0;
- break;
-
- default:
- sat = (m_pal_mode == PAL_MODE_NEW_VG) ? 0.5 : 0.7;
- rad = M_PI * ((rhue * 30 + hue) / 180.0);
- y = (m_pal_mode == PAL_MODE_NEW_VG) ? 0.4 : 0.9;
- break;
+ if(m_pal_mode == PAL_MODE_NEW_RGB) {
+ uint16_t rgbval = (m_newpal[i&0x7f] & 0xff) | ((m_newpal[(i&0x7f)+0x80] & 0xff)<<8);
+ uint8_t blue = (rgbval & 0x001f) << 3;
+ uint8_t green = (rgbval & 0x3e0) >> 2;
+ uint8_t red = (rgbval & 0x7C00) >> 7;
+ m_palette->set_pen_color(i & 0x7f, rgb_t(red, green, blue));
+ } else if(m_pal_mode == PAL_MODE_NEW_RGB12) {
+ uint16_t rgbval = (m_newpal[i&0x7f] & 0x3f) | ((m_newpal[(i&0x7f)+0x80] & 0x3f)<<6);
+ uint8_t red = (rgbval & 0x000f) << 4;
+ uint8_t green = (rgbval & 0x0f0);
+ uint8_t blue = (rgbval & 0xf00) >> 4;
+ m_palette->set_pen_color(i & 0x7f, rgb_t(red, green, blue));
+ } else {
+ // Credit to NewRisingSun
+ uint16_t palval = (m_newpal[i&0x7f] & 0x3f) | ((m_newpal[(i&0x7f)+0x80] & 0x3f)<<6);
+ int nPhase = (palval >>0) &0xF;
+ int nLuma = (palval >>4) &0xF;
+ int nChroma = (palval >>8) &0xF;
+ float phaseOffset = -11.0;
+ //bool inverted = false;
+ if ((nLuma < (nChroma+1) >>1 || nLuma > 15 -(nChroma >>1)) && (m_pal_mode != PAL_MODE_NEW_VG)) {
+ //inverted = true;
+ // Strange color number wrap-around. Is this for protection reasons, or a bug of the original hardware?
+ // The VT03 data sheet advises programmers that 4 <= nLuma*2 +nChroma <= 0x1F, which does not correspond exactly to this condition.
+ static const unsigned char altPhases[16] = { 13, 7, 8, 9, 10, 11, 12, 1, 2, 3, 4, 5, 6, 0, 14, 15};
+ static const float altPhaseOffset[16] = { -5, -5, -5, -5, -5, -5, -5, -5, -5, -5, -5, -5, 0, -5, -5, -5}; // Slight tweak in phase 6 for Z-Dog
+ phaseOffset += altPhaseOffset[nPhase]; // These "alternative" colors seem to be slightly shifted in addition to being wrapped-around, at least in EmuVT.
+ nPhase = altPhases[nPhase];
+ nChroma = 16 -nChroma;
+ nLuma = (nLuma -8) &0xF;
+ }
+ float fLuma = (nLuma-4) /9.625; // Value determined from matching saturation =0 phases 1-12
+ float fChroma = nChroma /18.975; // Value determined from matching phases 0 and 13 across all luminance and saturation levels
+ float fPhase = ((nPhase-2) *30.0 +phaseOffset) *M_PI /180.0;
+ if(m_pal_mode == PAL_MODE_NEW_VG) {
+ if(fPhase > 0 && fPhase < 13) {
+ fLuma /= 1.5;
+ fChroma /= 2;
+ }
+ }
+ float Y = fLuma;
+ float C = fChroma;
+ if (nPhase == 0 || nPhase >12) C =0.0;// Phases 0 and 13-15 are grays
+ if (nPhase == 0) Y += fChroma; // Phase 0 is the upper bound of the waveform
+ if (nPhase ==13) Y -= fChroma; // Phase 13 is the lower bound of the waveform
+ if (nPhase >=14) Y = 0.0; // Phases 14 and 15 always black
+
+ float V = sin(fPhase) *C *1.05; // 1.05 needed to get closer to EmuVT palette's color levels in phases 1-12
+ float U = cos(fPhase) *C *1.05;
+ float R = Y + 1.1400*V + 0.0000*U;
+ float G = Y - 0.5807*V - 0.3940*U;
+ float B = Y - 0.0000*V + 2.0290*U;
+ if (R <0.0) R =0.0;
+ if (R >1.0) R =1.0;
+ if (G <0.0) G =0.0;
+ if (G >1.0) G =1.0;
+ if (B <0.0) B =0.0;
+ if (B >1.0) B =1.0;
+ int RV = R *255.0;
+ int GV = G *255.0;
+ int BV = B *255.0;
+
+ m_palette->set_pen_color(i & 0x7f, rgb_t(RV, GV ,BV));
}
-
- sat *= (rsat / 15.0);
- y *= (rlum / 15.0);
- u = sat * cos(rad);
- v = sat * sin(rad);
-
- /* Transform to RGB */
- R = (y + Kv * v) * 255.0;
- G = (y - (Kb * Ku * u + Kr * Kv * v) / (1 - Kb - Kr)) * 255.0;
- B = (y + Ku * u) * 255.0;
-
- /* Clipping, in case of saturation */
- if (R < 0)
- R = 0;
- if (R > 255)
- R = 255;
- if (G < 0)
- G = 0;
- if (G > 255)
- G = 255;
- if (B < 0)
- B = 0;
- if (B > 255)
- B = 255;
-
- m_palette->set_pen_color(i & 0x7f, rgb_t(R, G ,B));
}
+
}
@@ -147,7 +134,13 @@ WRITE8_MEMBER(ppu_vt03_device::palette_write)
READ8_MEMBER( ppu_vt03_device::read )
{
- return ppu2c0x_device::read(space,offset);
+ if(offset <= 0xf) {
+ return ppu2c0x_device::read(space,offset);
+ } else if(offset <= 0x1f) {
+ return get_201x_reg(offset & 0x0f);
+ } else {
+ return 0;
+ }
}
void ppu_vt03_device::init_palette(palette_device &palette, int first_entry)
@@ -187,15 +180,13 @@ void ppu_vt03_device::device_reset()
m_read_sp.resolve_safe(0);
for (int i = 0;i < 0xff;i++)
m_newpal[i] = 0x0;
- set_2010_reg(0x00);
- set_2010_reg(0x80);
- set_2010_reg(0x00);
// todo: what are the actual defaults for these?
for (int i = 0;i < 0x20;i++)
set_201x_reg(i, 0x00);
init_palette(*m_palette, 0);
+
m_read_bg4_bg3 = 0;
m_va34 = 0;
}
@@ -233,6 +224,7 @@ void ppu_vt03_device::make_sprite_pixel_data(uint8_t &pixel_data, int flipx)
ppu2c0x_device::make_sprite_pixel_data(pixel_data, flipx);
int is4bpp = get_201x_reg(0x0) & 0x04;
+ int is16pix = get_201x_reg(0x0) & 0x01;
if (is4bpp)
{
@@ -242,6 +234,12 @@ void ppu_vt03_device::make_sprite_pixel_data(uint8_t &pixel_data, int flipx)
pixel_data |= (((m_extplanebuf[0] & 1) << 5) | ((m_extplanebuf[1] & 1) << 6));
m_extplanebuf[0] = m_extplanebuf[0] >> 1;
m_extplanebuf[1] = m_extplanebuf[1] >> 1;
+
+ if(is16pix) {
+ uint8_t pix0 = pixel_data & 0x03;
+ uint8_t pix1 = (pixel_data >> 5) & 0x03;
+ pixel_data = pix1 | (pix0 << 5);
+ }
}
else
{
@@ -268,7 +266,12 @@ void ppu_vt03_device::draw_sprite_pixel(int sprite_xpos, int color, int pixel, u
/* this mode makes use of the extra planes to increase sprite width instead
we probably need to split them out again and draw them at xpos+8 with a
cliprect - not seen used yet */
- bitmap.pix16(m_scanline, sprite_xpos + pixel) = pixel_data + (machine().rand()&3);
+ if((pixel_data & 0x03) != 0)
+ bitmap.pix16(m_scanline, sprite_xpos + pixel) = (pixel_data & 0x03) + (4 * color);
+ if(((pixel_data >> 5) & 0x03) != 0)
+ bitmap.pix16(m_scanline, sprite_xpos + pixel + 8) = ((pixel_data >> 5) & 0x03) + (4 * color);
+ //ppu2c0x_device::draw_sprite_pixel(sprite_xpos, color, pixel, pixel_data & 0x03, bitmap);
+ //ppu2c0x_device::draw_sprite_pixel(sprite_xpos, color, pixel + 8, (pixel_data >> 5) & 0x03, bitmap);
}
}
else
@@ -345,7 +348,7 @@ void ppu_vt03_device::draw_tile_pixel(uint8_t pix, int color, uint16_t back_pen,
}
else
{
- pen = back_pen; // fixme backpen logic probably differs on vt03 due to extra colours
+ pen = 0; // fixme backpen logic probably differs on vt03 due to extra colours
}
*dest = pen;
}
@@ -409,31 +412,32 @@ WRITE8_MEMBER(ppu_vt03_device::write)
break;
case 0x11:
+ m_201x_regs[0x1] = data;
break;
case 0x12:
- m_201x_regs[0x2] = data;
+ m_201x_regs[m_2012_2017_descramble[0]] = data;
break;
case 0x13:
- m_201x_regs[0x3] = data;
+ m_201x_regs[m_2012_2017_descramble[1]] = data;
break;
case 0x14:
- m_201x_regs[0x4] = data;
+ m_201x_regs[m_2012_2017_descramble[2]] = data;
break;
case 0x15:
- m_201x_regs[0x5] = data;
+ m_201x_regs[m_2012_2017_descramble[3]] = data;
break;
case 0x16:
- m_201x_regs[0x6] = data;
+ m_201x_regs[m_2012_2017_descramble[4]] = data;
break;
case 0x17:
logerror("set reg 7 %02x\n", data);
- m_201x_regs[0x7] = data;
+ m_201x_regs[m_2012_2017_descramble[5]] = data;
break;
case 0x18: