summaryrefslogtreecommitdiffstatshomepage
path: root/src/osd/modules/input/input_common.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/osd/modules/input/input_common.h')
-rw-r--r--src/osd/modules/input/input_common.h504
1 files changed, 167 insertions, 337 deletions
diff --git a/src/osd/modules/input/input_common.h b/src/osd/modules/input/input_common.h
index b4005a6b76a..73ddd2bf936 100644
--- a/src/osd/modules/input/input_common.h
+++ b/src/osd/modules/input/input_common.h
@@ -7,20 +7,26 @@
// SDLMAME by Olivier Galibert and R. Belmont
//
//============================================================
+#ifndef MAME_OSD_INPUT_INPUT_COMMON_H
+#define MAME_OSD_INPUT_INPUT_COMMON_H
-#ifndef INPUT_COMMON_H_
-#define INPUT_COMMON_H_
+#pragma once
#include "input_module.h"
-#include "inputdev.h"
+#include "interface/inputdev.h"
+#include "interface/inputman.h"
+#include "modules/osdmodule.h"
+#include "util/strformat.h"
+
+#include <algorithm>
+#include <cassert>
#include <chrono>
+#include <functional>
#include <memory>
#include <mutex>
#include <queue>
-#include <algorithm>
-#include <functional>
//============================================================
@@ -41,225 +47,66 @@ enum
#define MAX_HATS 8
#define MAX_POV 4
-/****************************************************************************
-* DirectInput compatible keyboard scan codes
-****************************************************************************/
-#define KEY_UNKNOWN 0x00
-#define KEY_ESCAPE 0x01
-#define KEY_1 0x02
-#define KEY_2 0x03
-#define KEY_3 0x04
-#define KEY_4 0x05
-#define KEY_5 0x06
-#define KEY_6 0x07
-#define KEY_7 0x08
-#define KEY_8 0x09
-#define KEY_9 0x0A
-#define KEY_0 0x0B
-#define KEY_MINUS 0x0C /* - on main keyboard */
-#define KEY_EQUALS 0x0D
-#define KEY_BACK 0x0E /* backspace */
-#define KEY_TAB 0x0F
-#define KEY_Q 0x10
-#define KEY_W 0x11
-#define KEY_E 0x12
-#define KEY_R 0x13
-#define KEY_T 0x14
-#define KEY_Y 0x15
-#define KEY_U 0x16
-#define KEY_I 0x17
-#define KEY_O 0x18
-#define KEY_P 0x19
-#define KEY_LBRACKET 0x1A
-#define KEY_RBRACKET 0x1B
-#define KEY_RETURN 0x1C /* Enter on main keyboard */
-#define KEY_LCONTROL 0x1D
-#define KEY_A 0x1E
-#define KEY_S 0x1F
-#define KEY_D 0x20
-#define KEY_F 0x21
-#define KEY_G 0x22
-#define KEY_H 0x23
-#define KEY_J 0x24
-#define KEY_K 0x25
-#define KEY_L 0x26
-#define KEY_SEMICOLON 0x27
-#define KEY_APOSTROPHE 0x28
-#define KEY_GRAVE 0x29 /* accent grave */
-#define KEY_LSHIFT 0x2A
-#define KEY_BACKSLASH 0x2B
-#define KEY_Z 0x2C
-#define KEY_X 0x2D
-#define KEY_C 0x2E
-#define KEY_V 0x2F
-#define KEY_B 0x30
-#define KEY_N 0x31
-#define KEY_M 0x32
-#define KEY_COMMA 0x33
-#define KEY_PERIOD 0x34 /* . on main keyboard */
-#define KEY_SLASH 0x35 /* / on main keyboard */
-#define KEY_RSHIFT 0x36
-#define KEY_MULTIPLY 0x37 /* * on numeric keypad */
-#define KEY_LMENU 0x38 /* left Alt */
-#define KEY_SPACE 0x39
-#define KEY_CAPITAL 0x3A
-#define KEY_F1 0x3B
-#define KEY_F2 0x3C
-#define KEY_F3 0x3D
-#define KEY_F4 0x3E
-#define KEY_F5 0x3F
-#define KEY_F6 0x40
-#define KEY_F7 0x41
-#define KEY_F8 0x42
-#define KEY_F9 0x43
-#define KEY_F10 0x44
-#define KEY_NUMLOCK 0x45
-#define KEY_SCROLL 0x46 /* Scroll Lock */
-#define KEY_NUMPAD7 0x47
-#define KEY_NUMPAD8 0x48
-#define KEY_NUMPAD9 0x49
-#define KEY_SUBTRACT 0x4A /* - on numeric keypad */
-#define KEY_NUMPAD4 0x4B
-#define KEY_NUMPAD5 0x4C
-#define KEY_NUMPAD6 0x4D
-#define KEY_ADD 0x4E /* + on numeric keypad */
-#define KEY_NUMPAD1 0x4F
-#define KEY_NUMPAD2 0x50
-#define KEY_NUMPAD3 0x51
-#define KEY_NUMPAD0 0x52
-#define KEY_DECIMAL 0x53 /* . on numeric keypad */
-#define KEY_OEM_102 0x56 /* <> or \| on RT 102-key keyboard (Non-U.S.) */
-#define KEY_F11 0x57
-#define KEY_F12 0x58
-#define KEY_F13 0x64 /* (NEC PC98) */
-#define KEY_F14 0x65 /* (NEC PC98) */
-#define KEY_F15 0x66 /* (NEC PC98) */
-#define KEY_KANA 0x70 /* (Japanese keyboard) */
-#define KEY_ABNT_C1 0x73 /* /? on Brazilian keyboard */
-#define KEY_CONVERT 0x79 /* (Japanese keyboard) */
-#define KEY_NOCONVERT 0x7B /* (Japanese keyboard) */
-#define KEY_YEN 0x7D /* (Japanese keyboard) */
-#define KEY_ABNT_C2 0x7E /* Numpad . on Brazilian keyboard */
-#define KEY_NUMPADEQUALS 0x8D /* = on numeric keypad (NEC PC98) */
-#define KEY_PREVTRACK 0x90 /* Previous Track (DIK_CIRCUMFLEX on Japanese keyboard) */
-#define KEY_AT 0x91 /* (NEC PC98) */
-#define KEY_COLON 0x92 /* (NEC PC98) */
-#define KEY_UNDERLINE 0x93 /* (NEC PC98) */
-#define KEY_KANJI 0x94 /* (Japanese keyboard) */
-#define KEY_STOP 0x95 /* (NEC PC98) */
-#define KEY_AX 0x96 /* (Japan AX) */
-#define KEY_UNLABELED 0x97 /* (J3100) */
-#define KEY_NEXTTRACK 0x99 /* Next Track */
-#define KEY_NUMPADENTER 0x9C /* Enter on numeric keypad */
-#define KEY_RCONTROL 0x9D
-#define KEY_MUTE 0xA0 /* Mute */
-#define KEY_CALCULATOR 0xA1 /* Calculator */
-#define KEY_PLAYPAUSE 0xA2 /* Play / Pause */
-#define KEY_MEDIASTOP 0xA4 /* Media Stop */
-#define KEY_VOLUMEDOWN 0xAE /* Volume - */
-#define KEY_VOLUMEUP 0xB0 /* Volume + */
-#define KEY_WEBHOME 0xB2 /* Web home */
-#define KEY_NUMPADCOMMA 0xB3 /* , on numeric keypad (NEC PC98) */
-#define KEY_DIVIDE 0xB5 /* / on numeric keypad */
-#define KEY_SYSRQ 0xB7
-#define KEY_RMENU 0xB8 /* right Alt */
-#define KEY_PAUSE 0xC5 /* Pause */
-#define KEY_HOME 0xC7 /* Home on arrow keypad */
-#define KEY_UP 0xC8 /* UpArrow on arrow keypad */
-#define KEY_PRIOR 0xC9 /* PgUp on arrow keypad */
-#define KEY_LEFT 0xCB /* LeftArrow on arrow keypad */
-#define KEY_RIGHT 0xCD /* RightArrow on arrow keypad */
-#define KEY_END 0xCF /* End on arrow keypad */
-#define KEY_DOWN 0xD0 /* DownArrow on arrow keypad */
-#define KEY_NEXT 0xD1 /* PgDn on arrow keypad */
-#define KEY_INSERT 0xD2 /* Insert on arrow keypad */
-#define KEY_DELETE 0xD3 /* Delete on arrow keypad */
-#define KEY_LWIN 0xDB /* Left Windows key */
-#define KEY_RWIN 0xDC /* Right Windows key */
-#define KEY_APPS 0xDD /* AppMenu key */
-#define KEY_POWER 0xDE /* System Power */
-#define KEY_SLEEP 0xDF /* System Sleep */
-#define KEY_WAKE 0xE3 /* System Wake */
-#define KEY_WEBSEARCH 0xE5 /* Web Search */
-#define KEY_WEBFAVORITES 0xE6 /* Web Favorites */
-#define KEY_WEBREFRESH 0xE7 /* Web Refresh */
-#define KEY_WEBSTOP 0xE8 /* Web Stop */
-#define KEY_WEBFORWARD 0xE9 /* Web Forward */
-#define KEY_WEBBACK 0xEA /* Web Back */
-#define KEY_MYCOMPUTER 0xEB /* My Computer */
-#define KEY_MAIL 0xEC /* Mail */
-#define KEY_MEDIASELECT 0xED /* Media Select */
//============================================================
// device_info
//============================================================
-class input_device_list;
-
class device_info
{
- friend input_device_list;
-
private:
- std::string m_name;
- std::string m_id;
- input_device * m_device;
- running_machine & m_machine;
+ const std::string m_name;
+ const std::string m_id;
input_module & m_module;
- input_device_class m_deviceclass;
public:
// Constructor
- device_info(running_machine &machine, const char *name, const char *id, input_device_class deviceclass, input_module &module)
- : m_name(name),
- m_id(id),
- m_device(nullptr),
- m_machine(machine),
- m_module(module),
- m_deviceclass(deviceclass)
+ device_info(std::string &&name, std::string &&id, input_module &module) :
+ m_name(std::move(name)),
+ m_id(std::move(id)),
+ m_module(module)
{
}
// Destructor
- virtual ~device_info() {}
+ virtual ~device_info() = default;
// Getters
- running_machine & machine() const { return m_machine; }
- const char * name() const { return m_name.c_str(); }
- const char * id() const { return m_id.c_str(); }
- input_device * device() const { return m_device; }
- input_module & module() const { return m_module; }
- input_device_class deviceclass() const { return m_deviceclass; }
+ const std::string &name() const { return m_name; }
+ const std::string &id() const { return m_id; }
+ input_module &module() const { return m_module; }
// Poll and reset methods
- virtual void poll() {};
+ virtual void poll(bool relative_reset) = 0;
virtual void reset() = 0;
+ virtual void configure(osd::input_device &device) = 0;
};
+
//============================================================
// event_based_device
//============================================================
-#define DEFAULT_EVENT_QUEUE_SIZE 20
-
template <class TEvent>
class event_based_device : public device_info
{
private:
- std::queue<TEvent> m_event_queue;
+ static inline constexpr unsigned DEFAULT_EVENT_QUEUE_SIZE = 64;
+
+ std::queue<TEvent> m_event_queue;
protected:
std::mutex m_device_lock;
- virtual void process_event(TEvent &ev) = 0;
+ virtual void process_event(TEvent const &ev) = 0;
public:
- event_based_device(running_machine &machine, const char *name, const char *id, input_device_class deviceclass, input_module &module)
- : device_info(machine, name, id, deviceclass, module)
+ event_based_device(std::string &&name, std::string &&id, input_module &module) :
+ device_info(std::move(name), std::move(id), module)
{
}
- void queue_events(const TEvent *events, int count)
+ void queue_events(TEvent const *events, int count)
{
std::lock_guard<std::mutex> scope_lock(m_device_lock);
for (int i = 0; i < count; i++)
@@ -270,38 +117,46 @@ public:
m_event_queue.pop();
}
- void virtual poll() override
+ virtual void poll(bool relative_reset) override
{
std::lock_guard<std::mutex> scope_lock(m_device_lock);
// Process each event until the queue is empty
while (!m_event_queue.empty())
{
- TEvent &next_event = m_event_queue.front();
- process_event(next_event);
+ process_event(m_event_queue.front());
m_event_queue.pop();
}
}
+
+ virtual void reset() override
+ {
+ std::lock_guard<std::mutex> scope_lock(m_device_lock);
+ std::queue<TEvent>().swap(m_event_queue);
+ }
};
+
//============================================================
// input_device_list class
//============================================================
+template <typename Info>
class input_device_list
{
private:
- std::vector<std::unique_ptr<device_info>> m_list;
+ std::vector<std::unique_ptr<Info> > m_list;
public:
- size_t size() const { return m_list.size(); }
- auto begin() { return m_list.begin(); }
- auto end() { return m_list.end(); }
+ auto size() const { return m_list.size(); }
+ auto empty() const { return m_list.empty(); }
+ auto begin() const { return m_list.begin(); }
+ auto end() const { return m_list.end(); }
- void poll_devices()
+ void poll_devices(bool relative_reset)
{
for (auto &device: m_list)
- device->poll();
+ device->poll(relative_reset);
}
void reset_devices()
@@ -310,17 +165,11 @@ public:
device->reset();
}
- void free_device(device_info* devinfo)
- {
- // find the device to remove
- auto device_matches = [devinfo](std::unique_ptr<device_info> &device) { return devinfo == device.get(); };
- m_list.erase(std::remove_if(std::begin(m_list), std::end(m_list), device_matches), m_list.end());
- }
-
- void for_each_device(std::function<void (device_info*)> action)
+ template <typename T>
+ void for_each_device(T &&action)
{
for (auto &device: m_list)
- action(device.get());
+ action(*device);
}
void free_all_devices()
@@ -329,46 +178,34 @@ public:
m_list.pop_back();
}
- template <typename TActual, typename... TArgs>
- TActual* create_device(running_machine &machine, const char *name, const char *id, input_module &module, TArgs&&... args)
+ template <typename Actual>
+ Actual &add_device(std::unique_ptr<Actual> &&devinfo)
{
- // allocate the device object
- auto devinfo = std::make_unique<TActual>(machine, name, id, module, std::forward<TArgs>(args)...);
-
- return add_device(machine, std::move(devinfo));
- }
-
- template <typename TActual>
- TActual* add_device(running_machine &machine, std::unique_ptr<TActual> devinfo)
- {
- // Add the device to the machine
- devinfo->m_device = machine.input().device_class(devinfo->deviceclass()).add_device(devinfo->name(), devinfo->id(), devinfo.get());
-
- // append us to the list
- m_list.push_back(std::move(devinfo));
-
- return static_cast<TActual*>(m_list.back().get());
+ // append us to the list and return reference
+ Actual &result = *devinfo;
+ m_list.emplace_back(std::move(devinfo));
+ return result;
}
};
+
// keyboard translation table
-struct key_trans_entry {
+struct key_trans_entry
+{
input_item_id mame_key;
-#if defined(OSD_SDL)
+#if defined(OSD_SDL) || defined(SDLMAME_WIN32)
int sdl_scancode;
-#elif defined(OSD_WINDOWS)
- int scan_code;
+#endif
+#if defined(OSD_WINDOWS) || defined(SDLMAME_WIN32)
+ uint16_t scan_code;
unsigned char virtual_key;
-#elif defined(OSD_UWP)
- int scan_code;
- Windows::System::VirtualKey virtual_key;
#endif
char ascii_key;
- char const * mame_key_name;
- char * ui_name;
+ char const * mame_key_name;
+ char const * ui_name;
};
class keyboard_trans_table
@@ -381,7 +218,7 @@ private:
std::unique_ptr<key_trans_entry[]> m_custom_table;
key_trans_entry * m_table;
- uint32_t m_table_size;
+ uint32_t m_table_size;
public:
// constructor
@@ -394,12 +231,9 @@ public:
input_item_id lookup_mame_code(const char * scode) const;
int lookup_mame_index(const char * scode) const;
-#if defined(OSD_WINDOWS)
+#if defined(OSD_WINDOWS) || defined(SDLMAME_WIN32)
input_item_id map_di_scancode_to_itemid(int di_scancode) const;
int vkey_for_mame_code(input_code code) const;
-#elif defined(OSD_UWP)
- input_item_id map_di_scancode_to_itemid(int di_scancode) const;
- const char* ui_label_for_mame_key(input_item_id code) const;
#endif
static keyboard_trans_table& instance()
@@ -411,155 +245,153 @@ public:
key_trans_entry & operator [](int i) const { return m_table[i]; }
};
+
//============================================================
// input_module_base - base class for input modules
//============================================================
-class osd_options;
-
-typedef std::chrono::high_resolution_clock clock_type;
-typedef std::chrono::time_point<std::chrono::high_resolution_clock> timepoint_type;
-
-// 10 milliseconds polling interval
-#define MIN_POLLING_INTERVAL 10
-
-class input_module_base : public input_module
+class input_module_base : public osd_module, public input_module
{
-public:
- input_module_base(const char *type, const char* name)
- : input_module(type, name),
- m_input_enabled(false),
- m_mouse_enabled(false),
- m_lightgun_enabled(false),
- m_input_paused(false),
- m_options(nullptr)
- {
- }
-
private:
- bool m_input_enabled;
- bool m_mouse_enabled;
- bool m_lightgun_enabled;
- bool m_input_paused;
- const osd_options * m_options;
- input_device_list m_devicelist;
+ // 10 milliseconds polling interval
+ static constexpr inline unsigned MIN_POLLING_INTERVAL = 2;
+
+ using clock_type = std::chrono::high_resolution_clock;
+ using timepoint_type = std::chrono::time_point<std::chrono::high_resolution_clock>;
+
clock_type m_clock;
timepoint_type m_last_poll;
+ bool m_background_input;
+ const osd_options * m_options;
+ osd::input_manager * m_manager;
+
+ virtual void poll(bool relative_reset) = 0;
protected:
- void set_mouse_enabled(bool value) { m_mouse_enabled = value; }
+ input_module_base(char const *type, char const *name);
+
+ osd::input_manager & manager() { assert(m_manager); return *m_manager; }
+ const osd_options * options() const { return m_options; }
+ bool background_input() const { return m_background_input; }
+
+ virtual void before_poll() { }
public:
+ virtual int init(osd_interface &osd, const osd_options &options) override;
- const osd_options * options() const { return m_options; }
- input_device_list * devicelist() { return &m_devicelist; }
- bool input_enabled() const { return m_input_enabled; }
- bool input_paused() const { return m_input_paused; }
- bool mouse_enabled() const { return m_mouse_enabled; }
- bool lightgun_enabled() const { return m_lightgun_enabled; }
+ virtual void input_init(running_machine &machine) override;
+ virtual void poll_if_necessary(bool relative_reset) override;
+
+ virtual void reset_devices() = 0; // SDL OSD uses this to forcibly release keys
+};
- int init(const osd_options &options) override;
- void poll_if_necessary(running_machine &machine) override
+//============================================================
+// input_module_impl - base class for input modules
+//============================================================
+
+template <typename Info, typename OsdImpl>
+class input_module_impl : public input_module_base
+{
+public:
+ virtual void exit() override
{
- auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(m_clock.now() - m_last_poll);
- if (elapsed.count() >= MIN_POLLING_INTERVAL)
- {
- poll(machine);
- }
+ devicelist().free_all_devices();
}
- virtual void poll(running_machine &machine)
+ virtual int init(osd_interface &osd, const osd_options &options) override
{
- // ignore if not enabled
- if (m_input_enabled)
- {
- // grab the current time
- m_last_poll = m_clock.now();
+ m_osd = dynamic_cast<OsdImpl *>(&osd);
+ if (!m_osd)
+ return -1;
- before_poll(machine);
+ return input_module_base::init(osd, options);
+ }
- // track if mouse/lightgun is enabled, for mouse hiding purposes
- m_mouse_enabled = machine.input().device_class(DEVICE_CLASS_MOUSE).enabled();
- m_lightgun_enabled = machine.input().device_class(DEVICE_CLASS_LIGHTGUN).enabled();
- }
+ virtual void reset_devices() override { devicelist().reset_devices(); }
- // poll all of the devices
- if (should_poll_devices(machine))
- {
- m_devicelist.poll_devices();
- }
- else
- {
- m_devicelist.reset_devices();
- }
+protected:
+ using input_module_base::input_module_base;
+
+ input_device_list<Info> &devicelist() { return m_devicelist; }
+ OsdImpl &osd() { assert(m_osd); return *m_osd; }
+
+ virtual void before_poll() override
+ {
+ // periodically process events, in case they're not coming through
+ // this also will make sure the mouse state is up-to-date
+ osd().process_events();
}
- virtual void pause() override
+ virtual bool should_poll_devices()
{
- // keep track of the paused state
- m_input_paused = true;
+ return background_input() || osd().has_focus();
}
- virtual void resume() override
+ template <typename Actual, typename... Params>
+ Actual &create_device(input_device_class deviceclass, std::string &&name, std::string &&id, Params &&... args)
{
- // keep track of the paused state
- m_input_paused = false;
+ // allocate the device object and add it to the input manager
+ return add_device(
+ deviceclass,
+ std::make_unique<Actual>(std::move(name), std::move(id), *this, std::forward<Params>(args)...));
}
- virtual void exit() override
+ template <typename Actual>
+ Actual &add_device(input_device_class deviceclass, std::unique_ptr<Actual> &&devinfo)
{
- devicelist()->free_all_devices();
+ // add it to the input manager and append it to the list
+ osd::input_device &osddev = manager().add_device(deviceclass, devinfo->name(), devinfo->id(), devinfo.get());
+ devinfo->configure(osddev);
+ return devicelist().add_device(std::move(devinfo));
}
-protected:
- virtual int init_internal() { return 0; }
- virtual bool should_poll_devices(running_machine &machine) = 0;
- virtual void before_poll(running_machine &machine) {}
+private:
+ virtual void poll(bool relative_reset) override final
+ {
+ // poll all of the devices
+ if (should_poll_devices())
+ m_devicelist.poll_devices(relative_reset);
+ else
+ m_devicelist.reset_devices();
+ }
+
+ input_device_list<Info> m_devicelist;
+ OsdImpl *m_osd = nullptr;
};
+
template <class TItem>
int generic_button_get_state(void *device_internal, void *item_internal)
{
- device_info *devinfo = static_cast<device_info *>(device_internal);
- TItem *itemdata = static_cast<TItem*>(item_internal);
-
// return the current state
- devinfo->module().poll_if_necessary(devinfo->machine());
- return *itemdata >> 7;
+ return *reinterpret_cast<TItem const *>(item_internal) >> 7;
}
+
template <class TItem>
int generic_axis_get_state(void *device_internal, void *item_internal)
{
- device_info *devinfo = static_cast<device_info *>(device_internal);
- TItem *axisdata = static_cast<TItem*>(item_internal);
-
- // return the current state
- devinfo->module().poll_if_necessary(devinfo->machine());
- return *axisdata;
+ return *reinterpret_cast<TItem const *>(item_internal);
}
+
//============================================================
// default_button_name
//============================================================
-inline static const char *default_button_name(int which)
+inline std::string default_button_name(int which)
{
- static char buffer[20];
- snprintf(buffer, ARRAY_LENGTH(buffer), "B%d", which);
- return buffer;
+ return util::string_format("Button %d", which + 1);
}
//============================================================
// default_pov_name
//============================================================
-inline static const char *default_pov_name(int which)
+inline std::string default_pov_name(int which)
{
- static char buffer[20];
- snprintf(buffer, ARRAY_LENGTH(buffer), "POV%d", which);
- return buffer;
+ return util::string_format("Hat %d", which + 1);
}
// default axis names
@@ -569,27 +401,25 @@ const char *const default_axis_name[] =
"RY", "RZ", "SL1", "SL2"
};
-inline static int32_t normalize_absolute_axis(double raw, double rawmin, double rawmax)
+inline int32_t normalize_absolute_axis(double raw, double rawmin, double rawmax)
{
- double center = (rawmax + rawmin) / 2.0;
-
- // make sure we have valid data
+ // make sure we have valid arguments
if (rawmin >= rawmax)
return int32_t(raw);
- // above center
+ double const center = (rawmax + rawmin) / 2.0;
if (raw >= center)
{
- double result = (raw - center) * INPUT_ABSOLUTE_MAX / (rawmax - center);
- return std::min(result, (double)INPUT_ABSOLUTE_MAX);
+ // above center
+ double const result = (raw - center) * double(osd::input_device::ABSOLUTE_MAX) / (rawmax - center);
+ return int32_t(std::min(result, double(osd::input_device::ABSOLUTE_MAX)));
}
-
- // below center
else
{
- double result = -((center - raw) * (double)-INPUT_ABSOLUTE_MIN / (center - rawmin));
- return std::max(result, (double)INPUT_ABSOLUTE_MIN);
+ // below center
+ double result = -((center - raw) * double(-osd::input_device::ABSOLUTE_MIN) / (center - rawmin));
+ return int32_t(std::max(result, double(osd::input_device::ABSOLUTE_MIN)));
}
}
-#endif // INPUT_COMMON_H_
+#endif // MAME_OSD_INPUT_INPUT_COMMON_H