diff options
Diffstat (limited to 'src/devices/video/ppu2c0x_vt.cpp')
-rw-r--r-- | src/devices/video/ppu2c0x_vt.cpp | 93 |
1 files changed, 85 insertions, 8 deletions
diff --git a/src/devices/video/ppu2c0x_vt.cpp b/src/devices/video/ppu2c0x_vt.cpp index a9f02890832..fad7f78ab97 100644 --- a/src/devices/video/ppu2c0x_vt.cpp +++ b/src/devices/video/ppu2c0x_vt.cpp @@ -47,23 +47,100 @@ void ppu_vt03_device::set_new_pen(int i) uint8_t red = (rgbval & 0x7C00) >> 7; m_palette->set_pen_color(i & 0x7f, rgb_t(red, green, blue)); } else { + // TODO: should this be tidied up? uint16_t palval = (m_newpal[i&0x7f] & 0x3f) | ((m_newpal[(i&0x7f)+0x80] & 0x3f)<<6); - // &0x3f so we don't attempt to use any of the extended colours right now because - // I haven't managed to work out the format - m_palette->set_pen_indirect(i&0x7f,palval&0x3f); + + 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; + } + + 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)); } } WRITE8_MEMBER(ppu_vt03_device::palette_write) { - if (m_201x_regs[0] & 0x80) + //logerror("pal write %d %02x\n", offset, data); + uint8_t pal_mask = (m_pal_mode == PAL_MODE_NEW_VG) ? 0x04 : 0x80; + + if (m_201x_regs[0] & pal_mask) { m_newpal[offset] = data; set_new_pen(offset); } else { + if(m_pal_mode == PAL_MODE_NEW_VG) + m_newpal[offset] = data; ppu2c0x_device::palette_write(space, offset, data); } } @@ -118,7 +195,7 @@ void ppu_vt03_device::device_reset() 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; } @@ -294,10 +371,10 @@ void ppu_vt03_device::set_2010_reg(uint8_t data) 2 : SP16EN 1 : BK16EN 0 : PIX16EN */ - - if ((m_201x_regs[0x0] & 0x80) != (data & 0x80)) + uint8_t pal_mask = (m_pal_mode == PAL_MODE_NEW_VG) ? 0x08 : 0x80; + if ((m_201x_regs[0x0] & pal_mask) != (data & pal_mask)) { - if (data & 0x80) + if (data & pal_mask) { for (int i = 0;i < 256;i++) { |