diff options
Diffstat (limited to 'src/devices/video/ppu2c0x_vt.cpp')
-rw-r--r-- | src/devices/video/ppu2c0x_vt.cpp | 190 |
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: |