Slightly cleaned up OSD input modules.

Removed support for DirectInput 7 and earlier.  It hasn't been tested in
years, and it's not relevant on any supported OS.  DirectInput is
effectively finalised at version 8, and is unlikely to get an API update
in the future.

Use more string[_view] and fewer C strings, and tightened up scope of a
few things.
This commit is contained in:
Vas Crabb 2021-07-29 15:22:51 +10:00
parent db1ddb7cee
commit 23bd2ecf6a
23 changed files with 839 additions and 922 deletions

View File

@ -27,7 +27,6 @@
# NO_OPENGL = 0
# USE_DISPATCH_GL = 0
# MODERN_WIN_API = 0
# DIRECTINPUT = 7
# USE_SDL = 1
# SDL_INI_PATH = .;$HOME/.mame/;ini;
# SDL2_MULTIAPI = 1
@ -783,10 +782,6 @@ ifdef MODERN_WIN_API
PARAMS += --MODERN_WIN_API='$(MODERN_WIN_API)'
endif
ifdef DIRECTINPUT
PARAMS += --DIRECTINPUT='$(DIRECTINPUT)'
endif
ifdef USE_SDL
PARAMS += --USE_SDL='$(USE_SDL)'
endif

View File

@ -22,17 +22,6 @@ function maintargetosdoptions(_target,_subtarget)
configuration { }
if _OPTIONS["DIRECTINPUT"] == "8" then
links {
"dinput8",
}
else
links {
"dinput",
}
end
if _OPTIONS["USE_SDL"] == "1" then
links {
"SDL.dll",
@ -40,6 +29,7 @@ function maintargetosdoptions(_target,_subtarget)
end
links {
"dinput8",
"comctl32",
"comdlg32",
"psapi",
@ -49,19 +39,6 @@ function maintargetosdoptions(_target,_subtarget)
end
newoption {
trigger = "DIRECTINPUT",
description = "Minimum DirectInput version to support",
allowed = {
{ "7", "Support DirectInput 7 or later" },
{ "8", "Support DirectInput 8 or later" },
},
}
if not _OPTIONS["DIRECTINPUT"] then
_OPTIONS["DIRECTINPUT"] = "8"
end
newoption {
trigger = "USE_SDL",
description = "Enable SDL sound output",
@ -124,18 +101,9 @@ project ("osd_" .. _OPTIONS["osd"])
defines {
"DIRECT3D_VERSION=0x0900",
"DIRECTINPUT_VERSION=0x0800",
}
if _OPTIONS["DIRECTINPUT"] == "8" then
defines {
"DIRECTINPUT_VERSION=0x0800",
}
else
defines {
"DIRECTINPUT_VERSION=0x0700",
}
end
includedirs {
MAME_DIR .. "src/emu",
MAME_DIR .. "src/devices", -- accessing imagedev from debugger

View File

@ -800,7 +800,7 @@ std::string input_manager::code_name(input_code code) const
}
// devcode part comes from the item name
const char *devcode = item->name();
std::string_view devcode = item->name();
// determine the modifier part
const char *modifier = (*modifier_string_table)[code.item_modifier()];
@ -808,13 +808,13 @@ std::string input_manager::code_name(input_code code) const
// devcode is redundant with joystick switch left/right/up/down
if (device_class == DEVICE_CLASS_JOYSTICK && code.item_class() == ITEM_CLASS_SWITCH)
if (code.item_modifier() >= ITEM_MODIFIER_LEFT && code.item_modifier() <= ITEM_MODIFIER_DOWN)
devcode = "";
devcode = std::string_view();
// concatenate the strings
std::string str(devclass);
if (!devindex.empty())
str.append(" ").append(devindex);
if (devcode[0] != 0)
if (!devcode.empty())
str.append(" ").append(devcode);
if (modifier != nullptr)
str.append(" ").append(modifier);
@ -830,6 +830,8 @@ std::string input_manager::code_name(input_code code) const
std::string input_manager::code_to_token(input_code code) const
{
using namespace std::literals;
// determine the devclass part
const char *devclass = (*devclass_token_table)[code.device_class()];
if (devclass == nullptr)
@ -842,14 +844,14 @@ std::string input_manager::code_to_token(input_code code) const
// determine the itemid part; look up in the table if we don't have a token
input_device_item *item = item_from_code(code);
const char *devcode = (item != nullptr) ? item->token() : "UNKNOWN";
std::string_view devcode = item ? item->token() : "UNKNOWN"sv;
// determine the modifier part
const char *modifier = (*modifier_token_table)[code.item_modifier()];
// determine the itemclass part; if we match the native class, we don't include this
const char *itemclass = "";
if (item == nullptr || item->itemclass() != code.item_class())
if (!item || (item->itemclass() != code.item_class()))
itemclass = (*itemclass_token_table)[code.item_class()];
// concatenate the strings
@ -994,14 +996,16 @@ bool input_manager::seq_pressed(const input_seq &seq)
bool first = true;
for (int codenum = 0; ; codenum++)
{
// handle NOT
input_code code = seq[codenum];
if (code == input_seq::not_code)
{
// handle NOT
invert = true;
// handle OR and END
}
else if (code == input_seq::or_code || code == input_seq::end_code)
{
// handle OR and END
// if we have a positive result from the previous set, we're done
if (result || code == input_seq::end_code)
break;
@ -1011,10 +1015,10 @@ bool input_manager::seq_pressed(const input_seq &seq)
invert = false;
first = true;
}
// handle everything else as a series of ANDs
else
{
// handle everything else as a series of ANDs
// if this is the first in the sequence, result is set equal
if (first)
result = code_pressed(code) ^ invert;
@ -1313,9 +1317,9 @@ void input_manager::seq_from_tokens(input_seq &seq, std::string_view string)
// controller based on device map table
//-------------------------------------------------
bool input_manager::map_device_to_controller(const devicemap_table_type &devicemap_table)
bool input_manager::map_device_to_controller(const devicemap_table &table)
{
for (const auto &it : devicemap_table)
for (const auto &it : table)
{
std::string_view deviceid = it.first;
std::string_view controllername = it.second;

View File

@ -350,9 +350,6 @@ DECLARE_ENUM_INCDEC_OPERATORS(input_item_id)
// TYPE DEFINITIONS
//**************************************************************************
// controller alias table typedef
typedef std::map<std::string, std::string> devicemap_table_type;
// ======================> input_code
// a combined code that describes a particular input on a particular device
@ -493,6 +490,9 @@ private:
class input_manager
{
public:
// controller alias table typedef
using devicemap_table = std::map<std::string, std::string>;
// construction/destruction
input_manager(running_machine &machine);
~input_manager();
@ -526,7 +526,7 @@ public:
void seq_from_tokens(input_seq &seq, std::string_view _token);
// misc
bool map_device_to_controller(const devicemap_table_type &devicemap_table);
bool map_device_to_controller(const devicemap_table &table);
private:
// internal helpers

View File

@ -15,6 +15,8 @@
#include "emuopts.h"
namespace {
//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
@ -26,7 +28,7 @@ class input_device_switch_item : public input_device_item
{
public:
// construction/destruction
input_device_switch_item(input_device &device, const char *name, void *internal, input_item_id itemid, item_get_state_func getstate);
input_device_switch_item(input_device &device, std::string_view name, void *internal, input_item_id itemid, item_get_state_func getstate);
// readers
virtual s32 read_as_switch(input_item_modifier modifier) override;
@ -52,7 +54,7 @@ class input_device_relative_item : public input_device_item
{
public:
// construction/destruction
input_device_relative_item(input_device &device, const char *name, void *internal, input_item_id itemid, item_get_state_func getstate);
input_device_relative_item(input_device &device, std::string_view name, void *internal, input_item_id itemid, item_get_state_func getstate);
// readers
virtual s32 read_as_switch(input_item_modifier modifier) override;
@ -69,7 +71,7 @@ class input_device_absolute_item : public input_device_item
{
public:
// construction/destruction
input_device_absolute_item(input_device &device, const char *name, void *internal, input_item_id itemid, item_get_state_func getstate);
input_device_absolute_item(input_device &device, std::string_view name, void *internal, input_item_id itemid, item_get_state_func getstate);
// readers
virtual s32 read_as_switch(input_item_modifier modifier) override;
@ -78,6 +80,8 @@ public:
virtual bool item_check_axis(input_item_modifier modifier, s32 memory) override;
};
} // anonymous namespace
//**************************************************************************
// GLOBAL VARIABLES
@ -253,7 +257,7 @@ u8 joystick_map::update(s32 xaxisval, s32 yaxisval)
// input_device - constructor
//-------------------------------------------------
input_device::input_device(input_manager &manager, const char *name, const char *id, void *internal)
input_device::input_device(input_manager &manager, std::string_view name, std::string_view id, void *internal)
: m_manager(manager),
m_name(name),
m_id(id),
@ -279,11 +283,10 @@ input_device::~input_device()
// add_item - add a new item to an input device
//-------------------------------------------------
input_item_id input_device::add_item(const char *name, input_item_id itemid, item_get_state_func getstate, void *internal)
input_item_id input_device::add_item(std::string_view name, input_item_id itemid, item_get_state_func getstate, void *internal)
{
if (machine().phase() != machine_phase::INIT)
throw emu_fatalerror("Can only call input_device::add_item at init time!");
assert(name != nullptr);
assert(itemid > ITEM_ID_INVALID && itemid < ITEM_ID_MAXIMUM);
assert(getstate != nullptr);
@ -346,7 +349,7 @@ bool input_device::match_device_id(std::string_view deviceid) const
// input_device_keyboard - constructor
//-------------------------------------------------
input_device_keyboard::input_device_keyboard(input_manager &manager, const char *_name, const char *_id, void *_internal)
input_device_keyboard::input_device_keyboard(input_manager &manager, std::string_view _name, std::string_view _id, void *_internal)
: input_device(manager, _name, _id, _internal)
{
}
@ -387,7 +390,7 @@ void input_device_keyboard::apply_steadykey() const
// input_device_mouse - constructor
//-------------------------------------------------
input_device_mouse::input_device_mouse(input_manager &manager, const char *_name, const char *_id, void *_internal)
input_device_mouse::input_device_mouse(input_manager &manager, std::string_view _name, std::string_view _id, void *_internal)
: input_device(manager, _name, _id, _internal)
{
}
@ -397,7 +400,7 @@ input_device_mouse::input_device_mouse(input_manager &manager, const char *_name
// input_device_lightgun - constructor
//-------------------------------------------------
input_device_lightgun::input_device_lightgun(input_manager &manager, const char *_name, const char *_id, void *_internal)
input_device_lightgun::input_device_lightgun(input_manager &manager, std::string_view _name, std::string_view _id, void *_internal)
: input_device(manager, _name, _id, _internal)
{
}
@ -407,7 +410,7 @@ input_device_lightgun::input_device_lightgun(input_manager &manager, const char
// input_device_joystick - constructor
//-------------------------------------------------
input_device_joystick::input_device_joystick(input_manager &manager, const char *_name, const char *_id, void *_internal)
input_device_joystick::input_device_joystick(input_manager &manager, std::string_view _name, std::string_view _id, void *_internal)
: input_device(manager, _name, _id, _internal),
m_joystick_deadzone(s32(manager.machine().options().joystick_deadzone() * INPUT_ABSOLUTE_MAX)),
m_joystick_saturation(s32(manager.machine().options().joystick_saturation() * INPUT_ABSOLUTE_MAX))
@ -494,18 +497,16 @@ input_class::~input_class()
// add_device - add a new input device
//-------------------------------------------------
input_device *input_class::add_device(const char *name, const char *id, void *internal)
input_device &input_class::add_device(std::string_view name, std::string_view id, void *internal)
{
if (machine().phase() != machine_phase::INIT)
throw emu_fatalerror("Can only call input_class::add_device at init time!");
assert(name != nullptr);
assert(id != nullptr);
// allocate a new device and add it to the index
return add_device(make_device(name, id, internal));
}
input_device *input_class::add_device(std::unique_ptr<input_device> &&new_device)
input_device &input_class::add_device(std::unique_ptr<input_device> &&new_device)
{
assert(new_device->devclass() == m_devclass);
@ -523,7 +524,7 @@ input_device *input_class::add_device(std::unique_ptr<input_device> &&new_device
osd_printf_verbose("Input: Adding %s #%d: %s (device id: %s)\n", m_name, devindex, new_device->name(), new_device->id());
m_device[devindex] = std::move(new_device);
return m_device[devindex].get();
return *m_device[devindex];
}
throw emu_fatalerror("Input: Too many %s devices\n", m_name);
@ -666,7 +667,7 @@ bool input_class_joystick::set_global_joystick_map(const char *mapstring)
// input_device_item - constructor
//-------------------------------------------------
input_device_item::input_device_item(input_device &device, const char *name, void *internal, input_item_id itemid, item_get_state_func getstate, input_item_class itemclass)
input_device_item::input_device_item(input_device &device, std::string_view name, void *internal, input_item_id itemid, item_get_state_func getstate, input_item_class itemclass)
: m_device(device),
m_name(name),
m_internal(internal),
@ -720,7 +721,7 @@ bool input_device_item::check_axis(input_item_modifier modifier, s32 memory)
// input_device_switch_item - constructor
//-------------------------------------------------
input_device_switch_item::input_device_switch_item(input_device &device, const char *name, void *internal, input_item_id itemid, item_get_state_func getstate)
input_device_switch_item::input_device_switch_item(input_device &device, std::string_view name, void *internal, input_item_id itemid, item_get_state_func getstate)
: input_device_item(device, name, internal, itemid, getstate, ITEM_CLASS_SWITCH),
m_steadykey(0),
m_oldkey(0)
@ -825,7 +826,7 @@ bool input_device_switch_item::steadykey_changed()
// input_device_relative_item - constructor
//-------------------------------------------------
input_device_relative_item::input_device_relative_item(input_device &device, const char *name, void *internal, input_item_id itemid, item_get_state_func getstate)
input_device_relative_item::input_device_relative_item(input_device &device, std::string_view name, void *internal, input_item_id itemid, item_get_state_func getstate)
: input_device_item(device, name, internal, itemid, getstate, ITEM_CLASS_RELATIVE)
{
}
@ -896,7 +897,7 @@ bool input_device_relative_item::item_check_axis(input_item_modifier modifier, s
// input_device_absolute_item - constructor
//-------------------------------------------------
input_device_absolute_item::input_device_absolute_item(input_device &device, const char *name, void *internal, input_item_id itemid, item_get_state_func getstate)
input_device_absolute_item::input_device_absolute_item(input_device &device, std::string_view name, void *internal, input_item_id itemid, item_get_state_func getstate)
: input_device_item(device, name, internal, itemid, getstate, ITEM_CLASS_ABSOLUTE)
{
}

View File

@ -87,10 +87,6 @@ private:
// a single item on an input device
class input_device_item
{
protected:
// construction/destruction
input_device_item(input_device &device, const char *name, void *internal, input_item_id itemid, item_get_state_func getstate, input_item_class itemclass);
public:
virtual ~input_device_item();
@ -98,12 +94,12 @@ public:
input_device &device() const { return m_device; }
input_manager &manager() const;
running_machine &machine() const;
const char *name() const { return m_name.c_str(); }
const std::string &name() const { return m_name; }
void *internal() const { return m_internal; }
input_item_id itemid() const { return m_itemid; }
input_item_class itemclass() const { return m_itemclass; }
input_code code() const;
const char *token() const { return m_token.c_str(); }
const std::string &token() const { return m_token; }
s32 current() const { return m_current; }
// helpers
@ -117,6 +113,9 @@ public:
virtual bool item_check_axis(input_item_modifier modifier, s32 memory) = 0;
protected:
// construction/destruction
input_device_item(input_device &device, std::string_view name, void *internal, input_item_id itemid, item_get_state_func getstate, input_item_class itemclass);
// internal state
input_device & m_device; // reference to our owning device
std::string m_name; // string name of item
@ -140,15 +139,15 @@ class input_device
public:
// construction/destruction
input_device(input_manager &manager, const char *_name, const char *_id, void *_internal);
input_device(input_manager &manager, std::string_view _name, std::string_view _id, void *_internal);
virtual ~input_device();
// getters
input_manager &manager() const { return m_manager; }
running_machine &machine() const { return m_manager.machine(); }
input_device_class devclass() const { return device_class(); }
const char *name() const { return m_name.c_str(); }
const char *id() const { return m_id.c_str(); }
const std::string &name() const { return m_name; }
const std::string &id() const { return m_id; }
int devindex() const { return m_devindex; }
input_device_item *item(input_item_id index) const { return m_item[index].get(); }
input_item_id maxitem() const { return m_maxitem; }
@ -160,7 +159,7 @@ public:
void set_devindex(int devindex) { m_devindex = devindex; }
// item management
input_item_id add_item(const char *name, input_item_id itemid, item_get_state_func getstate, void *internal = nullptr);
input_item_id add_item(std::string_view name, input_item_id itemid, item_get_state_func getstate, void *internal = nullptr);
// helpers
s32 adjust_absolute(s32 value) const { return adjust_absolute_value(value); }
@ -192,7 +191,7 @@ class input_device_keyboard : public input_device
{
public:
// construction/destruction
input_device_keyboard(input_manager &manager, const char *_name, const char *_id, void *_internal);
input_device_keyboard(input_manager &manager, std::string_view _name, std::string_view _id, void *_internal);
// helpers
void apply_steadykey() const;
@ -209,7 +208,7 @@ class input_device_mouse : public input_device
{
public:
// construction/destruction
input_device_mouse(input_manager &manager, const char *_name, const char *_id, void *_internal);
input_device_mouse(input_manager &manager, std::string_view _name, std::string_view _id, void *_internal);
protected:
// specific overrides
@ -223,7 +222,7 @@ class input_device_lightgun : public input_device
{
public:
// construction/destruction
input_device_lightgun(input_manager &manager, const char *_name, const char *_id, void *_internal);
input_device_lightgun(input_manager &manager, std::string_view _name, std::string_view _id, void *_internal);
protected:
// specific overrides
@ -238,7 +237,7 @@ class input_device_joystick : public input_device
{
public:
// construction/destruction
input_device_joystick(input_manager &manager, const char *_name, const char *_id, void *_internal);
input_device_joystick(input_manager &manager, std::string_view _name, std::string_view _id, void *_internal);
// getters
joystick_map &joymap() { return m_joymap; }
@ -284,8 +283,7 @@ public:
void set_multi(bool multi = true) { m_multi = multi; }
// device management
input_device *add_device(const char *name, const char *id, void *internal = nullptr);
input_device *add_device(std::unique_ptr<input_device> &&new_device);
input_device &add_device(std::string_view name, std::string_view id, void *internal = nullptr);
// misc helpers
input_item_class standard_item_class(input_item_id itemid) const;
@ -293,10 +291,11 @@ public:
protected:
// specific overrides
virtual std::unique_ptr<input_device> make_device(const char *name, const char *id, void *internal) = 0;
virtual std::unique_ptr<input_device> make_device(std::string_view name, std::string_view id, void *internal) = 0;
private:
// indexing helpers
// internal helpers
input_device &add_device(std::unique_ptr<input_device> &&new_device);
int newindex(input_device &device);
// internal state
@ -321,7 +320,7 @@ public:
protected:
// specific overrides
virtual std::unique_ptr<input_device> make_device(const char *name, const char *id, void *internal) override
virtual std::unique_ptr<input_device> make_device(std::string_view name, std::string_view id, void *internal) override
{
return std::make_unique<input_device_keyboard>(manager(), name, id, internal);
}
@ -343,7 +342,7 @@ public:
protected:
// specific overrides
virtual std::unique_ptr<input_device> make_device(const char *name, const char *id, void *internal) override
virtual std::unique_ptr<input_device> make_device(std::string_view name, std::string_view id, void *internal) override
{
return std::make_unique<input_device_mouse>(manager(), name, id, internal);
}
@ -361,7 +360,7 @@ public:
protected:
// specific overrides
virtual std::unique_ptr<input_device> make_device(const char *name, const char *id, void *internal) override
virtual std::unique_ptr<input_device> make_device(std::string_view name, std::string_view id, void *internal) override
{
return std::make_unique<input_device_lightgun>(manager(), name, id, internal);
}
@ -386,7 +385,7 @@ public:
protected:
// specific overrides
virtual std::unique_ptr<input_device> make_device(const char *name, const char *id, void *internal) override
virtual std::unique_ptr<input_device> make_device(std::string_view name, std::string_view id, void *internal) override
{
return std::make_unique<input_device_joystick>(manager(), name, id, internal);
}

View File

@ -2067,18 +2067,18 @@ void ioport_manager::load_config(config_type cfg_type, config_level cfg_level, u
// iterate over all the remap nodes
load_remap_table(*parentnode);
devicemap_table_type devicemap_table;
input_manager::devicemap_table devicemap;
for (util::xml::data_node const *mapdevice_node = parentnode->get_child("mapdevice"); mapdevice_node != nullptr; mapdevice_node = mapdevice_node->get_next_sibling("mapdevice"))
{
char const *const devicename = mapdevice_node->get_attribute_string("device", nullptr);
char const *const controllername = mapdevice_node->get_attribute_string("controller", nullptr);
if (devicename && controllername)
devicemap_table.emplace(devicename, controllername);
devicemap.emplace(devicename, controllername);
}
// map device to controller if we have a device map
if (!devicemap_table.empty())
machine().input().map_device_to_controller(devicemap_table);
if (!devicemap.empty())
machine().input().map_device_to_controller(devicemap);
}
// iterate over all the port nodes

View File

@ -8,21 +8,17 @@
//
//============================================================
#include "input_module.h"
#include "modules/lib/osdobj_common.h"
#include <memory>
// MAME headers
#include "emu.h"
#include "input_common.h"
// winnt.h defines this
#ifdef DELETE
#undef DELETE
#endif
#include "input_common.h"
//============================================================
// Keyboard translation table
//============================================================

View File

@ -7,20 +7,21 @@
// 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 <algorithm>
#include <chrono>
#include <functional>
#include <memory>
#include <mutex>
#include <queue>
#include <algorithm>
#include <functional>
//============================================================
@ -201,8 +202,8 @@ class device_info
friend input_device_list;
private:
std::string m_name;
std::string m_id;
const std::string m_name;
const std::string m_id;
input_device * m_device;
running_machine & m_machine;
input_module & m_module;
@ -210,9 +211,9 @@ private:
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),
device_info(running_machine &machine, std::string &&name, std::string &&id, input_device_class deviceclass, input_module &module) :
m_name(std::move(name)),
m_id(std::move(id)),
m_device(nullptr),
m_machine(machine),
m_module(module),
@ -221,18 +222,18 @@ public:
}
// Destructor
virtual ~device_info() {}
virtual ~device_info() { }
// 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(); }
const std::string & name() const { return m_name; }
const std::string & id() const { return m_id; }
input_device * device() const { return m_device; }
input_module & module() const { return m_module; }
input_device_class deviceclass() const { return m_deviceclass; }
// Poll and reset methods
virtual void poll() {};
virtual void poll() { }
virtual void reset() = 0;
};
@ -254,8 +255,8 @@ protected:
virtual void process_event(TEvent &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(running_machine &machine, std::string &&name, std::string &&id, input_device_class deviceclass, input_module &module)
: device_info(machine, std::move(name), std::move(id), deviceclass, module)
{
}
@ -310,10 +311,10 @@ public:
device->reset();
}
void free_device(device_info* devinfo)
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(); };
const 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());
}
@ -330,24 +331,22 @@ public:
}
template <typename TActual, typename... TArgs>
TActual* create_device(running_machine &machine, const char *name, const char *id, input_module &module, TArgs&&... args)
TActual &create_device(running_machine &machine, std::string &&name, std::string &&id, input_module &module, TArgs&&... args)
{
// allocate the device object
auto devinfo = std::make_unique<TActual>(machine, name, id, module, std::forward<TArgs>(args)...);
auto devinfo = std::make_unique<TActual>(machine, std::move(name), std::move(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)
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());
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());
return *static_cast<TActual *>(m_list.emplace_back(std::move(devinfo)).get());
}
};
@ -426,8 +425,8 @@ typedef std::chrono::time_point<std::chrono::high_resolution_clock> timepoint_ty
class input_module_base : public input_module
{
public:
input_module_base(const char *type, const char* name)
: input_module(type, name),
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),
@ -544,7 +543,7 @@ int generic_axis_get_state(void *device_internal, void *item_internal)
// default_button_name
//============================================================
inline static const char *default_button_name(int which)
inline const char *default_button_name(int which)
{
static char buffer[20];
snprintf(buffer, std::size(buffer), "B%d", which);
@ -555,7 +554,7 @@ inline static const char *default_button_name(int which)
// default_pov_name
//============================================================
inline static const char *default_pov_name(int which)
inline const char *default_pov_name(int which)
{
static char buffer[20];
snprintf(buffer, std::size(buffer), "POV%d", which);
@ -569,7 +568,7 @@ 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;
@ -577,19 +576,18 @@ inline static int32_t normalize_absolute_axis(double raw, double rawmin, double
if (rawmin >= rawmax)
return int32_t(raw);
// above center
if (raw >= center)
{
// above center
double result = (raw - center) * INPUT_ABSOLUTE_MAX / (rawmax - center);
return std::min(result, (double)INPUT_ABSOLUTE_MAX);
}
// below center
else
{
// below center
double result = -((center - raw) * (double)-INPUT_ABSOLUTE_MIN / (center - rawmin));
return std::max(result, (double)INPUT_ABSOLUTE_MIN);
}
}
#endif // INPUT_COMMON_H_
#endif // MAME_OSD_INPUT_INPUT_COMMON_H

View File

@ -38,17 +38,44 @@
using namespace Microsoft::WRL;
static int32_t dinput_joystick_pov_get_state(void *device_internal, void *item_internal);
namespace {
//============================================================
// dinput_joystick_pov_get_state
//============================================================
int32_t dinput_joystick_pov_get_state(void *device_internal, void *item_internal)
{
auto *devinfo = static_cast<dinput_joystick_device *>(device_internal);
int povnum = reinterpret_cast<uintptr_t>(item_internal) / 4;
int povdir = reinterpret_cast<uintptr_t>(item_internal) % 4;
int32_t result = 0;
// get the current state
devinfo->module().poll_if_necessary(devinfo->machine());
const DWORD pov = devinfo->joystick.state.rgdwPOV[povnum];
// if invalid, return 0
if ((pov & 0xffff) == 0xffff)
return result;
// return the current state
switch (povdir)
{
case POVDIR_LEFT: result = (pov >= 22500 && pov <= 31500); break;
case POVDIR_RIGHT: result = (pov >= 4500 && pov <= 13500); break;
case POVDIR_UP: result = (pov >= 31500 || pov <= 4500); break;
case POVDIR_DOWN: result = (pov >= 13500 && pov <= 22500); break;
}
return result;
}
//============================================================
// dinput_set_dword_property
//============================================================
#if DIRECTINPUT_VERSION >= 0x0800
static HRESULT dinput_set_dword_property(ComPtr<IDirectInputDevice8> device, REFGUID property_guid, DWORD object, DWORD how, DWORD value)
#else
static HRESULT dinput_set_dword_property(ComPtr<IDirectInputDevice> device, REFGUID property_guid, DWORD object, DWORD how, DWORD value)
#endif
HRESULT dinput_set_dword_property(ComPtr<IDirectInputDevice8> device, REFGUID property_guid, DWORD object, DWORD how, DWORD value)
{
DIPROPDWORD dipdw;
@ -61,144 +88,6 @@ static HRESULT dinput_set_dword_property(ComPtr<IDirectInputDevice> device, REFG
return device->SetProperty(property_guid, &dipdw.diph);
}
//============================================================
// dinput_device - base directinput device
//============================================================
dinput_device::dinput_device(running_machine &machine, const char *name, const char *id, input_device_class deviceclass, input_module &module)
: device_info(machine, name, id, deviceclass, module),
dinput({nullptr})
{
}
dinput_device::~dinput_device()
{
if (dinput.device != nullptr)
dinput.device.Reset();
}
HRESULT dinput_device::poll_dinput(LPVOID pState) const
{
HRESULT result;
// first poll the device, then get the state
#if DIRECTINPUT_VERSION >= 0x0800
dinput.device->Poll();
#else
if (dinput.device2 != nullptr)
dinput.device2->Poll();
#endif
// GetDeviceState returns the immediate state
result = dinput.device->GetDeviceState(dinput.format->dwDataSize, pState);
// handle lost inputs here
if (result == DIERR_INPUTLOST || result == DIERR_NOTACQUIRED)
{
result = dinput.device->Acquire();
if (result == DI_OK)
result = dinput.device->GetDeviceState(dinput.format->dwDataSize, pState);
}
return result;
}
//============================================================
// dinput_keyboard_device - directinput keyboard device
//============================================================
dinput_keyboard_device::dinput_keyboard_device(running_machine &machine, const char *name, const char *id, input_module &module)
: dinput_device(machine, name, id, DEVICE_CLASS_KEYBOARD, module),
keyboard({{0}})
{
}
// Polls the direct input immediate state
void dinput_keyboard_device::poll()
{
std::lock_guard<std::mutex> scope_lock(m_device_lock);
// Poll the state
dinput_device::poll_dinput(&keyboard.state);
}
void dinput_keyboard_device::reset()
{
memset(&keyboard.state, 0, sizeof(keyboard.state));
}
//============================================================
// dinput_api_helper - DirectInput API helper
//============================================================
dinput_api_helper::dinput_api_helper(int version)
: m_dinput(nullptr),
m_dinput_version(version),
m_dinput_create_prt(nullptr)
{
}
dinput_api_helper::~dinput_api_helper()
{
m_dinput.Reset();
}
int dinput_api_helper::initialize()
{
HRESULT result;
#if DIRECTINPUT_VERSION >= 0x0800
if (m_dinput_version >= 0x0800)
{
result = DirectInput8Create(GetModuleHandleUni(), m_dinput_version, IID_IDirectInput8, reinterpret_cast<void **>(m_dinput.GetAddressOf()), nullptr);
if (result != DI_OK)
{
m_dinput_version = 0;
return result;
}
}
else
#endif
{
m_dinput_dll = osd::dynamic_module::open({ "dinput.dll" });
m_dinput_create_prt = m_dinput_dll->bind<dinput_create_fn>("DirectInputCreateW");
if (m_dinput_create_prt == nullptr)
{
osd_printf_verbose("Legacy DirectInput library dinput.dll is not available\n");
return ERROR_DLL_NOT_FOUND;
}
// first attempt to initialize DirectInput at v7
m_dinput_version = 0x0700;
result = (*m_dinput_create_prt)(GetModuleHandleUni(), m_dinput_version, m_dinput.GetAddressOf(), nullptr);
if (result != DI_OK)
{
// if that fails, try version 5
m_dinput_version = 0x0500;
result = (*m_dinput_create_prt)(GetModuleHandleUni(), m_dinput_version, m_dinput.GetAddressOf(), nullptr);
if (result != DI_OK)
{
m_dinput_version = 0;
return result;
}
}
}
osd_printf_verbose("DirectInput: Using DirectInput %d\n", m_dinput_version >> 8);
return 0;
}
HRESULT dinput_api_helper::enum_attached_devices(int devclass, device_enum_interface *enumerate_interface, void *state) const
{
device_enum_interface::dinput_callback_context ctx;
ctx.self = enumerate_interface;
ctx.state = state;
return m_dinput->EnumDevices(devclass, device_enum_interface::enum_callback, &ctx, DIEDFL_ATTACHEDONLY);
}
//============================================================
// dinput_module - base directinput module
@ -218,7 +107,7 @@ public:
int init_internal() override
{
m_dinput_helper = std::make_unique<dinput_api_helper>(DIRECTINPUT_VERSION);
m_dinput_helper = std::make_unique<dinput_api_helper>();
int result = m_dinput_helper->initialize();
if (result != 0)
return result;
@ -236,7 +125,7 @@ public:
{
HRESULT result = m_dinput_helper->enum_attached_devices(dinput_devclass(), this, &machine);
if (result != DI_OK)
fatalerror("DirectInput: Unable to enumerate keyboards (result=%08X)\n", static_cast<uint32_t>(result));
fatalerror("DirectInput: Unable to enumerate devices (result=%08X)\n", uint32_t(result));
}
static std::string device_item_name(dinput_device * devinfo, int offset, const char * defstring, const TCHAR * suffix)
@ -286,11 +175,7 @@ public:
int dinput_devclass() override
{
#if DIRECTINPUT_VERSION >= 0x0800
return DI8DEVCLASS_KEYBOARD;
#else
return DIDEVTYPE_KEYBOARD;
#endif
}
BOOL device_enum_callback(LPCDIDEVICEINSTANCE instance, LPVOID ref) override
@ -316,7 +201,7 @@ public:
name = device_item_name(devinfo, keynum, defname, nullptr);
// add the item to the device
devinfo->device()->add_item(name.c_str(), itemid, generic_button_get_state<std::uint8_t>, &devinfo->keyboard.state[keynum]);
devinfo->device()->add_item(name, itemid, generic_button_get_state<std::uint8_t>, &devinfo->keyboard.state[keynum]);
}
exit:
@ -324,29 +209,6 @@ public:
}
};
dinput_mouse_device::dinput_mouse_device(running_machine &machine, const char *name, const char *id, input_module &module)
: dinput_device(machine, name, id, DEVICE_CLASS_MOUSE, module),
mouse({0})
{
}
void dinput_mouse_device::poll()
{
// poll
dinput_device::poll_dinput(&mouse);
// scale the axis data
mouse.lX *= INPUT_RELATIVE_PER_PIXEL;
mouse.lY *= INPUT_RELATIVE_PER_PIXEL;
mouse.lZ *= INPUT_RELATIVE_PER_PIXEL;
}
void dinput_mouse_device::reset()
{
memset(&mouse, 0, sizeof(mouse));
}
class mouse_input_dinput : public dinput_module
{
public:
@ -357,11 +219,7 @@ public:
int dinput_devclass() override
{
#if DIRECTINPUT_VERSION >= 0x0800
return DI8DEVCLASS_POINTER;
#else
return DIDEVTYPE_MOUSE;
#endif
}
BOOL device_enum_callback(LPCDIDEVICEINSTANCE instance, LPVOID ref) override
@ -373,7 +231,7 @@ public:
// allocate and link in a new device
devinfo = m_dinput_helper->create_device<dinput_mouse_device>(machine, *this, instance, &c_dfDIMouse2, &c_dfDIMouse, dinput_cooperative_level::FOREGROUND);
if (devinfo == nullptr)
if (!devinfo)
goto exit;
// set relative mode on the mouse device
@ -394,7 +252,7 @@ public:
// add to the mouse device and optionally to the gun device as well
std::string name = device_item_name(devinfo, offsetof(DIMOUSESTATE, lX) + axisnum * sizeof(LONG), default_axis_name[axisnum], nullptr);
devinfo->device()->add_item(
name.c_str(),
name,
static_cast<input_item_id>(ITEM_ID_XAXIS + axisnum),
generic_axis_get_state<LONG>,
&devinfo->mouse.lX + axisnum);
@ -408,7 +266,7 @@ public:
// add to the mouse device
std::string name = device_item_name(devinfo, offset, default_button_name(butnum), nullptr);
devinfo->device()->add_item(
name.c_str(),
name,
static_cast<input_item_id>(ITEM_ID_BUTTON1 + butnum),
generic_button_get_state<BYTE>,
&devinfo->mouse.rgbButtons[butnum]);
@ -418,140 +276,12 @@ public:
return DIENUM_CONTINUE;
error:
if (devinfo != nullptr)
devicelist()->free_device(devinfo);
if (devinfo)
devicelist()->free_device(*devinfo);
goto exit;
}
};
dinput_joystick_device::dinput_joystick_device(running_machine &machine, const char *name, const char *id, input_module &module)
: dinput_device(machine, name, id, DEVICE_CLASS_JOYSTICK, module),
joystick({{0}})
{
}
void dinput_joystick_device::reset()
{
memset(&joystick.state, 0, sizeof(joystick.state));
}
void dinput_joystick_device::poll()
{
int axisnum;
// poll the device first
if (dinput_device::poll_dinput(&joystick.state) != ERROR_SUCCESS)
return;
// normalize axis values
for (axisnum = 0; axisnum < 8; axisnum++)
{
LONG *axis = (&joystick.state.lX) + axisnum;
*axis = normalize_absolute_axis(*axis, joystick.rangemin[axisnum], joystick.rangemax[axisnum]);
}
}
int dinput_joystick_device::configure()
{
HRESULT result;
uint32_t axisnum, axiscount;
auto devicelist = static_cast<input_module_base&>(module()).devicelist();
// temporary approximation of index
int devindex = devicelist->size();
// set absolute mode
result = dinput_set_dword_property(dinput.device, DIPROP_AXISMODE, 0, DIPH_DEVICE, DIPROPAXISMODE_ABS);
if (result != DI_OK && result != DI_PROPNOEFFECT)
osd_printf_warning("DirectInput: Unable to set absolute mode for joystick %d (%s)\n", devindex, name());
// turn off deadzone; we do our own calculations
result = dinput_set_dword_property(dinput.device, DIPROP_DEADZONE, 0, DIPH_DEVICE, 0);
if (result != DI_OK && result != DI_PROPNOEFFECT)
osd_printf_warning("DirectInput: Unable to reset deadzone for joystick %d (%s)\n", devindex, name());
// turn off saturation; we do our own calculations
result = dinput_set_dword_property(dinput.device, DIPROP_SATURATION, 0, DIPH_DEVICE, 10000);
if (result != DI_OK && result != DI_PROPNOEFFECT)
osd_printf_warning("DirectInput: Unable to reset saturation for joystick %d (%s)\n", devindex, name());
// cap the number of axes, POVs, and buttons based on the format
dinput.caps.dwAxes = std::min(dinput.caps.dwAxes, DWORD(8));
dinput.caps.dwPOVs = std::min(dinput.caps.dwPOVs, DWORD(4));
dinput.caps.dwButtons = std::min(dinput.caps.dwButtons, DWORD(128));
// populate the axes
for (axisnum = axiscount = 0; axiscount < dinput.caps.dwAxes && axisnum < 8; axisnum++)
{
DIPROPRANGE dipr;
std::string name;
// fetch the range of this axis
dipr.diph.dwSize = sizeof(dipr);
dipr.diph.dwHeaderSize = sizeof(dipr.diph);
dipr.diph.dwObj = offsetof(DIJOYSTATE2, lX) + axisnum * sizeof(LONG);
dipr.diph.dwHow = DIPH_BYOFFSET;
result = dinput.device->GetProperty(DIPROP_RANGE, &dipr.diph);
if (result != DI_OK)
continue;
joystick.rangemin[axisnum] = dipr.lMin;
joystick.rangemax[axisnum] = dipr.lMax;
// populate the item description as well
name = dinput_module::device_item_name(this, offsetof(DIJOYSTATE2, lX) + axisnum * sizeof(LONG), default_axis_name[axisnum], nullptr);
device()->add_item(
name.c_str(),
static_cast<input_item_id>(ITEM_ID_XAXIS + axisnum),
generic_axis_get_state<LONG>,
&joystick.state.lX + axisnum);
axiscount++;
}
// populate the POVs
for (uint32_t povnum = 0; povnum < dinput.caps.dwPOVs; povnum++)
{
std::string name;
// left
name = dinput_module::device_item_name(this, offsetof(DIJOYSTATE2, rgdwPOV) + povnum * sizeof(DWORD), default_pov_name(povnum), TEXT("L"));
device()->add_item(name.c_str(), ITEM_ID_OTHER_SWITCH, dinput_joystick_pov_get_state, reinterpret_cast<void *>(static_cast<uintptr_t>(povnum * 4 + POVDIR_LEFT)));
// right
name = dinput_module::device_item_name(this, offsetof(DIJOYSTATE2, rgdwPOV) + povnum * sizeof(DWORD), default_pov_name(povnum), TEXT("R"));
device()->add_item(name.c_str(), ITEM_ID_OTHER_SWITCH, dinput_joystick_pov_get_state, reinterpret_cast<void *>(static_cast<uintptr_t>(povnum * 4 + POVDIR_RIGHT)));
// up
name = dinput_module::device_item_name(this, offsetof(DIJOYSTATE2, rgdwPOV) + povnum * sizeof(DWORD), default_pov_name(povnum), TEXT("U"));
device()->add_item(name.c_str(), ITEM_ID_OTHER_SWITCH, dinput_joystick_pov_get_state, reinterpret_cast<void *>(static_cast<uintptr_t>(povnum * 4 + POVDIR_UP)));
// down
name = dinput_module::device_item_name(this, offsetof(DIJOYSTATE2, rgdwPOV) + povnum * sizeof(DWORD), default_pov_name(povnum), TEXT("D"));
device()->add_item(name.c_str(), ITEM_ID_OTHER_SWITCH, dinput_joystick_pov_get_state, reinterpret_cast<void *>(static_cast<uintptr_t>(povnum * 4 + POVDIR_DOWN)));
}
// populate the buttons
for (uint32_t butnum = 0; butnum < dinput.caps.dwButtons; butnum++)
{
auto offset = reinterpret_cast<uintptr_t>(&static_cast<DIJOYSTATE2 *>(nullptr)->rgbButtons[butnum]);
std::string name = dinput_module::device_item_name(this, offset, default_button_name(butnum), nullptr);
input_item_id itemid;
if (butnum < INPUT_MAX_BUTTONS)
itemid = static_cast<input_item_id>(ITEM_ID_BUTTON1 + butnum);
else if (butnum < INPUT_MAX_BUTTONS + INPUT_MAX_ADD_SWITCH)
itemid = static_cast<input_item_id>(ITEM_ID_ADD_SWITCH1 - INPUT_MAX_BUTTONS + butnum);
else
itemid = ITEM_ID_OTHER_SWITCH;
device()->add_item(name.c_str(), itemid, generic_button_get_state<BYTE>, &joystick.state.rgbButtons[butnum]);
}
return 0;
}
class joystick_input_dinput : public dinput_module
{
@ -563,11 +293,7 @@ public:
int dinput_devclass() override
{
#if DIRECTINPUT_VERSION >= 0x0800
return DI8DEVCLASS_GAMECTRL;
#else
return DIDEVTYPE_JOYSTICK;
#endif
}
BOOL device_enum_callback(LPCDIDEVICEINSTANCE instance, LPVOID ref) override
@ -596,42 +322,273 @@ public:
}
};
} // anonymous namespace
//============================================================
// dinput_joystick_pov_get_state
// dinput_device - base directinput device
//============================================================
static int32_t dinput_joystick_pov_get_state(void *device_internal, void *item_internal)
dinput_device::dinput_device(running_machine &machine, std::string &&name, std::string &&id, input_device_class deviceclass, input_module &module)
: device_info(machine, std::move(name), std::move(id), deviceclass, module),
dinput({nullptr})
{
auto *devinfo = static_cast<dinput_joystick_device *>(device_internal);
int povnum = reinterpret_cast<uintptr_t>(item_internal) / 4;
int povdir = reinterpret_cast<uintptr_t>(item_internal) % 4;
int32_t result = 0;
DWORD pov;
}
// get the current state
devinfo->module().poll_if_necessary(devinfo->machine());
pov = devinfo->joystick.state.rgdwPOV[povnum];
dinput_device::~dinput_device()
{
if (dinput.device)
dinput.device.Reset();
}
// if invalid, return 0
if ((pov & 0xffff) == 0xffff)
return result;
HRESULT dinput_device::poll_dinput(LPVOID pState) const
{
HRESULT result;
// return the current state
switch (povdir)
// first poll the device, then get the state
dinput.device->Poll();
// GetDeviceState returns the immediate state
result = dinput.device->GetDeviceState(dinput.format->dwDataSize, pState);
// handle lost inputs here
if (result == DIERR_INPUTLOST || result == DIERR_NOTACQUIRED)
{
case POVDIR_LEFT: result = (pov >= 22500 && pov <= 31500); break;
case POVDIR_RIGHT: result = (pov >= 4500 && pov <= 13500); break;
case POVDIR_UP: result = (pov >= 31500 || pov <= 4500); break;
case POVDIR_DOWN: result = (pov >= 13500 && pov <= 22500); break;
result = dinput.device->Acquire();
if (result == DI_OK)
result = dinput.device->GetDeviceState(dinput.format->dwDataSize, pState);
}
return result;
}
#else
//============================================================
// dinput_keyboard_device - directinput keyboard device
//============================================================
dinput_keyboard_device::dinput_keyboard_device(running_machine &machine, std::string &&name, std::string &&id, input_module &module)
: dinput_device(machine, std::move(name), std::move(id), DEVICE_CLASS_KEYBOARD, module),
keyboard({{0}})
{
}
// Polls the direct input immediate state
void dinput_keyboard_device::poll()
{
std::lock_guard<std::mutex> scope_lock(m_device_lock);
// Poll the state
dinput_device::poll_dinput(&keyboard.state);
}
void dinput_keyboard_device::reset()
{
memset(&keyboard.state, 0, sizeof(keyboard.state));
}
//============================================================
// dinput_mouse_device - directinput mouse device
//============================================================
dinput_mouse_device::dinput_mouse_device(running_machine &machine, std::string &&name, std::string &&id, input_module &module)
: dinput_device(machine, std::move(name), std::move(id), DEVICE_CLASS_MOUSE, module),
mouse({0})
{
}
void dinput_mouse_device::poll()
{
// poll
dinput_device::poll_dinput(&mouse);
// scale the axis data
mouse.lX *= INPUT_RELATIVE_PER_PIXEL;
mouse.lY *= INPUT_RELATIVE_PER_PIXEL;
mouse.lZ *= INPUT_RELATIVE_PER_PIXEL;
}
void dinput_mouse_device::reset()
{
memset(&mouse, 0, sizeof(mouse));
}
//============================================================
// dinput_joystick_device - directinput joystick device
//============================================================
dinput_joystick_device::dinput_joystick_device(running_machine &machine, std::string &&name, std::string &&id, input_module &module)
: dinput_device(machine, std::move(name), std::move(id), DEVICE_CLASS_JOYSTICK, module),
joystick({{0}})
{
}
void dinput_joystick_device::reset()
{
memset(&joystick.state, 0, sizeof(joystick.state));
}
void dinput_joystick_device::poll()
{
int axisnum;
// poll the device first
if (dinput_device::poll_dinput(&joystick.state) != ERROR_SUCCESS)
return;
// normalize axis values
for (axisnum = 0; axisnum < 8; axisnum++)
{
LONG *axis = (&joystick.state.lX) + axisnum;
*axis = normalize_absolute_axis(*axis, joystick.rangemin[axisnum], joystick.rangemax[axisnum]);
}
}
int dinput_joystick_device::configure()
{
HRESULT result;
auto devicelist = static_cast<input_module_base&>(module()).devicelist();
// temporary approximation of index
int devindex = devicelist->size();
// set absolute mode
result = dinput_set_dword_property(dinput.device, DIPROP_AXISMODE, 0, DIPH_DEVICE, DIPROPAXISMODE_ABS);
if (result != DI_OK && result != DI_PROPNOEFFECT)
osd_printf_warning("DirectInput: Unable to set absolute mode for joystick %d (%s)\n", devindex, name());
// turn off deadzone; we do our own calculations
result = dinput_set_dword_property(dinput.device, DIPROP_DEADZONE, 0, DIPH_DEVICE, 0);
if (result != DI_OK && result != DI_PROPNOEFFECT)
osd_printf_warning("DirectInput: Unable to reset deadzone for joystick %d (%s)\n", devindex, name());
// turn off saturation; we do our own calculations
result = dinput_set_dword_property(dinput.device, DIPROP_SATURATION, 0, DIPH_DEVICE, 10000);
if (result != DI_OK && result != DI_PROPNOEFFECT)
osd_printf_warning("DirectInput: Unable to reset saturation for joystick %d (%s)\n", devindex, name());
// cap the number of axes, POVs, and buttons based on the format
dinput.caps.dwAxes = std::min(dinput.caps.dwAxes, DWORD(8));
dinput.caps.dwPOVs = std::min(dinput.caps.dwPOVs, DWORD(4));
dinput.caps.dwButtons = std::min(dinput.caps.dwButtons, DWORD(128));
// populate the axes
for (uint32_t axisnum = 0, axiscount = 0; axiscount < dinput.caps.dwAxes && axisnum < 8; axisnum++)
{
// fetch the range of this axis
DIPROPRANGE dipr;
dipr.diph.dwSize = sizeof(dipr);
dipr.diph.dwHeaderSize = sizeof(dipr.diph);
dipr.diph.dwObj = offsetof(DIJOYSTATE2, lX) + axisnum * sizeof(LONG);
dipr.diph.dwHow = DIPH_BYOFFSET;
result = dinput.device->GetProperty(DIPROP_RANGE, &dipr.diph);
if (result != DI_OK)
continue;
joystick.rangemin[axisnum] = dipr.lMin;
joystick.rangemax[axisnum] = dipr.lMax;
// populate the item description as well
std::string name = dinput_module::device_item_name(this, offsetof(DIJOYSTATE2, lX) + axisnum * sizeof(LONG), default_axis_name[axisnum], nullptr);
device()->add_item(
name,
static_cast<input_item_id>(ITEM_ID_XAXIS + axisnum),
generic_axis_get_state<LONG>,
&joystick.state.lX + axisnum);
axiscount++;
}
// populate the POVs
for (uint32_t povnum = 0; povnum < dinput.caps.dwPOVs; povnum++)
{
std::string name;
// left
name = dinput_module::device_item_name(this, offsetof(DIJOYSTATE2, rgdwPOV) + povnum * sizeof(DWORD), default_pov_name(povnum), TEXT("L"));
device()->add_item(name, ITEM_ID_OTHER_SWITCH, dinput_joystick_pov_get_state, reinterpret_cast<void *>(static_cast<uintptr_t>(povnum * 4 + POVDIR_LEFT)));
// right
name = dinput_module::device_item_name(this, offsetof(DIJOYSTATE2, rgdwPOV) + povnum * sizeof(DWORD), default_pov_name(povnum), TEXT("R"));
device()->add_item(name, ITEM_ID_OTHER_SWITCH, dinput_joystick_pov_get_state, reinterpret_cast<void *>(static_cast<uintptr_t>(povnum * 4 + POVDIR_RIGHT)));
// up
name = dinput_module::device_item_name(this, offsetof(DIJOYSTATE2, rgdwPOV) + povnum * sizeof(DWORD), default_pov_name(povnum), TEXT("U"));
device()->add_item(name, ITEM_ID_OTHER_SWITCH, dinput_joystick_pov_get_state, reinterpret_cast<void *>(static_cast<uintptr_t>(povnum * 4 + POVDIR_UP)));
// down
name = dinput_module::device_item_name(this, offsetof(DIJOYSTATE2, rgdwPOV) + povnum * sizeof(DWORD), default_pov_name(povnum), TEXT("D"));
device()->add_item(name, ITEM_ID_OTHER_SWITCH, dinput_joystick_pov_get_state, reinterpret_cast<void *>(static_cast<uintptr_t>(povnum * 4 + POVDIR_DOWN)));
}
// populate the buttons
for (uint32_t butnum = 0; butnum < dinput.caps.dwButtons; butnum++)
{
auto offset = reinterpret_cast<uintptr_t>(&static_cast<DIJOYSTATE2 *>(nullptr)->rgbButtons[butnum]);
std::string name = dinput_module::device_item_name(this, offset, default_button_name(butnum), nullptr);
input_item_id itemid;
if (butnum < INPUT_MAX_BUTTONS)
itemid = static_cast<input_item_id>(ITEM_ID_BUTTON1 + butnum);
else if (butnum < INPUT_MAX_BUTTONS + INPUT_MAX_ADD_SWITCH)
itemid = static_cast<input_item_id>(ITEM_ID_ADD_SWITCH1 - INPUT_MAX_BUTTONS + butnum);
else
itemid = ITEM_ID_OTHER_SWITCH;
device()->add_item(name, itemid, generic_button_get_state<BYTE>, &joystick.state.rgbButtons[butnum]);
}
return 0;
}
//============================================================
// dinput_api_helper - DirectInput API helper
//============================================================
dinput_api_helper::dinput_api_helper()
: m_dinput(nullptr),
m_dinput_create_prt(nullptr)
{
}
dinput_api_helper::~dinput_api_helper()
{
m_dinput.Reset();
}
int dinput_api_helper::initialize()
{
HRESULT result = DirectInput8Create(GetModuleHandleUni(), DIRECTINPUT_VERSION, IID_IDirectInput8, reinterpret_cast<void **>(m_dinput.GetAddressOf()), nullptr);
if (result != DI_OK)
{
return result;
}
osd_printf_verbose("DirectInput: Using DirectInput %d\n", DIRECTINPUT_VERSION >> 8);
return 0;
}
HRESULT dinput_api_helper::enum_attached_devices(int devclass, device_enum_interface *enumerate_interface, void *state) const
{
device_enum_interface::dinput_callback_context ctx;
ctx.self = enumerate_interface;
ctx.state = state;
return m_dinput->EnumDevices(devclass, device_enum_interface::enum_callback, &ctx, DIEDFL_ATTACHEDONLY);
}
#else // defined(OSD_WINDOWS)
MODULE_NOT_SUPPORTED(keyboard_input_dinput, OSD_KEYBOARDINPUT_PROVIDER, "dinput")
MODULE_NOT_SUPPORTED(mouse_input_dinput, OSD_MOUSEINPUT_PROVIDER, "dinput")
MODULE_NOT_SUPPORTED(joystick_input_dinput, OSD_JOYSTICKINPUT_PROVIDER, "dinput")
#endif
#endif // defined(OSD_WINDOWS)
MODULE_DEFINITION(KEYBOARDINPUT_DINPUT, keyboard_input_dinput)
MODULE_DEFINITION(MOUSEINPUT_DINPUT, mouse_input_dinput)

View File

@ -1,5 +1,7 @@
#ifndef INPUT_DINPUT_H_
#define INPUT_DINPUT_H_
#ifndef MAME_OSD_INPUT_INPUT_DINPUT_H
#define MAME_OSD_INPUT_INPUT_DINPUT_H
#pragma once
#include "input_common.h"
#include "modules/lib/osdlib.h"
@ -8,19 +10,6 @@
// dinput_device - base directinput device
//============================================================
// DirectInput-specific information about a device
struct dinput_api_state
{
#if DIRECTINPUT_VERSION >= 0x0800
Microsoft::WRL::ComPtr<IDirectInputDevice8> device;
#else
Microsoft::WRL::ComPtr<IDirectInputDevice> device;
Microsoft::WRL::ComPtr<IDirectInputDevice2> device2;
#endif
DIDEVCAPS caps;
LPCDIDATAFORMAT format;
};
class device_enum_interface
{
public:
@ -44,11 +33,7 @@ public:
};
// Typedef for dynamically loaded function
#if DIRECTINPUT_VERSION >= 0x0800
typedef HRESULT (WINAPI *dinput_create_fn)(HINSTANCE, DWORD, LPDIRECTINPUT8 *, LPUNKNOWN);
#else
typedef HRESULT (WINAPI *dinput_create_fn)(HINSTANCE, DWORD, LPDIRECTINPUT *, LPUNKNOWN);
#endif
enum class dinput_cooperative_level
{
@ -59,17 +44,12 @@ enum class dinput_cooperative_level
class dinput_api_helper
{
private:
#if DIRECTINPUT_VERSION >= 0x0800
Microsoft::WRL::ComPtr<IDirectInput8> m_dinput;
#else
Microsoft::WRL::ComPtr<IDirectInput> m_dinput;
#endif
int m_dinput_version;
osd::dynamic_module::ptr m_dinput_dll;
dinput_create_fn m_dinput_create_prt;
public:
dinput_api_helper(int version);
dinput_api_helper();
virtual ~dinput_api_helper();
int initialize();
@ -93,36 +73,29 @@ public:
std::string utf8_instance_id = utf8_instance_name + " product_" + guid_to_string(instance->guidProduct) + " instance_" + guid_to_string(instance->guidInstance);
// allocate memory for the device object
TDevice* devinfo = module.devicelist()->create_device<TDevice>(machine, utf8_instance_name.c_str(), utf8_instance_id.c_str(), module);
TDevice &devinfo = module.devicelist()->create_device<TDevice>(machine, std::move(utf8_instance_name), std::move(utf8_instance_id), module);
// attempt to create a device
result = m_dinput->CreateDevice(instance->guidInstance, devinfo->dinput.device.GetAddressOf(), nullptr);
result = m_dinput->CreateDevice(instance->guidInstance, devinfo.dinput.device.GetAddressOf(), nullptr);
if (result != DI_OK)
goto error;
#if DIRECTINPUT_VERSION < 0x0800
// try to get a version 2 device for it so we can use the poll method
result = devinfo->dinput.device.CopyTo(IID_IDirectInputDevice2, reinterpret_cast<void**>(devinfo->dinput.device2.GetAddressOf()));
if (result != DI_OK)
devinfo->dinput.device2 = nullptr;
#endif
// get the caps
devinfo->dinput.caps.dwSize = sizeof(devinfo->dinput.caps);
result = devinfo->dinput.device->GetCapabilities(&devinfo->dinput.caps);
devinfo.dinput.caps.dwSize = sizeof(devinfo.dinput.caps);
result = devinfo.dinput.device->GetCapabilities(&devinfo.dinput.caps);
if (result != DI_OK)
goto error;
// attempt to set the data format
devinfo->dinput.format = format1;
result = devinfo->dinput.device->SetDataFormat(devinfo->dinput.format);
devinfo.dinput.format = format1;
result = devinfo.dinput.device->SetDataFormat(devinfo.dinput.format);
if (result != DI_OK)
{
// use the secondary format if available
if (format2 != nullptr)
if (format2)
{
devinfo->dinput.format = format2;
result = devinfo->dinput.device->SetDataFormat(devinfo->dinput.format);
devinfo.dinput.format = format2;
result = devinfo.dinput.device->SetDataFormat(devinfo.dinput.format);
}
if (result != DI_OK)
goto error;
@ -154,11 +127,11 @@ public:
}
// set the cooperative level
result = devinfo->dinput.device->SetCooperativeLevel(hwnd, di_cooperative_level);
result = devinfo.dinput.device->SetCooperativeLevel(hwnd, di_cooperative_level);
if (result != DI_OK)
goto error;
return devinfo;
return &devinfo;
error:
module.devicelist()->free_device(devinfo);
@ -187,9 +160,17 @@ public:
class dinput_device : public device_info
{
public:
// DirectInput-specific information about a device
struct dinput_api_state
{
Microsoft::WRL::ComPtr<IDirectInputDevice8> device;
DIDEVCAPS caps;
LPCDIDATAFORMAT format;
};
dinput_api_state dinput;
dinput_device(running_machine &machine, const char *name, const char *id, input_device_class deviceclass, input_module &module);
dinput_device(running_machine &machine, std::string &&name, std::string &&id, input_device_class deviceclass, input_module &module);
virtual ~dinput_device();
protected:
@ -204,7 +185,7 @@ private:
public:
keyboard_state keyboard;
dinput_keyboard_device(running_machine &machine, const char *name, const char *id, input_module &module);
dinput_keyboard_device(running_machine &machine, std::string &&name, std::string &&id, input_module &module);
void poll() override;
void reset() override;
@ -216,7 +197,7 @@ public:
mouse_state mouse;
public:
dinput_mouse_device(running_machine &machine, const char *name, const char *id, input_module &module);
dinput_mouse_device(running_machine &machine, std::string &&name, std::string &&id, input_module &module);
void poll() override;
void reset() override;
};
@ -234,11 +215,10 @@ class dinput_joystick_device : public dinput_device
public:
dinput_joystick_state joystick;
public:
dinput_joystick_device(running_machine &machine, const char *name, const char *id, input_module &module);
dinput_joystick_device(running_machine &machine, std::string &&name, std::string &&id, input_module &module);
void reset() override;
void poll() override;
int configure();
};
#endif
#endif // MAME_OSD_INPUT_INPUT_DINPUT_H

View File

@ -5,9 +5,10 @@
// input_module.h - OSD input module contracts
//
//============================================================
#ifndef MAME_OSD_INPUT_INPUT_MODULE_H
#define MAME_OSD_INPUT_INPUT_MODULE_H
#ifndef INPUT_MODULE_H_
#define INPUT_MODULE_H_
#pragma once
#include "osdepend.h"
@ -39,4 +40,4 @@ public:
#define OSD_LIGHTGUNINPUT_PROVIDER "lightgunprovider"
#define OSD_JOYSTICKINPUT_PROVIDER "joystickprovider"
#endif /* INPUT_MODULE_H_ */
#endif // MAME_OSD_INPUT_INPUT_MODULE_H

View File

@ -12,13 +12,12 @@
class keyboard_input_none : public input_module
{
public:
keyboard_input_none()
: input_module(OSD_KEYBOARDINPUT_PROVIDER, "none") {}
keyboard_input_none() : input_module(OSD_KEYBOARDINPUT_PROVIDER, "none") { }
int init(const osd_options &options) override { return 0; }
void poll_if_necessary(running_machine &machine) override {};
void input_init(running_machine &machine) override {};
void pause() override {};
void resume() override {};
void poll_if_necessary(running_machine &machine) override { }
void input_init(running_machine &machine) override { }
void pause() override { }
void resume() override { }
};
MODULE_DEFINITION(KEYBOARD_NONE, keyboard_input_none)
@ -26,13 +25,12 @@ MODULE_DEFINITION(KEYBOARD_NONE, keyboard_input_none)
class mouse_input_none : public input_module
{
public:
mouse_input_none()
: input_module(OSD_MOUSEINPUT_PROVIDER, "none") {}
mouse_input_none() : input_module(OSD_MOUSEINPUT_PROVIDER, "none") { }
int init(const osd_options &options) override { return 0; }
void input_init(running_machine &machine) override {};
void poll_if_necessary(running_machine &machine) override {};
void pause() override {};
void resume() override {};
void input_init(running_machine &machine) override { }
void poll_if_necessary(running_machine &machine) override { }
void pause() override { }
void resume() override { }
};
MODULE_DEFINITION(MOUSE_NONE, mouse_input_none)
@ -40,13 +38,12 @@ MODULE_DEFINITION(MOUSE_NONE, mouse_input_none)
class lightgun_input_none : public input_module
{
public:
lightgun_input_none()
: input_module(OSD_LIGHTGUNINPUT_PROVIDER, "none") {}
lightgun_input_none() : input_module(OSD_LIGHTGUNINPUT_PROVIDER, "none") { }
int init(const osd_options &options) override { return 0; }
void input_init(running_machine &machine) override {};
void poll_if_necessary(running_machine &machine) override {};
void pause() override {};
void resume() override {};
void input_init(running_machine &machine) override { }
void poll_if_necessary(running_machine &machine) override { }
void pause() override { }
void resume() override { }
};
MODULE_DEFINITION(LIGHTGUN_NONE, lightgun_input_none)
@ -54,13 +51,12 @@ MODULE_DEFINITION(LIGHTGUN_NONE, lightgun_input_none)
class joystick_input_none : public input_module
{
public:
joystick_input_none()
: input_module(OSD_JOYSTICKINPUT_PROVIDER, "none") {}
joystick_input_none() : input_module(OSD_JOYSTICKINPUT_PROVIDER, "none") { }
int init(const osd_options &options) override { return 0; }
void input_init(running_machine &machine) override {};
void poll_if_necessary(running_machine &machine) override {};
void pause() override {};
void resume() override {};
void input_init(running_machine &machine) override { }
void poll_if_necessary(running_machine &machine) override { }
void pause() override { }
void resume() override { }
};
MODULE_DEFINITION(JOYSTICK_NONE, joystick_input_none)

View File

@ -16,9 +16,9 @@
#include <tchar.h>
#undef interface
#include <mutex>
#include <functional>
#include <algorithm>
#include <functional>
#include <mutex>
// MAME headers
#include "emu.h"
@ -274,8 +274,8 @@ private:
HANDLE m_handle = nullptr;
public:
rawinput_device(running_machine &machine, const char *name, const char *id, input_device_class deviceclass, input_module &module) :
event_based_device(machine, name, id, deviceclass, module)
rawinput_device(running_machine &machine, std::string &&name, std::string &&id, input_device_class deviceclass, input_module &module) :
event_based_device(machine, std::move(name), std::move(id), deviceclass, module)
{
}
@ -292,8 +292,8 @@ class rawinput_keyboard_device : public rawinput_device
public:
keyboard_state keyboard;
rawinput_keyboard_device(running_machine &machine, const char *name, const char *id, input_module &module) :
rawinput_device(machine, name, id, DEVICE_CLASS_KEYBOARD, module),
rawinput_keyboard_device(running_machine &machine, std::string &&name, std::string &&id, input_module &module) :
rawinput_device(machine, std::move(name), std::move(id), DEVICE_CLASS_KEYBOARD, module),
keyboard({{0}})
{
}
@ -328,8 +328,8 @@ private:
public:
mouse_state mouse;
rawinput_mouse_device(running_machine &machine, const char *name, const char *id, input_module &module) :
rawinput_device(machine, name, id, DEVICE_CLASS_MOUSE, module),
rawinput_mouse_device(running_machine &machine, std::string &&name, std::string &&id, input_module &module) :
rawinput_device(machine, std::move(name), std::move(id), DEVICE_CLASS_MOUSE, module),
mouse({0})
{
}
@ -388,8 +388,8 @@ private:
public:
mouse_state lightgun;
rawinput_lightgun_device(running_machine &machine, const char *name, const char *id, input_module &module) :
rawinput_device(machine, name, id, DEVICE_CLASS_LIGHTGUN, module),
rawinput_lightgun_device(running_machine &machine, std::string &&name, std::string &&id, input_module &module) :
rawinput_device(machine, std::move(name), std::move(id), DEVICE_CLASS_LIGHTGUN, module),
lightgun({0})
{
}
@ -545,17 +545,17 @@ protected:
std::wstring name = rawinput_device_improve_name(tname.get());
// convert name to utf8
std::string utf8_name = osd::text::from_wstring(name.c_str());
std::string utf8_name = osd::text::from_wstring(name);
// set device id to raw input name
std::string utf8_id = osd::text::from_wstring(tname.get());
TDevice *devinfo = devicelist()->create_device<TDevice>(machine, utf8_name.c_str(), utf8_id.c_str(), *this);
TDevice &devinfo = devicelist()->create_device<TDevice>(machine, std::move(utf8_name), std::move(utf8_id), *this);
// Add the handle
devinfo->set_handle(rawinputdevice->hDevice);
devinfo.set_handle(rawinputdevice->hDevice);
return devinfo;
return &devinfo;
}
bool handle_input_event(input_event eventid, void *eventdata) override
@ -658,7 +658,7 @@ protected:
std::string name = osd::text::from_wstring(keyname);
// add the item to the device
devinfo->device()->add_item(name.c_str(), itemid, generic_button_get_state<std::uint8_t>, &devinfo->keyboard.state[keynum]);
devinfo->device()->add_item(name, itemid, generic_button_get_state<std::uint8_t>, &devinfo->keyboard.state[keynum]);
}
}
};
@ -764,11 +764,13 @@ protected:
} // anonymous namespace
#else
#else // defined(OSD_WINDOWS)
MODULE_NOT_SUPPORTED(keyboard_input_rawinput, OSD_KEYBOARDINPUT_PROVIDER, "rawinput")
MODULE_NOT_SUPPORTED(mouse_input_rawinput, OSD_MOUSEINPUT_PROVIDER, "rawinput")
MODULE_NOT_SUPPORTED(lightgun_input_rawinput, OSD_LIGHTGUNINPUT_PROVIDER, "rawinput")
#endif
#endif // defined(OSD_WINDOWS)
MODULE_DEFINITION(KEYBOARDINPUT_RAWINPUT, keyboard_input_rawinput)
MODULE_DEFINITION(MOUSEINPUT_RAWINPUT, mouse_input_rawinput)

View File

@ -46,6 +46,8 @@
#endif
namespace {
// FIXME: sdl does not properly report the window for certain OS.
#define GET_FOCUS_WINDOW(ev) focus_window()
//#define GET_FOCUS_WINDOW(ev) window_from_id((ev)->windowID)
@ -62,7 +64,7 @@ struct key_lookup_table
#define KE5(A, B, C, D, E) KE(A) KE(B) KE(C) KE(D) KE(E)
#define KE3(A, B, C) KE(A) KE(B) KE(C)
static key_lookup_table sdl_lookup_table[] =
key_lookup_table sdl_lookup_table[] =
{
KE(UNKNOWN)
@ -332,7 +334,7 @@ static key_lookup_table sdl_lookup_table[] =
// lookup_sdl_code
//============================================================
static int lookup_sdl_code(const char *scode)
int lookup_sdl_code(const char *scode)
{
int i = 0;
@ -352,8 +354,8 @@ static int lookup_sdl_code(const char *scode)
class sdl_device : public event_based_device<SDL_Event>
{
public:
sdl_device(running_machine &machine, const char *name, const char *id, input_device_class devclass, input_module &module)
: event_based_device(machine, name, id, devclass, module)
sdl_device(running_machine &machine, std::string &&name, std::string &&id, input_device_class devclass, input_module &module) :
event_based_device(machine, std::move(name), std::move(id), devclass, module)
{
}
@ -373,8 +375,8 @@ class sdl_keyboard_device : public sdl_device
public:
keyboard_state keyboard;
sdl_keyboard_device(running_machine &machine, const char *name, const char *id, input_module &module)
: sdl_device(machine, name, id, DEVICE_CLASS_KEYBOARD, module),
sdl_keyboard_device(running_machine &machine, std::string &&name, std::string &&id, input_module &module) :
sdl_device(machine, std::move(name), std::move(id), DEVICE_CLASS_KEYBOARD, module),
keyboard({{0}})
{
#ifdef __APPLE__
@ -483,8 +485,8 @@ private:
public:
mouse_state mouse;
sdl_mouse_device(running_machine &machine, const char *name, const char *id, input_module &module)
: sdl_device(machine, name, id, DEVICE_CLASS_MOUSE, module),
sdl_mouse_device(running_machine &machine, std::string &&name, std::string &&id, input_module &module) :
sdl_device(machine, std::move(name), std::move(id), DEVICE_CLASS_MOUSE, module),
last_x(0),
last_y(0),
mouse({0})
@ -622,10 +624,10 @@ public:
sdl_joystick_state joystick;
sdl_api_state sdl_state;
sdl_joystick_device(running_machine &machine, const char *name, const char *id, input_module &module)
: sdl_device(machine, name, id, DEVICE_CLASS_JOYSTICK, module),
joystick({{0}}),
sdl_state({ nullptr })
sdl_joystick_device(running_machine &machine, std::string &&name, std::string &&id, input_module &module) :
sdl_device(machine, std::move(name), std::move(id), DEVICE_CLASS_JOYSTICK, module),
joystick({{0}}),
sdl_state({ nullptr })
{
}
@ -709,8 +711,8 @@ public:
class sdl_sixaxis_joystick_device : public sdl_joystick_device
{
public:
sdl_sixaxis_joystick_device(running_machine &machine, const char *name, const char *id, input_module &module)
: sdl_joystick_device(machine, name, id, module)
sdl_sixaxis_joystick_device(running_machine &machine, std::string &&name, std::string &&id, input_module &module) :
sdl_joystick_device(machine, std::move(name), std::move(id), module)
{
}
@ -749,8 +751,7 @@ public:
class sdl_input_module : public input_module_base, public sdl_event_subscriber
{
public:
sdl_input_module(const char *type)
: input_module_base(type, "sdl")
sdl_input_module(const char *type) : input_module_base(type, "sdl")
{
}
@ -799,8 +800,9 @@ class sdl_keyboard_module : public sdl_input_module
{
keyboard_trans_table * m_key_trans_table;
public:
sdl_keyboard_module()
: sdl_input_module(OSD_KEYBOARDINPUT_PROVIDER), m_key_trans_table(nullptr)
sdl_keyboard_module() :
sdl_input_module(OSD_KEYBOARDINPUT_PROVIDER),
m_key_trans_table(nullptr)
{
}
@ -816,8 +818,6 @@ public:
sdl_event_manager::instance().subscribe(event_types, std::size(event_types), this);
sdl_keyboard_device *devinfo;
// Read our keymap and store a pointer to our table
m_key_trans_table = sdlinput_read_keymap(machine);
@ -826,7 +826,7 @@ public:
osd_printf_verbose("Keyboard: Start initialization\n");
// SDL only has 1 keyboard add it now
devinfo = devicelist()->create_device<sdl_keyboard_device>(machine, "System keyboard", "System keyboard", *this);
auto &devinfo = devicelist()->create_device<sdl_keyboard_device>(machine, "System keyboard", "System keyboard", *this);
// populate it
for (int keynum = 0; local_table[keynum].mame_key != ITEM_ID_INVALID; keynum++)
@ -837,31 +837,26 @@ public:
char defname[20];
snprintf(defname, sizeof(defname) - 1, "%s", local_table[keynum].ui_name);
devinfo->device()->add_item(defname, itemid, generic_button_get_state<std::int32_t>, &devinfo->keyboard.state[local_table[keynum].sdl_scancode]);
devinfo.device()->add_item(defname, itemid, generic_button_get_state<std::int32_t>, &devinfo.keyboard.state[local_table[keynum].sdl_scancode]);
}
osd_printf_verbose("Keyboard: Registered %s\n", devinfo->name());
osd_printf_verbose("Keyboard: Registered %s\n", devinfo.name());
osd_printf_verbose("Keyboard: End initialization\n");
}
private:
keyboard_trans_table* sdlinput_read_keymap(running_machine &machine)
keyboard_trans_table *sdlinput_read_keymap(running_machine &machine)
{
char *keymap_filename;
FILE *keymap_file;
int line = 1;
int sdl2section = 0;
keyboard_trans_table &default_table = keyboard_trans_table::instance();
if (!machine.options().bool_value(SDLOPTION_KEYMAP))
return &default_table;
keymap_filename = (char *)downcast<sdl_options &>(machine.options()).keymap_file();
const char *const keymap_filename = downcast<sdl_options &>(machine.options()).keymap_file();
osd_printf_verbose("Keymap: Start reading keymap_file %s\n", keymap_filename);
keymap_file = fopen(keymap_filename, "r");
if (keymap_file == nullptr)
FILE *const keymap_file = fopen(keymap_filename, "r");
if (!keymap_file)
{
osd_printf_warning("Keymap: Unable to open keymap %s, using default\n", keymap_filename);
return &default_table;
@ -877,6 +872,8 @@ private:
// Allocate the trans table to be associated with the machine so we don't have to free it
m_custom_table = std::make_unique<keyboard_trans_table>(std::move(key_trans_entries), default_table.size());
int line = 1;
int sdl2section = 0;
while (!feof(keymap_file))
{
char buf[256];
@ -913,7 +910,9 @@ private:
osd_printf_verbose("Keymap: Mapped <%s> to <%s> with ui-text <%s>\n", sks, mks, kns);
}
else
{
osd_printf_error("Keymap: Error on line %d - %s key not found: %s\n", line, (sk<0) ? "sdl" : "mame", buf);
}
}
}
line++;
@ -935,8 +934,7 @@ private:
class sdl_mouse_module : public sdl_input_module
{
public:
sdl_mouse_module()
: sdl_input_module(OSD_MOUSEINPUT_PROVIDER)
sdl_mouse_module() : sdl_input_module(OSD_MOUSEINPUT_PROVIDER)
{
}
@ -953,45 +951,42 @@ public:
sdl_event_manager::instance().subscribe(event_types, std::size(event_types), this);
sdl_mouse_device *devinfo;
char defname[20];
int button;
osd_printf_verbose("Mouse: Start initialization\n");
// SDL currently only supports one mouse
devinfo = devicelist()->create_device<sdl_mouse_device>(machine, "System mouse", "System mouse", *this);
auto &devinfo = devicelist()->create_device<sdl_mouse_device>(machine, "System mouse", "System mouse", *this);
// add the axes
devinfo->device()->add_item("X", ITEM_ID_XAXIS, generic_axis_get_state<std::int32_t>, &devinfo->mouse.lX);
devinfo->device()->add_item("Y", ITEM_ID_YAXIS, generic_axis_get_state<std::int32_t>, &devinfo->mouse.lY);
devinfo.device()->add_item("X", ITEM_ID_XAXIS, generic_axis_get_state<std::int32_t>, &devinfo.mouse.lX);
devinfo.device()->add_item("Y", ITEM_ID_YAXIS, generic_axis_get_state<std::int32_t>, &devinfo.mouse.lY);
for (button = 0; button < 4; button++)
for (int button = 0; button < 4; button++)
{
input_item_id itemid = (input_item_id)(ITEM_ID_BUTTON1 + button);
char defname[20];
snprintf(defname, sizeof(defname), "B%d", button + 1);
devinfo->device()->add_item(defname, itemid, generic_button_get_state<std::int32_t>, &devinfo->mouse.buttons[button]);
devinfo.device()->add_item(defname, itemid, generic_button_get_state<std::int32_t>, &devinfo.mouse.buttons[button]);
}
osd_printf_verbose("Mouse: Registered %s\n", devinfo->name());
osd_printf_verbose("Mouse: Registered %s\n", devinfo.name());
osd_printf_verbose("Mouse: End initialization\n");
}
};
static void devmap_register(device_map_t &devmap, int physical_idx, const std::string &name)
void devmap_register(device_map_t &devmap, int physical_idx, const std::string &name)
{
// Attempt to find the entry by name
auto entry = std::find_if(std::begin(devmap.map), std::end(devmap.map), [&name](auto &item)
{
return item.name == name && item.physical < 0;
});
auto entry = std::find_if(
std::begin(devmap.map),
std::end(devmap.map),
[&name] (auto &item) { return (item.name == name) && (item.physical < 0); });
// If we didn't find it by name, find the first free slot
if (entry == std::end(devmap.map))
{
entry = std::find_if(std::begin(devmap.map), std::end(devmap.map), [](auto &item) { return item.name.empty(); });
entry = std::find_if(std::begin(devmap.map), std::end(devmap.map), [] (auto &item) { return item.name.empty(); });
}
if (entry != std::end(devmap.map))
@ -1015,8 +1010,11 @@ private:
bool m_initialized_haptic;
bool m_sixaxis_mode;
public:
sdl_joystick_module()
: sdl_input_module(OSD_JOYSTICKINPUT_PROVIDER), m_initialized_joystick(false), m_initialized_haptic(false), m_sixaxis_mode(false)
sdl_joystick_module() :
sdl_input_module(OSD_JOYSTICKINPUT_PROVIDER),
m_initialized_joystick(false),
m_initialized_haptic(false),
m_sixaxis_mode(false)
{
}
@ -1064,15 +1062,15 @@ public:
int physical_stick;
for (physical_stick = 0; physical_stick < SDL_NumJoysticks(); physical_stick++)
{
std::string joy_name = remove_spaces(SDL_JoystickNameForIndex(physical_stick));
devmap_register(m_joy_map, physical_stick, joy_name);
std::string joy_name = remove_spaces(SDL_JoystickNameForIndex(physical_stick));
devmap_register(m_joy_map, physical_stick, joy_name);
}
for (int stick = 0; stick < MAX_DEVMAP_ENTRIES; stick++)
{
sdl_joystick_device *devinfo = create_joystick_device(machine, &m_joy_map, stick, DEVICE_CLASS_JOYSTICK);
sdl_joystick_device *const devinfo = create_joystick_device(machine, &m_joy_map, stick, DEVICE_CLASS_JOYSTICK);
if (devinfo == nullptr)
if (!devinfo)
continue;
physical_stick = m_joy_map.map[stick].physical;
@ -1110,7 +1108,7 @@ public:
else
itemid = ITEM_ID_OTHER_AXIS_ABSOLUTE;
snprintf(tempname, sizeof(tempname), "A%d %s", axis, devinfo->name());
snprintf(tempname, sizeof(tempname), "A%d %s", axis, devinfo->name().c_str());
devinfo->device()->add_item(tempname, itemid, generic_axis_get_state<std::int32_t>, &devinfo->joystick.axes[axis]);
}
@ -1163,9 +1161,9 @@ public:
else
itemid = ITEM_ID_OTHER_AXIS_RELATIVE;
snprintf(tempname, sizeof(tempname), "R%d %s", ball * 2, devinfo->name());
snprintf(tempname, sizeof(tempname), "R%d %s", ball * 2, devinfo->name().c_str());
devinfo->device()->add_item(tempname, (input_item_id)itemid, generic_axis_get_state<std::int32_t>, &devinfo->joystick.balls[ball * 2]);
snprintf(tempname, sizeof(tempname), "R%d %s", ball * 2 + 1, devinfo->name());
snprintf(tempname, sizeof(tempname), "R%d %s", ball * 2 + 1, devinfo->name().c_str());
devinfo->device()->add_item(tempname, (input_item_id)(itemid + 1), generic_axis_get_state<std::int32_t>, &devinfo->joystick.balls[ball * 2 + 1]);
}
}
@ -1186,11 +1184,14 @@ public:
virtual void handle_event(SDL_Event &sdlevent) override
{
// Figure out which joystick this event id destined for
auto target_device = std::find_if(devicelist()->begin(), devicelist()->end(), [&sdlevent](auto &device)
{
std::unique_ptr<device_info> &ptr = device;
return downcast<sdl_joystick_device*>(ptr.get())->sdl_state.joystick_id == sdlevent.jdevice.which;
});
auto target_device = std::find_if(
devicelist()->begin(),
devicelist()->end(),
[&sdlevent] (auto &device)
{
std::unique_ptr<device_info> &ptr = device;
return downcast<sdl_joystick_device*>(ptr.get())->sdl_state.joystick_id == sdlevent.jdevice.which;
});
// If we find a matching joystick, dispatch the event to the joystick
if (target_device != devicelist()->end())
@ -1200,12 +1201,12 @@ public:
}
private:
sdl_joystick_device* create_joystick_device(running_machine &machine, device_map_t *devmap, int index, input_device_class devclass)
sdl_joystick_device *create_joystick_device(running_machine &machine, device_map_t *devmap, int index, input_device_class devclass)
{
char tempname[20];
char guid_str[256];
SDL_JoystickGUID guid = SDL_JoystickGetDeviceGUID(m_joy_map.map[index].physical);
SDL_JoystickGetGUIDString(guid, guid_str, sizeof(guid_str)-1);
SDL_JoystickGetGUIDString(guid, guid_str, sizeof(guid_str) - 1);
if (devmap->map[index].name.empty())
{
@ -1222,16 +1223,20 @@ private:
}
return m_sixaxis_mode
? devicelist()->create_device<sdl_sixaxis_joystick_device>(machine, devmap->map[index].name.c_str(), guid_str, *this)
: devicelist()->create_device<sdl_joystick_device>(machine, devmap->map[index].name.c_str(), guid_str, *this);
? &devicelist()->create_device<sdl_sixaxis_joystick_device>(machine, std::string(devmap->map[index].name), guid_str, *this)
: &devicelist()->create_device<sdl_joystick_device>(machine, std::string(devmap->map[index].name), guid_str, *this);
}
};
#else
} // anonymous namespace
#else // defined(SDLMAME_SDL2)
MODULE_NOT_SUPPORTED(sdl_keyboard_module, OSD_KEYBOARDINPUT_PROVIDER, "sdl")
MODULE_NOT_SUPPORTED(sdl_mouse_module, OSD_MOUSEINPUT_PROVIDER, "sdl")
MODULE_NOT_SUPPORTED(sdl_joystick_module, OSD_JOYSTICKINPUT_PROVIDER, "sdl")
#endif
#endif // defined(SDLMAME_SDL2)
MODULE_DEFINITION(KEYBOARDINPUT_SDL, sdl_keyboard_module)
MODULE_DEFINITION(MOUSEINPUT_SDL, sdl_mouse_module)

View File

@ -26,6 +26,9 @@
#include "input_common.h"
#include "input_windows.h"
namespace {
#define UWP_BUTTON_COUNT 32
using namespace concurrency;
@ -54,10 +57,10 @@ private:
input_device *m_inputdevice;
internal:
UwpInputDevice(running_machine &machine, const char *name, const char *id, input_device_class deviceclass, input_module &module)
: m_machine(machine),
m_name(name),
m_id(id),
UwpInputDevice(running_machine &machine, std::string &&name, std::string &&id, input_device_class deviceclass, input_module &module) :
m_machine(machine),
m_name(std::move(name)),
m_id(std::move(id)),
m_devclass(deviceclass),
m_module(module),
m_inputdevice(nullptr)
@ -115,8 +118,8 @@ private:
UwpInputDevice ^m_wrapped_device;
public:
uwp_input_device(UwpInputDevice ^device)
: device_info(device->Machine, device->Name.c_str(), device->Id.c_str(), device->DeviceClass, device->Module),
uwp_input_device(UwpInputDevice ^device) :
device_info(device->Machine, std::string(device->Name), std::string(device->Id), device->DeviceClass, device->Module),
m_wrapped_device(device)
{
}
@ -148,9 +151,9 @@ private:
uwp_input_module *m_module;
internal:
UwpInputModule(const char *type, const char *name)
: m_type(type),
m_name(name),
UwpInputModule(std::string &&type, std::string &&name) :
m_type(std::move(type)),
m_name(std::move(name)),
m_module(nullptr)
{
}
@ -187,8 +190,8 @@ private:
UwpInputModule^ m_refmodule;
public:
uwp_input_module(UwpInputModule^ refmodule)
: wininput_module(refmodule->Type.c_str(), refmodule->Name.c_str()),
uwp_input_module(UwpInputModule^ refmodule) :
wininput_module(refmodule->Type.c_str(), refmodule->Name.c_str()),
m_refmodule(refmodule)
{
refmodule->NativeModule = this;
@ -216,8 +219,8 @@ private:
std::mutex m_state_lock;
internal:
UwpKeyboardDevice(Platform::Agile<CoreWindow> coreWindow, running_machine& machine, char *name, const char *id, input_module &module)
: UwpInputDevice(machine, name, id, DEVICE_CLASS_KEYBOARD, module),
UwpKeyboardDevice(Platform::Agile<CoreWindow> coreWindow, running_machine& machine, std::string &&name, std::string &&id, input_module &module) :
UwpInputDevice(machine, std::move(name), std::move(id), DEVICE_CLASS_KEYBOARD, module),
keyboard({{0}}),
m_coreWindow(coreWindow)
{
@ -244,7 +247,7 @@ internal:
const char *keyname = table.ui_label_for_mame_key(itemid);
char temp[256];
if (keyname == nullptr)
if (!keyname)
{
snprintf(temp, std::size(temp), "Scan%03d", keynum);
keyname = temp;
@ -301,8 +304,7 @@ private:
running_machine *m_machine;
internal:
UwpKeyboardModule()
: UwpInputModule(OSD_KEYBOARDINPUT_PROVIDER, "uwp")
UwpKeyboardModule() : UwpInputModule(OSD_KEYBOARDINPUT_PROVIDER, "uwp")
{
}
@ -316,10 +318,10 @@ internal:
// Allocate the wrapper and add it to the list
auto created_devinfo = std::make_unique<uwp_input_device>(refdevice);
uwp_input_device *devinfo = NativeModule->devicelist()->add_device<uwp_input_device>(machine, std::move(created_devinfo));
uwp_input_device &devinfo = NativeModule->devicelist()->add_device<uwp_input_device>(machine, std::move(created_devinfo));
// Give the UWP implementation a handle to the input_device
refdevice->InputDevice = devinfo->device();
refdevice->InputDevice = devinfo.device();
// Configure the device
refdevice->Configure();
@ -577,8 +579,6 @@ internal:
int padindex = 0;
std::for_each(begin(pads), end(pads), [&](Gamepad^ pad)
{
uwp_input_device *devinfo;
std::ostringstream namestream;
namestream << "UWP Gamepad " << (padindex + 1);
@ -589,7 +589,7 @@ internal:
// Allocate the wrapper and add it to the list
auto created_devinfo = std::make_unique<uwp_input_device>(refdevice);
devinfo = NativeModule->devicelist()->add_device<uwp_input_device>(machine, std::move(created_devinfo));
auto &devinfo = NativeModule->devicelist()->add_device<uwp_input_device>(machine, std::move(created_devinfo));
// Give the UWP implementation a handle to the input_device
refdevice->InputDevice = devinfo->device();
@ -634,16 +634,19 @@ private:
class uwp_joystick_module : public uwp_input_module
{
public:
uwp_joystick_module()
: uwp_input_module(ref new UwpJoystickModule())
uwp_joystick_module() : uwp_input_module(ref new UwpJoystickModule())
{
}
};
#else
} // anonymous namespace
#else // defined(OSD_UWP)
MODULE_NOT_SUPPORTED(uwp_keyboard_module, OSD_KEYBOARDINPUT_PROVIDER, "uwp")
MODULE_NOT_SUPPORTED(uwp_joystick_module, OSD_JOYSTICKINPUT_PROVIDER, "uwp")
#endif
#endif // defined(OSD_UWP)
MODULE_DEFINITION(KEYBOARDINPUT_UWP, uwp_keyboard_module)
MODULE_DEFINITION(JOYSTICKINPUT_UWP, uwp_joystick_module)

View File

@ -27,6 +27,8 @@
#include "input_common.h"
#include "input_windows.h"
namespace {
//============================================================
// win32_keyboard_device
//============================================================
@ -37,8 +39,8 @@ class win32_keyboard_device : public event_based_device<KeyPressEventArgs>
public:
keyboard_state keyboard;
win32_keyboard_device(running_machine& machine, const char *name, const char *id, input_module &module)
: event_based_device(machine, name, id, DEVICE_CLASS_KEYBOARD, module),
win32_keyboard_device(running_machine& machine, std::string &&name, std::string &&id, input_module &module)
: event_based_device(machine, std::move(name), std::move(id), DEVICE_CLASS_KEYBOARD, module),
keyboard({{0}})
{
}
@ -72,7 +74,7 @@ public:
virtual void input_init(running_machine &machine) override
{
// Add a single win32 keyboard device that we'll monitor using Win32
auto *devinfo = devicelist()->create_device<win32_keyboard_device>(machine, "Win32 Keyboard 1", "Win32 Keyboard 1", *this);
auto &devinfo = devicelist()->create_device<win32_keyboard_device>(machine, "Win32 Keyboard 1", "Win32 Keyboard 1", *this);
keyboard_trans_table &table = keyboard_trans_table::instance();
@ -88,7 +90,7 @@ public:
std::string name = osd::text::from_tstring(keyname);
// add the item to the device
devinfo->device()->add_item(name.c_str(), itemid, generic_button_get_state<std::uint8_t>, &devinfo->keyboard.state[keynum]);
devinfo.device()->add_item(name, itemid, generic_button_get_state<std::uint8_t>, &devinfo.keyboard.state[keynum]);
}
}
@ -134,8 +136,8 @@ public:
mouse_state mouse;
win32_mouse_state win32_mouse;
win32_mouse_device(running_machine& machine, const char *name, const char *id, input_module &module)
: event_based_device(machine, name, id, DEVICE_CLASS_MOUSE, module),
win32_mouse_device(running_machine& machine, std::string &&name, std::string &&id, input_module &module)
: event_based_device(machine, std::move(name), std::move(id), DEVICE_CLASS_MOUSE, module),
mouse({0}),
win32_mouse({{0}})
{
@ -200,35 +202,30 @@ public:
virtual void input_init(running_machine &machine) override
{
win32_mouse_device *devinfo;
int axisnum, butnum;
if (!input_enabled() || !mouse_enabled())
return;
// allocate a device
devinfo = devicelist()->create_device<win32_mouse_device>(machine, "Win32 Mouse 1", "Win32 Mouse 1", *this);
if (devinfo == nullptr)
return;
auto &devinfo = devicelist()->create_device<win32_mouse_device>(machine, "Win32 Mouse 1", "Win32 Mouse 1", *this);
// populate the axes
for (axisnum = 0; axisnum < 2; axisnum++)
for (int axisnum = 0; axisnum < 2; axisnum++)
{
devinfo->device()->add_item(
devinfo.device()->add_item(
default_axis_name[axisnum],
static_cast<input_item_id>(ITEM_ID_XAXIS + axisnum),
generic_axis_get_state<LONG>,
&devinfo->mouse.lX + axisnum);
&devinfo.mouse.lX + axisnum);
}
// populate the buttons
for (butnum = 0; butnum < 2; butnum++)
for (int butnum = 0; butnum < 2; butnum++)
{
devinfo->device()->add_item(
devinfo.device()->add_item(
default_button_name(butnum),
static_cast<input_item_id>(ITEM_ID_BUTTON1 + butnum),
generic_button_get_state<BYTE>,
&devinfo->mouse.rgbButtons[butnum]);
&devinfo.mouse.rgbButtons[butnum]);
}
}
@ -262,8 +259,8 @@ private:
public:
mouse_state mouse;
win32_lightgun_device(running_machine& machine, const char *name, const char *id, input_module &module)
: event_based_device(machine, name, id, DEVICE_CLASS_LIGHTGUN, module),
win32_lightgun_device(running_machine& machine, std::string &&name, std::string &&id, input_module &module)
: event_based_device(machine, std::move(name), std::move(id), DEVICE_CLASS_LIGHTGUN, module),
m_lightgun_shared_axis_mode(FALSE),
m_gun_index(0),
mouse({0})
@ -392,32 +389,28 @@ public:
for (int gunnum = 0; gunnum < max_guns; gunnum++)
{
static const char *const gun_names[] = { "Win32 Gun 1", "Win32 Gun 2" };
win32_lightgun_device *devinfo;
int axisnum, butnum;
// allocate a device
devinfo = devicelist()->create_device<win32_lightgun_device>(machine, gun_names[gunnum], gun_names[gunnum], *this);
if (devinfo == nullptr)
break;
auto &devinfo = devicelist()->create_device<win32_lightgun_device>(machine, gun_names[gunnum], gun_names[gunnum], *this);
// populate the axes
for (axisnum = 0; axisnum < 2; axisnum++)
for (int axisnum = 0; axisnum < 2; axisnum++)
{
devinfo->device()->add_item(
devinfo.device()->add_item(
default_axis_name[axisnum],
static_cast<input_item_id>(ITEM_ID_XAXIS + axisnum),
generic_axis_get_state<LONG>,
&devinfo->mouse.lX + axisnum);
&devinfo.mouse.lX + axisnum);
}
// populate the buttons
for (butnum = 0; butnum < 2; butnum++)
for (int butnum = 0; butnum < 2; butnum++)
{
devinfo->device()->add_item(
devinfo.device()->add_item(
default_button_name(butnum),
static_cast<input_item_id>(ITEM_ID_BUTTON1 + butnum),
generic_button_get_state<BYTE>,
&devinfo->mouse.rgbButtons[butnum]);
&devinfo.mouse.rgbButtons[butnum]);
}
}
}
@ -439,11 +432,15 @@ public:
}
};
#else
} // anonymous namespace
#else // defined(OSD_WINDOWS)
MODULE_NOT_SUPPORTED(keyboard_input_win32, OSD_KEYBOARDINPUT_PROVIDER, "win32")
MODULE_NOT_SUPPORTED(mouse_input_win32, OSD_MOUSEINPUT_PROVIDER, "win32")
MODULE_NOT_SUPPORTED(lightgun_input_win32, OSD_LIGHTGUNINPUT_PROVIDER, "win32")
#endif
#endif // defined(OSD_WINDOWS)
MODULE_DEFINITION(KEYBOARDINPUT_WIN32, keyboard_input_win32)
MODULE_DEFINITION(MOUSEINPUT_WIN32, mouse_input_win32)

View File

@ -167,4 +167,4 @@ void windows_osd_interface::customize_input_type_list(std::vector<input_type_ent
}
}
#endif
#endif // defined(OSD_WINDOWS) || defined(OSD_UWP)

View File

@ -5,9 +5,10 @@
// input_windows.h - Common code used by Windows input modules
//
//============================================================
#ifndef MAME_OSD_INPUT_INPUT_WINDOWS_H
#define MAME_OSD_INPUT_INPUT_WINDOWS_H
#ifndef INPUT_WIN_H_
#define INPUT_WIN_H_
#pragma once
// standard windows headers
#include <windows.h>
@ -80,4 +81,4 @@ protected:
}
};
#endif
#endif // MAME_OSD_INPUT_INPUT_WINDOWS_H

View File

@ -37,6 +37,8 @@
#include "input_xinput.h"
#include "input_dinput.h"
namespace {
using namespace Microsoft::WRL;
template<class TCom>
@ -46,8 +48,7 @@ private:
std::vector<TCom*> m_entries;
public:
ComArray(size_t capacity)
: m_entries(capacity, nullptr)
ComArray(size_t capacity) : m_entries(capacity, nullptr)
{
}
@ -76,12 +77,12 @@ public:
void Release()
{
for (int i = 0; i < m_entries.size(); i++)
for (auto &entry : m_entries)
{
if (m_entries[i] != nullptr)
if (entry != nullptr)
{
m_entries[i]->Release();
m_entries[i] = nullptr;
entry->Release();
entry = nullptr;
}
}
}
@ -91,7 +92,7 @@ struct bstr_deleter
{
void operator () (BSTR bstr) const
{
if (bstr != nullptr)
if (bstr)
SysFreeString(bstr);
}
};
@ -146,8 +147,8 @@ private:
bool m_xinput_detect_failed;
public:
winhybrid_joystick_module()
: wininput_module(OSD_JOYSTICKINPUT_PROVIDER, "winhybrid"),
winhybrid_joystick_module() :
wininput_module(OSD_JOYSTICKINPUT_PROVIDER, "winhybrid"),
m_xinput_helper(nullptr),
m_dinput_helper(nullptr),
m_xinput_detect_failed(false)
@ -232,13 +233,13 @@ protected:
if (result != 0)
{
m_xinput_detect_failed = true;
osd_printf_warning("XInput device detection failed. XInput won't be used. Error: 0x%X\n", static_cast<unsigned int>(result));
osd_printf_warning("XInput device detection failed. XInput won't be used. Error: 0x%X\n", uint32_t(result));
}
// Enumerate all the directinput joysticks and add them if they aren't xinput compatible
result = m_dinput_helper->enum_attached_devices(DI8DEVCLASS_GAMECTRL, this, &machine);
if (result != DI_OK)
fatalerror("DirectInput: Unable to enumerate keyboards (result=%08X)\n", static_cast<uint32_t>(result));
fatalerror("DirectInput: Unable to enumerate game controllers (result=%08X)\n", uint32_t(result));
xinput_joystick_device *devinfo;
@ -254,7 +255,7 @@ protected:
{
// allocate and link in a new device
devinfo = m_xinput_helper->create_xinput_device(machine, i, *this);
if (devinfo == nullptr)
if (!devinfo)
continue;
// Configure each gamepad to add buttons and Axes, etc.
@ -269,7 +270,7 @@ private:
{
int status = 0;
if (m_xinput_helper == nullptr)
if (!m_xinput_helper)
{
m_xinput_helper = std::make_shared<xinput_api_helper>();
status = m_xinput_helper->initialize();
@ -280,9 +281,9 @@ private:
}
}
if (m_dinput_helper == nullptr)
if (!m_dinput_helper)
{
m_dinput_helper = std::make_unique<dinput_api_helper>(DIRECTINPUT_VERSION);
m_dinput_helper = std::make_unique<dinput_api_helper>();
status = m_dinput_helper->initialize();
if (status != DI_OK)
{
@ -441,8 +442,12 @@ private:
}
};
#else
} // anonymous namespace
#else // defined(OSD_WINDOWS)
MODULE_NOT_SUPPORTED(winhybrid_joystick_module, OSD_JOYSTICKINPUT_PROVIDER, "winhybrid")
#endif
#endif // defined(OSD_WINDOWS)
MODULE_DEFINITION(JOYSTICKINPUT_WINHYBRID, winhybrid_joystick_module)

View File

@ -38,6 +38,9 @@
#include "../../sdl/osdsdl.h"
#include "input_sdlcommon.h"
namespace {
#define MAX_DEVMAP_ENTRIES 16
#define INVALID_EVENT_TYPE -1
@ -71,7 +74,7 @@ struct x11_api_state
#define XI_DBG(format, ...) osd_printf_verbose(format, __VA_ARGS__)
#define print_motion_event(motion) print_motion_event_impl(motion)
static inline void print_motion_event_impl(XDeviceMotionEvent *motion)
inline void print_motion_event_impl(XDeviceMotionEvent *motion)
{
/*
* print a lot of debug informations of the motion event(s).
@ -185,7 +188,7 @@ find_device_info(Display *display,
}
//Copypasted from xinfo
static int
int
register_events(
Display *dpy,
XDeviceInfo *info,
@ -356,9 +359,9 @@ class x11_input_device : public event_based_device<XEvent>
public:
x11_api_state x11_state;
x11_input_device(running_machine &machine, const char *name, const char *id, input_device_class devclass, input_module &module)
: event_based_device(machine, name, id, devclass, module),
x11_state({0})
x11_input_device(running_machine &machine, std::string &&name, std::string &&id, input_device_class devclass, input_module &module) :
event_based_device(machine, std::move(name), std::move(id), devclass, module),
x11_state({0})
{
}
};
@ -372,9 +375,9 @@ class x11_lightgun_device : public x11_input_device
public:
lightgun_state lightgun;
x11_lightgun_device(running_machine &machine, const char *name, const char *id, input_module &module)
: x11_input_device(machine, name, id, DEVICE_CLASS_LIGHTGUN, module),
lightgun({0})
x11_lightgun_device(running_machine &machine, std::string &&name, std::string &&id, input_module &module) :
x11_input_device(machine, std::move(name), std::move(id), DEVICE_CLASS_LIGHTGUN, module),
lightgun({0})
{
}
@ -455,16 +458,16 @@ private:
device_map_t m_lightgun_map;
Display * m_display;
public:
x11_lightgun_module()
: input_module_base(OSD_LIGHTGUNINPUT_PROVIDER, "x11"),
m_display(nullptr)
x11_lightgun_module() :
input_module_base(OSD_LIGHTGUNINPUT_PROVIDER, "x11"),
m_display(nullptr)
{
}
virtual bool probe() override
{
// If there is no X server, X11 lightguns cannot be supported
if (XOpenDisplay(nullptr) == nullptr)
if (!XOpenDisplay(nullptr))
{
return false;
}
@ -474,8 +477,6 @@ public:
void input_init(running_machine &machine) override
{
int index;
osd_printf_verbose("Lightgun: Begin initialization\n");
devmap_init(machine, &m_lightgun_map, SDLOPTION_LIGHTGUNINDEX, 8, "Lightgun mapping");
@ -487,7 +488,7 @@ public:
assert(m_display != nullptr);
// Loop through all 8 possible devices
for (index = 0; index < 8; index++)
for (int index = 0; index < 8; index++)
{
XDeviceInfo *info;
@ -495,19 +496,18 @@ public:
if (m_lightgun_map.map[index].name.length() == 0)
continue;
x11_lightgun_device *devinfo;
std::string const &name = m_lightgun_map.map[index].name;
char defname[512];
// Register and add the device
devinfo = create_lightgun_device(machine, index);
auto *devinfo = create_lightgun_device(machine, index);
osd_printf_verbose("%i: %s\n", index, name);
// Find the device info associated with the name
info = find_device_info(m_display, name.c_str(), 0);
// If we couldn't find the device, skip
if (info == nullptr)
if (!info)
{
osd_printf_verbose("Can't find device %s!\n", name);
continue;
@ -517,17 +517,17 @@ public:
if (info->num_classes > 0)
{
// Add the lightgun buttons based on what we read
add_lightgun_buttons(static_cast<XAnyClassPtr>(info->inputclassinfo), info->num_classes, devinfo);
add_lightgun_buttons(static_cast<XAnyClassPtr>(info->inputclassinfo), info->num_classes, *devinfo);
// Also, set the axix min/max ranges if we got them
set_lightgun_axis_props(static_cast<XAnyClassPtr>(info->inputclassinfo), info->num_classes, devinfo);
set_lightgun_axis_props(static_cast<XAnyClassPtr>(info->inputclassinfo), info->num_classes, *devinfo);
}
// Add X and Y axis
sprintf(defname, "X %s", devinfo->name());
sprintf(defname, "X %s", devinfo->name().c_str());
devinfo->device()->add_item(defname, ITEM_ID_XAXIS, generic_axis_get_state<std::int32_t>, &devinfo->lightgun.lX);
sprintf(defname, "Y %s", devinfo->name());
sprintf(defname, "Y %s", devinfo->name().c_str());
devinfo->device()->add_item(defname, ITEM_ID_YAXIS, generic_axis_get_state<std::int32_t>, &devinfo->lightgun.lY);
// Save the device id
@ -596,24 +596,26 @@ public:
}
private:
x11_lightgun_device* create_lightgun_device(running_machine &machine, int index)
x11_lightgun_device *create_lightgun_device(running_machine &machine, int index)
{
char tempname[20];
if (m_lightgun_map.map[index].name.length() == 0)
{
if (m_lightgun_map.initialized)
{
char tempname[20];
snprintf(tempname, std::size(tempname), "NC%d", index);
return devicelist()->create_device<x11_lightgun_device>(machine, tempname, tempname, *this);
} else
return &devicelist()->create_device<x11_lightgun_device>(machine, tempname, tempname, *this);
}
else
{
return nullptr;
}
}
return devicelist()->create_device<x11_lightgun_device>(machine, m_lightgun_map.map[index].name.c_str(), m_lightgun_map.map[index].name.c_str(), *this);
return &devicelist()->create_device<x11_lightgun_device>(machine, std::string(m_lightgun_map.map[index].name), std::string(m_lightgun_map.map[index].name), *this);
}
void add_lightgun_buttons(XAnyClassPtr first_info_class, int num_classes, x11_lightgun_device *devinfo) const
void add_lightgun_buttons(XAnyClassPtr first_info_class, int num_classes, x11_lightgun_device &devinfo) const
{
XAnyClassPtr any = first_info_class;
@ -626,7 +628,7 @@ private:
for (int button = 0; button < b->num_buttons; button++)
{
input_item_id itemid = static_cast<input_item_id>(ITEM_ID_BUTTON1 + button);
devinfo->device()->add_item(default_button_name(button), itemid, generic_button_get_state<std::int32_t>, &devinfo->lightgun.buttons[button]);
devinfo.device()->add_item(default_button_name(button), itemid, generic_button_get_state<std::int32_t>, &devinfo.lightgun.buttons[button]);
}
break;
}
@ -635,7 +637,7 @@ private:
}
}
void set_lightgun_axis_props(XAnyClassPtr first_info_class, int num_classes, x11_lightgun_device *devinfo) const
void set_lightgun_axis_props(XAnyClassPtr first_info_class, int num_classes, x11_lightgun_device &devinfo) const
{
XAnyClassPtr any = first_info_class;
@ -651,15 +653,15 @@ private:
if (j == 0)
{
XI_DBG("Set minx=%d, maxx=%d\n", axis_info->min_value, axis_info->max_value);
devinfo->x11_state.maxx = axis_info->max_value;
devinfo->x11_state.minx = axis_info->min_value;
devinfo.x11_state.maxx = axis_info->max_value;
devinfo.x11_state.minx = axis_info->min_value;
}
if (j == 1)
{
XI_DBG("Set miny=%d, maxy=%d\n", axis_info->min_value, axis_info->max_value);
devinfo->x11_state.maxy = axis_info->max_value;
devinfo->x11_state.miny = axis_info->min_value;
devinfo.x11_state.maxy = axis_info->max_value;
devinfo.x11_state.miny = axis_info->min_value;
}
}
break;
@ -670,8 +672,12 @@ private:
}
};
#else
} // anonymous namespace
#else // defined(SDLMAME_SDL2) && !defined(SDLMAME_WIN32) && defined(USE_XINPUT) && USE_XINPUT
MODULE_NOT_SUPPORTED(x11_lightgun_module, OSD_LIGHTGUNINPUT_PROVIDER, "x11")
#endif
#endif // defined(SDLMAME_SDL2) && !defined(SDLMAME_WIN32) && defined(USE_XINPUT) && USE_XINPUT
MODULE_DEFINITION(LIGHTGUN_X11, x11_lightgun_module)

View File

@ -36,6 +36,127 @@
#define XINPUT_LIBRARIES { "xinput1_4.dll" }
#endif
#define XINPUT_AXIS_MINVALUE -32767
#define XINPUT_AXIS_MAXVALUE 32767
namespace {
// default axis names
const char *const xinput_axis_name[] =
{
"LSX",
"LSY",
"RSX",
"RSY"
};
const input_item_id xinput_axis_ids[] =
{
ITEM_ID_XAXIS,
ITEM_ID_YAXIS,
ITEM_ID_RXAXIS,
ITEM_ID_RYAXIS
};
const USHORT xinput_pov_dir[] = {
XINPUT_GAMEPAD_DPAD_UP,
XINPUT_GAMEPAD_DPAD_DOWN,
XINPUT_GAMEPAD_DPAD_LEFT,
XINPUT_GAMEPAD_DPAD_RIGHT
};
const char *const xinput_pov_names[] = {
"DPAD Up",
"DPAD Down",
"DPAD Left",
"DPAD Right"
};
const USHORT xinput_buttons[] = {
XINPUT_GAMEPAD_A,
XINPUT_GAMEPAD_B,
XINPUT_GAMEPAD_X,
XINPUT_GAMEPAD_Y,
XINPUT_GAMEPAD_LEFT_SHOULDER,
XINPUT_GAMEPAD_RIGHT_SHOULDER,
XINPUT_GAMEPAD_START,
XINPUT_GAMEPAD_BACK,
XINPUT_GAMEPAD_LEFT_THUMB,
XINPUT_GAMEPAD_RIGHT_THUMB,
};
const char *const xinput_button_names[] = {
"A",
"B",
"X",
"Y",
"LB",
"RB",
"Start",
"Back",
"LS",
"RS"
};
//============================================================
// xinput_joystick_module
//============================================================
class xinput_joystick_module : public wininput_module
{
public:
xinput_joystick_module() : wininput_module(OSD_JOYSTICKINPUT_PROVIDER, "xinput")
{
}
int init(const osd_options &options) override
{
// Call the base
int status = wininput_module::init(options);
if (status != 0)
return status;
// Create and initialize our helper
m_xinput_helper = std::make_shared<xinput_api_helper>();
status = m_xinput_helper->initialize();
if (status != 0)
{
osd_printf_error("xinput_joystick_module failed to get XInput interface! Error: %u\n", static_cast<unsigned int>(status));
return -1;
}
return 0;
}
protected:
virtual void input_init(running_machine &machine) override
{
// Loop through each gamepad to determine if they are connected
for (UINT i = 0; i < XUSER_MAX_COUNT; i++)
{
XINPUT_STATE state = {0};
if (m_xinput_helper->xinput_get_state(i, &state) == ERROR_SUCCESS)
{
// allocate and link in a new device
auto *devinfo = m_xinput_helper->create_xinput_device(machine, i, *this);
if (!devinfo)
continue;
// Configure each gamepad to add buttons and Axes, etc.
devinfo->configure();
}
}
}
private:
std::shared_ptr<xinput_api_helper> m_xinput_helper;
};
} // anonymous namespace
int xinput_api_helper::initialize()
{
m_xinput_dll = osd::dynamic_module::open(XINPUT_LIBRARIES);
@ -58,8 +179,6 @@ int xinput_api_helper::initialize()
xinput_joystick_device * xinput_api_helper::create_xinput_device(running_machine &machine, UINT index, wininput_module &module)
{
xinput_joystick_device *devinfo;
XINPUT_CAPABILITIES caps = { 0 };
if (FAILED(xinput_get_capabilities(index, 0, &caps)))
{
@ -71,23 +190,23 @@ xinput_joystick_device * xinput_api_helper::create_xinput_device(running_machine
snprintf(device_name, sizeof(device_name), "XInput Player %u", index + 1);
// allocate the device object
devinfo = module.devicelist()->create_device<xinput_joystick_device>(machine, device_name, device_name, module, shared_from_this());
auto &devinfo = module.devicelist()->create_device<xinput_joystick_device>(machine, device_name, device_name, module, shared_from_this());
// Set the player ID
devinfo->xinput_state.player_index = index;
devinfo.xinput_state.player_index = index;
// Assign the caps we captured earlier
devinfo->xinput_state.caps = caps;
devinfo.xinput_state.caps = caps;
return devinfo;
return &devinfo;
}
//============================================================
// xinput_joystick_device
//============================================================
xinput_joystick_device::xinput_joystick_device(running_machine &machine, const char *name, char const *id, input_module &module, std::shared_ptr<xinput_api_helper> helper)
: device_info(machine, name, id, DEVICE_CLASS_JOYSTICK, module),
xinput_joystick_device::xinput_joystick_device(running_machine &machine, std::string &&name, std::string &&id, input_module &module, std::shared_ptr<xinput_api_helper> helper)
: device_info(machine, std::string(name), std::string(id), DEVICE_CLASS_JOYSTICK, module),
gamepad({{0}}),
xinput_state({0}),
m_xinput_helper(helper),
@ -193,67 +312,10 @@ void xinput_joystick_device::configure()
m_configured = true;
}
//============================================================
// xinput_joystick_module
//============================================================
#else // defined(OSD_WINDOWS)
class xinput_joystick_module : public wininput_module
{
private:
std::shared_ptr<xinput_api_helper> m_xinput_helper;
public:
xinput_joystick_module()
: wininput_module(OSD_JOYSTICKINPUT_PROVIDER, "xinput"),
m_xinput_helper(nullptr)
{
}
int init(const osd_options &options) override
{
// Call the base
int status = wininput_module::init(options);
if (status != 0)
return status;
// Create and initialize our helper
m_xinput_helper = std::make_shared<xinput_api_helper>();
status = m_xinput_helper->initialize();
if (status != 0)
{
osd_printf_error("xinput_joystick_module failed to get XInput interface! Error: %u\n", static_cast<unsigned int>(status));
return -1;
}
return 0;
}
protected:
virtual void input_init(running_machine &machine) override
{
xinput_joystick_device *devinfo;
// Loop through each gamepad to determine if they are connected
for (UINT i = 0; i < XUSER_MAX_COUNT; i++)
{
XINPUT_STATE state = {0};
if (m_xinput_helper->xinput_get_state(i, &state) == ERROR_SUCCESS)
{
// allocate and link in a new device
devinfo = m_xinput_helper->create_xinput_device(machine, i, *this);
if (devinfo == nullptr)
continue;
// Configure each gamepad to add buttons and Axes, etc.
devinfo->configure();
}
}
}
};
#else
MODULE_NOT_SUPPORTED(xinput_joystick_module, OSD_JOYSTICKINPUT_PROVIDER, "xinput")
#endif
#endif // defined(OSD_WINDOWS)
MODULE_DEFINITION(JOYSTICKINPUT_XINPUT, xinput_joystick_module)

View File

@ -1,111 +1,24 @@
#ifndef INPUT_XINPUT_H_
#define INPUT_XINPUT_H_
#ifndef MAME_OSD_INPUT_INPUT_XINPUT_H
#define MAME_OSD_INPUT_INPUT_XINPUT_H
#include <mutex>
#pragma once
#include "modules/lib/osdlib.h"
#define XINPUT_MAX_POV 4
#define XINPUT_MAX_BUTTONS 10
#define XINPUT_MAX_AXIS 4
#define XINPUT_AXIS_MINVALUE -32767
#define XINPUT_AXIS_MAXVALUE 32767
#include <cstdint>
#include <memory>
#include <mutex>
#include <string_view>
class xinput_joystick_device;
// default axis names
static const char *const xinput_axis_name[] =
{
"LSX",
"LSY",
"RSX",
"RSY"
};
static const input_item_id xinput_axis_ids[] =
{
ITEM_ID_XAXIS,
ITEM_ID_YAXIS,
ITEM_ID_RXAXIS,
ITEM_ID_RYAXIS
};
static const USHORT xinput_pov_dir[] = {
XINPUT_GAMEPAD_DPAD_UP,
XINPUT_GAMEPAD_DPAD_DOWN,
XINPUT_GAMEPAD_DPAD_LEFT,
XINPUT_GAMEPAD_DPAD_RIGHT
};
static const char *const xinput_pov_names[] = {
"DPAD Up",
"DPAD Down",
"DPAD Left",
"DPAD Right"
};
static const USHORT xinput_buttons[] = {
XINPUT_GAMEPAD_A,
XINPUT_GAMEPAD_B,
XINPUT_GAMEPAD_X,
XINPUT_GAMEPAD_Y,
XINPUT_GAMEPAD_LEFT_SHOULDER,
XINPUT_GAMEPAD_RIGHT_SHOULDER,
XINPUT_GAMEPAD_START,
XINPUT_GAMEPAD_BACK,
XINPUT_GAMEPAD_LEFT_THUMB,
XINPUT_GAMEPAD_RIGHT_THUMB,
};
static const char *const xinput_button_names[] = {
"A",
"B",
"X",
"Y",
"LB",
"RB",
"Start",
"Back",
"LS",
"RS"
};
struct gamepad_state
{
BYTE buttons[XINPUT_MAX_BUTTONS];
BYTE povs[XINPUT_MAX_POV];
LONG left_trigger;
LONG right_trigger;
LONG left_thumb_x;
LONG left_thumb_y;
LONG right_thumb_x;
LONG right_thumb_y;
};
// state information for a gamepad; state must be first element
struct xinput_api_state
{
uint32_t player_index;
XINPUT_STATE xstate;
XINPUT_CAPABILITIES caps;
};
// Typedefs for dynamically loaded functions
typedef DWORD (WINAPI *xinput_get_state_fn)(DWORD, XINPUT_STATE *);
typedef DWORD (WINAPI *xinput_get_caps_fn)(DWORD, DWORD, XINPUT_CAPABILITIES *);
class xinput_api_helper : public std::enable_shared_from_this<xinput_api_helper>
{
public:
xinput_api_helper()
: m_xinput_dll(nullptr),
XInputGetState(nullptr),
XInputGetCapabilities(nullptr)
{
}
xinput_api_helper() { }
int initialize();
xinput_joystick_device * create_xinput_device(running_machine &machine, UINT index, wininput_module &module);
xinput_joystick_device *create_xinput_device(running_machine &machine, UINT index, wininput_module &module);
DWORD xinput_get_state(DWORD dwUserindex, XINPUT_STATE *pState) const
{
@ -118,14 +31,42 @@ public:
}
private:
osd::dynamic_module::ptr m_xinput_dll;
xinput_get_state_fn XInputGetState;
xinput_get_caps_fn XInputGetCapabilities;
// Typedefs for dynamically loaded functions
typedef DWORD (WINAPI *xinput_get_state_fn)(DWORD, XINPUT_STATE *);
typedef DWORD (WINAPI *xinput_get_caps_fn)(DWORD, DWORD, XINPUT_CAPABILITIES *);
osd::dynamic_module::ptr m_xinput_dll = nullptr;
xinput_get_state_fn XInputGetState = nullptr;
xinput_get_caps_fn XInputGetCapabilities = nullptr;
};
class xinput_joystick_device : public device_info
{
public:
static inline constexpr int XINPUT_MAX_POV = 4;
static inline constexpr int XINPUT_MAX_BUTTONS = 10;
static inline constexpr int XINPUT_MAX_AXIS = 4;
struct gamepad_state
{
BYTE buttons[XINPUT_MAX_BUTTONS];
BYTE povs[XINPUT_MAX_POV];
LONG left_trigger;
LONG right_trigger;
LONG left_thumb_x;
LONG left_thumb_y;
LONG right_thumb_x;
LONG right_thumb_y;
};
// state information for a gamepad; state must be first element
struct xinput_api_state
{
uint32_t player_index;
XINPUT_STATE xstate;
XINPUT_CAPABILITIES caps;
};
gamepad_state gamepad;
xinput_api_state xinput_state;
@ -135,11 +76,11 @@ private:
bool m_configured;
public:
xinput_joystick_device(running_machine &machine, const char *name, const char *id, input_module &module, std::shared_ptr<xinput_api_helper> helper);
xinput_joystick_device(running_machine &machine, std::string &&name, std::string &&id, input_module &module, std::shared_ptr<xinput_api_helper> helper);
void poll() override;
void reset() override;
void configure();
};
#endif
#endif // MAME_OSD_INPUT_INPUT_XINPUT_H