mirror of
https://github.com/holub/mame
synced 2025-10-08 01:28:00 +03:00
vector: Move clipping to avgdvg, the only user. Simplify [O. Galibert]
This commit is contained in:
parent
7f412c33aa
commit
19ed9384a6
@ -67,89 +67,9 @@ void vector_options::init(emu_options& options)
|
|||||||
s_flicker = options.flicker();
|
s_flicker = options.flicker();
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
|
|
||||||
#define TEXTURE_LENGTH_BUCKETS 32
|
|
||||||
#define TEXTURE_INTENSITY_BUCKETS 4
|
|
||||||
#define TEXTURE_WIDTH 16
|
|
||||||
|
|
||||||
#define MAX_INTENSITY 2
|
|
||||||
#define VECTOR_BLEED (0.25f)
|
|
||||||
#define VECTOR_INT_SCALE (255.0f * 1.5f)
|
|
||||||
|
|
||||||
|
|
||||||
struct vector_texture
|
|
||||||
{
|
|
||||||
render_texture * texture;
|
|
||||||
bitmap_argb32 * bitmap;
|
|
||||||
};
|
|
||||||
|
|
||||||
static vector_texture *vectortex[TEXTURE_INTENSITY_BUCKETS][TEXTURE_LENGTH_BUCKETS];
|
|
||||||
|
|
||||||
|
|
||||||
static render_texture *get_vector_texture(float dx, float dy, float intensity)
|
|
||||||
{
|
|
||||||
float length = sqrt(dx * dx + dy * dy);
|
|
||||||
int lbucket = length * (float)TEXTURE_LENGTH_BUCKETS;
|
|
||||||
int ibucket = (intensity / (float)MAX_INTENSITY) * (float)TEXTURE_INTENSITY_BUCKETS;
|
|
||||||
vector_texture *tex;
|
|
||||||
int height, x, y;
|
|
||||||
float totalint;
|
|
||||||
|
|
||||||
if (lbucket > TEXTURE_LENGTH_BUCKETS)
|
|
||||||
lbucket = TEXTURE_LENGTH_BUCKETS;
|
|
||||||
if (ibucket > TEXTURE_INTENSITY_BUCKETS)
|
|
||||||
ibucket = TEXTURE_INTENSITY_BUCKETS;
|
|
||||||
|
|
||||||
tex = &vectortex[ibucket][lbucket];
|
|
||||||
if (tex->texture != nullptr)
|
|
||||||
return tex->texture;
|
|
||||||
|
|
||||||
height = lbucket * VECTOR_WIDTH_DENOM / TEXTURE_LENGTH_BUCKETS;
|
|
||||||
tex->bitmap = global_alloc(bitmap_argb32(TEXTURE_WIDTH, height));
|
|
||||||
tex->bitmap.fill(rgb_t(0xff,0xff,0xff,0xff));
|
|
||||||
|
|
||||||
totalint = 1.0f;
|
|
||||||
for (x = TEXTURE_WIDTH / 2 - 1; x >= 0; x--)
|
|
||||||
{
|
|
||||||
int intensity = (int)(totalint * (1.0f - VECTOR_BLEED) * VECTOR_INT_SCALE);
|
|
||||||
intensity = MIN(255, intensity);
|
|
||||||
totalint -= (float)intensity * (1.0f / VECTOR_INT_SCALE);
|
|
||||||
|
|
||||||
for (y = 0; y < height; y++)
|
|
||||||
{
|
|
||||||
UINT32 *pix;
|
|
||||||
|
|
||||||
pix = (UINT32 *)bitmap.base + y * bitmap.rowpixels + x;
|
|
||||||
*pix = rgb_t((*pix.a() * intensity) >> 8,0xff,0xff,0xff);
|
|
||||||
|
|
||||||
pix = (UINT32 *)bitmap.base + y * bitmap.rowpixels + (TEXTURE_WIDTH - 1 - x);
|
|
||||||
*pix = rgb_t((*pix.a() * intensity) >> 8,0xff,0xff,0xff);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
tex->texture = render_texture_create();
|
|
||||||
return tex->texture;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define VCLEAN 0
|
|
||||||
#define VDIRTY 1
|
|
||||||
#define VCLIP 2
|
|
||||||
|
|
||||||
// device type definition
|
// device type definition
|
||||||
const device_type VECTOR = &device_creator<vector_device>;
|
const device_type VECTOR = &device_creator<vector_device>;
|
||||||
|
|
||||||
vector_device::vector_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source)
|
|
||||||
: device_t(mconfig, type, name, tag, owner, clock, shortname, source),
|
|
||||||
device_video_interface(mconfig, *this),
|
|
||||||
m_vector_list(nullptr),
|
|
||||||
m_min_intensity(255),
|
|
||||||
m_max_intensity(0)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
vector_device::vector_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
vector_device::vector_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||||
: device_t(mconfig, VECTOR, "VECTOR", tag, owner, clock, "vector_device", __FILE__),
|
: device_t(mconfig, VECTOR, "VECTOR", tag, owner, clock, "vector_device", __FILE__),
|
||||||
device_video_interface(mconfig, *this),
|
device_video_interface(mconfig, *this),
|
||||||
@ -206,30 +126,6 @@ void vector_device::add_point(int x, int y, rgb_t color, int intensity)
|
|||||||
newpoint->y = y;
|
newpoint->y = y;
|
||||||
newpoint->col = color;
|
newpoint->col = color;
|
||||||
newpoint->intensity = intensity;
|
newpoint->intensity = intensity;
|
||||||
newpoint->status = VDIRTY; /* mark identical lines as clean later */
|
|
||||||
|
|
||||||
m_vector_index++;
|
|
||||||
if (m_vector_index >= MAX_POINTS)
|
|
||||||
{
|
|
||||||
m_vector_index--;
|
|
||||||
logerror("*** Warning! Vector list overflow!\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Add new clipping info to the list
|
|
||||||
*/
|
|
||||||
void vector_device::add_clip(int x1, int yy1, int x2, int y2)
|
|
||||||
{
|
|
||||||
point *newpoint;
|
|
||||||
|
|
||||||
newpoint = &m_vector_list[m_vector_index];
|
|
||||||
newpoint->x = x1;
|
|
||||||
newpoint->y = yy1;
|
|
||||||
newpoint->arg1 = x2;
|
|
||||||
newpoint->arg2 = y2;
|
|
||||||
newpoint->status = VCLIP;
|
|
||||||
|
|
||||||
m_vector_index++;
|
m_vector_index++;
|
||||||
if (m_vector_index >= MAX_POINTS)
|
if (m_vector_index >= MAX_POINTS)
|
||||||
@ -264,7 +160,6 @@ UINT32 vector_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap,
|
|||||||
yratio = (yratio < 1.0f) ? yratio : 1.0f;
|
yratio = (yratio < 1.0f) ? yratio : 1.0f;
|
||||||
|
|
||||||
point *curpoint;
|
point *curpoint;
|
||||||
render_bounds clip;
|
|
||||||
int lastx = 0;
|
int lastx = 0;
|
||||||
int lasty = 0;
|
int lasty = 0;
|
||||||
|
|
||||||
@ -273,81 +168,63 @@ UINT32 vector_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap,
|
|||||||
screen.container().empty();
|
screen.container().empty();
|
||||||
screen.container().add_rect(0.0f, 0.0f, 1.0f, 1.0f, rgb_t(0xff,0x00,0x00,0x00), PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_VECTORBUF(1));
|
screen.container().add_rect(0.0f, 0.0f, 1.0f, 1.0f, rgb_t(0xff,0x00,0x00,0x00), PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_VECTORBUF(1));
|
||||||
|
|
||||||
clip.x0 = clip.y0 = 0.0f;
|
|
||||||
clip.x1 = clip.y1 = 1.0f;
|
|
||||||
|
|
||||||
for (int i = 0; i < m_vector_index; i++)
|
for (int i = 0; i < m_vector_index; i++)
|
||||||
{
|
{
|
||||||
render_bounds coords;
|
render_bounds coords;
|
||||||
|
|
||||||
if (curpoint->status == VCLIP)
|
float intensity = (float)curpoint->intensity / 255.0f;
|
||||||
{
|
float intensity_weight = normalized_sigmoid(intensity, vector_options::s_beam_intensity_weight);
|
||||||
coords.x0 = ((float)curpoint->x - xoffs) * xscale;
|
|
||||||
coords.y0 = ((float)curpoint->y - yoffs) * yscale;
|
|
||||||
coords.x1 = ((float)curpoint->arg1 - xoffs) * xscale;
|
|
||||||
coords.y1 = ((float)curpoint->arg2 - yoffs) * yscale;
|
|
||||||
|
|
||||||
clip.x0 = (coords.x0 > 0.0f) ? coords.x0 : 0.0f;
|
// check for static intensity
|
||||||
clip.y0 = (coords.y0 > 0.0f) ? coords.y0 : 0.0f;
|
float beam_width = m_min_intensity == m_max_intensity
|
||||||
clip.x1 = (coords.x1 < 1.0f) ? coords.x1 : 1.0f;
|
? vector_options::s_beam_width_min
|
||||||
clip.y1 = (coords.y1 < 1.0f) ? coords.y1 : 1.0f;
|
: vector_options::s_beam_width_min + intensity_weight * (vector_options::s_beam_width_max - vector_options::s_beam_width_min);
|
||||||
|
|
||||||
|
// normalize width
|
||||||
|
beam_width *= 1.0f / (float)VECTOR_WIDTH_DENOM;
|
||||||
|
|
||||||
|
coords.x0 = ((float)lastx - xoffs) * xscale;
|
||||||
|
coords.y0 = ((float)lasty - yoffs) * yscale;
|
||||||
|
coords.x1 = ((float)curpoint->x - xoffs) * xscale;
|
||||||
|
coords.y1 = ((float)curpoint->y - yoffs) * yscale;
|
||||||
|
|
||||||
|
float xdistance = coords.x0 - coords.x1;
|
||||||
|
float ydistance = coords.y0 - coords.y1;
|
||||||
|
|
||||||
|
// extend zero-length vector line (vector point) by 3/8 beam_width on both sides
|
||||||
|
if (fabs(xdistance) < FLT_EPSILON &&
|
||||||
|
fabs(ydistance) < FLT_EPSILON)
|
||||||
|
{
|
||||||
|
coords.x0 += xratio * beam_width * 0.375f;
|
||||||
|
coords.y0 += yratio * beam_width * 0.375f;
|
||||||
|
coords.x1 -= xratio * beam_width * 0.375f;
|
||||||
|
coords.y1 -= yratio * beam_width * 0.375f;
|
||||||
}
|
}
|
||||||
|
// extend vector line by 3/8 beam_width on both sides
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
float intensity = (float)curpoint->intensity / 255.0f;
|
float length = sqrt(xdistance * xdistance + ydistance * ydistance);
|
||||||
float intensity_weight = normalized_sigmoid(intensity, vector_options::s_beam_intensity_weight);
|
float xdirection = xdistance / length;
|
||||||
|
float ydirection = ydistance / length;
|
||||||
|
|
||||||
// check for static intensity
|
coords.x0 += xratio * beam_width * 0.375f * (xdirection / xratio);
|
||||||
float beam_width = m_min_intensity == m_max_intensity
|
coords.y0 += yratio * beam_width * 0.375f * (ydirection / yratio);
|
||||||
? vector_options::s_beam_width_min
|
coords.x1 -= xratio * beam_width * 0.375f * (xdirection / xratio);
|
||||||
: vector_options::s_beam_width_min + intensity_weight * (vector_options::s_beam_width_max - vector_options::s_beam_width_min);
|
coords.y1 -= yratio * beam_width * 0.375f * (ydirection / yratio);
|
||||||
|
|
||||||
// normalize width
|
|
||||||
beam_width *= 1.0f / (float)VECTOR_WIDTH_DENOM;
|
|
||||||
|
|
||||||
coords.x0 = ((float)lastx - xoffs) * xscale;
|
|
||||||
coords.y0 = ((float)lasty - yoffs) * yscale;
|
|
||||||
coords.x1 = ((float)curpoint->x - xoffs) * xscale;
|
|
||||||
coords.y1 = ((float)curpoint->y - yoffs) * yscale;
|
|
||||||
|
|
||||||
float xdistance = coords.x0 - coords.x1;
|
|
||||||
float ydistance = coords.y0 - coords.y1;
|
|
||||||
|
|
||||||
// extend zero-length vector line (vector point) by 3/8 beam_width on both sides
|
|
||||||
if (fabs(xdistance) < FLT_EPSILON &&
|
|
||||||
fabs(ydistance) < FLT_EPSILON)
|
|
||||||
{
|
|
||||||
coords.x0 += xratio * beam_width * 0.375f;
|
|
||||||
coords.y0 += yratio * beam_width * 0.375f;
|
|
||||||
coords.x1 -= xratio * beam_width * 0.375f;
|
|
||||||
coords.y1 -= yratio * beam_width * 0.375f;
|
|
||||||
}
|
|
||||||
// extend vector line by 3/8 beam_width on both sides
|
|
||||||
else
|
|
||||||
{
|
|
||||||
float length = sqrt(xdistance * xdistance + ydistance * ydistance);
|
|
||||||
float xdirection = xdistance / length;
|
|
||||||
float ydirection = ydistance / length;
|
|
||||||
|
|
||||||
coords.x0 += xratio * beam_width * 0.375f * (xdirection / xratio);
|
|
||||||
coords.y0 += yratio * beam_width * 0.375f * (ydirection / yratio);
|
|
||||||
coords.x1 -= xratio * beam_width * 0.375f * (xdirection / xratio);
|
|
||||||
coords.y1 -= yratio * beam_width * 0.375f * (ydirection / yratio);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (curpoint->intensity != 0 && !render_clip_line(&coords, &clip))
|
|
||||||
{
|
|
||||||
screen.container().add_line(
|
|
||||||
coords.x0, coords.y0, coords.x1, coords.y1,
|
|
||||||
beam_width,
|
|
||||||
(curpoint->intensity << 24) | (curpoint->col & 0xffffff),
|
|
||||||
flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
lastx = curpoint->x;
|
|
||||||
lasty = curpoint->y;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (curpoint->intensity != 0)
|
||||||
|
{
|
||||||
|
screen.container().add_line(
|
||||||
|
coords.x0, coords.y0, coords.x1, coords.y1,
|
||||||
|
beam_width,
|
||||||
|
(curpoint->intensity << 24) | (curpoint->col & 0xffffff),
|
||||||
|
flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
lastx = curpoint->x;
|
||||||
|
lasty = curpoint->y;
|
||||||
|
|
||||||
curpoint++;
|
curpoint++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,16 +21,11 @@ struct point
|
|||||||
x(0),
|
x(0),
|
||||||
y(0),
|
y(0),
|
||||||
col(0),
|
col(0),
|
||||||
intensity(0),
|
intensity(0) {}
|
||||||
arg1(0),
|
|
||||||
arg2(0),
|
|
||||||
status(0) {}
|
|
||||||
|
|
||||||
int x; int y;
|
int x; int y;
|
||||||
rgb_t col;
|
rgb_t col;
|
||||||
int intensity;
|
int intensity;
|
||||||
int arg1; int arg2; /* start/end in pixel array or clipping info */
|
|
||||||
int status; /* for dirty and clipping handling */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class vector_options
|
class vector_options
|
||||||
@ -52,13 +47,11 @@ class vector_device : public device_t, public device_video_interface
|
|||||||
public:
|
public:
|
||||||
// construction/destruction
|
// construction/destruction
|
||||||
vector_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
vector_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||||
vector_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source);
|
|
||||||
|
|
||||||
UINT32 screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
|
UINT32 screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
|
||||||
void clear_list();
|
void clear_list();
|
||||||
|
|
||||||
void add_point(int x, int y, rgb_t color, int intensity);
|
void add_point(int x, int y, rgb_t color, int intensity);
|
||||||
void add_clip(int minx, int miny, int maxx, int maxy);
|
|
||||||
|
|
||||||
void set_flicker(float newval);
|
void set_flicker(float newval);
|
||||||
float get_flicker();
|
float get_flicker();
|
||||||
|
@ -69,19 +69,81 @@ void avgdvg_device::apply_flipping(int *x, int *y)
|
|||||||
|
|
||||||
void avgdvg_device::vg_flush()
|
void avgdvg_device::vg_flush()
|
||||||
{
|
{
|
||||||
|
int cx0 = 0, cy0 = 0, cx1 = 0x2000000, cy1 = 0x2000000;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
while (vectbuf[i].status == VGCLIP)
|
while (vectbuf[i].status == VGCLIP)
|
||||||
i++;
|
i++;
|
||||||
m_vector->add_point(vectbuf[i].x, vectbuf[i].y, vectbuf[i].color, 0);
|
int xs = vectbuf[i].x;
|
||||||
|
int ys = vectbuf[i].y;
|
||||||
|
|
||||||
for (i = 0; i < nvect; i++)
|
for (i = 0; i < nvect; i++)
|
||||||
{
|
{
|
||||||
if (vectbuf[i].status == VGVECTOR)
|
if (vectbuf[i].status == VGVECTOR)
|
||||||
m_vector->add_point(vectbuf[i].x, vectbuf[i].y, vectbuf[i].color, vectbuf[i].intensity);
|
{
|
||||||
|
int xe = vectbuf[i].x;
|
||||||
|
int ye = vectbuf[i].y;
|
||||||
|
int x0 = xs, y0 = ys, x1 = xe, y1 = ye;
|
||||||
|
|
||||||
if (vectbuf[i].status == VGCLIP)
|
xs = xe;
|
||||||
m_vector->add_clip(vectbuf[i].x, vectbuf[i].y, vectbuf[i].arg1, vectbuf[i].arg2);
|
ys = ye;
|
||||||
|
|
||||||
|
if((x0 < cx0 && x1 < cx0) || (x0 > cx1 && x1 > cx1))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if(x0 < cx0) {
|
||||||
|
y0 += INT64(cx0-x0)*INT64(y1-y0)/(x1-x0);
|
||||||
|
x0 = cx0;
|
||||||
|
} else if(x0 > cx1) {
|
||||||
|
y0 += INT64(cx1-x0)*INT64(y1-y0)/(x1-x0);
|
||||||
|
x0 = cx1;
|
||||||
|
}
|
||||||
|
if(x1 < cx0) {
|
||||||
|
y1 += INT64(cx0-x1)*INT64(y1-y0)/(x1-x0);
|
||||||
|
x1 = cx0;
|
||||||
|
} else if(x1 > cx1) {
|
||||||
|
y1 += INT64(cx1-x1)*INT64(y1-y0)/(x1-x0);
|
||||||
|
x1 = cx1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if((y0 < cy0 && y1 < cy0) || (y0 > cy1 && y1 > cy1))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if(y0 < cy0) {
|
||||||
|
x0 += INT64(cy0-y0)*INT64(x1-x0)/(y1-y0);
|
||||||
|
y0 = cy0;
|
||||||
|
} else if(y0 > cy1) {
|
||||||
|
x0 += INT64(cy1-y0)*INT64(x1-x0)/(y1-y0);
|
||||||
|
y0 = cy1;
|
||||||
|
}
|
||||||
|
if(y1 < cy0) {
|
||||||
|
x1 += INT64(cy0-y1)*INT64(x1-x0)/(y1-y0);
|
||||||
|
y1 = cy0;
|
||||||
|
} else if(y1 > cy1) {
|
||||||
|
x1 += INT64(cy1-y1)*INT64(x1-x0)/(y1-y0);
|
||||||
|
y1 = cy1;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_vector->add_point(x0, y0, vectbuf[i].color, 0);
|
||||||
|
m_vector->add_point(x1, y1, vectbuf[i].color, vectbuf[i].intensity);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vectbuf[i].status == VGCLIP) {
|
||||||
|
cx0 = vectbuf[i].x;
|
||||||
|
cy0 = vectbuf[i].y;
|
||||||
|
cx1 = vectbuf[i].arg1;
|
||||||
|
cy1 = vectbuf[i].arg2;
|
||||||
|
if(cx0 > cx1) {
|
||||||
|
int t = cx1;
|
||||||
|
cx1 = cx0;
|
||||||
|
cx0 = t;
|
||||||
|
}
|
||||||
|
if(cy0 > cx1) {
|
||||||
|
int t = cy1;
|
||||||
|
cy1 = cy0;
|
||||||
|
cy0 = t;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nvect=0;
|
nvect=0;
|
||||||
@ -692,7 +754,7 @@ void avg_tempest_device::vggo() // tempest_vggo
|
|||||||
*
|
*
|
||||||
*************************************/
|
*************************************/
|
||||||
|
|
||||||
int avg_mhavoc_device::handler_1() // mhavoc_latch1
|
int avg_mhavoc_device::handler_1() // mhavoc_latch1
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Major Havoc just has ymin clipping
|
* Major Havoc just has ymin clipping
|
||||||
|
Loading…
Reference in New Issue
Block a user