diff --git a/src/devices/video/vector.cpp b/src/devices/video/vector.cpp index bc0d62c0244..993157e08de 100644 --- a/src/devices/video/vector.cpp +++ b/src/devices/video/vector.cpp @@ -67,89 +67,9 @@ void vector_options::init(emu_options& options) 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 const device_type VECTOR = &device_creator; -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) : device_t(mconfig, VECTOR, "VECTOR", tag, owner, clock, "vector_device", __FILE__), 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->col = color; 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++; 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; point *curpoint; - render_bounds clip; int lastx = 0; int lasty = 0; @@ -273,81 +168,63 @@ UINT32 vector_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, 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)); - clip.x0 = clip.y0 = 0.0f; - clip.x1 = clip.y1 = 1.0f; - for (int i = 0; i < m_vector_index; i++) { render_bounds coords; - if (curpoint->status == VCLIP) - { - 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; + float intensity = (float)curpoint->intensity / 255.0f; + float intensity_weight = normalized_sigmoid(intensity, vector_options::s_beam_intensity_weight); - clip.x0 = (coords.x0 > 0.0f) ? coords.x0 : 0.0f; - clip.y0 = (coords.y0 > 0.0f) ? coords.y0 : 0.0f; - clip.x1 = (coords.x1 < 1.0f) ? coords.x1 : 1.0f; - clip.y1 = (coords.y1 < 1.0f) ? coords.y1 : 1.0f; + // check for static intensity + float beam_width = m_min_intensity == m_max_intensity + ? vector_options::s_beam_width_min + : 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 { - float intensity = (float)curpoint->intensity / 255.0f; - float intensity_weight = normalized_sigmoid(intensity, vector_options::s_beam_intensity_weight); + float length = sqrt(xdistance * xdistance + ydistance * ydistance); + float xdirection = xdistance / length; + float ydirection = ydistance / length; - // check for static intensity - float beam_width = m_min_intensity == m_max_intensity - ? vector_options::s_beam_width_min - : 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 - { - 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; + 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) + { + 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++; } diff --git a/src/devices/video/vector.h b/src/devices/video/vector.h index fceadf3800b..6163d63ad69 100644 --- a/src/devices/video/vector.h +++ b/src/devices/video/vector.h @@ -21,16 +21,11 @@ struct point x(0), y(0), col(0), - intensity(0), - arg1(0), - arg2(0), - status(0) {} + intensity(0) {} int x; int y; rgb_t col; int intensity; - int arg1; int arg2; /* start/end in pixel array or clipping info */ - int status; /* for dirty and clipping handling */ }; class vector_options @@ -52,13 +47,11 @@ class vector_device : public device_t, public device_video_interface public: // construction/destruction 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); void clear_list(); 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); float get_flicker(); diff --git a/src/mame/video/avgdvg.cpp b/src/mame/video/avgdvg.cpp index 453ff4b44a2..21e7ea91265 100644 --- a/src/mame/video/avgdvg.cpp +++ b/src/mame/video/avgdvg.cpp @@ -69,19 +69,81 @@ void avgdvg_device::apply_flipping(int *x, int *y) void avgdvg_device::vg_flush() { + int cx0 = 0, cy0 = 0, cx1 = 0x2000000, cy1 = 0x2000000; int i = 0; while (vectbuf[i].status == VGCLIP) 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++) { 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) - m_vector->add_clip(vectbuf[i].x, vectbuf[i].y, vectbuf[i].arg1, vectbuf[i].arg2); + xs = xe; + 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; @@ -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