summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Tomer Verona <tverona@hotmail.com>2016-09-12 18:35:36 -0700
committer Tomer Verona <tverona@hotmail.com>2016-09-12 18:35:36 -0700
commit2bd18d5fea66bedcde02da1b2c17d83c4640a782 (patch)
tree21a026c276f83cd6a3619d49ca85cba088485e5b
parent597626d0593e84868d5d9887c1f44b96222bdd49 (diff)
Support for configuring device to conrtoller id
This change adds support for configuring device to conrtoller id. This allows for stable controller ids even if USB devices are plugged / unplugged, system is rebooted, etc. See documentation for additional context.
-rw-r--r--docs/source/advanced/devicemap.rst81
-rw-r--r--docs/source/advanced/index.rst3
-rw-r--r--src/emu/input.cpp103
-rw-r--r--src/emu/input.h8
-rw-r--r--src/emu/ioport.cpp18
-rw-r--r--src/osd/modules/input/input_rawinput.cpp12
6 files changed, 222 insertions, 3 deletions
diff --git a/docs/source/advanced/devicemap.rst b/docs/source/advanced/devicemap.rst
new file mode 100644
index 00000000000..2b52ef00c78
--- /dev/null
+++ b/docs/source/advanced/devicemap.rst
@@ -0,0 +1,81 @@
+Stable Controller IDs
+===============================
+
+By default, the mapping between devices and controller IDs is not stable. For instance, a gamepad controller may be assigned to "Joy 1" initially, but after a reboot, it may get re-assigned to "Joy 3".
+
+The reason is that MAME enumerates attached devices and assigns controller IDs based on the enumeration order. Factors that can cause controller IDs to change include plugging / unplugging USB devices, changing ports / hubs and even system reboots.
+
+It is quite cumbersome to ensure that controller IDs are always correct.
+
+That's where the "mapdevice" configuration setting comes into the picture. This setting allows you to map a device name to a controller ID, ensuring that the specified device always maps to the same controller ID in MAME.
+
+Usage of mapdevice
+------------------
+The "mapdevice" xml element is specified under the input xml element in the configuration. It requires two attributes, "device" and "controller".
+
+The "device" attribute specifies the name of the device to match. It may also be a substring of the name. To see the list of available devices, enable verbose output and available devices will then be listed to the console at startup (more on this below).
+
+The "controller" attribute specifies the MAME controller ID. It is made up of a controller class (i.e. "JOYCODE", "GUNCODE", "MOUSECODE") and controller index. For example: "JOYCODE_1".
+
+Example
+-------
+Here's an example:
+
+| <mameconfig version="10">
+| <system name="default">
+| <input>
+| **<mapdevice device="VID_D209&amp;PID_1601" controller="GUNCODE_1" />**
+| **<mapdevice device="VID_D209&amp;PID_1602" controller="GUNCODE_2" />**
+| **<mapdevice device="XInput Player 1" controller="JOYCODE_1" />**
+| **<mapdevice device="XInput Player 2" controller="JOYCODE_2" />**
+|
+| <port type="P1_JOYSTICK_UP">
+| <newseq type="standard">
+| JOYCODE_1_YAXIS_UP_SWITCH OR KEYCODE_8PAD
+| </newseq>
+| </port>
+| ...
+|
+
+In the above example, we have four device mappings specified:
+
+The first two mapdevice entries map player 1 and 2 lightguns to Gun 1 and Gun 2, respectively. We use a substring of the full raw device names to match each devices. Note that, since this is XML, we needed to escape the '&' in the name using '&amp;'.
+
+The last two mapdevices entries map player 1 and player 2 gamepad controllers to Joy 1 and Joy 2, respectively. In this case, these are XInput devices.
+
+Listing Available Devices
+-------------------------
+How did we obtain the device names in the above example? Easy!
+
+We simply set verbose to 1 in mame.ini:
+
+| #
+| # CORE DEBUGGING OPTIONS
+| #
+| **verbose 1**
+|
+
+Then, when MAME is started, it will list available devices to the console. For example:
+
+| Input: Adding Gun #0:
+| Input: Adding Gun #1:
+| Input: Adding Gun #2: HID-compliant mouse (\\?\HID#VID_045E&PID_0053#7&18297dcb&0&0000#{378de44c-56ef-11d1-bc8c-00a0c91405dd})
+| Input: Adding Gun #3: HID-compliant mouse (\\?\HID#IrDeviceV2&Col08#2&2818a073&0&0007#{378de44c-56ef-11d1-bc8c-00a0c91405dd})
+| Input: Adding Gun #4: HID-compliant mouse (\\?\HID#VID_D209&PID_1602&MI_02#8&389ab7f3&0&0000#{378de44c-56ef-11d1-bc8c-00a0c91405dd})
+| Input: Adding Gun #5: HID-compliant mouse (\\?\HID#VID_D209&PID_1601&MI_02#9&375eebb1&0&0000#{378de44c-56ef-11d1-bc8c-00a0c91405dd})
+| Input: Adding Gun #6: HID-compliant mouse (\\?\HID#VID_1241&PID_1111#8&198f3adc&0&0000#{378de44c-56ef-11d1-bc8c-00a0c91405dd})
+| Skipping DirectInput for XInput compatible joystick Controller (XBOX 360 For Windows).
+| Input: Adding Joy #0: ATRAK Device #1
+| Skipping DirectInput for XInput compatible joystick Controller (XBOX 360 For Windows).
+| Input: Adding Joy #1: ATRAK Device #2
+| Input: Adding Joy #2: XInput Player 1
+| Input: Adding Joy #3: XInput Player 2
+|
+
+Furthermore, when devices are mapped using mapdevice, you'll see that in the verbose logging too, such as:
+
+| Mapped device 'HID-compliant mouse (\\?\HID#VID_D209&PID_1601&MI_02#9&375eebb1&0&0000#{378de44c-56ef-11d1-bc8c-00a0c91405dd})' to Gun #0
+| Mapped device 'HID-compliant mouse (\\?\HID#VID_D209&PID_1602&MI_02#8&389ab7f3&0&0000#{378de44c-56ef-11d1-bc8c-00a0c91405dd})' to Gun #1
+| Mapped device 'XInput Player 1' to Joy #0
+| Mapped device 'XInput Player 2' to Joy #1
+|
diff --git a/docs/source/advanced/index.rst b/docs/source/advanced/index.rst
index d40a328fe2f..8ce1dfee49c 100644
--- a/docs/source/advanced/index.rst
+++ b/docs/source/advanced/index.rst
@@ -9,4 +9,5 @@ Advanced configuration
shiftertoggle
bgfx
hlsl
- glsl \ No newline at end of file
+ glsl
+ devicemap \ No newline at end of file
diff --git a/src/emu/input.cpp b/src/emu/input.cpp
index bbae55fcd34..560e9271797 100644
--- a/src/emu/input.cpp
+++ b/src/emu/input.cpp
@@ -941,6 +941,21 @@ void input_device::apply_steadykey() const
}
}
+//-------------------------------------------------
+// match_device_name - match device name via
+// substring search
+//-------------------------------------------------
+
+bool input_device::match_device_name(const char *devicename)
+{
+ std::string devicenameupper(devicename);
+ std::string nameupper(m_name);
+
+ strmakeupper(devicenameupper);
+ strmakeupper(nameupper);
+
+ return std::string::npos == nameupper.find(devicenameupper) ? false : true;
+}
//**************************************************************************
@@ -1020,6 +1035,29 @@ input_item_class input_class::standard_item_class(input_item_id itemid)
//-------------------------------------------------
+// remap_device_index - remaps device index by
+// mapping oldindex to newindex
+//-------------------------------------------------
+
+void input_class::remap_device_index(int oldindex, int newindex)
+{
+ assert(oldindex >= 0 && oldindex < DEVICE_INDEX_MAXIMUM);
+ assert(newindex >= 0 && newindex < DEVICE_INDEX_MAXIMUM);
+
+ // swap indexes in m_device array
+ m_device[oldindex].swap(m_device[newindex]);
+
+ // update device indexes
+ m_device[oldindex]->set_devindex(oldindex);
+ m_device[newindex]->set_devindex(newindex);
+
+ // update the maximum index found, since newindex may
+ // exceed current m_maxindex
+ m_maxindex = std::max(m_maxindex, newindex);
+}
+
+
+//-------------------------------------------------
// frame_callback - per-frame callback for various
// bookkeeping
//-------------------------------------------------
@@ -2058,6 +2096,71 @@ void input_manager::seq_from_tokens(input_seq &seq, const char *string)
}
}
+//-------------------------------------------------
+// map_device_to_controller - map device to
+// controller based on device map table
+//-------------------------------------------------
+
+bool input_manager::map_device_to_controller(const devicemap_table_type *devicemap_table)
+{
+ if (nullptr == devicemap_table)
+ return true;
+
+ for (devicemap_table_type::const_iterator it = devicemap_table->begin(); it != devicemap_table->end(); it++)
+ {
+ const char *devicename = it->first.c_str();
+ const char *controllername = it->second.c_str();
+
+ // tokenize the controller name into device class and index (i.e. controller name should be of the form "GUNCODE_1")
+ std::string token[2];
+ int numtokens;
+ const char *_token = controllername;
+ for (numtokens = 0; numtokens < ARRAY_LENGTH(token); )
+ {
+ // make a token up to the next underscore
+ char *score = (char *)strchr(_token, '_');
+ token[numtokens++].assign(_token, (score == nullptr) ? strlen(_token) : (score - _token));
+
+ // if we hit the end, we're done, else advance our pointer
+ if (score == nullptr)
+ break;
+ _token = score + 1;
+ }
+ if (2 != numtokens)
+ return false;
+
+ // first token should be the devclass
+ input_device_class devclass = input_device_class((*devclass_token_table)[strmakeupper(token[0]).c_str()]);
+ if (devclass == ~input_device_class(0))
+ return false;
+
+ // second token should be the devindex
+ int devindex = 0;
+ if (1 != sscanf(token[1].c_str(), "%d", &devindex))
+ return false;
+ devindex--;
+
+ if (devindex >= DEVICE_INDEX_MAXIMUM)
+ return false;
+
+ // enumerate through devices and look for a match
+ input_class *input_devclass = m_class[devclass];
+ for (int devnum = 0; devnum <= input_devclass->maxindex(); devnum++)
+ {
+ input_device *device = input_devclass->device(devnum);
+ if (device != nullptr && device->match_device_name(devicename))
+ {
+ // remap devindex
+ input_devclass->remap_device_index(device->devindex(), devindex);
+ osd_printf_info("Mapped device '%s' to %s #%d\n", device->name(), (*devclass_string_table)[input_devclass->devclass()], devindex);
+ break;
+ }
+ }
+ }
+
+ return true;
+}
+
//-------------------------------------------------
// set_global_joystick_map - set the joystick map
diff --git a/src/emu/input.h b/src/emu/input.h
index d7012c1f779..1c4276fef3d 100644
--- a/src/emu/input.h
+++ b/src/emu/input.h
@@ -352,6 +352,8 @@ class input_manager;
// callback for getting the value of an item on a device
typedef INT32 (*item_get_state_func)(void *device_internal, void *item_internal);
+// controller alias table typedef
+typedef std::map<std::string, std::string> devicemap_table_type;
// ======================> joystick_map
@@ -562,6 +564,9 @@ public:
bool steadykey_enabled() const { return m_steadykey_enabled; }
bool lightgun_reload_button() const { return m_lightgun_reload_button; }
+ // setters
+ 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);
void set_joystick_map(const joystick_map &map) { m_joymap = map; }
@@ -569,6 +574,7 @@ public:
// helpers
INT32 apply_deadzone_and_saturation(INT32 value) const;
void apply_steadykey() const;
+ bool match_device_name(const char * devicename);
private:
// internal state
@@ -616,6 +622,7 @@ public:
// misc helpers
input_item_class standard_item_class(input_item_id itemid);
+ void remap_device_index(int oldindex, int newindex);
private:
// internal helpers
@@ -679,6 +686,7 @@ public:
// misc
bool set_global_joystick_map(const char *mapstring);
+ bool map_device_to_controller(const devicemap_table_type *devicemap_table = nullptr);
private:
// internal helpers
diff --git a/src/emu/ioport.cpp b/src/emu/ioport.cpp
index 44e758b5752..00dbedb8de8 100644
--- a/src/emu/ioport.cpp
+++ b/src/emu/ioport.cpp
@@ -2904,6 +2904,24 @@ void ioport_manager::load_config(config_type cfg_type, xml_data_node *parentnode
if (cfg_type == config_type::CONFIG_TYPE_CONTROLLER)
load_remap_table(parentnode);
+ // load device map table, if any
+ std::unique_ptr<devicemap_table_type> devicemap_table = std::make_unique<devicemap_table_type>();
+ for (xml_data_node *mapdevice_node = xml_get_sibling(parentnode->child, "mapdevice"); mapdevice_node != nullptr; mapdevice_node = xml_get_sibling(mapdevice_node->next, "mapdevice"))
+ {
+ const char *devicename = xml_get_attribute_string(mapdevice_node, "device", nullptr);
+ const char *controllername = xml_get_attribute_string(mapdevice_node, "controller", nullptr);
+ if (devicename != nullptr && controllername != nullptr)
+ {
+ devicemap_table->insert(std::make_pair(std::string(devicename), std::string(controllername)));
+ }
+ }
+
+ // map device to controller if we have a device map
+ if (!devicemap_table->empty())
+ {
+ machine().input().map_device_to_controller(devicemap_table.get());
+ }
+
// iterate over all the port nodes
for (xml_data_node *portnode = xml_get_sibling(parentnode->child, "port"); portnode; portnode = xml_get_sibling(portnode->next, "port"))
{
diff --git a/src/osd/modules/input/input_rawinput.cpp b/src/osd/modules/input/input_rawinput.cpp
index ee6dbf4a511..44fba696e2c 100644
--- a/src/osd/modules/input/input_rawinput.cpp
+++ b/src/osd/modules/input/input_rawinput.cpp
@@ -572,8 +572,16 @@ protected:
// improve the name and then allocate a device
std::wstring name = rawinput_device_improve_name(tname.get());
- // convert name to utf8
- std::string utf8_name = utf8_from_wstring(name.c_str());
+ // convert name to utf8. Preserve raw name as well (if different than improved name) to allow mapping of device to controller.
+ std::string utf8_name;
+ if (0 == name.compare(tname.get()))
+ {
+ utf8_name = utf8_from_wstring(name.c_str());
+ }
+ else
+ {
+ utf8_name = util::string_format("%s (%s)", utf8_from_wstring(name.c_str()), utf8_from_wstring(tname.get()));
+ }
devinfo = devicelist()->create_device<TDevice>(machine, utf8_name.c_str(), *this);
ref='#n823'>823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856
-- license:BSD-3-Clause
-- copyright-holders:MAMEdev Team

---------------------------------------------------------------------------
--
--   tools.lua
--
--   Rules for the building of tools
--
---------------------------------------------------------------------------

--------------------------------------------------
-- romcmp
--------------------------------------------------

project("romcmp")
uuid ("1b40275b-194c-497b-8abd-9338775a21b8")
kind "ConsoleApp"

flags {
	"Symbols", -- always include minimum symbols for executables
}

if _OPTIONS["SEPARATE_BIN"]~="1" then
	targetdir(MAME_DIR)
end

links {
	"utils",
	ext_lib("expat"),
	"7z",
	"ocore_" .. _OPTIONS["osd"],
	ext_lib("zlib"),
	ext_lib("utf8proc"),
}

includedirs {
	MAME_DIR .. "src/osd",
	MAME_DIR .. "src/lib/util",
}

files {
	MAME_DIR .. "src/tools/romcmp.cpp",
}

configuration { "mingw*" or "vs*" }
	targetextension ".exe"

configuration { }

strip()

--------------------------------------------------
-- chdman
--------------------------------------------------

project("chdman")
uuid ("7d948868-42db-432a-9bb5-70ce5c5f4620")
kind "ConsoleApp"

flags {
	"Symbols", -- always include minimum symbols for executables
}

if _OPTIONS["SEPARATE_BIN"]~="1" then
	targetdir(MAME_DIR)
end

links {
	"utils",
	ext_lib("expat"),
	"7z",
	"ocore_" .. _OPTIONS["osd"],
	ext_lib("zlib"),
	ext_lib("flac"),
	ext_lib("utf8proc"),
}

includedirs {
	MAME_DIR .. "src/osd",
	MAME_DIR .. "src/lib/util",
	MAME_DIR .. "3rdparty",
}
includedirs {
	ext_includedir("flac"),
}

files {
	MAME_DIR .. "src/tools/chdman.cpp",
	GEN_DIR .. "version.cpp",
}

configuration { "mingw*" or "vs*" }
	targetextension ".exe"

configuration { }

strip()

--------------------------------------------------
-- jedutil
--------------------------------------------------

project("jedutil")
uuid ("bda60edb-f7f5-489f-b232-23d33c43dda1")
kind "ConsoleApp"

flags {
	"Symbols", -- always include minimum symbols for executables
}

if _OPTIONS["SEPARATE_BIN"]~="1" then
	targetdir(MAME_DIR)
end

links {
	"utils",
	ext_lib("expat"),
	"ocore_" .. _OPTIONS["osd"],
	ext_lib("zlib"),
	ext_lib("utf8proc"),
}

includedirs {
	MAME_DIR .. "src/osd",
	MAME_DIR .. "src/lib/util",
}

files {
	MAME_DIR .. "src/tools/jedutil.cpp",
}

configuration { "mingw*" or "vs*" }
	targetextension ".exe"

configuration { }

strip()

--------------------------------------------------
-- unidasm
--------------------------------------------------

project("unidasm")
uuid ("65f81d3b-299a-4b08-a3fa-d5241afa9fd1")
kind "ConsoleApp"

flags {
	"Symbols", -- always include minimum symbols for executables
}

if _OPTIONS["SEPARATE_BIN"]~="1" then
	targetdir(MAME_DIR)
end

links {
	"dasm",
	"utils",
	ext_lib("expat"),
	"7z",
	"ocore_" .. _OPTIONS["osd"],
	ext_lib("zlib"),
	ext_lib("flac"),
	ext_lib("utf8proc"),
}

includedirs {
	MAME_DIR .. "src/osd",
	MAME_DIR .. "src/devices",
	MAME_DIR .. "src/emu",
	MAME_DIR .. "src/lib/util",
	MAME_DIR .. "3rdparty",
}

files {
	MAME_DIR .. "src/tools/unidasm.cpp",
}

configuration { "mingw*" or "vs*" }
	targetextension ".exe"

configuration { }

strip()

--------------------------------------------------
-- ldresample
--------------------------------------------------

project("ldresample")
uuid ("3401561a-4407-4e13-9c6d-c0801330f7cc")
kind "ConsoleApp"

flags {
	"Symbols", -- always include minimum symbols for executables
}

if _OPTIONS["SEPARATE_BIN"]~="1" then
	targetdir(MAME_DIR)
end

links {
	"utils",
	ext_lib("expat"),
	"7z",
	"ocore_" .. _OPTIONS["osd"],
	ext_lib("zlib"),
	ext_lib("flac"),
	ext_lib("utf8proc"),
}

includedirs {
	MAME_DIR .. "src/osd",
	MAME_DIR .. "src/lib/util",
	MAME_DIR .. "3rdparty",
}
includedirs {
	ext_includedir("flac"),
}

files {
	MAME_DIR .. "src/tools/ldresample.cpp",
}

configuration { "mingw*" or "vs*" }
	targetextension ".exe"

configuration { }

strip()

--------------------------------------------------
-- ldverify
--------------------------------------------------

project("ldverify")
uuid ("3e66560d-b928-4227-928b-eadd0a10f00a")
kind "ConsoleApp"

flags {
	"Symbols", -- always include minimum symbols for executables
}

if _OPTIONS["SEPARATE_BIN"]~="1" then
	targetdir(MAME_DIR)
end

links {
	"utils",
	ext_lib("expat"),
	"7z",
	"ocore_" .. _OPTIONS["osd"],
	ext_lib("zlib"),
	ext_lib("flac"),
	ext_lib("utf8proc"),
}

includedirs {
	MAME_DIR .. "src/osd",
	MAME_DIR .. "src/lib/util",
	MAME_DIR .. "3rdparty",
}
includedirs {
	ext_includedir("flac"),
}

files {
	MAME_DIR .. "src/tools/ldverify.cpp",
}

configuration { "mingw*" or "vs*" }
	targetextension ".exe"

configuration { }

strip()

--------------------------------------------------
-- regrep
--------------------------------------------------

project("regrep")
uuid ("7f6de580-d800-4e8d-bed6-9fc86829584d")
kind "ConsoleApp"

flags {
	"Symbols", -- always include minimum symbols for executables
}

if _OPTIONS["SEPARATE_BIN"]~="1" then
	targetdir(MAME_DIR)
end

links {
	"utils",
	ext_lib("expat"),
	"ocore_" .. _OPTIONS["osd"],
	ext_lib("zlib"),
	ext_lib("utf8proc"),
}

includedirs {
	MAME_DIR .. "src/osd",
	MAME_DIR .. "src/lib/util",
}

files {
	MAME_DIR .. "src/tools/regrep.cpp",
}

configuration { "mingw*" or "vs*" }
	targetextension ".exe"

configuration { }

strip()

--------------------------------------------------
-- srcclean
---------------------------------------------------

project("srcclean")
uuid ("4dd58139-313a-42c5-965d-f378bdeed220")
kind "ConsoleApp"

flags {
	"Symbols", -- always include minimum symbols for executables
}

if _OPTIONS["SEPARATE_BIN"]~="1" then
	targetdir(MAME_DIR)
end

links {
	"utils",
	ext_lib("expat"),
	"ocore_" .. _OPTIONS["osd"],
	ext_lib("zlib"),
	ext_lib("utf8proc"),
}

includedirs {
	MAME_DIR .. "src/osd",
	MAME_DIR .. "src/lib/util",
}

files {
	MAME_DIR .. "src/tools/srcclean.cpp",
}

configuration { "mingw*" or "vs*" }
	targetextension ".exe"

configuration { }

strip()

--------------------------------------------------
-- split
--------------------------------------------------

project("split")
uuid ("8ef6ff18-3199-4cc2-afd0-d64033070faa")
kind "ConsoleApp"

flags {
	"Symbols", -- always include minimum symbols for executables
}

if _OPTIONS["SEPARATE_BIN"]~="1" then
	targetdir(MAME_DIR)
end

links {
	"utils",
	ext_lib("expat"),
	"7z",
	"ocore_" .. _OPTIONS["osd"],
	ext_lib("zlib"),
	ext_lib("flac"),
	ext_lib("utf8proc"),
}

includedirs {
	MAME_DIR .. "src/osd",
	MAME_DIR .. "src/lib/util",
}

files {
	MAME_DIR .. "src/tools/split.cpp",
}

configuration { "mingw*" or "vs*" }
	targetextension ".exe"

configuration { }

strip()

--------------------------------------------------
-- pngcmp
--------------------------------------------------

project("pngcmp")
uuid ("61f647d9-b129-409b-9c62-8acf98ed39be")
kind "ConsoleApp"

flags {
	"Symbols", -- always include minimum symbols for executables
}

if _OPTIONS["SEPARATE_BIN"]~="1" then
	targetdir(MAME_DIR)
end

links {
	"utils",
	ext_lib("expat"),
	"ocore_" .. _OPTIONS["osd"],
	ext_lib("zlib"),
	ext_lib("utf8proc"),
}

includedirs {
	MAME_DIR .. "src/osd",
	MAME_DIR .. "src/lib/util",
}

files {
	MAME_DIR .. "src/tools/pngcmp.cpp",
}

configuration { "mingw*" or "vs*" }
	targetextension ".exe"

configuration { }

strip()

--------------------------------------------------
-- nltool
--------------------------------------------------

project("nltool")
uuid ("853a03b7-fa37-41a8-8250-0dc23dd935d6")
kind "ConsoleApp"

flags {
	"Symbols", -- always include minimum symbols for executables
}

if _OPTIONS["SEPARATE_BIN"]~="1" then
	targetdir(MAME_DIR)
end

links {
	"netlist",
}

includedirs {
	MAME_DIR .. "src/lib",
	MAME_DIR .. "src/lib/netlist",
}

defines {
  "NL_DISABLE_DYNAMIC_LOAD=1",
}

files {
	MAME_DIR .. "src/lib/netlist/prg/nltool.cpp",
}

configuration { "mingw*" }
	linkoptions{
		"-municode",
	}
configuration { "vs*" }
	flags {
		"Unicode",
	}

configuration { "mingw*" or "vs*" }
	targetextension ".exe"

configuration { }

strip()

--------------------------------------------------
-- nlwav
--------------------------------------------------

project("nlwav")
uuid ("7c5396d1-2a1a-4c93-bed6-6b8fa182054a")
kind "ConsoleApp"

flags {
	"Symbols", -- always include minimum symbols for executables
}

if _OPTIONS["SEPARATE_BIN"]~="1" then
	targetdir(MAME_DIR)
end

links {
	"netlist",
}

includedirs {
	MAME_DIR .. "src/lib",
	MAME_DIR .. "src/lib/netlist",
}

files {
	MAME_DIR .. "src/lib/netlist/prg/nlwav.cpp",
}

configuration { "mingw*" }
	linkoptions{
		"-municode",
	}
configuration { "vs*" }
	flags {
		"Unicode",
	}

configuration { "mingw*" or "vs*" }
	targetextension ".exe"

configuration { }

strip()

--------------------------------------------------
-- castool
--------------------------------------------------

project("castool")
uuid ("7d9ed428-e2ba-4448-832d-d882a64d5c22")
kind "ConsoleApp"

flags {
	"Symbols", -- always include minimum symbols for executables
}

if _OPTIONS["SEPARATE_BIN"]~="1" then
	targetdir(MAME_DIR)
end

links {
	"formats",
	"utils",
	ext_lib("expat"),
	"7z",
	"ocore_" .. _OPTIONS["osd"],
	ext_lib("zlib"),
	ext_lib("flac"),
	ext_lib("utf8proc"),
}

includedirs {
	MAME_DIR .. "src/osd",
	MAME_DIR .. "src/lib",
	MAME_DIR .. "src/lib/util",
}

files {
	MAME_DIR .. "src/tools/castool.cpp",
}

configuration { "mingw*" or "vs*" }
	targetextension ".exe"

configuration { }

strip()

--------------------------------------------------
-- floptool
--------------------------------------------------

project("floptool")
uuid ("85d8e3a6-1661-4ac9-8c21-281d20cbaf5b")
kind "ConsoleApp"

flags {
	"Symbols", -- always include minimum symbols for executables
}

if _OPTIONS["SEPARATE_BIN"]~="1" then
	targetdir(MAME_DIR)
end

links {
	"formats",
	"utils",
	ext_lib("expat"),
	"7z",
	"ocore_" .. _OPTIONS["osd"],
	ext_lib("zlib"),
	ext_lib("flac"),
	ext_lib("utf8proc"),
}

includedirs {
	MAME_DIR .. "src/osd",
	MAME_DIR .. "src/lib",
	MAME_DIR .. "src/lib/util",
}

files {
	MAME_DIR .. "src/tools/image_handler.cpp",
	MAME_DIR .. "src/tools/image_handler.h",
	MAME_DIR .. "src/tools/floptool.cpp",
	GEN_DIR .. "version.cpp",
}

configuration { "mingw*" or "vs*" }
	targetextension ".exe"

configuration { }

strip()

--------------------------------------------------
-- imgtool
--------------------------------------------------

project("imgtool")
uuid ("f3707807-e587-4297-a5d8-bc98f3d0b1ca")
kind "ConsoleApp"

flags {
	"Symbols", -- always include minimum symbols for executables
}

if _OPTIONS["SEPARATE_BIN"]~="1" then
	targetdir(MAME_DIR)
end

links {
	"formats",
	"utils",
	ext_lib("expat"),
	"7z",
	"ocore_" .. _OPTIONS["osd"],
	ext_lib("zlib"),
	ext_lib("flac"),
	ext_lib("utf8proc"),
}

includedirs {
	MAME_DIR .. "src/osd",
	MAME_DIR .. "src/lib",
	MAME_DIR .. "src/lib/util",
	ext_includedir("zlib"),
	MAME_DIR .. "src/tools/imgtool",
}

files {
	MAME_DIR .. "src/tools/imgtool/main.cpp",
	MAME_DIR .. "src/tools/imgtool/main.h",
	MAME_DIR .. "src/tools/imgtool/stream.cpp",
	MAME_DIR .. "src/tools/imgtool/stream.h",
	MAME_DIR .. "src/tools/imgtool/library.cpp",
	MAME_DIR .. "src/tools/imgtool/library.h",
	MAME_DIR .. "src/tools/imgtool/modules.cpp",
	MAME_DIR .. "src/tools/imgtool/modules.h",
	MAME_DIR .. "src/tools/imgtool/iflopimg.cpp",
	MAME_DIR .. "src/tools/imgtool/iflopimg.h",
	MAME_DIR .. "src/tools/imgtool/filter.cpp",
	MAME_DIR .. "src/tools/imgtool/filter.h",
	MAME_DIR .. "src/tools/imgtool/filteoln.cpp",
	MAME_DIR .. "src/tools/imgtool/filtbas.cpp",
	MAME_DIR .. "src/tools/imgtool/imgtool.cpp",
	MAME_DIR .. "src/tools/imgtool/imgtool.h",
	MAME_DIR .. "src/tools/imgtool/imgterrs.cpp",
	MAME_DIR .. "src/tools/imgtool/imgterrs.h",
	MAME_DIR .. "src/tools/imgtool/imghd.cpp",
	MAME_DIR .. "src/tools/imgtool/imghd.h",
	MAME_DIR .. "src/tools/imgtool/charconv.cpp",
	MAME_DIR .. "src/tools/imgtool/charconv.h",
	MAME_DIR .. "src/tools/imgtool/formats/vt_dsk_legacy.cpp",
	MAME_DIR .. "src/tools/imgtool/formats/vt_dsk_legacy.h",
	MAME_DIR .. "src/tools/imgtool/formats/coco_dsk.cpp",
	MAME_DIR .. "src/tools/imgtool/formats/coco_dsk.h",
	MAME_DIR .. "src/tools/imgtool/formats/pc_dsk_legacy.cpp",
	MAME_DIR .. "src/tools/imgtool/formats/pc_dsk_legacy.h",
	MAME_DIR .. "src/tools/imgtool/modules/amiga.cpp",
	MAME_DIR .. "src/tools/imgtool/modules/rsdos.cpp",
	MAME_DIR .. "src/tools/imgtool/modules/dgndos.cpp",
	MAME_DIR .. "src/tools/imgtool/modules/os9.cpp",
	MAME_DIR .. "src/tools/imgtool/modules/ti99.cpp",
	MAME_DIR .. "src/tools/imgtool/modules/ti990hd.cpp",
	MAME_DIR .. "src/tools/imgtool/modules/concept.cpp",
	MAME_DIR .. "src/tools/imgtool/modules/fat.cpp",
	MAME_DIR .. "src/tools/imgtool/modules/fat.h",
	MAME_DIR .. "src/tools/imgtool/modules/pc_flop.cpp",
	MAME_DIR .. "src/tools/imgtool/modules/pc_hard.cpp",
	MAME_DIR .. "src/tools/imgtool/modules/vzdos.cpp",
	MAME_DIR .. "src/tools/imgtool/modules/thomson.cpp",
	MAME_DIR .. "src/tools/imgtool/modules/cybiko.cpp",
	MAME_DIR .. "src/tools/imgtool/modules/cybikoxt.cpp",
	MAME_DIR .. "src/tools/imgtool/modules/psion.cpp",
	MAME_DIR .. "src/tools/imgtool/modules/bml3.cpp",
	MAME_DIR .. "src/tools/imgtool/modules/hp48.cpp",
	MAME_DIR .. "src/tools/imgtool/modules/hp9845_tape.cpp",
	MAME_DIR .. "src/tools/imgtool/modules/hp85_tape.cpp",
	MAME_DIR .. "src/tools/imgtool/modules/rt11.cpp",
}

configuration { "mingw*" or "vs*" }
	targetextension ".exe"

configuration { }

strip()

--------------------------------------------------
-- aueffectutil
--------------------------------------------------

if _OPTIONS["targetos"] == "macosx" then
	project("aueffectutil")
		uuid ("3db8316d-fad7-4f5b-b46a-99373c91550e")
		kind "ConsoleApp"

		flags {
			"Symbols", -- always include minimum symbols for executables
		}

		if _OPTIONS["SEPARATE_BIN"]~="1" then
			targetdir(MAME_DIR)
		end

		linkoptions {
			"-sectcreate __TEXT __info_plist " .. _MAKE.esc(MAME_DIR) .. "src/tools/aueffectutil-Info.plist",
		}

		dependency {
			{ "aueffectutil",  MAME_DIR .. "src/tools/aueffectutil-Info.plist", true  },
		}

		links {
			"AudioUnit.framework",
			"AudioToolbox.framework",
			"CoreAudio.framework",
			"CoreAudioKit.framework",
			"CoreServices.framework",
		}

		files {
			MAME_DIR .. "src/tools/aueffectutil.mm",
		}

		configuration { }

		strip()
end

--------------------------------------------------
-- testkeys
--------------------------------------------------

if (_OPTIONS["osd"] == "sdl") then
	project("testkeys")
	uuid ("b3f5a5b8-3203-11e9-93e4-670b4f4e359d")
	kind "ConsoleApp"

	flags {
		"Symbols", -- always include minimum symbols for executables
	}

	if _OPTIONS["SEPARATE_BIN"]~="1" then
		targetdir(MAME_DIR)
	end

	links {
		"utils",
		"ocore_" .. _OPTIONS["osd"],
		ext_lib("utf8proc"),
	}

	if _OPTIONS["targetos"]=="windows" then
		if _OPTIONS["with-bundled-sdl2"]~=nil then
			configuration { "mingw*"}
				links {
					"SDL2",
					"imm32",
					"version",
					"ole32",
					"oleaut32",
				}
			configuration { "vs*" }
				links {
					"SDL2",
					"imm32",
					"version",
				}
			configuration { }
		else
			if _OPTIONS["USE_LIBSDL"]~="1" then
				configuration { "mingw*"}
					links {
						"SDL2main",
						"SDL2",
					}
				configuration { "vs*" }
					links {
						"SDL2",
						"imm32",
						"version",
					}
				configuration { }
			else
				local str = backtick(sdlconfigcmd() .. " --libs | sed 's/ -lSDLmain//'")
				addlibfromstring(str)
				addoptionsfromstring(str)
			end
			configuration { "x32", "vs*" }
				libdirs {
					path.join(_OPTIONS["SDL_INSTALL_ROOT"],"lib","x86")
				}
			configuration { "x64", "vs*" }
				libdirs {
					path.join(_OPTIONS["SDL_INSTALL_ROOT"],"lib","x64")
				}
		end
	end

	if BASE_TARGETOS=="unix" then
		if _OPTIONS["with-bundled-sdl2"]~=nil then
			links {
				"SDL2",
			}
		end
	end

	dofile("osd/sdl_cfg.lua")

	includedirs {
		MAME_DIR .. "src/osd",
		MAME_DIR .. "src/lib/util",
	}

	files {
		MAME_DIR .. "src/tools/testkeys.cpp",
	}

	configuration { "mingw*" or "vs*" }
		targetextension ".exe"

	configuration { }

	strip()
end