trunk/src/emu/emuopts.c
| r249890 | r249891 | |
| 112 | 112 | // vector options |
| 113 | 113 | { NULL, NULL, OPTION_HEADER, "CORE VECTOR OPTIONS" }, |
| 114 | 114 | { OPTION_ANTIALIAS ";aa", "1", OPTION_BOOLEAN, "use antialiasing when drawing vectors" }, |
| 115 | | { OPTION_BEAM, "1.0", OPTION_FLOAT, "set vector beam width" }, |
| 115 | { OPTION_BEAM_MIN, "1.0", OPTION_FLOAT, "set vector beam width minimum" }, |
| 116 | { OPTION_BEAM_MAX, "1.0", OPTION_FLOAT, "set vector beam width maximum" }, |
| 117 | { OPTION_BEAM_INTENSITY_WEIGHT, "0", OPTION_FLOAT, "set vector beam intensity weight " }, |
| 116 | 118 | { OPTION_FLICKER, "0", OPTION_FLOAT, "set vector flicker effect" }, |
| 117 | 119 | |
| 118 | 120 | // sound options |
trunk/src/emu/ui/ui.c
| r249890 | r249891 | |
| 124 | 124 | static INT32 slider_overxoffset(running_machine &machine, void *arg, std::string *str, INT32 newval); |
| 125 | 125 | static INT32 slider_overyoffset(running_machine &machine, void *arg, std::string *str, INT32 newval); |
| 126 | 126 | static INT32 slider_flicker(running_machine &machine, void *arg, std::string *str, INT32 newval); |
| 127 | | static INT32 slider_beam(running_machine &machine, void *arg, std::string *str, INT32 newval); |
| 127 | static INT32 slider_beam_min(running_machine &machine, void *arg, std::string *str, INT32 newval); |
| 128 | static INT32 slider_beam_max(running_machine &machine, void *arg, std::string *str, INT32 newval); |
| 129 | static INT32 slider_beam_intensity_weight(running_machine &machine, void *arg, std::string *str, INT32 newval); |
| 128 | 130 | static char *slider_get_screen_desc(screen_device &screen); |
| 129 | 131 | #ifdef MAME_DEBUG |
| 130 | 132 | static INT32 slider_crossscale(running_machine &machine, void *arg, std::string *str, INT32 newval); |
| r249890 | r249891 | |
| 1964 | 1966 | for (screen_device *screen = scriter.first(); screen != NULL; screen = scriter.next()) |
| 1965 | 1967 | if (screen->screen_type() == SCREEN_TYPE_VECTOR) |
| 1966 | 1968 | { |
| 1967 | | // add flicker control |
| 1969 | // add vector control |
| 1968 | 1970 | *tailptr = slider_alloc(machine, "Vector Flicker", 0, 0, 1000, 10, slider_flicker, NULL); |
| 1969 | 1971 | tailptr = &(*tailptr)->next; |
| 1970 | | *tailptr = slider_alloc(machine, "Beam Width", 10, 100, 1000, 10, slider_beam, NULL); |
| 1972 | *tailptr = slider_alloc(machine, "Beam Width Minimum", 10, 100, 1000, 10, slider_beam_min, NULL); |
| 1971 | 1973 | tailptr = &(*tailptr)->next; |
| 1974 | *tailptr = slider_alloc(machine, "Beam Width Maximum", 10, 100, 1000, 10, slider_beam_max, NULL); |
| 1975 | tailptr = &(*tailptr)->next; |
| 1976 | *tailptr = slider_alloc(machine, "Beam Intensity Weight", -1000, 0, 1000, 10, slider_beam_intensity_weight, NULL); |
| 1977 | tailptr = &(*tailptr)->next; |
| 1972 | 1978 | break; |
| 1973 | 1979 | } |
| 1974 | 1980 | |
| r249890 | r249891 | |
| 2348 | 2354 | |
| 2349 | 2355 | |
| 2350 | 2356 | //------------------------------------------------- |
| 2351 | | // slider_beam - vector beam width slider |
| 2357 | // slider_beam_min - minimum vector beam width slider |
| 2352 | 2358 | // callback |
| 2353 | 2359 | //------------------------------------------------- |
| 2354 | 2360 | |
| 2355 | | static INT32 slider_beam(running_machine &machine, void *arg, std::string *str, INT32 newval) |
| 2361 | static INT32 slider_beam_min(running_machine &machine, void *arg, std::string *str, INT32 newval) |
| 2356 | 2362 | { |
| 2357 | 2363 | vector_device *vector = NULL; |
| 2358 | 2364 | if (newval != SLIDER_NOCHANGE) |
| 2359 | | vector->set_beam((float)newval * 0.01f); |
| 2365 | vector->set_beam_min(MIN((float)newval * 0.001f, vector->get_beam_max())); |
| 2360 | 2366 | if (str != NULL) |
| 2361 | | strprintf(*str,"%1.2f", (double) vector->get_beam()); |
| 2362 | | return floor(vector->get_beam() * 100.0f + 0.5f); |
| 2367 | strprintf(*str,"%1.2f", (double) vector->get_beam_min()); |
| 2368 | return floor(vector->get_beam_min() * 1000.0f + 0.5f); |
| 2363 | 2369 | } |
| 2364 | 2370 | |
| 2365 | 2371 | |
| 2366 | 2372 | //------------------------------------------------- |
| 2373 | // slider_beam_max - maximum vector beam width slider |
| 2374 | // callback |
| 2375 | //------------------------------------------------- |
| 2376 | |
| 2377 | static INT32 slider_beam_max(running_machine &machine, void *arg, std::string *str, INT32 newval) |
| 2378 | { |
| 2379 | vector_device *vector = NULL; |
| 2380 | if (newval != SLIDER_NOCHANGE) |
| 2381 | vector->set_beam_max(MAX((float)newval * 0.001f, vector->get_beam_min())); |
| 2382 | if (str != NULL) |
| 2383 | strprintf(*str,"%1.2f", (double) vector->get_beam_max()); |
| 2384 | return floor(vector->get_beam_max() * 1000.0f + 0.5f); |
| 2385 | } |
| 2386 | |
| 2387 | |
| 2388 | //------------------------------------------------- |
| 2389 | // slider_beam_intensity_weight - vector beam intensity weight slider |
| 2390 | // callback |
| 2391 | //------------------------------------------------- |
| 2392 | |
| 2393 | static INT32 slider_beam_intensity_weight(running_machine &machine, void *arg, std::string *str, INT32 newval) |
| 2394 | { |
| 2395 | vector_device *vector = NULL; |
| 2396 | if (newval != SLIDER_NOCHANGE) |
| 2397 | vector->set_beam_intensity_weight((float)newval * 0.001f); |
| 2398 | if (str != NULL) |
| 2399 | strprintf(*str,"%1.2f", (double) vector->get_beam_intensity_weight()); |
| 2400 | return floor(vector->get_beam_intensity_weight() * 1000.0f + 0.5f); |
| 2401 | } |
| 2402 | |
| 2403 | |
| 2404 | //------------------------------------------------- |
| 2367 | 2405 | // slider_get_screen_desc - returns the |
| 2368 | 2406 | // description for a given screen |
| 2369 | 2407 | //------------------------------------------------- |
trunk/src/emu/video/vector.c
| r249890 | r249891 | |
| 35 | 35 | #include "vector.h" |
| 36 | 36 | |
| 37 | 37 | |
| 38 | #define FLT_EPSILON 1E-5 |
| 38 | 39 | |
| 39 | | #define VECTOR_WIDTH_DENOM 512 |
| 40 | #define VECTOR_WIDTH_DENOM 512 |
| 40 | 41 | |
| 42 | #define MAX_POINTS 10000 |
| 41 | 43 | |
| 42 | | #define MAX_POINTS 10000 |
| 43 | | |
| 44 | 44 | #define VECTOR_TEAM \ |
| 45 | 45 | "-* Vector Heads *-\n" \ |
| 46 | 46 | "Brad Oliver\n" \ |
| r249890 | r249891 | |
| 141 | 141 | } |
| 142 | 142 | |
| 143 | 143 | float vector_device::m_flicker = 0.0f; |
| 144 | | float vector_device::m_beam_width = 0.0f; |
| 144 | float vector_device::m_beam_width_min = 0.0f; |
| 145 | float vector_device::m_beam_width_max = 0.0f; |
| 146 | float vector_device::m_beam_intensity_weight = 0.0f; |
| 145 | 147 | int vector_device::m_vector_index; |
| 146 | 148 | |
| 147 | 149 | void vector_device::device_start() |
| 148 | 150 | { |
| 149 | | m_beam_width = machine().options().beam(); |
| 150 | | |
| 151 | 151 | /* Grab the settings for this session */ |
| 152 | | set_flicker(machine().options().flicker()); |
| 152 | m_beam_width_min = machine().options().beam_min(); |
| 153 | m_beam_width_max = machine().options().beam_max(); |
| 154 | m_beam_intensity_weight = machine().options().beam_intensity_weight(); |
| 155 | m_flicker = machine().options().flicker(); |
| 153 | 156 | |
| 154 | 157 | m_vector_index = 0; |
| 155 | 158 | |
| r249890 | r249891 | |
| 167 | 170 | return m_flicker; |
| 168 | 171 | } |
| 169 | 172 | |
| 170 | | void vector_device::set_beam(float _beam) |
| 173 | void vector_device::set_beam_min(float _beam) |
| 171 | 174 | { |
| 172 | | m_beam_width = _beam; |
| 175 | m_beam_width_min = _beam; |
| 173 | 176 | } |
| 174 | 177 | |
| 175 | | float vector_device::get_beam() |
| 178 | float vector_device::get_beam_min() |
| 176 | 179 | { |
| 177 | | return m_beam_width; |
| 180 | return m_beam_width_min; |
| 178 | 181 | } |
| 179 | 182 | |
| 183 | void vector_device::set_beam_max(float _beam) |
| 184 | { |
| 185 | m_beam_width_max = _beam; |
| 186 | } |
| 180 | 187 | |
| 188 | float vector_device::get_beam_max() |
| 189 | { |
| 190 | return m_beam_width_max; |
| 191 | } |
| 192 | |
| 193 | void vector_device::set_beam_intensity_weight(float _beam) |
| 194 | { |
| 195 | m_beam_intensity_weight = _beam; |
| 196 | } |
| 197 | |
| 198 | float vector_device::get_beam_intensity_weight() |
| 199 | { |
| 200 | return m_beam_intensity_weight; |
| 201 | } |
| 202 | |
| 203 | |
| 181 | 204 | /* |
| 205 | * www.dinodini.wordpress.com/2010/04/05/normalized-tunable-sigmoid-functions/ |
| 206 | */ |
| 207 | float vector_device::normalized_sigmoid(float n, float k) |
| 208 | { |
| 209 | // valid for n and k in range of -1.0 and 1.0 |
| 210 | return (n - n * k) / (k - fabs(n) * 2.0f * k + 1.0f); |
| 211 | } |
| 212 | |
| 213 | |
| 214 | /* |
| 182 | 215 | * Adds a line end point to the vertices list. The vector processor emulation |
| 183 | 216 | * needs to call this. |
| 184 | 217 | */ |
| r249890 | r249891 | |
| 263 | 296 | float yscale = 1.0f / (65536 * visarea.height()); |
| 264 | 297 | float xoffs = (float)visarea.min_x; |
| 265 | 298 | float yoffs = (float)visarea.min_y; |
| 299 | float xratio = xscale / yscale; |
| 300 | float yratio = yscale / xscale; |
| 301 | xratio = (xratio < 1.0f) ? xratio : 1.0f; |
| 302 | xratio = (yratio < 1.0f) ? yratio : 1.0f; |
| 303 | |
| 266 | 304 | point *curpoint; |
| 267 | 305 | render_bounds clip; |
| 268 | | int lastx = 0, lasty = 0; |
| 269 | | int i; |
| 306 | int lastx = 0; |
| 307 | int lasty = 0; |
| 270 | 308 | |
| 271 | 309 | curpoint = m_vector_list; |
| 272 | 310 | |
| r249890 | r249891 | |
| 276 | 314 | clip.x0 = clip.y0 = 0.0f; |
| 277 | 315 | clip.x1 = clip.y1 = 1.0f; |
| 278 | 316 | |
| 279 | | for (i = 0; i < m_vector_index; i++) |
| 317 | for (int i = 0; i < m_vector_index; i++) |
| 280 | 318 | { |
| 281 | 319 | render_bounds coords; |
| 282 | 320 | |
| r249890 | r249891 | |
| 294 | 332 | } |
| 295 | 333 | else |
| 296 | 334 | { |
| 297 | | // todo: implement beam_width_overdrive based on intensity |
| 335 | float intensity = (float)curpoint->intensity / 255.0f; |
| 336 | float intensity_weight = normalized_sigmoid(intensity, m_beam_intensity_weight); |
| 298 | 337 | |
| 299 | | float beam_width = m_beam_width * (1.0f / (float)VECTOR_WIDTH_DENOM); |
| 338 | float beam_intensity_width = (m_beam_width_max - m_beam_width_min) * intensity_weight + m_beam_width_min; |
| 339 | float beam_width = beam_intensity_width * (1.0f / (float)VECTOR_WIDTH_DENOM); |
| 300 | 340 | |
| 301 | 341 | coords.x0 = ((float)lastx - xoffs) * xscale; |
| 302 | 342 | coords.y0 = ((float)lasty - yoffs) * yscale; |
| 303 | 343 | coords.x1 = ((float)curpoint->x - xoffs) * xscale; |
| 304 | 344 | coords.y1 = ((float)curpoint->y - yoffs) * yscale; |
| 305 | 345 | |
| 306 | | // todo: extend line length by half beam_width on both sides |
| 346 | // extend zero-length vector line (vector point) by quarter beam_width on both sides |
| 347 | if (fabs(coords.x0 - coords.x1) < FLT_EPSILON && |
| 348 | fabs(coords.y0 - coords.y1) < FLT_EPSILON) |
| 349 | { |
| 350 | coords.x0 += xratio * beam_width * 0.25f; |
| 351 | coords.y0 += yratio * beam_width * 0.25f; |
| 352 | coords.x1 -= xratio * beam_width * 0.25f; |
| 353 | coords.y1 -= yratio * beam_width * 0.25f; |
| 354 | } |
| 307 | 355 | |
| 308 | 356 | if (curpoint->intensity != 0 && !render_clip_line(&coords, &clip)) |
| 309 | 357 | { |
trunk/src/emu/video/vector.h
| r249890 | r249891 | |
| 16 | 16 | /* The vertices are buffered here */ |
| 17 | 17 | struct point |
| 18 | 18 | { |
| 19 | | point(): |
| 19 | point() : |
| 20 | 20 | x(0), |
| 21 | 21 | y(0), |
| 22 | 22 | col(0), |
| r249890 | r249891 | |
| 32 | 32 | int status; /* for dirty and clipping handling */ |
| 33 | 33 | }; |
| 34 | 34 | |
| 35 | | class vector_device : public device_t, |
| 36 | | public device_video_interface |
| 35 | class vector_device : public device_t, public device_video_interface |
| 37 | 36 | { |
| 38 | 37 | public: |
| 39 | 38 | // construction/destruction |
| r249890 | r249891 | |
| 46 | 45 | void add_point(int x, int y, rgb_t color, int intensity); |
| 47 | 46 | void add_clip(int minx, int miny, int maxx, int maxy); |
| 48 | 47 | |
| 49 | | void set_flicker(float m_flicker_correction); |
| 48 | void set_flicker(float m_flicker); |
| 50 | 49 | float get_flicker(); |
| 51 | 50 | |
| 52 | | void set_beam(float _beam); |
| 53 | | float get_beam(); |
| 51 | void set_beam_min(float _beam); |
| 52 | float get_beam_min(); |
| 54 | 53 | |
| 54 | void set_beam_max(float _beam); |
| 55 | float get_beam_max(); |
| 56 | |
| 57 | void set_beam_intensity_weight(float _beam); |
| 58 | float get_beam_intensity_weight(); |
| 59 | |
| 55 | 60 | // device-level overrides |
| 56 | 61 | virtual void device_start(); |
| 57 | 62 | |
| 58 | 63 | private: |
| 59 | 64 | static float m_flicker; |
| 60 | | static float m_beam_width; |
| 65 | static float m_beam_width_min; |
| 66 | static float m_beam_width_max; |
| 67 | static float m_beam_intensity_weight; |
| 61 | 68 | point *m_vector_list; |
| 62 | 69 | static int m_vector_index; |
| 70 | |
| 71 | float normalized_sigmoid(float n, float k); |
| 63 | 72 | }; |
| 64 | 73 | |
| 65 | 74 | |