diff options
author | 2015-10-25 20:54:00 +0100 | |
---|---|---|
committer | 2015-10-25 20:54:00 +0100 | |
commit | 5f1f5d500aac6248a76ca1c3424454cf9ce691d3 (patch) | |
tree | 0e88406e44181fe77561e3ad9568df45321c9857 | |
parent | 0ad0e5548efd6c82d62058c92ae381fa51932a2a (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.c | 4 | ||||
-rw-r--r-- | src/emu/emuopts.h | 8 | ||||
-rw-r--r-- | src/emu/ui/ui.c | 54 | ||||
-rw-r--r-- | src/emu/video/vector.c | 82 | ||||
-rw-r--r-- | src/emu/video/vector.h | 23 | ||||
-rw-r--r-- | src/osd/sdl/video.c | 2 |
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()) |