Small batch of input refactoring:

emu/input.cpp: Fixed regression in display of some joystick inputs.

osd/interface: Split up interface classes into a few more files to
reduce where the input device interface class needs to be included.
Made OSD independent of concrete input_device class.

osd/modules/input, emu/inputdev.cpp, emu/ioport.cpp: Allow input devices
to provide tokens for controls without standard item types and
additional default input assignments.  Fixes issues assigning Yen and
Backslash on Japanese keyboards.

ui/textbox.cpp: Added a fixed-content text box menu class for future
use.

Got main.h out of emu.h as it’s only used in a very small number of
places, mostly for getting the application name.  Added eminline.h to
attotime.h as it's used without emu.h.  Cleaned up forward declarations
in emufwd.h a little.
This commit is contained in:
Vas Crabb 2023-02-05 04:50:30 +11:00
parent 519554c846
commit b98fb7c98e
36 changed files with 677 additions and 236 deletions

View File

@ -257,5 +257,7 @@ Heres an example numbering two light guns and two XInput game controllers:
</input>
</system>
MAME applies ``mapdevice`` elements found inside any applicable ``system``
element.
MAME applies ``mapdevice`` elements found inside the first applicable ``system``
element only. To avoid confusion, its simplest place the ``system`` element
element applying to all systems (``name`` attribute set to ``default``) first
in the file, and use it to assign input device numbers.

View File

