-newport: Various fixes. [Ryan Holtz]

* Added support for 4bpp RGB framebuffer display.
 * Added dithering support.
 * Fixed shaded rendering mode.
This commit is contained in:
mooglyguy 2019-04-21 20:09:13 +02:00 committed by Vas Crabb
parent 31c495a112
commit 95aa67b728
2 changed files with 179 additions and 28 deletions

View File

@ -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
{

View File

@ -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);