summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author ImJezze <jezze@gmx.net>2015-10-25 20:54:00 +0100
committer ImJezze <jezze@gmx.net>2015-10-25 20:54:00 +0100
commit5f1f5d500aac6248a76ca1c3424454cf9ce691d3 (patch)
tree0e88406e44181fe77561e3ad9568df45321c9857
parent0ad0e5548efd6c82d62058c92ae381fa51932a2a (diff)
Experimental Dynamic Beam Width
- replace beam width by beam min. and beam max. width, this makes it possible to create a linear dynamic beam width by the amount of intensity of the beam - added beam intensity weight, this adds an exponential factor to the dynamic beam width (values greater than 0 will push larger intensities more than smaller intensities) - fixed displayed ratio of vector points (zero-length lines)
-rw-r--r--src/emu/emuopts.c4
-rw-r--r--src/emu/emuopts.h8
-rw-r--r--src/emu/ui/ui.c54
-rw-r--r--src/emu/video/vector.c82
-rw-r--r--src/emu/video/vector.h23
-rw-r--r--src/osd/sdl/video.c2
6 files changed, 137 insertions, 36 deletions
diff --git a/src/emu/emuopts.c b/src/emu/emuopts.c
index 21128e53e93..884a5fad290 100644
--- a/src/emu/emuopts.c
+++ b/src/emu/emuopts.c
@@ -112,7 +112,9 @@ const options_entry emu_options::s_option_entries[] =
// vector options
{ NULL, NULL, OPTION_HEADER, "CORE VECTOR OPTIONS" },
{ OPTION_ANTIALIAS ";aa", "1", OPTION_BOOLEAN, "use antialiasing when drawing vectors" },
- { OPTION_BEAM, "1.0", OPTION_FLOAT, "set vector beam width" },
+ { OPTION_BEAM_MIN, "1.0", OPTION_FLOAT, "set vector beam width minimum" },
+ { OPTION_BEAM_MAX, "1.0", OPTION_FLOAT, "set vector beam width maximum" },
+ { OPTION_BEAM_INTENSITY_WEIGHT, "0", OPTION_FLOAT, "set vector beam intensity weight " },
{ OPTION_FLICKER, "0", OPTION_FLOAT, "set vector flicker effect" },
// sound options
diff --git a/src/emu/emuopts.h b/src/emu/emuopts.h
index 0bbeb6ae3d7..79531ca5368 100644
--- a/src/emu/emuopts.h
+++ b/src/emu/emuopts.h
@@ -119,7 +119,9 @@ enum
// core vector options
#define OPTION_ANTIALIAS "antialias"
-#define OPTION_BEAM "beam"
+#define OPTION_BEAM_MIN "beam_min"
+#define OPTION_BEAM_MAX "beam_max"
+#define OPTION_BEAM_INTENSITY_WEIGHT "beam_intensity_weight"
#define OPTION_FLICKER "flicker"
// core sound options
@@ -296,7 +298,9 @@ public:
// core vector options
bool antialias() const { return bool_value(OPTION_ANTIALIAS); }
- float beam() const { return float_value(OPTION_BEAM); }
+ float beam_min() const { return float_value(OPTION_BEAM_MIN); }
+ float beam_max() const { return float_value(OPTION_BEAM_MAX); }
+ float beam_intensity_weight() const { return float_value(OPTION_BEAM_INTENSITY_WEIGHT); }
float flicker() const { return float_value(OPTION_FLICKER); }
// core sound options
diff --git a/src/emu/ui/ui.c b/src/emu/ui/ui.c
index a10d9e2f07f..5252a3695d8 100644
--- a/src/emu/ui/ui.c
+++ b/src/emu/ui/ui.c
@@ -124,7 +124,9 @@ static INT32 slider_overyscale(running_machine &machine, void *arg, std::string
static INT32 slider_overxoffset(running_machine &machine, void *arg, std::string *str, INT32 newval);
static INT32 slider_overyoffset(running_machine &machine, void *arg, std::string *str, INT32 newval);
static INT32 slider_flicker(running_machine &machine, void *arg, std::string *str, INT32 newval);
-static INT32 slider_beam(running_machine &machine, void *arg, std::string *str, INT32 newval);
+static INT32 slider_beam_min(running_machine &machine, void *arg, std::string *str, INT32 newval);
+static INT32 slider_beam_max(running_machine &machine, void *arg, std::string *str, INT32 newval);
+static INT32 slider_beam_intensity_weight(running_machine &machine, void *arg, std::string *str, INT32 newval);
static char *slider_get_screen_desc(screen_device &screen);
#ifdef MAME_DEBUG
static INT32 slider_crossscale(running_machine &machine, void *arg, std::string *str, INT32 newval);
@@ -1964,10 +1966,14 @@ static slider_state *slider_init(running_machine &machine)
for (screen_device *screen = scriter.first(); screen != NULL; screen = scriter.next())
if (screen->screen_type() == SCREEN_TYPE_VECTOR)
{
- // add flicker control
+ // add vector control
*tailptr = slider_alloc(machine, "Vector Flicker", 0, 0, 1000, 10, slider_flicker, NULL);
tailptr = &(*tailptr)->next;
- *tailptr = slider_alloc(machine, "Beam Width", 10, 100, 1000, 10, slider_beam, NULL);
+ *tailptr = slider_alloc(machine, "Beam Width Minimum", 10, 100, 1000, 10, slider_beam_min, NULL);
+ tailptr = &(*tailptr)->next;
+ *tailptr = slider_alloc(machine, "Beam Width Maximum", 10, 100, 1000, 10, slider_beam_max, NULL);
+ tailptr = &(*tailptr)->next;
+ *tailptr = slider_alloc(machine, "Beam Intensity Weight", -1000, 0, 1000, 10, slider_beam_intensity_weight, NULL);
tailptr = &(*tailptr)->next;
break;
}
@@ -2348,18 +2354,50 @@ static INT32 slider_flicker(running_machine &machine, void *arg, std::string *st
//-------------------------------------------------
-// slider_beam - vector beam width slider
+// slider_beam_min - minimum vector beam width slider
+// callback
+//-------------------------------------------------
+
+static INT32 slider_beam_min(running_machine &machine, void *arg, std::string *str, INT32 newval)
+{
+ vector_device *vector = NULL;
+ if (newval != SLIDER_NOCHANGE)
+ vector->set_beam_min(MIN((float)newval * 0.001f, vector->get_beam_max()));
+ if (str != NULL)
+ strprintf(*str,"%1.2f", (double) vector->get_beam_min());
+ return floor(vector->get_beam_min() * 1000.0f + 0.5f);
+}
+
+
+//-------------------------------------------------
+// slider_beam_max - maximum vector beam width slider
+// callback
+//-------------------------------------------------
+
+static INT32 slider_beam_max(running_machine &machine, void *arg, std::string *str, INT32 newval)
+{
+ vector_device *vector = NULL;
+ if (newval != SLIDER_NOCHANGE)
+ vector->set_beam_max(MAX((float)newval * 0.001f, vector->get_beam_min()));
+ if (str != NULL)
+ strprintf(*str,"%1.2f", (double) vector->get_beam_max());
+ return floor(vector->get_beam_max() * 1000.0f + 0.5f);
+}
+
+
+//-------------------------------------------------
+// slider_beam_intensity_weight - vector beam intensity weight slider
// callback
//-------------------------------------------------
-static INT32 slider_beam(running_machine &machine, void *arg, std::string *str, INT32 newval)
+static INT32 slider_beam_intensity_weight(running_machine &machine, void *arg, std::string *str, INT32 newval)
{
vector_device *vector = NULL;
if (newval != SLIDER_NOCHANGE)
- vector->set_beam((float)newval * 0.01f);
+ vector->set_beam_intensity_weight((float)newval * 0.001f);
if (str != NULL)
- strprintf(*str,"%1.2f", (double) vector->get_beam());
- return floor(vector->get_beam() * 100.0f + 0.5f);
+ strprintf(*str,"%1.2f", (double) vector->get_beam_intensity_weight());
+ return floor(vector->get_beam_intensity_weight() * 1000.0f + 0.5f);
}
diff --git a/src/emu/video/vector.c b/src/emu/video/vector.c
index 8857de4c22f..9b629c8f242 100644
--- a/src/emu/video/vector.c
+++ b/src/emu/video/vector.c
@@ -35,11 +35,11 @@
#include "vector.h"
+#define FLT_EPSILON 1E-5
-#define VECTOR_WIDTH_DENOM 512
+#define VECTOR_WIDTH_DENOM 512
-
-#define MAX_POINTS 10000
+#define MAX_POINTS 10000
#define VECTOR_TEAM \
"-* Vector Heads *-\n" \
@@ -141,15 +141,18 @@ vector_device::vector_device(const machine_config &mconfig, const char *tag, dev
}
float vector_device::m_flicker = 0.0f;
-float vector_device::m_beam_width = 0.0f;
+float vector_device::m_beam_width_min = 0.0f;
+float vector_device::m_beam_width_max = 0.0f;
+float vector_device::m_beam_intensity_weight = 0.0f;
int vector_device::m_vector_index;
void vector_device::device_start()
{
- m_beam_width = machine().options().beam();
-
/* Grab the settings for this session */
- set_flicker(machine().options().flicker());
+ m_beam_width_min = machine().options().beam_min();
+ m_beam_width_max = machine().options().beam_max();
+ m_beam_intensity_weight = machine().options().beam_intensity_weight();
+ m_flicker = machine().options().flicker();
m_vector_index = 0;
@@ -167,14 +170,44 @@ float vector_device::get_flicker()
return m_flicker;
}
-void vector_device::set_beam(float _beam)
+void vector_device::set_beam_min(float _beam)
+{
+ m_beam_width_min = _beam;
+}
+
+float vector_device::get_beam_min()
+{
+ return m_beam_width_min;
+}
+
+void vector_device::set_beam_max(float _beam)
{
- m_beam_width = _beam;
+ m_beam_width_max = _beam;
}
-float vector_device::get_beam()
+float vector_device::get_beam_max()
{
- return m_beam_width;
+ return m_beam_width_max;
+}
+
+void vector_device::set_beam_intensity_weight(float _beam)
+{
+ m_beam_intensity_weight = _beam;
+}
+
+float vector_device::get_beam_intensity_weight()
+{
+ return m_beam_intensity_weight;
+}
+
+
+/*
+ * www.dinodini.wordpress.com/2010/04/05/normalized-tunable-sigmoid-functions/
+ */
+float vector_device::normalized_sigmoid(float n, float k)
+{
+ // valid for n and k in range of -1.0 and 1.0
+ return (n - n * k) / (k - fabs(n) * 2.0f * k + 1.0f);
}
@@ -263,10 +296,15 @@ UINT32 vector_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap,
float yscale = 1.0f / (65536 * visarea.height());
float xoffs = (float)visarea.min_x;
float yoffs = (float)visarea.min_y;
+ float xratio = xscale / yscale;
+ float yratio = yscale / xscale;
+ xratio = (xratio < 1.0f) ? xratio : 1.0f;
+ xratio = (yratio < 1.0f) ? yratio : 1.0f;
+
point *curpoint;
render_bounds clip;
- int lastx = 0, lasty = 0;
- int i;
+ int lastx = 0;
+ int lasty = 0;
curpoint = m_vector_list;
@@ -276,7 +314,7 @@ UINT32 vector_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap,
clip.x0 = clip.y0 = 0.0f;
clip.x1 = clip.y1 = 1.0f;
- for (i = 0; i < m_vector_index; i++)
+ for (int i = 0; i < m_vector_index; i++)
{
render_bounds coords;
@@ -294,16 +332,26 @@ UINT32 vector_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap,
}
else
{
- // todo: implement beam_width_overdrive based on intensity
+ float intensity = (float)curpoint->intensity / 255.0f;
+ float intensity_weight = normalized_sigmoid(intensity, m_beam_intensity_weight);
- float beam_width = m_beam_width * (1.0f / (float)VECTOR_WIDTH_DENOM);
+ float beam_intensity_width = (m_beam_width_max - m_beam_width_min) * intensity_weight + m_beam_width_min;
+ float beam_width = beam_intensity_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;
- // todo: extend line length by half beam_width on both sides
+ // extend zero-length vector line (vector point) by quarter beam_width on both sides
+ if (fabs(coords.x0 - coords.x1) < FLT_EPSILON &&
+ fabs(coords.y0 - coords.y1) < FLT_EPSILON)
+ {
+ coords.x0 += xratio * beam_width * 0.25f;
+ coords.y0 += yratio * beam_width * 0.25f;
+ coords.x1 -= xratio * beam_width * 0.25f;
+ coords.y1 -= yratio * beam_width * 0.25f;
+ }
if (curpoint->intensity != 0 && !render_clip_line(&coords, &clip))
{
diff --git a/src/emu/video/vector.h b/src/emu/video/vector.h
index 7827fce4a21..1f1731ca415 100644
--- a/src/emu/video/vector.h
+++ b/src/emu/video/vector.h
@@ -16,7 +16,7 @@
/* The vertices are buffered here */
struct point
{
- point():
+ point() :
x(0),
y(0),
col(0),
@@ -32,8 +32,7 @@ struct point
int status; /* for dirty and clipping handling */
};
-class vector_device : public device_t,
- public device_video_interface
+class vector_device : public device_t, public device_video_interface
{
public:
// construction/destruction
@@ -46,20 +45,30 @@ public:
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 m_flicker_correction);
+ void set_flicker(float m_flicker);
float get_flicker();
- void set_beam(float _beam);
- float get_beam();
+ void set_beam_min(float _beam);
+ float get_beam_min();
+
+ void set_beam_max(float _beam);
+ float get_beam_max();
+
+ void set_beam_intensity_weight(float _beam);
+ float get_beam_intensity_weight();
// device-level overrides
virtual void device_start();
private:
static float m_flicker;
- static float m_beam_width;
+ static float m_beam_width_min;
+ static float m_beam_width_max;
+ static float m_beam_intensity_weight;
point *m_vector_list;
static int m_vector_index;
+
+ float normalized_sigmoid(float n, float k);
};
diff --git a/src/osd/sdl/video.c b/src/osd/sdl/video.c
index f9b18c9041f..2220e35c1cc 100644
--- a/src/osd/sdl/video.c
+++ b/src/osd/sdl/video.c
@@ -96,7 +96,7 @@ bool sdl_osd_interface::video_init()
sdl_monitor_info::init();
// we need the beam width in a float, contrary to what the core does.
- video_config.beamwidth = options().beam();
+ video_config.beamwidth = options().beam_min();
// initialize the window system so we can make windows
if (!window_init())