@ -308,7 +308,9 @@ Input provider modules are part of the OS-dependent layer (OSD), and are
not directly exposed to emulation and user interface code. Input
provider modules are responsible for detecting available host input
devices, setting up input devices for the input manager, and providing
callbacks to read the current state of input device items.
callbacks to read the current state of input device items. Input
provider modules may also provide additional default input assignments
suitable for host input devices that are present.
The user is given a choice of input modules to use. One input provider
module is used for each of the four input device classes (keyboard,

View File

@ -55,6 +55,8 @@ function osdmodulesbuild()
MAME_DIR .. "src/osd/watchdog.cpp",
MAME_DIR .. "src/osd/watchdog.h",
MAME_DIR .. "src/osd/interface/inputcode.h",
MAME_DIR .. "src/osd/interface/inputdev.h",
MAME_DIR .. "src/osd/interface/inputfwd.h",
MAME_DIR .. "src/osd/interface/inputman.h",
MAME_DIR .. "src/osd/interface/inputseq.cpp",
MAME_DIR .. "src/osd/interface/inputseq.h",

View File

@ -38,9 +38,10 @@
#include "emucore.h"
#include "xtal.h"
#include "eminline.h"
#include <cmath>
#undef min
#undef max
//**************************************************************************
// CONSTANTS

View File

@ -79,7 +79,6 @@
#include "parameters.h"
// the running machine
#include "main.h"
#include "machine.h"
#include "driver.h"

View File

@ -14,6 +14,8 @@
#pragma once
#include "utilfwd.h"
#include <type_traits>
@ -40,24 +42,6 @@ class osd_midi_device;
//----------------------------------
// lib/util
//----------------------------------
// declared in aviio.h
class avi_file;
// declared in chd.h
class chd_file;
// declared in unzip.h
namespace util { class archive_file; }
// declared in xmlfile.h
namespace util::xml { class data_node; class file; }
//----------------------------------
// emu
//----------------------------------
@ -195,6 +179,9 @@ namespace emu::detail { class machine_config_replace; }
struct internal_layout;
class machine_config;
// declared in main.h
class machine_manager;
// declared in natkeyboard.h
class natural_keyboard;

View File

@ -436,6 +436,18 @@ input_manager::~input_manager()
}
//-------------------------------------------------
// class_enabled - return whether input device
// class is enabled
//-------------------------------------------------
bool input_manager::class_enabled(input_device_class devclass) const
{
assert(devclass >= DEVICE_CLASS_FIRST_VALID && devclass <= DEVICE_CLASS_LAST_VALID);
return m_class[devclass]->enabled();
}
//-------------------------------------------------
// add_device - add a representation of a host
// input device
@ -659,16 +671,22 @@ std::string input_manager::code_name(input_code code) const
}
// append item name - redundant with joystick switch left/right/up/down
if ((device_class != DEVICE_CLASS_JOYSTICK) || (code.item_class() == ITEM_CLASS_SWITCH))
bool const joydir =
(device_class == DEVICE_CLASS_JOYSTICK) &&
(code.item_class() == ITEM_CLASS_SWITCH) &&
(code.item_modifier() >= ITEM_MODIFIER_LEFT) &&
(code.item_modifier() <= ITEM_MODIFIER_DOWN);
if (joydir)
{
if ((code.item_modifier() < ITEM_MODIFIER_LEFT) || (code.item_modifier() > ITEM_MODIFIER_DOWN))
str.append(item->name());
str.append((*modifier_string_table)[code.item_modifier()]);
}
else
{
str.append(item->name());
char const *const modifier = (*modifier_string_table)[code.item_modifier()];
if (modifier && *modifier)
str.append(" ").append(modifier);
}
// append the modifier
char const *const modifier = (*modifier_string_table)[code.item_modifier()];
if (modifier && *modifier)
str.append(" ").append(modifier);
return str;
}
@ -969,7 +987,7 @@ s32 input_manager::seq_axis_value(const input_seq &seq, input_item_class &itemcl
// saturate mixed absolute values, report neutral type
if (ITEM_CLASS_ABSOLUTE == itemclass)
result = std::clamp(result, osd::INPUT_ABSOLUTE_MIN, osd::INPUT_ABSOLUTE_MAX);
result = std::clamp(result, osd::input_device::ABSOLUTE_MIN, osd::input_device::ABSOLUTE_MAX);
else if (ITEM_CLASS_INVALID == itemclass)
itemclass = itemclasszero;
return result;

View File

@ -52,6 +52,7 @@ public:
~input_manager();
// OSD interface
virtual bool class_enabled(input_device_class devclass) const override;
virtual osd::input_device &add_device(input_device_class devclass, std::string_view name, std::string_view id, void *internal) override;
// getters

View File

@ -31,6 +31,7 @@ public:
input_device_switch_item(
input_device &device,
std::string_view name,
std::string_view tokenhint,
void *internal,
input_item_id itemid,
item_get_state_func getstate);
@ -62,6 +63,7 @@ public:
input_device_relative_item(
input_device &device,
std::string_view name,
std::string_view tokenhint,
void *internal,
input_item_id itemid,
item_get_state_func getstate);
@ -84,6 +86,7 @@ public:
input_device_absolute_item(
input_device &device,
std::string_view name,
std::string_view tokenhint,
void *internal,
input_item_id itemid,
item_get_state_func getstate);
@ -248,8 +251,8 @@ std::string joystick_map::to_string() const
u8 joystick_map::update(s32 xaxisval, s32 yaxisval)
{
// now map the X and Y axes to a 9x9 grid using the raw values
xaxisval = ((xaxisval - osd::INPUT_ABSOLUTE_MIN) * 9) / (osd::INPUT_ABSOLUTE_MAX - osd::INPUT_ABSOLUTE_MIN + 1);
yaxisval = ((yaxisval - osd::INPUT_ABSOLUTE_MIN) * 9) / (osd::INPUT_ABSOLUTE_MAX - osd::INPUT_ABSOLUTE_MIN + 1);
xaxisval = ((xaxisval - osd::input_device::ABSOLUTE_MIN) * 9) / (osd::input_device::ABSOLUTE_MAX - osd::input_device::ABSOLUTE_MIN + 1);
yaxisval = ((yaxisval - osd::input_device::ABSOLUTE_MIN) * 9) / (osd::input_device::ABSOLUTE_MAX - osd::input_device::ABSOLUTE_MIN + 1);
u8 mapval = m_map[yaxisval][xaxisval];
// handle stickiness
@ -279,7 +282,7 @@ input_device::input_device(input_manager &manager, std::string_view name, std::s
, m_devindex(-1)
, m_maxitem(input_item_id(0))
, m_internal(internal)
, m_threshold(std::max<s32>(s32(manager.machine().options().joystick_threshold() * osd::INPUT_ABSOLUTE_MAX), 1))
, m_threshold(std::max<s32>(s32(manager.machine().options().joystick_threshold() * osd::input_device::ABSOLUTE_MAX), 1))
, m_steadykey_enabled(manager.machine().options().steadykey())
, m_lightgun_reload_button(manager.machine().options().offscreen_reload())
{
@ -301,6 +304,7 @@ input_device::~input_device()
input_item_id input_device::add_item(
std::string_view name,
std::string_view tokenhint,
input_item_id itemid,
item_get_state_func getstate,
void *internal)
@ -325,15 +329,15 @@ input_item_id input_device::add_item(
switch (m_manager.device_class(devclass()).standard_item_class(originalid))
{
case ITEM_CLASS_SWITCH:
m_item[itemid] = std::make_unique<input_device_switch_item>(*this, name, internal, itemid, getstate);
m_item[itemid] = std::make_unique<input_device_switch_item>(*this, name, tokenhint, internal, itemid, getstate);
break;
case ITEM_CLASS_RELATIVE:
m_item[itemid] = std::make_unique<input_device_relative_item>(*this, name, internal, itemid, getstate);
m_item[itemid] = std::make_unique<input_device_relative_item>(*this, name, tokenhint, internal, itemid, getstate);
break;
case ITEM_CLASS_ABSOLUTE:
m_item[itemid] = std::make_unique<input_device_absolute_item>(*this, name, internal, itemid, getstate);
m_item[itemid] = std::make_unique<input_device_absolute_item>(*this, name, tokenhint, internal, itemid, getstate);
break;
default:
@ -347,6 +351,17 @@ input_item_id input_device::add_item(
}
//-------------------------------------------------
// set_default_assignments - set additional input
// assignments suitable for device
//-------------------------------------------------
void input_device::set_default_assignments(assignment_vector &&assignments)
{
m_default_assignments = std::move(assignments);
}
//-------------------------------------------------
// match_device_id - match device id via
// substring search
@ -432,8 +447,8 @@ input_device_lightgun::input_device_lightgun(input_manager &manager, std::string
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_deadzone(s32(manager.machine().options().joystick_deadzone() * osd::INPUT_ABSOLUTE_MAX))
, m_saturation(s32(manager.machine().options().joystick_saturation() * osd::INPUT_ABSOLUTE_MAX))
, m_deadzone(s32(manager.machine().options().joystick_deadzone() * osd::input_device::ABSOLUTE_MAX))
, m_saturation(s32(manager.machine().options().joystick_saturation() * osd::input_device::ABSOLUTE_MAX))
, m_range(m_saturation - m_deadzone)
{
// get the default joystick map
@ -468,9 +483,9 @@ s32 input_device_joystick::adjust_absolute_value(s32 result) const
if (result < m_deadzone) // if in the deadzone, return 0
result = 0;
else if (result >= m_saturation) // if saturated, return the max
result = osd::INPUT_ABSOLUTE_MAX;
result = osd::input_device::ABSOLUTE_MAX;
else // otherwise, scale
result = s64(result - m_deadzone) * s64(osd::INPUT_ABSOLUTE_MAX) / m_range;
result = s64(result - m_deadzone) * s64(osd::input_device::ABSOLUTE_MAX) / m_range;
// re-apply sign and return
return negative ? -result : result;
@ -687,6 +702,7 @@ bool input_class_joystick::set_global_joystick_map(const char *mapstring)
input_device_item::input_device_item(
input_device &device,
std::string_view name,
std::string_view tokenhint,
void *internal,
input_item_id itemid,
item_get_state_func getstate,
@ -705,6 +721,11 @@ input_device_item::input_device_item(
// use a standard token name for known item IDs
m_token = standard_token;
}
else if (!tokenhint.empty())
{
// fall back to token hint if supplied
m_token = tokenhint;
}
else
{
// otherwise, create a tokenized name
@ -732,7 +753,7 @@ input_device_item::~input_device_item()
bool input_device_item::check_axis(input_item_modifier modifier, s32 memory)
{
// use osd::INVALID_AXIS_VALUE as a short-circuit
return (memory != osd::INVALID_AXIS_VALUE) && item_check_axis(modifier, memory);
return (memory != osd::input_device::INVALID_AXIS_VALUE) && item_check_axis(modifier, memory);
}
@ -747,10 +768,11 @@ bool input_device_item::check_axis(input_item_modifier modifier, s32 memory)
input_device_switch_item::input_device_switch_item(
input_device &device,
std::string_view name,
std::string_view tokenhint,
void *internal,
input_item_id itemid,
item_get_state_func getstate)
: input_device_item(device, name, internal, itemid, getstate, ITEM_CLASS_SWITCH)
: input_device_item(device, name, tokenhint, internal, itemid, getstate, ITEM_CLASS_SWITCH)
, m_steadykey(0)
, m_oldkey(0)
{
@ -857,10 +879,11 @@ bool input_device_switch_item::steadykey_changed()
input_device_relative_item::input_device_relative_item(
input_device &device,
std::string_view name,
std::string_view tokenhint,
void *internal,
input_item_id itemid,
item_get_state_func getstate)
: input_device_item(device, name, internal, itemid, getstate, ITEM_CLASS_RELATIVE)
: input_device_item(device, name, tokenhint, internal, itemid, getstate, ITEM_CLASS_RELATIVE)
{
}
@ -927,7 +950,7 @@ bool input_device_relative_item::item_check_axis(input_item_modifier modifier, s
const s32 curval = read_as_relative(modifier);
// for relative axes, look for ~20 pixels movement
return std::abs(curval - memory) > (20 * osd::INPUT_RELATIVE_PER_PIXEL);
return std::abs(curval - memory) > (20 * osd::input_device::RELATIVE_PER_PIXEL);
}
@ -943,10 +966,11 @@ bool input_device_relative_item::item_check_axis(input_item_modifier modifier, s
input_device_absolute_item::input_device_absolute_item(
input_device &device,
std::string_view name,
std::string_view tokenhint,
void *internal,
input_item_id itemid,
item_get_state_func getstate)
: input_device_item(device, name, internal, itemid, getstate, ITEM_CLASS_ABSOLUTE)
: input_device_item(device, name, tokenhint, internal, itemid, getstate, ITEM_CLASS_ABSOLUTE)
{
}
@ -1020,7 +1044,7 @@ s32 input_device_absolute_item::read_as_absolute(input_item_modifier modifier)
{
// start with the current value
s32 result = m_device.adjust_absolute(update_value());
assert(result >= osd::INPUT_ABSOLUTE_MIN && result <= osd::INPUT_ABSOLUTE_MAX);
assert(result >= osd::input_device::ABSOLUTE_MIN && result <= osd::input_device::ABSOLUTE_MAX);
// if we're doing a lightgun reload hack, override the value
if (m_device.devclass() == DEVICE_CLASS_LIGHTGUN && m_device.lightgun_reload_button())
@ -1028,16 +1052,16 @@ s32 input_device_absolute_item::read_as_absolute(input_item_modifier modifier)
// if it is pressed, return (min,max)
input_device_item *button2_item = m_device.item(ITEM_ID_BUTTON2);
if (button2_item != nullptr && button2_item->update_value())
result = (m_itemid == ITEM_ID_XAXIS) ? osd::INPUT_ABSOLUTE_MIN : osd::INPUT_ABSOLUTE_MAX;
result = (m_itemid == ITEM_ID_XAXIS) ? osd::input_device::ABSOLUTE_MIN : osd::input_device::ABSOLUTE_MAX;
}
// positive/negative: scale to full axis
if (modifier == ITEM_MODIFIER_REVERSE)
result = -result;
else if (modifier == ITEM_MODIFIER_POS)
result = std::max(result, 0) * 2 + osd::INPUT_ABSOLUTE_MIN;
result = std::max(result, 0) * 2 + osd::input_device::ABSOLUTE_MIN;
else if (modifier == ITEM_MODIFIER_NEG)
result = std::max(-result, 0) * 2 + osd::INPUT_ABSOLUTE_MIN;
result = std::max(-result, 0) * 2 + osd::input_device::ABSOLUTE_MIN;
return result;
}
@ -1053,9 +1077,9 @@ bool input_device_absolute_item::item_check_axis(input_item_modifier modifier, s
// so the selection will not be affected by a gun going out of range
const s32 curval = read_as_absolute(modifier);
if (m_device.devclass() == DEVICE_CLASS_LIGHTGUN &&
(curval == osd::INPUT_ABSOLUTE_MAX || curval == osd::INPUT_ABSOLUTE_MIN))
(curval == osd::input_device::ABSOLUTE_MAX || curval == osd::input_device::ABSOLUTE_MIN))
return false;
// for absolute axes, look for 25% of maximum
return std::abs(curval - memory) > ((osd::INPUT_ABSOLUTE_MAX - osd::INPUT_ABSOLUTE_MIN) / 4);
return std::abs(curval - memory) > ((osd::input_device::ABSOLUTE_MAX - osd::input_device::ABSOLUTE_MIN) / 4);
}

View File

@ -13,7 +13,7 @@
#pragma once
#include "interface/inputman.h"
#include "interface/inputdev.h"
//**************************************************************************
@ -103,6 +103,7 @@ protected:
input_device_item(
input_device &device,
std::string_view name,
std::string_view tokenhint,
void *internal,
input_item_id itemid,
item_get_state_func getstate,
@ -142,6 +143,7 @@ public:
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(); }
const assignment_vector &default_assignments() const { return m_default_assignments; }
input_item_id maxitem() const { return m_maxitem; }
void *internal() const { return m_internal; }
s32 threshold() const { return m_threshold; }
@ -154,9 +156,11 @@ public:
// interface for host input device
virtual input_item_id add_item(
std::string_view name,
std::string_view tokenhint,
input_item_id itemid,
item_get_state_func getstate,
void *internal) override;
virtual void set_default_assignments(assignment_vector &&assignments) override;
// helpers
s32 adjust_absolute(s32 value) const { return adjust_absolute_value(value); }
@ -174,6 +178,7 @@ private:
std::string m_id; // id of device
int m_devindex; // device index of this device
std::unique_ptr<input_device_item> m_item[ITEM_ID_ABSOLUTE_MAXIMUM+1]; // array of pointers to items
assignment_vector m_default_assignments; // additional assignments
input_item_id m_maxitem; // maximum item index
void *const m_internal; // internal callback pointer

View File

@ -1787,6 +1787,7 @@ ioport_manager::ioport_manager(running_machine &machine)
, m_playback_accumulated_speed(0)
, m_playback_accumulated_frames(0)
, m_deselected_card_config()
, m_applied_device_defaults(false)
{
for (auto &entries : m_type_to_entry)
std::fill(std::begin(entries), std::end(entries), nullptr);
@ -2199,6 +2200,17 @@ s32 ioport_manager::frame_interpolate(s32 oldval, s32 newval)
void ioport_manager::load_config(config_type cfg_type, config_level cfg_level, util::xml::data_node const *parentnode)
{
// make sure device defaults get applied at some point
if ((cfg_type > config_type::CONTROLLER) && !m_applied_device_defaults)
{
apply_device_defaults();
// after applying controller config, push that to the backup, as it's what we'll diff against
for (input_type_entry &entry : m_typelist)
for (input_seq_type seqtype = SEQ_TYPE_STANDARD; seqtype < SEQ_TYPE_TOTAL; ++seqtype)
entry.defseq(seqtype) = entry.seq(seqtype);
}
// in the completion phase, we finish the initialization with the final ports
if (cfg_type == config_type::FINAL)
{
@ -2213,9 +2225,7 @@ void ioport_manager::load_config(config_type cfg_type, config_level cfg_level, u
// load device map table for controller configs only
if (cfg_type == config_type::CONTROLLER)
{
// iterate over all the remap nodes
load_remap_table(*parentnode);
// iterate over device remapping entries
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"))
{
@ -2225,9 +2235,23 @@ void ioport_manager::load_config(config_type cfg_type, config_level cfg_level, u
devicemap.emplace(devicename, controllername);
}
// map device to controller if we have a device map
if (!devicemap.empty())
machine().input().map_device_to_controller(devicemap);
// we can't rearrange controllers after applying device-supplied defaults
if (!m_applied_device_defaults)
{
// map device to controller if we have a device map
if (!devicemap.empty())
machine().input().map_device_to_controller(devicemap);
// add extra default assignments for input devices
apply_device_defaults();
}
else if (!devicemap.empty())
{
osd_printf_warning("Controller configuration: Only <mapdevice> elements from the first applicable <system> element are applied\n");
}
// iterate over any input code remapping nodes
load_remap_table(*parentnode);
}
// iterate over all the port nodes
@ -2270,16 +2294,16 @@ void ioport_manager::load_config(config_type cfg_type, config_level cfg_level, u
load_default_config(type, player, newseq);
}
// after applying the controller config, push that back into the backup, since that is
// what we will diff against
if (cfg_type == config_type::CONTROLLER)
{
// after applying the controller config, push that back into the backup, since that is what we will diff against
for (input_type_entry &entry : m_typelist)
for (input_seq_type seqtype = SEQ_TYPE_STANDARD; seqtype < SEQ_TYPE_TOTAL; ++seqtype)
entry.defseq(seqtype) = entry.seq(seqtype);
// load keyboard enable/disable state
if (cfg_type == config_type::SYSTEM)
}
else if (cfg_type == config_type::SYSTEM)
{
// load keyboard enable/disable state
std::vector<bool> kbd_enable_set;
bool keyboard_enabled = false, missing_enabled = false;
natural_keyboard &natkbd = machine().natkeyboard();
@ -2611,6 +2635,82 @@ void ioport_manager::load_system_config(
}
//-------------------------------------------------
// apply_device_defaults - add default assignments
// supplied by input devices
//-------------------------------------------------
void ioport_manager::apply_device_defaults()
{
// make sure this only happens once
assert(!m_applied_device_defaults);
m_applied_device_defaults = true;
// TODO: come up with a way to deal with non-multi device classes here?
for (input_device_class classno = DEVICE_CLASS_FIRST_VALID; DEVICE_CLASS_LAST_VALID >= classno; ++classno)
{
input_class &devclass = machine().input().device_class(classno);
for (int devnum = 0; devclass.maxindex() >= devnum; ++devnum)
{
// make sure device exists
input_device const *const device = devclass.device(devnum);
if (!device)
continue;
// iterate over default assignments
for (auto [porttype, seqtype, seq] : device->default_assignments())
{
assert(!seq.empty());
assert(seq.is_valid());
assert(!seq.is_default());
// only apply UI assignments for first device in a class
if ((IPT_UI_FIRST < porttype) && (IPT_UI_LAST > porttype) && (device->devindex() != 0))
continue;
// limit to maximum player count
if (device->devindex() >= MAX_PLAYERS)
continue;
// find a matching port in the list
auto const found = std::find_if(
m_typelist.begin(),
m_typelist.end(),
[type = porttype, device] (input_type_entry const &entry)
{
return (entry.type() == type) && (entry.player() == device->devindex());
});
if (m_typelist.end() == found)
continue;
// start with the current setting
input_seq remapped(found->seq(seqtype));
if (!remapped.empty())
remapped += input_seq::or_code;
// append adjusting the device index
for (int i = 0, len = seq.length(); i < len; ++i)
{
input_code code = seq[i];
if (!code.internal())
{
assert(code.device_class() == classno);
assert(code.device_index() == 0);
assert(code.item_id() >= ITEM_ID_FIRST_VALID);
assert(code.item_id() <= ITEM_ID_ABSOLUTE_MAXIMUM);
code.set_device_index(device->devindex());
}
remapped += code;
}
// apply to the entry
found->set_seq(seqtype, remapped);
}
}
}
}
//**************************************************************************
// SETTINGS SAVE
@ -3406,8 +3506,8 @@ analog_field::analog_field(ioport_field &field)
, m_accum(0)
, m_previous(0)
, m_previousanalog(0)
, m_minimum(osd::INPUT_ABSOLUTE_MIN)
, m_maximum(osd::INPUT_ABSOLUTE_MAX)
, m_minimum(osd::input_device::ABSOLUTE_MIN)
, m_maximum(osd::input_device::ABSOLUTE_MAX)
, m_center(0)
, m_reverse_val(0)
, m_scalepos(0)
@ -3441,7 +3541,7 @@ analog_field::analog_field(ioport_field &field)
case IPT_PEDAL:
case IPT_PEDAL2:
case IPT_PEDAL3:
m_center = osd::INPUT_ABSOLUTE_MIN;
m_center = osd::input_device::ABSOLUTE_MIN;
m_accum = apply_inverse_sensitivity(m_center);
m_absolute = true;
m_autocenter = true;
@ -3460,7 +3560,7 @@ analog_field::analog_field(ioport_field &field)
// set each position to be 512 units
case IPT_POSITIONAL:
case IPT_POSITIONAL_V:
m_positionalscale = compute_scale(field.maxval(), osd::INPUT_ABSOLUTE_MAX - osd::INPUT_ABSOLUTE_MIN);
m_positionalscale = compute_scale(field.maxval(), osd::input_device::ABSOLUTE_MAX - osd::input_device::ABSOLUTE_MIN);
m_adjmin = 0;
m_adjmax = field.maxval() - 1;
m_wraps = field.analog_wraps();
@ -3499,10 +3599,10 @@ analog_field::analog_field(ioport_field &field)
// unsigned, potentially passing through zero
m_scalepos = compute_scale(
(m_adjmax - m_adjdefvalue) & (field.mask() >> m_shift),
osd::INPUT_ABSOLUTE_MAX);
osd::input_device::ABSOLUTE_MAX);
m_scaleneg = compute_scale(
(m_adjdefvalue - m_adjmin) & (field.mask() >> m_shift),
-osd::INPUT_ABSOLUTE_MIN);
-osd::input_device::ABSOLUTE_MIN);
// reverse point is at center
m_reverse_val = 0;
@ -3510,7 +3610,7 @@ analog_field::analog_field(ioport_field &field)
else
{
// single axis that increases from default
m_scalepos = compute_scale(m_adjmax - m_adjmin, osd::INPUT_ABSOLUTE_MAX - osd::INPUT_ABSOLUTE_MIN);
m_scalepos = compute_scale(m_adjmax - m_adjmin, osd::input_device::ABSOLUTE_MAX - osd::input_device::ABSOLUTE_MIN);
// make the scaling the same for easier coding when we need to scale
m_scaleneg = m_scalepos;
@ -3534,11 +3634,11 @@ analog_field::analog_field(ioport_field &field)
if (m_wraps)
m_adjmax++;
m_minimum = (m_adjmin - m_adjdefvalue) * osd::INPUT_RELATIVE_PER_PIXEL;
m_maximum = (m_adjmax - m_adjdefvalue) * osd::INPUT_RELATIVE_PER_PIXEL;
m_minimum = (m_adjmin - m_adjdefvalue) * osd::input_device::RELATIVE_PER_PIXEL;
m_maximum = (m_adjmax - m_adjdefvalue) * osd::input_device::RELATIVE_PER_PIXEL;
// make the scaling the same for easier coding when we need to scale
m_scaleneg = m_scalepos = compute_scale(1, osd::INPUT_RELATIVE_PER_PIXEL);
m_scaleneg = m_scalepos = compute_scale(1, osd::input_device::RELATIVE_PER_PIXEL);
if (m_field.analog_reset())
{
@ -3553,11 +3653,11 @@ analog_field::analog_field(ioport_field &field)
// relative controls reverse from 1 past their max range
if (m_wraps)
{
// FIXME: positional needs -1, using osd::INPUT_RELATIVE_PER_PIXEL skips a position (and reads outside the table array)
// FIXME: positional needs -1, using osd::input_device::RELATIVE_PER_PIXEL skips a position (and reads outside the table array)
if (field.type() == IPT_POSITIONAL || field.type() == IPT_POSITIONAL_V)
m_reverse_val--;
else
m_reverse_val -= osd::INPUT_RELATIVE_PER_PIXEL;
m_reverse_val -= osd::input_device::RELATIVE_PER_PIXEL;
}
}
}
@ -3630,7 +3730,7 @@ s32 analog_field::apply_settings(s32 value) const
else if (m_single_scale)
// it's a pedal or the default value is equal to min/max
// so we need to adjust the center to the minimum
value -= osd::INPUT_ABSOLUTE_MIN;
value -= osd::input_device::ABSOLUTE_MIN;
// map differently for positive and negative values
if (value >= 0)
@ -3735,7 +3835,7 @@ void analog_field::frame_update(running_machine &machine)
// if port is positional, we will take the full analog control and divide it
// into positions, that way as the control is moved full scale,
// it moves through all the positions
rawvalue = apply_scale(rawvalue - osd::INPUT_ABSOLUTE_MIN, m_positionalscale) * osd::INPUT_RELATIVE_PER_PIXEL + m_minimum;
rawvalue = apply_scale(rawvalue - osd::input_device::ABSOLUTE_MIN, m_positionalscale) * osd::input_device::RELATIVE_PER_PIXEL + m_minimum;
// clamp the high value so it does not roll over
rawvalue = std::min(rawvalue, m_maximum);

View File

@ -49,7 +49,7 @@ constexpr char32_t UCHAR_MAMEKEY_BEGIN = UCHAR_PRIVATE + 2;
// sequence types for input_port_seq() call
enum input_seq_type
enum input_seq_type : int
{
SEQ_TYPE_INVALID = -1,
SEQ_TYPE_STANDARD = 0,
@ -90,7 +90,7 @@ enum ioport_group
// various input port types
enum ioport_type
enum ioport_type : u32
{
// pseudo-port types
IPT_INVALID = 0,
@ -1165,8 +1165,8 @@ private:
ioport_field & m_field; // pointer to the input field referenced
// adjusted values (right-justified and tweaked)
u8 m_shift; // shift to align final value in the port
s32 m_adjdefvalue; // adjusted default value from the config
u8 const m_shift; // shift to align final value in the port
s32 const m_adjdefvalue; // adjusted default value from the config
s32 m_adjmin; // adjusted minimum value from the config
s32 m_adjmax; // adjusted maximum value from the config
s32 m_adjoverride; // programmatically set adjusted value
@ -1303,6 +1303,7 @@ private:
bool load_default_config(int type, int player, const std::pair<input_seq, char const *> (&newseq)[SEQ_TYPE_TOTAL]);
bool load_controller_config(util::xml::data_node const &portnode, int type, int player, const std::pair<input_seq, char const *> (&newseq)[SEQ_TYPE_TOTAL]);
void load_system_config(util::xml::data_node const &portnode, int type, int player, const std::pair<input_seq, char const *> (&newseq)[SEQ_TYPE_TOTAL]);
void apply_device_defaults();
void save_config(config_type cfg_type, util::xml::data_node *parentnode);
bool save_this_input_field_type(ioport_type type);
@ -1347,6 +1348,7 @@ private:
// storage for inactive configuration
std::unique_ptr<util::xml::file> m_deselected_card_config;
bool m_applied_device_defaults;
};

View File

@ -6,18 +6,17 @@
Controls execution of the core emulator system.
***************************************************************************/
#pragma once
#ifndef __EMU_H__
#error Dont include this file directly; include emu.h instead.
#endif
#ifndef MAME_EMU_MAIN_H
#define MAME_EMU_MAIN_H
#include <thread>
#include <ctime>
#pragma once
#include "emufwd.h"
#include <memory>
#include <string>
#include <vector>
//**************************************************************************
// CONSTANTS
@ -66,10 +65,11 @@ public:
class machine_manager
{
DISABLE_COPYING(machine_manager);
protected:
// construction/destruction
machine_manager(emu_options& options, osd_interface& osd);
machine_manager(emu_options &options, osd_interface &osd);
machine_manager(machine_manager const &) = delete;
public:
virtual ~machine_manager();

View File

@ -1389,7 +1389,7 @@ void output_input(std::ostream &out, const ioport_list &portlist)
int player; // player which the input belongs to
int nbuttons; // total number of buttons
int reqbuttons; // total number of non-optional buttons
int maxbuttons; // max index of buttons (using IPT_BUTTONn) [probably to be removed soonish]
uint32_t maxbuttons; // max index of buttons (using IPT_BUTTONn) [probably to be removed soonish]
int ways; // directions for joystick
bool analog; // is analog input?
uint8_t helper[3]; // for dual joysticks [possibly to be removed soonish]
@ -1404,7 +1404,7 @@ void output_input(std::ostream &out, const ioport_list &portlist)
// tracking info as we iterate
int nplayer = 0;
int ncoin = 0;
uint32_t ncoin = 0;
bool service = false;
bool tilt = false;
@ -1732,7 +1732,7 @@ void output_input(std::ostream &out, const ioport_list &portlist)
out << "\t\t<input";
util::stream_format(out, " players=\"%d\"", nplayer);
if (ncoin != 0)
util::stream_format(out, " coins=\"%d\"", ncoin);
util::stream_format(out, " coins=\"%u\"", ncoin);
if (service)
util::stream_format(out, " service=\"yes\"");
if (tilt)
@ -1751,7 +1751,7 @@ void output_input(std::ostream &out, const ioport_list &portlist)
util::stream_format(out, " player=\"%d\"", elem.player);
if (elem.nbuttons > 0)
{
util::stream_format(out, " buttons=\"%d\"", strcmp(elem.type, "stick") ? elem.nbuttons : elem.maxbuttons);
util::stream_format(out, " buttons=\"%u\"", strcmp(elem.type, "stick") ? elem.nbuttons : elem.maxbuttons);
if (elem.reqbuttons < elem.nbuttons)
util::stream_format(out, " reqbuttons=\"%d\"", elem.reqbuttons);
}
@ -1777,7 +1777,7 @@ void output_input(std::ostream &out, const ioport_list &portlist)
util::stream_format(out, " player=\"%d\"", elem.player);
if (elem.nbuttons > 0)
{
util::stream_format(out, " buttons=\"%d\"", strcmp(elem.type, "joy") ? elem.nbuttons : elem.maxbuttons);
util::stream_format(out, " buttons=\"%u\"", strcmp(elem.type, "joy") ? elem.nbuttons : elem.maxbuttons);
if (elem.reqbuttons < elem.nbuttons)
util::stream_format(out, " reqbuttons=\"%d\"", elem.reqbuttons);
}

View File

@ -246,8 +246,13 @@ void menu_analog::handle(event const *ev)
switch (ev->iptkey)
{
// if selected, reset to default value
// flip toggles when selected
case IPT_UI_SELECT:
if (ANALOG_ITEM_REVERSE == data.type)
newval = newval ? 0 : 1;
break;
// if cleared, reset to default value
case IPT_UI_CLEAR:
newval = data.defvalue;
break;

View File

@ -89,12 +89,12 @@ protected:
s32 const value = (input.itemclass() == ITEM_CLASS_ABSOLUTE) ? input.read_as_absolute(ITEM_MODIFIER_NONE) : input.read_as_relative(ITEM_MODIFIER_NONE);
if (0 < value)
{
float const fillright = indcentre + (float(value) / float(osd::INPUT_ABSOLUTE_MAX) * (indright - indcentre));
float const fillright = indcentre + (float(value) / float(osd::input_device::ABSOLUTE_MAX) * (indright - indcentre));
container().add_rect(indcentre, indtop, (std::min)(fillright, indright), indbottom, fgcolor, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA));
}
else if (0 > value)
{
float const fillleft = indcentre - (float(value) / float(osd::INPUT_ABSOLUTE_MIN) * (indcentre - indleft));
float const fillleft = indcentre - (float(value) / float(osd::input_device::ABSOLUTE_MIN) * (indcentre - indleft));
container().add_rect((std::max)(fillleft, indleft), indtop, indcentre, indbottom, fgcolor, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA));
}
container().add_line(indleft, indtop, indright, indtop, UI_LINE_WIDTH, fgcolor, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA));

View File

@ -119,14 +119,13 @@ void menu_input_toggles::handle(event const *ev)
bool invalidate = false;
switch (ev->iptkey)
{
case IPT_UI_SELECT: // toggle regular items, set multi-value items to default
case IPT_UI_SELECT: // toggle regular items, cycle multi-value items
if (field.settings().empty())
{
field.live().value ^= field.mask();
invalidate = true;
break;
}
[[fallthrough]];
else
field.select_next_setting();
invalidate = true;
break;
case IPT_UI_CLEAR: // set to default
if (field.defvalue() != field.live().value)

View File

@ -15,19 +15,73 @@
#include "ui/utils.h"
#include <string_view>
#include <utility>
namespace ui {
namespace {
inline std::string_view split_column(std::string_view &line)
{
auto const split = line.find('\t');
if (std::string::npos == split)
{
return std::exchange(line, std::string_view());
}
else
{
std::string_view result = line.substr(0, split);
line.remove_prefix(split + 1);
return result;
}
}
template <typename T, typename U, typename V>
void populate_three_column_layout(std::string_view text, T &&l, U &&c, V &&r)
{
while (!text.empty())
{
// pop a line from the front
auto const eol = text.find('\n');
std::string_view line = (std::string_view::npos != eol)
? text.substr(0, eol + 1)
: text;
text.remove_prefix(line.length());
// left-justify up to the first tab
std::string_view const lcol = split_column(line);
if (!lcol.empty())
l(lcol);
// centre up to the second tab
if (!line.empty())
{
std::string_view const ccol = split_column(line);
if (!ccol.empty())
c(ccol);
}
// right-justify the rest
if (!line.empty())
r(line);
}
}
} // anonymous namespace
//-------------------------------------------------
// constructor
// menu_textbox - base text box menu class
//-------------------------------------------------
menu_textbox::menu_textbox(mame_ui_manager &mui, render_container &container)
: menu(mui, container)
, m_layout()
, m_layout_width(-1.0f)
, m_desired_width(-1.0f)
, m_layout_width(-1.0F)
, m_desired_width(-1.0F)
, m_desired_lines(-1)
, m_window_lines(0)
, m_top_line(0)
@ -35,31 +89,19 @@ menu_textbox::menu_textbox(mame_ui_manager &mui, render_container &container)
}
//-------------------------------------------------
// destructor
//-------------------------------------------------
menu_textbox::~menu_textbox()
{
}
//-------------------------------------------------
// reset_layout - force repopulate and scroll to
// top
//-------------------------------------------------
void menu_textbox::reset_layout()
{
// force recompute and scroll to top
m_layout = std::nullopt;
m_top_line = 0;
}
//-------------------------------------------------
// handle_key - handle basic navigation keys
//-------------------------------------------------
void menu_textbox::handle_key(int key)
{
switch (key)
@ -91,10 +133,6 @@ void menu_textbox::handle_key(int key)
}
//-------------------------------------------------
// recompute_metrics - recompute metrics
//-------------------------------------------------
void menu_textbox::recompute_metrics(uint32_t width, uint32_t height, float aspect)
{
menu::recompute_metrics(width, height, aspect);
@ -103,10 +141,6 @@ void menu_textbox::recompute_metrics(uint32_t width, uint32_t height, float aspe
}
//-------------------------------------------------
// custom_mouse_scroll - handle scroll events
//-------------------------------------------------
bool menu_textbox::custom_mouse_scroll(int lines)
{
m_top_line += lines;
@ -114,25 +148,21 @@ bool menu_textbox::custom_mouse_scroll(int lines)
}
//-------------------------------------------------
// draw - draw the menu
//-------------------------------------------------
void menu_textbox::draw(uint32_t flags)
{
float const visible_width = 1.0f - (2.0f * lr_border());
float const visible_left = (1.0f - visible_width) * 0.5f;
float const extra_height = 2.0f * line_height();
float const visible_width = 1.0F - (2.0F * lr_border());
float const visible_left = (1.0F - visible_width) * 0.5F;
float const extra_height = 2.0F * line_height();
float const visible_extra_menu_height = get_customtop() + get_custombottom() + extra_height;
// determine effective positions
float const maximum_width = visible_width - (2.0f * gutter_width());
float const maximum_width = visible_width - (2.0F * gutter_width());
draw_background();
map_mouse();
// account for extra space at the top and bottom and the separator/item for closing
float visible_main_menu_height = 1.0f - 2.0f * tb_border() - visible_extra_menu_height;
float visible_main_menu_height = 1.0F - 2.0F * tb_border() - visible_extra_menu_height;
m_window_lines = int(std::trunc(visible_main_menu_height / line_height()));
// lay out the text if necessary
@ -146,7 +176,7 @@ void menu_textbox::draw(uint32_t flags)
visible_main_menu_height = float(m_window_lines) * line_height();
// compute top/left of inner menu area by centering, if the menu is at the bottom of the extra, adjust
float const visible_top = ((1.0f - (visible_main_menu_height + visible_extra_menu_height)) * 0.5f) + get_customtop();
float const visible_top = ((1.0F - (visible_main_menu_height + visible_extra_menu_height)) * 0.5F) + get_customtop();
// get width required to draw the sole menu item
menu_item const &pitem = item(0);
@ -155,13 +185,13 @@ void menu_textbox::draw(uint32_t flags)
float const draw_width = std::min(maximum_width, std::max(itemwidth, m_desired_width));
// compute text box size
float const x1 = visible_left + ((maximum_width - draw_width) * 0.5f);
float const x1 = visible_left + ((maximum_width - draw_width) * 0.5F);
float const y1 = visible_top - tb_border();
float const x2 = visible_left + visible_width - ((maximum_width - draw_width) * 0.5f);
float const x2 = visible_left + visible_width - ((maximum_width - draw_width) * 0.5F);
float const y2 = visible_top + visible_main_menu_height + tb_border() + extra_height;
float const effective_left = x1 + gutter_width();
float const line_x0 = x1 + 0.5f * UI_LINE_WIDTH;
float const line_x1 = x2 - 0.5f * UI_LINE_WIDTH;
float const line_x0 = x1 + 0.5F * UI_LINE_WIDTH;
float const line_x1 = x2 - 0.5F * UI_LINE_WIDTH;
float const separator = visible_top + float(m_window_lines) * line_height();
ui().draw_outlined_box(container(), x1, y1, x2, y2, ui().colors().background_color());
@ -187,8 +217,8 @@ void menu_textbox::draw(uint32_t flags)
set_hover(HOVER_ARROW_UP);
}
draw_arrow(
0.5f * (x1 + x2 - ud_arrow_width()), visible_top + (0.25f * line_height()),
0.5f * (x1 + x2 + ud_arrow_width()), visible_top + (0.75f * line_height()),
0.5F * (x1 + x2 - ud_arrow_width()), visible_top + (0.25F * line_height()),
0.5F * (x1 + x2 + ud_arrow_width()), visible_top + (0.75F * line_height()),
fgcolor, ROT0);
}
if ((m_top_line + m_window_lines) < visible_items)
@ -206,8 +236,8 @@ void menu_textbox::draw(uint32_t flags)
set_hover(HOVER_ARROW_DOWN);
}
draw_arrow(
0.5f * (x1 + x2 - ud_arrow_width()), line_y + (0.25f * line_height()),
0.5f * (x1 + x2 + ud_arrow_width()), line_y + (0.75f * line_height()),
0.5F * (x1 + x2 - ud_arrow_width()), line_y + (0.25F * line_height()),
0.5F * (x1 + x2 + ud_arrow_width()), line_y + (0.75F * line_height()),
fgcolor, ROT0 ^ ORIENTATION_FLIP_Y);
}
@ -216,12 +246,12 @@ void menu_textbox::draw(uint32_t flags)
m_layout->emit(
container(),
m_top_line ? (m_top_line + 1) : 0, text_lines,
effective_left, visible_top + (m_top_line ? line_height() : 0.0f));
effective_left, visible_top + (m_top_line ? line_height() : 0.0F));
// add visual separator before the "return to prevous menu" item
container().add_line(
x1, separator + (0.5f * line_height()),
x2, separator + (0.5f * line_height()),
x1, separator + (0.5F * line_height()),
x2, separator + (0.5F * line_height()),
UI_LINE_WIDTH, ui().colors().text_color(), PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA));
float const line_y0 = separator + line_height();
@ -244,4 +274,101 @@ void menu_textbox::draw(uint32_t flags)
custom_render(get_selection_ref(), get_customtop(), get_custombottom(), x1, y1, x2, y2);
}
//-------------------------------------------------
// menu_fixed_textbox - text box with three-
// column content supplied at construction
//-------------------------------------------------
menu_fixed_textbox::menu_fixed_textbox(
mame_ui_manager &mui,
render_container &container,
std::string &&heading,
std::string &&content)
: menu_textbox(mui, container)
, m_heading(std::move(heading))
, m_content(std::move(content))
{
}
menu_fixed_textbox::~menu_fixed_textbox()
{
}
void menu_fixed_textbox::recompute_metrics(uint32_t width, uint32_t height, float aspect)
{
menu_textbox::recompute_metrics(width, height, aspect);
set_custom_space(line_height() + 3.0F * tb_border(), 0.0F);
}
void menu_fixed_textbox::custom_render(void *selectedref, float top, float bottom, float x1, float y1, float x2, float y2)
{
std::string_view const toptext[] = { m_heading };
draw_text_box(
std::begin(toptext), std::end(toptext),
x1, x2, y1 - top, y1 - tb_border(),
text_layout::text_justify::CENTER, text_layout::word_wrapping::NEVER, false,
ui().colors().text_color(), UI_GREEN_COLOR);
}
void menu_fixed_textbox::populate_text(
std::optional<text_layout> &layout,
float &width,
int &lines)
{
// ugly - use temporary layouts to compute required width
{
text_layout l(create_layout(width));
text_layout c(create_layout(width));
text_layout r(create_layout(width));
populate_three_column_layout(
m_content,
[&l] (std::string_view s)
{
l.add_text(s, text_layout::text_justify::LEFT);
if (s.back() != '\n')
l.add_text("\n", text_layout::text_justify::LEFT);
},
[&c] (std::string_view s) {
c.add_text(s, text_layout::text_justify::LEFT);
if (s.back() != '\n')
c.add_text("\n", text_layout::text_justify::LEFT);
},
[&r] (std::string_view s) {
r.add_text(s, text_layout::text_justify::LEFT);
if (s.back() != '\n')
r.add_text("\n", text_layout::text_justify::LEFT);
});
width = (std::min)(l.actual_width() + c.actual_width() + r.actual_width(), width);
}
// now do it for real
layout.emplace(create_layout(width));
rgb_t const color = ui().colors().text_color();
populate_three_column_layout(
m_content,
[&layout, color] (std::string_view s) { layout->add_text(s, text_layout::text_justify::LEFT, color); },
[&layout, color] (std::string_view s) { layout->add_text(s, text_layout::text_justify::CENTER, color); },
[&layout, color] (std::string_view s) { layout->add_text(s, text_layout::text_justify::RIGHT, color); });
lines = layout->lines();
}
void menu_fixed_textbox::populate()
{
}
void menu_fixed_textbox::handle(event const *ev)
{
if (ev)
handle_key(ev->iptkey);
}
} // namespace ui

View File

@ -14,6 +14,7 @@
#include "ui/text.h"
#include <optional>
#include <string>
namespace ui {
@ -45,6 +46,31 @@ private:
int m_top_line;
};
class menu_fixed_textbox : public menu_textbox
{
public:
menu_fixed_textbox(
mame_ui_manager &mui,
render_container &container,
std::string &&headig,
std::string &&content);
virtual ~menu_fixed_textbox() override;
protected:
virtual void recompute_metrics(uint32_t width, uint32_t height, float aspect) override;
virtual void custom_render(void *selectedref, float top, float bottom, float x, float y, float x2, float y2) override;
virtual void populate_text(std::optional<text_layout> &layout, float &width, int &lines) override;
private:
virtual void populate() override;
virtual void handle(event const *ev) override;
std::string const m_heading;
std::string const m_content;
};
} // namespace ui
#endif // MAME_FRONTEND_UI_TEXTBOX_H

View File

@ -10,6 +10,9 @@
#ifndef MAME_LIB_UTIL_UTILFWD_H
#define MAME_LIB_UTIL_UTILFWD_H
// aviio.h
class avi_file;
// chd.h
class chd_file;

View File

@ -4,7 +4,7 @@
inputcode.h
Codes for representing host inputs
Codes for representing host controls
***************************************************************************/
#ifndef MAME_OSD_INTERFACE_INPUTCODE_H

View File

@ -0,0 +1,66 @@
// license:BSD-3-Clause
// copyright-holders:Aaron Giles
/***************************************************************************
inputdev.h
OSD interface to input devices
***************************************************************************/
#ifndef MAME_OSD_INTERFACE_INPUTDEV_H
#define MAME_OSD_INTERFACE_INPUTDEV_H
#pragma once
#include "inputcode.h"
#include "inputfwd.h"
#include <string_view>
#include <tuple>
#include <vector>
namespace osd {
//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
// base for application representation of host input device
class input_device
{
protected:
virtual ~input_device() = default;
public:
using assignment_vector = std::vector<std::tuple<ioport_type, input_seq_type, input_seq> >;
// relative devices return ~512 units per on-screen pixel
static inline constexpr s32 RELATIVE_PER_PIXEL = 512;
// absolute devices return values between -65536 and +65536
static inline constexpr s32 ABSOLUTE_MIN = -65'536;
static inline constexpr s32 ABSOLUTE_MAX = 65'536;
// invalid memory value for axis polling
static inline constexpr s32 INVALID_AXIS_VALUE = 0x7fff'ffff;
// callback for getting the value of an individual input on a device
typedef s32 (*item_get_state_func)(void *device_internal, void *item_internal);
// add a control item to an input device
virtual input_item_id add_item(
std::string_view name,
std::string_view tokenhint,
input_item_id itemid,
item_get_state_func getstate,
void *internal) = 0;
// set additional default assignments suitable for device
virtual void set_default_assignments(assignment_vector &&assignments) = 0;
};
} // namespace osd
#endif // MAME_OSD_INTERFACE_INPUTDEV_H

View File

@ -0,0 +1,36 @@
// license:BSD-3-Clause
// copyright-holders:Aaron Giles
/***************************************************************************
inputfwd.h
Forward declarations for OSD input interface types
***************************************************************************/
#ifndef MAME_OSD_INTERFACE_INPUTFWD_H
#define MAME_OSD_INTERFACE_INPUTFWD_H
#include <cstdint>
#pragma once
//**************************************************************************
// FORWARD DECLARATIONS
//**************************************************************************
enum ioport_type : std::uint32_t;
enum input_seq_type : int;
class input_code;
namespace osd {
class input_device;
class input_manager;
class input_seq;
} // namespace osd
#endif // MAME_OSD_INTERFACE_INPUTFWD_H

View File

@ -4,7 +4,7 @@
inputman.h
OSD interface to the input manager.
OSD interface to the input manager
***************************************************************************/
#ifndef MAME_OSD_INTERFACE_INPUTMAN_H
@ -13,57 +13,27 @@
#pragma once
#include "inputcode.h"
#include "inputfwd.h"
#include <string_view>
namespace osd {
//**************************************************************************
// CONSTANTS
//**************************************************************************
// relative devices return ~512 units per on-screen pixel
constexpr s32 INPUT_RELATIVE_PER_PIXEL = 512;
// absolute devices return values between -65536 and +65536
constexpr s32 INPUT_ABSOLUTE_MIN = -65'536;
constexpr s32 INPUT_ABSOLUTE_MAX = 65'536;
// invalid memory value for axis polling
constexpr s32 INVALID_AXIS_VALUE = 0x7fff'ffff;
//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
// base for application representation of host input device
class input_device
{
public:
// callback for getting the value of an individual input on a device
typedef s32 (*item_get_state_func)(void *device_internal, void *item_internal);
virtual ~input_device() = default;
virtual input_item_id add_item(
std::string_view name,
input_item_id itemid,
item_get_state_func getstate,
void *internal = nullptr) = 0;
};
// base for application input manager
// interface to application input manager
class input_manager
{
public:
protected:
virtual ~input_manager() = default;
public:
virtual bool class_enabled(input_device_class devclass) const = 0;
virtual input_device &add_device(
input_device_class devclass,
std::string_view name,
@ -71,7 +41,6 @@ public:
void *internal = nullptr) = 0;
};
} // namespace osd
#endif // MAME_OSD_INTERFACE_INPUTMAN_H

View File

@ -14,6 +14,7 @@
#include "input_module.h"
#include "interface/inputdev.h"
#include "interface/inputman.h"
#include "modules/osdmodule.h"
@ -562,14 +563,14 @@ inline int32_t normalize_absolute_axis(double raw, double rawmin, double rawmax)
if (raw >= center)
{
// above center
double const result = (raw - center) * double(osd::INPUT_ABSOLUTE_MAX) / (rawmax - center);
return int32_t(std::min(result, double(osd::INPUT_ABSOLUTE_MAX)));
double const result = (raw - center) * double(osd::input_device::ABSOLUTE_MAX) / (rawmax - center);
return int32_t(std::min(result, double(osd::input_device::ABSOLUTE_MAX)));
}
else
{
// below center
double result = -((center - raw) * double(-osd::INPUT_ABSOLUTE_MIN) / (center - rawmin));
return int32_t(std::max(result, double(osd::INPUT_ABSOLUTE_MIN)));
double result = -((center - raw) * double(-osd::input_device::ABSOLUTE_MIN) / (center - rawmin));
return int32_t(std::max(result, double(osd::input_device::ABSOLUTE_MIN)));
}
}

View File

@ -323,6 +323,7 @@ void dinput_keyboard_device::configure(input_device &device)
// add the item to the device
device.add_item(
item_name(keynum, defname, nullptr),
strmakeupper(defname),
itemid,
generic_button_get_state<std::uint8_t>,
&m_keyboard.state[keynum]);
@ -355,9 +356,9 @@ void dinput_mouse_device::poll()
if (poll_dinput(&m_mouse) == DI_OK)
{
// scale the axis data
m_mouse.lX *= INPUT_RELATIVE_PER_PIXEL;
m_mouse.lY *= INPUT_RELATIVE_PER_PIXEL;
m_mouse.lZ *= INPUT_RELATIVE_PER_PIXEL;
m_mouse.lX *= input_device::RELATIVE_PER_PIXEL;
m_mouse.lY *= input_device::RELATIVE_PER_PIXEL;
m_mouse.lZ *= input_device::RELATIVE_PER_PIXEL;
}
}
@ -374,6 +375,7 @@ void dinput_mouse_device::configure(input_device &device)
// add to the mouse device and optionally to the gun device as well
device.add_item(
item_name(offsetof(DIMOUSESTATE, lX) + axisnum * sizeof(LONG), default_axis_name[axisnum], nullptr),
std::string_view(),
input_item_id(ITEM_ID_XAXIS + axisnum),
generic_axis_get_state<LONG>,
&m_mouse.lX + axisnum);
@ -387,6 +389,7 @@ void dinput_mouse_device::configure(input_device &device)
// add to the mouse device
device.add_item(
item_name(offset, default_button_name(butnum), nullptr),
std::string_view(),
input_item_id(ITEM_ID_BUTTON1 + butnum),
generic_button_get_state<BYTE>,
&m_mouse.rgbButtons[butnum]);
@ -470,6 +473,7 @@ void dinput_joystick_device::configure(input_device &device)
// populate the item description as well
device.add_item(
item_name(offsetof(DIJOYSTATE2, lX) + axisnum * sizeof(LONG), default_axis_name[axisnum], nullptr),
std::string_view(),
input_item_id(ITEM_ID_XAXIS + axisnum),
generic_axis_get_state<LONG>,
&m_joystick.state.lX + axisnum);
@ -483,6 +487,7 @@ void dinput_joystick_device::configure(input_device &device)
// left
device.add_item(
item_name(offsetof(DIJOYSTATE2, rgdwPOV) + povnum * sizeof(DWORD), default_pov_name(povnum), "Left"),
std::string_view(),
input_item_id(povnum * 4 + ITEM_ID_HAT1LEFT),
&dinput_joystick_device::pov_get_state,
reinterpret_cast<void *>(uintptr_t(povnum * 4 + POVDIR_LEFT)));
@ -490,6 +495,7 @@ void dinput_joystick_device::configure(input_device &device)
// right
device.add_item(
item_name(offsetof(DIJOYSTATE2, rgdwPOV) + povnum * sizeof(DWORD), default_pov_name(povnum), "Right"),
std::string_view(),
input_item_id(povnum * 4 + ITEM_ID_HAT1RIGHT),
&dinput_joystick_device::pov_get_state,
reinterpret_cast<void *>(uintptr_t(povnum * 4 + POVDIR_RIGHT)));
@ -497,6 +503,7 @@ void dinput_joystick_device::configure(input_device &device)
// up
device.add_item(
item_name(offsetof(DIJOYSTATE2, rgdwPOV) + povnum * sizeof(DWORD), default_pov_name(povnum), "Up"),
std::string_view(),
input_item_id(povnum * 4 + ITEM_ID_HAT1UP),
&dinput_joystick_device::pov_get_state,
reinterpret_cast<void *>(uintptr_t(povnum * 4 + POVDIR_UP)));
@ -504,6 +511,7 @@ void dinput_joystick_device::configure(input_device &device)
// down
device.add_item(
item_name(offsetof(DIJOYSTATE2, rgdwPOV) + povnum * sizeof(DWORD), default_pov_name(povnum), "Down"),
std::string_view(),
input_item_id(povnum * 4 + ITEM_ID_HAT1DOWN),
&dinput_joystick_device::pov_get_state,
reinterpret_cast<void *>(uintptr_t(povnum * 4 + POVDIR_DOWN)));
@ -524,6 +532,7 @@ void dinput_joystick_device::configure(input_device &device)
device.add_item(
item_name(offset, default_button_name(butnum), nullptr),
std::string_view(),
itemid,
generic_button_get_state<BYTE>,
&m_joystick.state.rgbButtons[butnum]);

View File

@ -346,6 +346,7 @@ public:
// add the item to the device
device.add_item(
name,
util::string_format("SCAN%03d", keynum),
itemid,
generic_button_get_state<std::uint8_t>,
&m_keyboard.state[keynum]);
@ -391,6 +392,7 @@ public:
{
device.add_item(
default_axis_name[axisnum],
std::string_view(),
input_item_id(ITEM_ID_XAXIS + axisnum),
generic_axis_get_state<LONG>,
&m_mouse.lX + axisnum);
@ -401,6 +403,7 @@ public:
{
device.add_item(
default_button_name(butnum),
std::string_view(),
input_item_id(ITEM_ID_BUTTON1 + butnum),
generic_button_get_state<BYTE>,
&m_mouse.rgbButtons[butnum]);
@ -414,12 +417,12 @@ public:
if (rawinput.data.mouse.usFlags == MOUSE_MOVE_RELATIVE)
{
m_mouse.lX += rawinput.data.mouse.lLastX * INPUT_RELATIVE_PER_PIXEL;
m_mouse.lY += rawinput.data.mouse.lLastY * INPUT_RELATIVE_PER_PIXEL;
m_mouse.lX += rawinput.data.mouse.lLastX * input_device::RELATIVE_PER_PIXEL;
m_mouse.lY += rawinput.data.mouse.lLastY * input_device::RELATIVE_PER_PIXEL;
// update zaxis
if (rawinput.data.mouse.usButtonFlags & RI_MOUSE_WHEEL)
m_mouse.lZ += int16_t(rawinput.data.mouse.usButtonData) * INPUT_RELATIVE_PER_PIXEL;
m_mouse.lZ += int16_t(rawinput.data.mouse.usButtonData) * input_device::RELATIVE_PER_PIXEL;
// update the button states; always update the corresponding mouse buttons
if (rawinput.data.mouse.usButtonFlags & RI_MOUSE_BUTTON_1_DOWN) m_mouse.rgbButtons[0] = 0x80;
@ -472,6 +475,7 @@ public:
{
device.add_item(
default_axis_name[axisnum],
std::string_view(),
input_item_id(ITEM_ID_XAXIS + axisnum),
generic_axis_get_state<LONG>,
&m_lightgun.lX + axisnum);
@ -480,6 +484,7 @@ public:
// scroll wheel is always relative if present
device.add_item(
default_axis_name[2],
std::string_view(),
ITEM_ID_ADD_RELATIVE1,
generic_axis_get_state<LONG>,
&m_lightgun.lZ);
@ -489,6 +494,7 @@ public:
{
device.add_item(
default_button_name(butnum),
std::string_view(),
input_item_id(ITEM_ID_BUTTON1 + butnum),
generic_button_get_state<BYTE>,
&m_lightgun.rgbButtons[butnum]);
@ -502,12 +508,12 @@ public:
{
// update the X/Y positions
m_lightgun.lX = normalize_absolute_axis(rawinput.data.mouse.lLastX, 0, INPUT_ABSOLUTE_MAX);
m_lightgun.lY = normalize_absolute_axis(rawinput.data.mouse.lLastY, 0, INPUT_ABSOLUTE_MAX);
m_lightgun.lX = normalize_absolute_axis(rawinput.data.mouse.lLastX, 0, input_device::ABSOLUTE_MAX);
m_lightgun.lY = normalize_absolute_axis(rawinput.data.mouse.lLastY, 0, input_device::ABSOLUTE_MAX);
// update zaxis
if (rawinput.data.mouse.usButtonFlags & RI_MOUSE_WHEEL)
m_lightgun.lZ += int16_t(rawinput.data.mouse.usButtonData) * INPUT_RELATIVE_PER_PIXEL;
m_lightgun.lZ += int16_t(rawinput.data.mouse.usButtonData) * input_device::RELATIVE_PER_PIXEL;
// update the button states; always update the corresponding mouse buttons
if (rawinput.data.mouse.usButtonFlags & RI_MOUSE_BUTTON_1_DOWN) m_lightgun.rgbButtons[0] = 0x80;

View File

@ -623,6 +623,7 @@ public:
device.add_item(
defname,
std::string_view(),
itemid,
generic_button_get_state<s32>,
&m_keyboard.state[m_trans_table[keynum].sdl_scancode]);
@ -676,21 +677,25 @@ public:
// add the axes
device.add_item(
"X",
std::string_view(),
ITEM_ID_XAXIS,
generic_axis_get_state<s32>,
&m_mouse.lX);
device.add_item(
"Y",
std::string_view(),
ITEM_ID_YAXIS,
generic_axis_get_state<s32>,
&m_mouse.lY);
device.add_item(
"Scroll V",
std::string_view(),
ITEM_ID_ZAXIS,
generic_axis_get_state<s32>,
&m_mouse.lV);
device.add_item(
"Scroll H",
std::string_view(),
ITEM_ID_RZAXIS,
generic_axis_get_state<s32>,
&m_mouse.lH);
@ -702,6 +707,7 @@ public:
int const offset = button ^ (((1 == button) || (2 == button)) ? 3 : 0);
device.add_item(
default_button_name(button),
std::string_view(),
itemid,
generic_button_get_state<s32>,
&m_mouse.buttons[offset]);
@ -713,8 +719,8 @@ public:
switch (event.type)
{
case SDL_MOUSEMOTION:
m_mouse.lX += event.motion.xrel * INPUT_RELATIVE_PER_PIXEL;
m_mouse.lY += event.motion.yrel * INPUT_RELATIVE_PER_PIXEL;
m_mouse.lX += event.motion.xrel * input_device::RELATIVE_PER_PIXEL;
m_mouse.lY += event.motion.yrel * input_device::RELATIVE_PER_PIXEL;
break;
case SDL_MOUSEBUTTONDOWN:
@ -727,11 +733,11 @@ public:
case SDL_MOUSEWHEEL:
#if SDL_VERSION_ATLEAST(2, 0, 18)
m_mouse.lV += event.wheel.preciseY * INPUT_RELATIVE_PER_PIXEL;
m_mouse.lH += event.wheel.preciseX * INPUT_RELATIVE_PER_PIXEL;
m_mouse.lV += event.wheel.preciseY * input_device::RELATIVE_PER_PIXEL;
m_mouse.lH += event.wheel.preciseX * input_device::RELATIVE_PER_PIXEL;
#else
m_mouse.lV += event.wheel.y * INPUT_RELATIVE_PER_PIXEL;
m_mouse.lH += event.wheel.x * INPUT_RELATIVE_PER_PIXEL;
m_mouse.lV += event.wheel.y * input_device::RELATIVE_PER_PIXEL;
m_mouse.lH += event.wheel.x * input_device::RELATIVE_PER_PIXEL;
#endif
break;
}
@ -850,6 +856,7 @@ public:
snprintf(tempname, sizeof(tempname), "A%d", axis + 1);
device.add_item(
tempname,
std::string_view(),
itemid,
generic_axis_get_state<s32>,
&m_joystick.axes[axis]);
@ -871,6 +878,7 @@ public:
device.add_item(
default_button_name(button),
std::string_view(),
itemid,
generic_button_get_state<s32>,
&m_joystick.buttons[button]);
@ -885,6 +893,7 @@ public:
itemid = input_item_id((hat < INPUT_MAX_HATS) ? ITEM_ID_HAT1UP + (4 * hat) : ITEM_ID_OTHER_SWITCH);
device.add_item(
tempname,
std::string_view(),
itemid,
generic_button_get_state<s32>,
&m_joystick.hatsU[hat]);
@ -893,6 +902,7 @@ public:
itemid = input_item_id((hat < INPUT_MAX_HATS) ? ITEM_ID_HAT1DOWN + (4 * hat) : ITEM_ID_OTHER_SWITCH);
device.add_item(
tempname,
std::string_view(),
itemid,
generic_button_get_state<s32>,
&m_joystick.hatsD[hat]);
@ -901,6 +911,7 @@ public:
itemid = input_item_id((hat < INPUT_MAX_HATS) ? ITEM_ID_HAT1LEFT + (4 * hat) : ITEM_ID_OTHER_SWITCH);
device.add_item(
tempname,
std::string_view(),
itemid,
generic_button_get_state<s32>,
&m_joystick.hatsL[hat]);
@ -909,6 +920,7 @@ public:
itemid = input_item_id((hat < INPUT_MAX_HATS) ? ITEM_ID_HAT1RIGHT + (4 * hat) : ITEM_ID_OTHER_SWITCH);
device.add_item(
tempname,
std::string_view(),
itemid,
generic_button_get_state<s32>,
&m_joystick.hatsR[hat]);
@ -927,6 +939,7 @@ public:
snprintf(tempname, sizeof(tempname), "R%d X", ball + 1);
device.add_item(
tempname,
std::string_view(),
input_item_id(itemid),
generic_axis_get_state<s32>,
&m_joystick.balls[ball * 2]);
@ -934,6 +947,7 @@ public:
snprintf(tempname, sizeof(tempname), "R%d Y", ball + 1);
device.add_item(
tempname,
std::string_view(),
input_item_id(itemid + 1),
generic_axis_get_state<s32>,
&m_joystick.balls[ball * 2 + 1]);
@ -972,8 +986,8 @@ public:
//printf("Ball %d %d\n", event.jball.xrel, event.jball.yrel);
if (event.jball.ball < (MAX_AXES / 2))
{
m_joystick.balls[event.jball.ball * 2] = event.jball.xrel * INPUT_RELATIVE_PER_PIXEL;
m_joystick.balls[event.jball.ball * 2 + 1] = event.jball.yrel * INPUT_RELATIVE_PER_PIXEL;
m_joystick.balls[event.jball.ball * 2] = event.jball.xrel * input_device::RELATIVE_PER_PIXEL;
m_joystick.balls[event.jball.ball * 2 + 1] = event.jball.yrel * input_device::RELATIVE_PER_PIXEL;
}
break;
@ -1225,6 +1239,7 @@ public:
{
device.add_item(
axisnames[axis],
std::string_view(),
item,
generic_axis_get_state<s32>,
&m_controller.axes[axis]);
@ -1280,6 +1295,7 @@ public:
{
device.add_item(
buttonnames[button],
std::string_view(),
button_item++,
generic_button_get_state<s32>,
&m_controller.buttons[button]);
@ -1308,6 +1324,7 @@ public:
{
device.add_item(
axisnames[axis],
std::string_view(),
button_item++,
[] (void *device_internal, void *item_internal) -> int
{
@ -1349,6 +1366,7 @@ public:
{
device.add_item(
buttonnames[button],
std::string_view(),
item,
generic_button_get_state<s32>,
&m_controller.buttons[button]);

View File

@ -19,7 +19,6 @@
// emu
#include "emu.h"
#include "inputdev.h"
#include "strconv.h"
@ -67,6 +66,7 @@ public:
// add the item to the device
device.add_item(
name,
util::string_format("SCAN%03d", keynum),
itemid,
generic_button_get_state<std::uint8_t>,
&m_keyboard.state[keynum]);
@ -150,8 +150,8 @@ public:
if (!(cursor_info.flags & CURSOR_SHOWING))
{
// We measure the position change from the previously set center position
m_mouse.lX = (cursor_info.ptScreenPos.x - m_win32_mouse.last_point.x) * INPUT_RELATIVE_PER_PIXEL;
m_mouse.lY = (cursor_info.ptScreenPos.y - m_win32_mouse.last_point.y) * INPUT_RELATIVE_PER_PIXEL;
m_mouse.lX = (cursor_info.ptScreenPos.x - m_win32_mouse.last_point.x) * input_device::RELATIVE_PER_PIXEL;
m_mouse.lY = (cursor_info.ptScreenPos.y - m_win32_mouse.last_point.y) * input_device::RELATIVE_PER_PIXEL;
RECT window_pos = {0};
GetWindowRect(
@ -173,6 +173,7 @@ public:
{
device.add_item(
default_axis_name[axisnum],
std::string_view(),
input_item_id(ITEM_ID_XAXIS + axisnum),
generic_axis_get_state<LONG>,
&m_mouse.lX + axisnum);
@ -183,6 +184,7 @@ public:
{
device.add_item(
default_button_name(butnum),
std::string_view(),
input_item_id(ITEM_ID_BUTTON1 + butnum),
generic_button_get_state<BYTE>,
&m_mouse.rgbButtons[butnum]);
@ -241,8 +243,7 @@ public:
virtual bool handle_input_event(input_event eventid, void *eventdata) override
{
// TODO: remove need for this downcast
if (!downcast<::input_manager &>(manager()).device_class(DEVICE_CLASS_MOUSE).enabled() || eventid != INPUT_EVENT_MOUSE_BUTTON)
if (!manager().class_enabled(DEVICE_CLASS_MOUSE) || eventid != INPUT_EVENT_MOUSE_BUTTON)
return false;
auto const *const args = static_cast<MouseButtonEventArgs *>(eventdata);
@ -273,6 +274,7 @@ public:
{
device.add_item(
default_axis_name[axisnum],
std::string_view(),
input_item_id(ITEM_ID_XAXIS + axisnum),
generic_axis_get_state<LONG>,
&m_mouse.lX + axisnum);
@ -283,6 +285,7 @@ public:
{
device.add_item(
default_button_name(butnum),
std::string_view(),
input_item_id(ITEM_ID_BUTTON1 + butnum),
generic_button_get_state<BYTE>,
&m_mouse.rgbButtons[butnum]);
@ -445,8 +448,7 @@ public:
virtual bool handle_input_event(input_event eventid, void *eventdata) override
{
// TODO: remove need for this downcast
if (!downcast<::input_manager &>(manager()).device_class(DEVICE_CLASS_LIGHTGUN).enabled() || eventid != INPUT_EVENT_MOUSE_BUTTON)
if (!manager().class_enabled(DEVICE_CLASS_LIGHTGUN) || eventid != INPUT_EVENT_MOUSE_BUTTON)
return false;
auto const *const args = static_cast<MouseButtonEventArgs *>(eventdata);

View File

@ -12,7 +12,6 @@
// MAME headers
#include "emu.h"
#include "inputdev.h"
#include "input_windows.h"
@ -33,8 +32,8 @@ bool windows_osd_interface::should_hide_mouse() const
return false;
// track if mouse/lightgun is enabled, for mouse hiding purposes
bool const mouse_enabled = machine().input().device_class(DEVICE_CLASS_MOUSE).enabled();
bool const lightgun_enabled = machine().input().device_class(DEVICE_CLASS_LIGHTGUN).enabled();
bool const mouse_enabled = machine().input().class_enabled(DEVICE_CLASS_MOUSE);
bool const lightgun_enabled = machine().input().class_enabled(DEVICE_CLASS_LIGHTGUN);
if (!mouse_enabled && !lightgun_enabled)
return false;

View File

@ -494,14 +494,14 @@ public:
for (int button = 0; button < m_button_count; button++)
{
input_item_id const itemid = input_item_id(ITEM_ID_BUTTON1 + button);
device.add_item(default_button_name(button), itemid, generic_button_get_state<std::int32_t>, &m_lightgun.buttons[button]);
device.add_item(default_button_name(button), std::string_view(), itemid, generic_button_get_state<std::int32_t>, &m_lightgun.buttons[button]);
}
// Add X and Y axis
if (1 <= m_axis_count)
device.add_item("X", ITEM_ID_XAXIS, generic_axis_get_state<std::int32_t>, &m_lightgun.lX);
device.add_item("X", std::string_view(), ITEM_ID_XAXIS, generic_axis_get_state<std::int32_t>, &m_lightgun.lX);
if (2 <= m_axis_count)
device.add_item("Y", ITEM_ID_YAXIS, generic_axis_get_state<std::int32_t>, &m_lightgun.lY);
device.add_item("Y", std::string_view(), ITEM_ID_YAXIS, generic_axis_get_state<std::int32_t>, &m_lightgun.lY);
}
virtual void process_event(XEvent const &xevent) override

View File

@ -791,6 +791,7 @@ void xinput_joystick_device::configure(input_device &device)
{
device.add_item(
axis_names[i],
std::string_view(),
axis_ids[i],
generic_axis_get_state<s32>,
&m_axes[AXIS_LSX + i]);
@ -813,6 +814,7 @@ void xinput_joystick_device::configure(input_device &device)
{
device.add_item(
hat_names[i],
std::string_view(),
input_item_id(ITEM_ID_HAT1UP + i), // matches up/down/left/right order
generic_button_get_state<u8>,
&m_switches[SWITCH_DPAD_UP + i]);
@ -839,6 +841,7 @@ void xinput_joystick_device::configure(input_device &device)
{
device.add_item(
button_names[i],
std::string_view(),
button_id++,
generic_button_get_state<u8>,
&m_switches[offset]);
@ -850,6 +853,7 @@ void xinput_joystick_device::configure(input_device &device)
{
device.add_item(
"Start",
std::string_view(),
ITEM_ID_START,
generic_button_get_state<u8>,
&m_switches[SWITCH_START]);
@ -858,6 +862,7 @@ void xinput_joystick_device::configure(input_device &device)
{
device.add_item(
"Back",
std::string_view(),
ITEM_ID_SELECT,
generic_button_get_state<u8>,
&m_switches[SWITCH_BACK]);
@ -872,6 +877,7 @@ void xinput_joystick_device::configure(input_device &device)
{
device.add_item(
axis_names[4 + i],
std::string_view(),
axis_ids[4 + i],
generic_axis_get_state<s32>,
&m_axes[AXIS_LT + i]);
@ -1029,6 +1035,7 @@ void xinput_guitar_device::configure(input_device &device)
{
device.add_item(
name,
std::string_view(),
item,
generic_axis_get_state<s32>,
&m_axes[AXIS_SLIDER + i]);
@ -1042,6 +1049,7 @@ void xinput_guitar_device::configure(input_device &device)
{
device.add_item(
HAT_NAMES_GUITAR[i],
std::string_view(),
input_item_id(ITEM_ID_HAT1UP + i), // matches up/down/left/right order
generic_button_get_state<u8>,
&m_switches[SWITCH_DPAD_UP + i]);
@ -1056,6 +1064,7 @@ void xinput_guitar_device::configure(input_device &device)
{
device.add_item(
BUTTON_NAMES_GUITAR[i],
std::string_view(),
button_id++,
generic_button_get_state<u8>,
&m_switches[SWITCH_FRET1 + i]);
@ -1067,6 +1076,7 @@ void xinput_guitar_device::configure(input_device &device)
{
device.add_item(
"Start",
std::string_view(),
ITEM_ID_START,
generic_button_get_state<u8>,
&m_switches[SWITCH_START]);
@ -1075,6 +1085,7 @@ void xinput_guitar_device::configure(input_device &device)
{
device.add_item(
"Back",
std::string_view(),
ITEM_ID_SELECT,
generic_button_get_state<u8>,
&m_switches[SWITCH_BACK]);
@ -1219,6 +1230,7 @@ void xinput_drumkit_device::configure(input_device &device)
{
device.add_item(
name,
std::string_view(),
item,
generic_axis_get_state<s32>,
&m_axes[AXIS_GREEN + i]);
@ -1232,6 +1244,7 @@ void xinput_drumkit_device::configure(input_device &device)
{
device.add_item(
HAT_NAMES_GAMEPAD[i],
std::string_view(),
input_item_id(ITEM_ID_HAT1UP + i), // matches up/down/left/right order
generic_button_get_state<u8>,
&m_switches[SWITCH_DPAD_UP + i]);
@ -1246,6 +1259,7 @@ void xinput_drumkit_device::configure(input_device &device)
{
device.add_item(
BUTTON_NAMES_DRUMKIT[i],
std::string_view(),
button_id++,
generic_button_get_state<u8>,
&m_switches[SWITCH_GREEN + i]);
@ -1257,6 +1271,7 @@ void xinput_drumkit_device::configure(input_device &device)
{
device.add_item(
"Start",
std::string_view(),
ITEM_ID_START,
generic_button_get_state<u8>,
&m_switches[SWITCH_START]);
@ -1265,6 +1280,7 @@ void xinput_drumkit_device::configure(input_device &device)
{
device.add_item(
"Back",
std::string_view(),
ITEM_ID_SELECT,
generic_button_get_state<u8>,
&m_switches[SWITCH_BACK]);
@ -1382,7 +1398,7 @@ void xinput_turntable_device::poll()
m_switches[SWITCH_GREEN + i] = BIT(trigger_right(), i) ? 0xff : 0x00;
// translate axes
m_axes[AXIS_TURNTABLE] = s32(thumb_left_y()) * INPUT_RELATIVE_PER_PIXEL * 2;
m_axes[AXIS_TURNTABLE] = s32(thumb_left_y()) * input_device::RELATIVE_PER_PIXEL * 2;
m_axes[AXIS_CROSSFADE] = normalize_absolute_axis(thumb_right_y(), XINPUT_AXIS_MINVALUE, XINPUT_AXIS_MAXVALUE);
// convert effect dial value to relative displacement
@ -1393,7 +1409,7 @@ void xinput_turntable_device::poll()
effect_delta -= 0x1'0000;
else if (-0x8000 > effect_delta)
effect_delta += 0x1'0000;
m_axes[AXIS_EFFECT] = effect_delta * INPUT_RELATIVE_PER_PIXEL / 128;
m_axes[AXIS_EFFECT] = effect_delta * input_device::RELATIVE_PER_PIXEL / 128;
}
m_prev_effect = u16(thumb_right_x());
}
@ -1419,16 +1435,19 @@ void xinput_turntable_device::configure(input_device &device)
// add axes
device.add_item(
"Turntable",
std::string_view(),
ITEM_ID_ADD_RELATIVE1,
generic_axis_get_state<s32>,
&m_axes[AXIS_TURNTABLE]);
device.add_item(
"Effect",
std::string_view(),
ITEM_ID_ADD_RELATIVE2,
generic_axis_get_state<s32>,
&m_axes[AXIS_EFFECT]);
device.add_item(
"Crossfade",
std::string_view(),
ITEM_ID_XAXIS,
generic_axis_get_state<s32>,
&m_axes[AXIS_CROSSFADE]);
@ -1440,6 +1459,7 @@ void xinput_turntable_device::configure(input_device &device)
{
device.add_item(
HAT_NAMES_GAMEPAD[i],
std::string_view(),
input_item_id(ITEM_ID_HAT1UP + i), // matches up/down/left/right order
generic_button_get_state<u8>,
&m_switches[SWITCH_DPAD_UP + i]);
@ -1454,6 +1474,7 @@ void xinput_turntable_device::configure(input_device &device)
{
device.add_item(
BUTTON_NAMES_KEYBOARD[i],
std::string_view(),
button_id++,
generic_button_get_state<u8>,
&m_switches[SWITCH_A + i]);
@ -1461,16 +1482,19 @@ void xinput_turntable_device::configure(input_device &device)
}
device.add_item(
"Green",
std::string_view(),
button_id++,
generic_button_get_state<u8>,
&m_switches[SWITCH_GREEN]);
device.add_item(
"Red",
std::string_view(),
button_id++,
generic_button_get_state<u8>,
&m_switches[SWITCH_RED]);
device.add_item(
"Blue",
std::string_view(),
button_id++,
generic_button_get_state<u8>,
&m_switches[SWITCH_BLUE]);
@ -1480,6 +1504,7 @@ void xinput_turntable_device::configure(input_device &device)
{
device.add_item(
"Start",
std::string_view(),
ITEM_ID_START,
generic_button_get_state<u8>,
&m_switches[SWITCH_START]);
@ -1488,6 +1513,7 @@ void xinput_turntable_device::configure(input_device &device)
{
device.add_item(
"Back",
std::string_view(),
ITEM_ID_SELECT,
generic_button_get_state<u8>,
&m_switches[SWITCH_BACK]);
@ -1627,11 +1653,13 @@ void xinput_keyboard_device::configure(input_device &device)
// add axes
device.add_item(
"Velocity",
std::string_view(),
ITEM_ID_SLIDER1,
generic_axis_get_state<s32>,
&m_axes[AXIS_VELOCITY]);
device.add_item(
"Pedal",
std::string_view(),
ITEM_ID_SLIDER2,
generic_axis_get_state<s32>,
&m_axes[AXIS_PEDAL]);
@ -1643,6 +1671,7 @@ void xinput_keyboard_device::configure(input_device &device)
{
device.add_item(
HAT_NAMES_GAMEPAD[i],
std::string_view(),
input_item_id(ITEM_ID_HAT1UP + i), // matches up/down/left/right order
generic_button_get_state<u8>,
&m_switches[SWITCH_DPAD_UP + i]);
@ -1657,6 +1686,7 @@ void xinput_keyboard_device::configure(input_device &device)
{
device.add_item(
BUTTON_NAMES_KEYBOARD[i],
std::string_view(),
button_id++,
generic_button_get_state<u8>,
&m_switches[SWITCH_A + i]);
@ -1670,6 +1700,7 @@ void xinput_keyboard_device::configure(input_device &device)
{
device.add_item(
util::string_format(key_formats[i % 12], (i / 12) + 1),
std::string_view(),
(ITEM_ID_BUTTON32 >= button_id) ? button_id++ : ITEM_ID_OTHER_SWITCH,
generic_button_get_state<u8>,
&m_switches[SWITCH_C1 + i]);
@ -1680,6 +1711,7 @@ void xinput_keyboard_device::configure(input_device &device)
{
device.add_item(
"Start",
std::string_view(),
ITEM_ID_START,
generic_button_get_state<u8>,
&m_switches[SWITCH_START]);
@ -1688,6 +1720,7 @@ void xinput_keyboard_device::configure(input_device &device)
{
device.add_item(
"Back",
std::string_view(),
ITEM_ID_SELECT,
generic_button_get_state<u8>,
&m_switches[SWITCH_BACK]);

View File

@ -11,8 +11,6 @@
#pragma once
#include "eminline.h" // attotime.h needs this - add it to attotime.h on the next emu.h update
// emu
#include "attotime.h"

View File

@ -8,15 +8,18 @@
// MAME headers
#include "emu.h"
#include "drivenum.h"
#include "emuopts.h"
#include "fileio.h"
#include "main.h"
#include "render.h"
#include "rendlay.h"
#include "rendutil.h"
#include "emuopts.h"
#include "fileio.h"
#include "screen.h"
#include "aviio.h"
#include "png.h"
#include "screen.h"
// MAMEOS headers
#include "winmain.h"

View File

@ -12,7 +12,6 @@
#include "modules/osdmodule.h"
#include "modules/osdwindow.h"
#include "emu.h" // FIXME: only here for main.h, won't be necessary soon
#include "main.h"
#include "render.h"

View File

@ -4,7 +4,6 @@
#include "sdlopts.h"
// emu
#include "emu.h"
#include "main.h"
// lib/util