From 95aa67b728e99f5ec05273eaf0b4c54855049f4f Mon Sep 17 00:00:00 2001 From: mooglyguy Date: Sun, 21 Apr 2019 20:09:13 +0200 Subject: [PATCH] -newport: Various fixes. [Ryan Holtz] * Added support for 4bpp RGB framebuffer display. * Added dithering support. * Fixed shaded rendering mode. --- src/mame/video/newport.cpp | 203 ++++++++++++++++++++++++++++++++----- src/mame/video/newport.h | 4 +- 2 files changed, 179 insertions(+), 28 deletions(-) diff --git a/src/mame/video/newport.cpp b/src/mame/video/newport.cpp index e3b500c7adb..69f7275acee 100644 --- a/src/mame/video/newport.cpp +++ b/src/mame/video/newport.cpp @@ -338,7 +338,7 @@ uint32_t newport_video_device::screen_update(screen_device &device, bitmap_rgb32 { switch ((table_entry >> 8) & 3) { - case 0: + case 0: // CI switch ((table_entry >> 10) & 3) { case 0: // 4bpp @@ -356,17 +356,40 @@ uint32_t newport_video_device::screen_update(screen_device &device, bitmap_rgb32 break; } break; - case 1: - case 2: - case 3: - { - const uint8_t pix_in = *src_ci; - const uint8_t r = (0x92 * BIT(pix_in, 2)) | (0x49 * BIT(pix_in, 1)) | (0x24 * BIT(pix_in, 0)); - const uint8_t g = (0x92 * BIT(pix_in, 5)) | (0x49 * BIT(pix_in, 4)) | (0x24 * BIT(pix_in, 3)); - const uint8_t b = (0xaa * BIT(pix_in, 7)) | (0x55 * BIT(pix_in, 6)); - *dest++ = (r << 16) | (g << 8) | b; + case 1: // RGB Map0 + switch ((table_entry >> 10) & 3) + { + case 0: // 4bpp + { + const uint8_t shift = BIT(table_entry, 0) ? 4 : 0; + const uint8_t pix_in = *src_ci >> shift; + const uint8_t r = 0xff * BIT(pix_in, 3); + const uint8_t g = (0xaa * BIT(pix_in, 2)) | (0x55 * BIT(pix_in, 1)); + const uint8_t b = 0xff * BIT(pix_in, 0); + *dest++ = (r << 16) | (g << 8) | b; + break; + } + case 1: // 8bpp + { + const uint8_t pix_in = *src_ci; + const uint8_t r = (0x92 * BIT(pix_in, 2)) | (0x49 * BIT(pix_in, 1)) | (0x24 * BIT(pix_in, 0)); + const uint8_t g = (0x92 * BIT(pix_in, 5)) | (0x49 * BIT(pix_in, 4)) | (0x24 * BIT(pix_in, 3)); + const uint8_t b = (0xaa * BIT(pix_in, 7)) | (0x55 * BIT(pix_in, 6)); + *dest++ = (r << 16) | (g << 8) | b; + break; + } + case 2: // 12bpp (not yet supported) + case 3: // 24bpp (not yet supported) + *dest++ = 0xffffff; + break; + } + break; + case 2: // RGB Map1 (not yet supported) + *dest++ = 0xff00ff; + break; + case 3: // RGB Map2 (not yet supported) + *dest++ = 0x00ff00; break; - } } } @@ -1297,7 +1320,7 @@ READ64_MEMBER(newport_video_device::rex3_r) void newport_video_device::write_pixel(uint8_t color, bool shade) { if (shade) - write_pixel(m_rex3.m_x_start_i, m_rex3.m_y_start_i, (uint8_t)(m_rex3.m_color_red >> 11)); + write_pixel(m_rex3.m_x_start_i, m_rex3.m_y_start_i, get_shade_color(m_rex3.m_x_start_i, m_rex3.m_y_start_i)); else write_pixel(m_rex3.m_x_start_i, m_rex3.m_y_start_i, color); } @@ -1444,6 +1467,85 @@ void newport_video_device::write_pixel(int16_t x, int16_t y, uint8_t color) } } +uint8_t newport_video_device::get_shade_color(int16_t x, int16_t y) +{ + static const uint8_t s_bayer[4][4] = { { 0, 12, 3, 15 },{ 8, 4, 11, 7 },{ 2, 14, 1, 13 },{ 10, 6, 9, 5 } }; + + const uint8_t red = (uint8_t)(m_rex3.m_color_red >> 11); + const uint8_t green = (uint8_t)(m_rex3.m_color_green >> 11); + const uint8_t blue = (uint8_t)(m_rex3.m_color_blue >> 11); + + if (!BIT(m_rex3.m_draw_mode1, 15)) // RGB + { + return red; + } + + if (BIT(m_rex3.m_draw_mode1, 16)) // Dithering + { + switch ((m_rex3.m_draw_mode1 >> 3) & 3) + { + case 0: // 4bpp + { + const uint8_t sr = (red >> 3) - (red >> 4); + const uint8_t sg = (green >> 2) - (green >> 4); + const uint8_t sb = (blue >> 3) - (blue >> 4); + + uint8_t dr = BIT(sr, 4); + uint8_t dg = (sg >> 4) & 3; + uint8_t db = BIT(sb, 4); + + if ((sr & 0xf) > s_bayer[x & 3][y & 3]) dr++; + if ((sg & 0xf) > s_bayer[x & 3][y & 3]) dg++; + if ((sb & 0xf) > s_bayer[x & 3][y & 3]) db++; + + if (dr > 1) dr = 1; + if (dg > 3) dg = 3; + if (db > 1) db = 1; + + return (dr << 3) | (dg << 1) | db; + } + case 1: // 8bpp + { + const uint8_t sr = (red >> 1) - (red >> 4); + const uint8_t sg = (green >> 1) - (green >> 4); + const uint8_t sb = (blue >> 2) - (blue >> 4); + + uint8_t dr = (sr >> 4) & 7; + uint8_t dg = (sg >> 4) & 7; + uint8_t db = (sb >> 4) & 3; + + if ((sr & 0xf) > s_bayer[x & 3][y & 3]) dr++; + if ((sg & 0xf) > s_bayer[x & 3][y & 3]) dg++; + if ((sb & 0xf) > s_bayer[x & 3][y & 3]) db++; + + if (dr > 7) dr = 7; + if (dg > 7) dg = 7; + if (db > 3) db = 3; + + return (dr << 5) | (dg << 2) | db; + } + case 2: // 12bpp (not yet supported) + case 3: // 24bpp (not yet supported) + default: + return 0; + } + } + else + { + switch ((m_rex3.m_draw_mode1 >> 3) & 3) + { + case 0: // 4bpp + return (BIT(red, 7) << 3) | ((green & 0xc0) >> 5) | BIT(blue, 7); + case 1: // 8bpp + return (red & 0xe0) | ((green & 0xe0) >> 3) | ((blue & 0xc0) >> 6); + case 2: // 12bpp (not yet supported) + case 3: // 24bpp (not yet supported) + default: + return 0; + } + } +} + void newport_video_device::do_v_iline(uint8_t color, bool skip_last, bool shade) { int16_t x1 = m_rex3.m_x_start_i; @@ -1455,22 +1557,33 @@ void newport_video_device::do_v_iline(uint8_t color, bool skip_last, bool shade) do { if (shade) - write_pixel(x1, y1, (uint8_t)(m_rex3.m_color_red >> 11)); + write_pixel(x1, y1, get_shade_color(x1, y1)); else write_pixel(x1, y1, color); y1 += incy; if (shade) - m_rex3.m_color_red += (m_rex3.m_slope_red << 8) >> 8; + { + m_rex3.m_color_red += m_rex3.m_slope_red; + m_rex3.m_color_green += m_rex3.m_slope_green; + m_rex3.m_color_blue += m_rex3.m_slope_blue; + } } while (y1 != y2); if (!skip_last) { if (shade) - write_pixel(x1, y1, (uint8_t)(m_rex3.m_color_red >> 11)); + { + write_pixel(x1, y1, get_shade_color(x1, y1)); + m_rex3.m_color_red += m_rex3.m_slope_red; + m_rex3.m_color_green += m_rex3.m_slope_green; + m_rex3.m_color_blue += m_rex3.m_slope_blue; + } else + { write_pixel(x1, y1, color); + } } write_x_start(x1 << 11); @@ -1488,21 +1601,33 @@ void newport_video_device::do_h_iline(uint8_t color, bool skip_last, bool shade) do { if (shade) - write_pixel(x1, y1, (uint8_t)(m_rex3.m_color_red >> 11)); + write_pixel(x1, y1, get_shade_color(x1, y1)); else write_pixel(x1, y1, color); x1 += incx; if (shade) - m_rex3.m_color_red += (m_rex3.m_slope_red << 8) >> 8; + { + m_rex3.m_color_red += m_rex3.m_slope_red; + m_rex3.m_color_green += m_rex3.m_slope_green; + m_rex3.m_color_blue += m_rex3.m_slope_blue; + } } while (x1 != x2); - if (!skip_last) { + if (!skip_last) + { if (shade) - write_pixel(x1, y1, (uint8_t)(m_rex3.m_color_red >> 11)); + { + write_pixel(x1, y1, get_shade_color(x1, y1)); + m_rex3.m_color_red += m_rex3.m_slope_red; + m_rex3.m_color_green += m_rex3.m_slope_green; + m_rex3.m_color_blue += m_rex3.m_slope_blue; + } else + { write_pixel(x1, y1, color); + } } write_x_start(x1 << 11); @@ -1564,7 +1689,7 @@ void newport_video_device::do_iline(uint8_t color, bool skip_last, bool shade) do { if (shade) - write_pixel(y1, x1, (uint8_t)(m_rex3.m_color_red >> 11)); + write_pixel(y1, x1, get_shade_color(x1, y1)); else write_pixel(y1, x1, color); @@ -1580,15 +1705,26 @@ void newport_video_device::do_iline(uint8_t color, bool skip_last, bool shade) x1++; if (shade) - m_rex3.m_color_red += (m_rex3.m_slope_red << 8) >> 8; + { + m_rex3.m_color_red += m_rex3.m_slope_red; + m_rex3.m_color_green += m_rex3.m_slope_green; + m_rex3.m_color_blue += m_rex3.m_slope_blue; + } } while (x1 != x2); if (!skip_last) { if (shade) - write_pixel(y1, x1, (uint8_t)(m_rex3.m_color_red >> 11)); + { + write_pixel(y1, x1, get_shade_color(x1, y1)); + m_rex3.m_color_red += m_rex3.m_slope_red; + m_rex3.m_color_green += m_rex3.m_slope_green; + m_rex3.m_color_blue += m_rex3.m_slope_blue; + } else + { write_pixel(y1, x1, color); + } } } else @@ -1596,7 +1732,7 @@ void newport_video_device::do_iline(uint8_t color, bool skip_last, bool shade) do { if (shade) - write_pixel(x1, y1, (uint8_t)(m_rex3.m_color_red >> 11)); + write_pixel(x1, y1, get_shade_color(x1, y1)); else write_pixel(x1, y1, color); @@ -1612,15 +1748,26 @@ void newport_video_device::do_iline(uint8_t color, bool skip_last, bool shade) x1++; if (shade) - m_rex3.m_color_red += (m_rex3.m_slope_red << 8) >> 8; + { + m_rex3.m_color_red += m_rex3.m_slope_red; + m_rex3.m_color_green += m_rex3.m_slope_green; + m_rex3.m_color_blue += m_rex3.m_slope_blue; + } } while (x1 != x2); if (!skip_last) { if (shade) - write_pixel(x1, y1, (uint8_t)(m_rex3.m_color_red >> 11)); + { + write_pixel(x1, y1, get_shade_color(x1, y1)); + m_rex3.m_color_red += m_rex3.m_slope_red; + m_rex3.m_color_green += m_rex3.m_slope_green; + m_rex3.m_color_blue += m_rex3.m_slope_blue; + } else + { write_pixel(x1, y1, color); + } } } @@ -1771,8 +1918,10 @@ void newport_video_device::do_rex3_command() { if (shade) { - write_pixel(start_x, start_y, (uint8_t)(m_rex3.m_color_red >> 11)); - m_rex3.m_color_red += (m_rex3.m_slope_red << 8) >> 8; + write_pixel(start_x, start_y, get_shade_color(start_x, start_y)); + m_rex3.m_color_red += m_rex3.m_slope_red; + m_rex3.m_color_green += m_rex3.m_slope_green; + m_rex3.m_color_blue += m_rex3.m_slope_blue; } else { diff --git a/src/mame/video/newport.h b/src/mame/video/newport.h index f49a75529c6..518dc65b8d9 100644 --- a/src/mame/video/newport.h +++ b/src/mame/video/newport.h @@ -11,7 +11,7 @@ #include "machine/hpc3.h" -#define ENABLE_NEWVIEW_LOG (0) +#define ENABLE_NEWVIEW_LOG (1) class newport_video_device : public device_t, public device_palette_interface { @@ -191,6 +191,8 @@ private: void write_pixel(int16_t x, int16_t y, uint8_t color); void store_pixel(uint8_t *dest_buf, uint8_t src); + uint8_t get_shade_color(int16_t x, int16_t y); + void do_v_iline(uint8_t color, bool skip_last, bool shade); void do_h_iline(uint8_t color, bool skip_last, bool shade); void do_iline(uint8_t color, bool skip_last, bool shade);