summaryrefslogtreecommitdiffstatshomepage
path: root/src/osd/modules/lib
diff options
context:
space:
mode:
Diffstat (limited to 'src/osd/modules/lib')
-rw-r--r--src/osd/modules/lib/osdlib.h136
-rw-r--r--src/osd/modules/lib/osdlib_macosx.cpp228
-rw-r--r--src/osd/modules/lib/osdlib_unix.cpp261
-rw-r--r--src/osd/modules/lib/osdlib_uwp.cpp190
-rw-r--r--src/osd/modules/lib/osdlib_win32.cpp239
-rw-r--r--src/osd/modules/lib/osdobj_common.cpp686
-rw-r--r--src/osd/modules/lib/osdobj_common.h149
7 files changed, 1115 insertions, 774 deletions
diff --git a/src/osd/modules/lib/osdlib.h b/src/osd/modules/lib/osdlib.h
index 0095244d6fe..967cb0d61ae 100644
--- a/src/osd/modules/lib/osdlib.h
+++ b/src/osd/modules/lib/osdlib.h
@@ -12,15 +12,21 @@
// - osd_ticks
// - osd_sleep
//============================================================
+#ifndef MAME_OSD_LIB_OSDLIB_H
+#define MAME_OSD_LIB_OSDLIB_H
-#ifndef __OSDLIB__
-#define __OSDLIB__
+#pragma once
+#include <cstdint>
+#include <initializer_list>
#include <string>
+#include <string_view>
+#include <system_error>
#include <type_traits>
#include <vector>
#include <memory>
+
/*-----------------------------------------------------------------------------
osd_process_kill: kill the current process
@@ -33,7 +39,7 @@
None.
-----------------------------------------------------------------------------*/
-void osd_process_kill(void);
+void osd_process_kill();
/*-----------------------------------------------------------------------------
@@ -53,10 +59,108 @@ void osd_process_kill(void);
int osd_setenv(const char *name, const char *value, int overwrite);
-/*-----------------------------------------------------------------------------
- osd_get_clipboard_text: retrieves text from the clipboard
------------------------------------------------------------------------------*/
-std::string osd_get_clipboard_text(void);
+/// \brief Get clipboard text
+///
+/// Gets current clipboard content as UTF-8 text. Returns an empty
+/// string if the clipboard contents cannot be converted to plain text.
+/// \return Clipboard contents or an empty string.
+std::string osd_get_clipboard_text() noexcept;
+
+
+/// \brief Set clipboard text
+///
+/// Sets the desktop environment's clipboard contents to the supplied
+/// UTF-8 text. The contents of the clipboard may be changed on error.
+/// \param [in] text The text to copy to the clipboard.
+/// \return An error condition if the operation failed or is
+/// unsupported.
+std::error_condition osd_set_clipboard_text(std::string_view text) noexcept;
+
+
+namespace osd {
+
+bool invalidate_instruction_cache(void const *start, std::size_t size) noexcept;
+
+
+class virtual_memory_allocation
+{
+public:
+ enum : unsigned
+ {
+ NONE = 0x00,
+ READ = 0x01,
+ WRITE = 0x02,
+ EXECUTE = 0x04,
+ READ_WRITE = READ | WRITE,
+ READ_EXECUTE = READ | EXECUTE,
+ READ_WRITE_EXECUTE = READ | WRITE | EXECUTE
+ };
+
+ virtual_memory_allocation(virtual_memory_allocation const &) = delete;
+ virtual_memory_allocation &operator=(virtual_memory_allocation const &) = delete;
+
+ virtual_memory_allocation() noexcept { }
+ virtual_memory_allocation(std::initializer_list<std::size_t> blocks, unsigned intent) noexcept
+ {
+ m_memory = do_alloc(blocks, intent, m_size, m_page_size);
+ }
+ virtual_memory_allocation(virtual_memory_allocation &&that) noexcept : m_memory(that.m_memory), m_size(that.m_size), m_page_size(that.m_page_size)
+ {
+ that.m_memory = nullptr;
+ that.m_size = that.m_page_size = 0U;
+ }
+ ~virtual_memory_allocation()
+ {
+ if (m_memory)
+ do_free(m_memory, m_size);
+ }
+
+ explicit operator bool() const noexcept { return bool(m_memory); }
+ void *get() noexcept { return m_memory; }
+ std::size_t size() const noexcept { return m_size; }
+ std::size_t page_size() const noexcept { return m_page_size; }
+
+ bool set_access(std::size_t start, std::size_t size, unsigned access) noexcept
+ {
+ if ((start % m_page_size) || (size % m_page_size) || (start > m_size) || ((m_size - start) < size))
+ return false;
+ else
+ return do_set_access(reinterpret_cast<std::uint8_t *>(m_memory) + start, size, access);
+ }
+
+ virtual_memory_allocation &operator=(std::nullptr_t) noexcept
+ {
+ if (m_memory)
+ do_free(m_memory, m_size);
+ m_memory = nullptr;
+ m_size = m_page_size = 0U;
+ return *this;
+ }
+
+ virtual_memory_allocation &operator=(virtual_memory_allocation &&that) noexcept
+ {
+ if (&that != this)
+ {
+ if (m_memory)
+ do_free(m_memory, m_size);
+ m_memory = that.m_memory;
+ m_size = that.m_size;
+ m_page_size = that.m_page_size;
+ that.m_memory = nullptr;
+ that.m_size = that.m_page_size = 0U;
+ }
+ return *this;
+ }
+
+private:
+ static void *do_alloc(std::initializer_list<std::size_t> blocks, unsigned intent, std::size_t &size, std::size_t &page_size) noexcept;
+ static void do_free(void *start, std::size_t size) noexcept;
+ static bool do_set_access(void *start, std::size_t size, unsigned access) noexcept;
+
+ void *m_memory = nullptr;
+ std::size_t m_size = 0U, m_page_size = 0U;
+};
+
/*-----------------------------------------------------------------------------
dynamic_module: load functions from optional shared libraries
@@ -69,7 +173,6 @@ std::string osd_get_clipboard_text(void);
revisions of a same library)
-----------------------------------------------------------------------------*/
-namespace osd {
class dynamic_module
{
public:
@@ -77,10 +180,10 @@ public:
static ptr open(std::vector<std::string> &&libraries);
- virtual ~dynamic_module() { };
+ virtual ~dynamic_module() { }
template <typename T>
- typename std::enable_if<std::is_pointer<T>::value, T>::type bind(char const *symbol)
+ typename std::enable_if_t<std::is_pointer_v<T>, T> bind(char const *symbol)
{
return reinterpret_cast<T>(get_symbol_address(symbol));
}
@@ -102,20 +205,9 @@ protected:
// Calling then looks like: DYNAMIC_CALL(CreateDXGIFactory1, p1, p2, etc)
//=========================================================================================================
-#if !defined(OSD_UWP)
-
#define OSD_DYNAMIC_API(apiname, ...) osd::dynamic_module::ptr m_##apiname##module = osd::dynamic_module::open( { __VA_ARGS__ } )
#define OSD_DYNAMIC_API_FN(apiname, ret, conv, fname, ...) ret(conv *m_##fname##_pfn)( __VA_ARGS__ ) = m_##apiname##module->bind<ret(conv *)( __VA_ARGS__ )>(#fname)
#define OSD_DYNAMIC_CALL(fname, ...) (*m_##fname##_pfn) ( __VA_ARGS__ )
#define OSD_DYNAMIC_API_TEST(fname) (m_##fname##_pfn != nullptr)
-#else
-
-#define OSD_DYNAMIC_API(apiname, ...)
-#define OSD_DYNAMIC_API_FN(apiname, ret, conv, fname, ...)
-#define OSD_DYNAMIC_CALL(fname, ...) fname( __VA_ARGS__ )
-#define OSD_DYNAMIC_API_TEST(fname) (true)
-
-#endif
-
-#endif /* __OSDLIB__ */
+#endif // MAME_OSD_LIB_OSDLIB_H
diff --git a/src/osd/modules/lib/osdlib_macosx.cpp b/src/osd/modules/lib/osdlib_macosx.cpp
index 372293ec1a3..54836f9ec69 100644
--- a/src/osd/modules/lib/osdlib_macosx.cpp
+++ b/src/osd/modules/lib/osdlib_macosx.cpp
@@ -8,26 +8,26 @@
//
//============================================================
-#include <stdlib.h>
-#include <unistd.h>
-#include <sys/mman.h>
-#include <sys/sysctl.h>
-#include <sys/types.h>
-#include <signal.h>
-#include <dlfcn.h>
+// MAME headers
+#include "osdcore.h"
+#include "osdlib.h"
+#include <csignal>
#include <cstdio>
+#include <cstdlib>
#include <iomanip>
#include <memory>
+#include <dlfcn.h>
+#include <sys/mman.h>
+#include <sys/sysctl.h>
+#include <sys/types.h>
+#include <unistd.h>
#include <mach/mach.h>
#include <mach/mach_time.h>
#include <Carbon/Carbon.h>
-// MAME headers
-#include "osdcore.h"
-#include "osdlib.h"
//============================================================
// osd_getenv
@@ -56,36 +56,6 @@ void osd_process_kill()
kill(getpid(), SIGKILL);
}
-//============================================================
-// osd_alloc_executable
-//
-// allocates "size" bytes of executable memory. this must take
-// things like NX support into account.
-//============================================================
-
-void *osd_alloc_executable(size_t size)
-{
-#if defined(SDLMAME_BSD) || defined(SDLMAME_MACOSX)
- return (void *)mmap(0, size, PROT_EXEC|PROT_READ|PROT_WRITE, MAP_ANON|MAP_SHARED, -1, 0);
-#elif defined(SDLMAME_UNIX)
- return (void *)mmap(0, size, PROT_EXEC|PROT_READ|PROT_WRITE, MAP_ANON|MAP_SHARED, 0, 0);
-#endif
-}
-
-//============================================================
-// osd_free_executable
-//
-// frees memory allocated with osd_alloc_executable
-//============================================================
-
-void osd_free_executable(void *ptr, size_t size)
-{
-#ifdef SDLMAME_SOLARIS
- munmap((char *)ptr, size);
-#else
- munmap(ptr, size);
-#endif
-}
//============================================================
// osd_break_into_debugger
@@ -98,7 +68,7 @@ void osd_break_into_debugger(const char *message)
struct kinfo_proc info;
info.kp_proc.p_flag = 0;
std::size_t infosz = sizeof(info);
- sysctl(mib, ARRAY_LENGTH(mib), &info, &infosz, nullptr, 0);
+ sysctl(mib, std::size(mib), &info, &infosz, nullptr, 0);
if (info.kp_proc.p_flag & P_TRACED)
{
printf("MAME exception: %s\n", message);
@@ -113,10 +83,26 @@ void osd_break_into_debugger(const char *message)
//============================================================
+// osd_get_cache_line_size
+//============================================================
+
+std::pair<std::error_condition, unsigned> osd_get_cache_line_size() noexcept
+{
+ size_t result = 0;
+ size_t resultsize = sizeof(result);
+ int const err = sysctlbyname("hw.cachelinesize", &result, &resultsize, 0, 0);
+ if (!err)
+ return std::make_pair(std::error_condition(), unsigned(result));
+ else
+ return std::make_pair(std::error_condition(err, std::generic_category()), 0U);
+}
+
+
+//============================================================
// osd_get_clipboard_text
//============================================================
-std::string osd_get_clipboard_text(void)
+std::string osd_get_clipboard_text() noexcept
{
std::string result;
bool has_result = false;
@@ -152,31 +138,48 @@ std::string osd_get_clipboard_text(void)
CFStringEncoding encoding;
if (UTTypeConformsTo(flavor_type, kUTTypeUTF16PlainText))
encoding = kCFStringEncodingUTF16;
- else if (UTTypeConformsTo (flavor_type, kUTTypeUTF8PlainText))
+ else if (UTTypeConformsTo(flavor_type, kUTTypeUTF8PlainText))
encoding = kCFStringEncodingUTF8;
- else if (UTTypeConformsTo (flavor_type, kUTTypePlainText))
+ else if (UTTypeConformsTo(flavor_type, kUTTypePlainText))
encoding = kCFStringEncodingMacRoman;
else
continue;
CFDataRef flavor_data;
err = PasteboardCopyItemFlavorData(pasteboard_ref, item_id, flavor_type, &flavor_data);
+ if (err)
+ continue;
- if (!err)
+ CFDataRef utf8_data;
+ if (kCFStringEncodingUTF8 == encoding)
+ {
+ utf8_data = flavor_data;
+ }
+ else
{
CFStringRef string_ref = CFStringCreateFromExternalRepresentation(kCFAllocatorDefault, flavor_data, encoding);
- CFDataRef data_ref = CFStringCreateExternalRepresentation (kCFAllocatorDefault, string_ref, kCFStringEncodingUTF8, '?');
- CFRelease(string_ref);
CFRelease(flavor_data);
+ if (!string_ref)
+ continue;
- CFIndex const length = CFDataGetLength(data_ref);
- CFRange const range = CFRangeMake(0, length);
-
- result.resize(length);
- CFDataGetBytes(data_ref, range, reinterpret_cast<unsigned char *>(&result[0]));
- has_result = true;
+ utf8_data = CFStringCreateExternalRepresentation(kCFAllocatorDefault, string_ref, kCFStringEncodingUTF8, '?');
+ CFRelease(string_ref);
+ }
- CFRelease(data_ref);
+ if (utf8_data)
+ {
+ CFIndex const length = CFDataGetLength(utf8_data);
+ CFRange const range = CFRangeMake(0, length);
+ try
+ {
+ result.resize(length);
+ CFDataGetBytes(utf8_data, range, reinterpret_cast<UInt8 *>(result.data()));
+ has_result = true;
+ }
+ catch (std::bad_alloc const &)
+ {
+ }
+ CFRelease(utf8_data);
}
}
@@ -188,34 +191,72 @@ std::string osd_get_clipboard_text(void)
return result;
}
+
//============================================================
-// osd_getpid
+// osd_set_clipboard_text
//============================================================
-int osd_getpid(void)
+std::error_condition osd_set_clipboard_text(std::string_view text) noexcept
{
- return getpid();
+ // FIXME: better conversion of OSStatus to std::error_condition
+ OSStatus err;
+
+ CFDataRef const data = CFDataCreate(kCFAllocatorDefault, reinterpret_cast<UInt8 const *>(text.data()), text.length());
+ if (!data)
+ return std::errc::not_enough_memory;
+
+ PasteboardRef pasteboard_ref;
+ err = PasteboardCreate(kPasteboardClipboard, &pasteboard_ref);
+ if (err)
+ {
+ CFRelease(data);
+ return std::errc::io_error;
+ }
+
+ err = PasteboardClear(pasteboard_ref);
+ if (err)
+ {
+ CFRelease(data);
+ CFRelease(pasteboard_ref);
+ return std::errc::io_error;
+ }
+
+ err = PasteboardPutItemFlavor(pasteboard_ref, PasteboardItemID(1), kUTTypeUTF8PlainText, data, kPasteboardFlavorNoFlags);
+ CFRelease(data);
+ CFRelease(pasteboard_ref);
+ if (err)
+ return std::errc::io_error;
+
+ return std::error_condition();
}
+
//============================================================
-// dynamic_module_posix_impl
+// osd_getpid
//============================================================
+int osd_getpid() noexcept
+{
+ return getpid();
+}
+
+
namespace osd {
+
+namespace {
+
class dynamic_module_posix_impl : public dynamic_module
{
public:
- dynamic_module_posix_impl(std::vector<std::string> &libraries)
- : m_module(nullptr)
+ dynamic_module_posix_impl(std::vector<std::string> &&libraries) : m_libraries(std::move(libraries))
{
- m_libraries = libraries;
}
virtual ~dynamic_module_posix_impl() override
{
- if (m_module != nullptr)
+ if (m_module)
dlclose(m_module);
- };
+ }
protected:
virtual generic_fptr_t get_symbol_address(char const *symbol) override
@@ -225,19 +266,17 @@ protected:
* one of them, all additional symbols will be loaded from the same library
*/
if (m_module)
- {
return reinterpret_cast<generic_fptr_t>(dlsym(m_module, symbol));
- }
for (auto const &library : m_libraries)
{
- void *module = dlopen(library.c_str(), RTLD_LAZY);
+ void *const module = dlopen(library.c_str(), RTLD_LAZY);
if (module != nullptr)
{
- generic_fptr_t function = reinterpret_cast<generic_fptr_t>(dlsym(module, symbol));
+ generic_fptr_t const function = reinterpret_cast<generic_fptr_t>(dlsym(module, symbol));
- if (function != nullptr)
+ if (function)
{
m_module = module;
return function;
@@ -254,12 +293,61 @@ protected:
private:
std::vector<std::string> m_libraries;
- void * m_module;
+ void * m_module = nullptr;
};
+} // anonymous namespace
+
+
+bool invalidate_instruction_cache(void const *start, std::size_t size) noexcept
+{
+ char const *const begin(reinterpret_cast<char const *>(start));
+ char const *const end(begin + size);
+ __builtin___clear_cache(const_cast<char *>(begin), const_cast<char *>(end));
+ return true;
+}
+
+
+void *virtual_memory_allocation::do_alloc(std::initializer_list<std::size_t> blocks, unsigned intent, std::size_t &size, std::size_t &page_size) noexcept
+{
+ long const p(sysconf(_SC_PAGE_SIZE));
+ if (0 >= p)
+ return nullptr;
+ std::size_t s(0);
+ for (std::size_t b : blocks)
+ s += (b + p - 1) / p;
+ s *= p;
+ if (!s)
+ return nullptr;
+ void *const result(mmap(nullptr, s, PROT_NONE, MAP_ANON | MAP_SHARED, -1, 0));
+ if (result == (void *)-1)
+ return nullptr;
+ size = s;
+ page_size = p;
+ return result;
+}
+
+void virtual_memory_allocation::do_free(void *start, std::size_t size) noexcept
+{
+ munmap(start, size);
+}
+
+bool virtual_memory_allocation::do_set_access(void *start, std::size_t size, unsigned access) noexcept
+{
+ int prot((NONE == access) ? PROT_NONE : 0);
+ if (access & READ)
+ prot |= PROT_READ;
+ if (access & WRITE)
+ prot |= PROT_WRITE;
+ if (access & EXECUTE)
+ prot |= PROT_EXEC;
+ return mprotect(start, size, prot) == 0;
+}
+
+
dynamic_module::ptr dynamic_module::open(std::vector<std::string> &&names)
{
- return std::make_unique<dynamic_module_posix_impl>(names);
+ return std::make_unique<dynamic_module_posix_impl>(std::move(names));
}
} // namespace osd
diff --git a/src/osd/modules/lib/osdlib_unix.cpp b/src/osd/modules/lib/osdlib_unix.cpp
index 178fb4594cb..1cfa9b1f183 100644
--- a/src/osd/modules/lib/osdlib_unix.cpp
+++ b/src/osd/modules/lib/osdlib_unix.cpp
@@ -8,23 +8,25 @@
//
//============================================================
-#include <stdlib.h>
-#include <unistd.h>
-#include <sys/mman.h>
-#include <sys/types.h>
-#include <signal.h>
-#include <dlfcn.h>
+// MAME headers
+#include "osdcore.h"
+#include "osdlib.h"
+#include <SDL2/SDL.h>
+
+#include <csignal>
#include <cstdio>
+#include <cstdlib>
+#include <cstring>
#include <iomanip>
#include <memory>
+#include <string_view>
+#include <dlfcn.h>
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <unistd.h>
-// MAME headers
-#include "osdcore.h"
-#include "osdlib.h"
-
-#include <SDL2/SDL.h>
//============================================================
// osd_getenv
@@ -53,105 +55,175 @@ void osd_process_kill()
kill(getpid(), SIGKILL);
}
+
//============================================================
-// osd_alloc_executable
-//
-// allocates "size" bytes of executable memory. this must take
-// things like NX support into account.
+// osd_break_into_debugger
//============================================================
-void *osd_alloc_executable(size_t size)
+void osd_break_into_debugger(const char *message)
{
-#if defined(SDLMAME_BSD) || defined(SDLMAME_MACOSX) || defined(SDLMAME_EMSCRIPTEN)
- return (void *)mmap(0, size, PROT_EXEC|PROT_READ|PROT_WRITE, MAP_ANON|MAP_SHARED, -1, 0);
+#if defined(__linux__)
+ bool do_break = false;
+ FILE *const f = std::fopen("/proc/self/status", "r");
+ if (f)
+ {
+ using namespace std::literals;
+
+ std::string_view const tag = "TracerPid:\t"sv;
+ char buf[128];
+ bool ignore = false;
+ while (std::fgets(buf, std::size(buf), f))
+ {
+ // ignore excessively long lines
+ auto const len = strnlen(buf, std::size(buf));
+ bool const noeol = !len || ('\n' != buf[len - 1]);
+ if (ignore || noeol)
+ {
+ ignore = noeol;
+ continue;
+ }
+
+ if (!std::strncmp(buf, tag.data(), tag.length()))
+ {
+ long tpid;
+ if ((std::sscanf(buf + tag.length(), "%ld", &tpid) == 1) && (0 != tpid))
+ do_break = true;
+ break;
+ }
+ }
+ std::fclose(f);
+ }
+#elif defined(MAME_DEBUG)
+ bool const do_break = true;
#else
- return (void *)mmap(0, size, PROT_EXEC|PROT_READ|PROT_WRITE, MAP_ANON|MAP_SHARED, 0, 0);
+ bool const do_break = false;
#endif
+ if (do_break)
+ {
+ printf("MAME exception: %s\n", message);
+ printf("Attempting to fall into debugger\n");
+ kill(getpid(), SIGTRAP);
+ }
+ else
+ {
+ printf("Ignoring MAME exception: %s\n", message);
+ }
}
+
//============================================================
-// osd_free_executable
-//
-// frees memory allocated with osd_alloc_executable
+// osd_get_cache_line_size
//============================================================
-void osd_free_executable(void *ptr, size_t size)
+std::pair<std::error_condition, unsigned> osd_get_cache_line_size() noexcept
{
-#ifdef SDLMAME_SOLARIS
- munmap((char *)ptr, size);
-#else
- munmap(ptr, size);
+#if defined(__linux__)
+ FILE *const f = std::fopen("/sys/devices/system/cpu/cpu0/cache/index0/coherency_line_size", "r");
+ if (!f)
+ return std::make_pair(std::error_condition(errno, std::generic_category()), 0U);
+
+ unsigned result = 0;
+ auto const cnt = std::fscanf(f, "%u", &result);
+ std::fclose(f);
+ if (1 == cnt)
+ return std::make_pair(std::error_condition(), result);
+ else
+ return std::make_pair(std::errc::io_error, 0U);
+#else // defined(__linux__)
+ return std::make_pair(std::errc::not_supported, 0U);
#endif
}
-//============================================================
-// osd_break_into_debugger
-//============================================================
-void osd_break_into_debugger(const char *message)
+#ifdef SDLMAME_ANDROID
+std::string osd_get_clipboard_text() noexcept
{
- #ifdef MAME_DEBUG
- printf("MAME exception: %s\n", message);
- printf("Attempting to fall into debugger\n");
- kill(getpid(), SIGTRAP);
- #else
- printf("Ignoring MAME exception: %s\n", message);
- #endif
+ return std::string();
}
-#ifdef SDLMAME_ANDROID
-std::string osd_get_clipboard_text(void)
+std::error_condition osd_set_clipboard_text(std::string_view text) noexcept
{
- return std::string();
+ return std::errc::io_error; // TODO: better error code?
}
#else
//============================================================
// osd_get_clipboard_text
//============================================================
-std::string osd_get_clipboard_text(void)
+std::string osd_get_clipboard_text() noexcept
{
+ // TODO: better error handling
std::string result;
if (SDL_HasClipboardText())
{
- char *temp = SDL_GetClipboardText();
- result.assign(temp);
- SDL_free(temp);
+ char *const temp = SDL_GetClipboardText();
+ if (temp)
+ {
+ try
+ {
+ result.assign(temp);
+ }
+ catch (std::bad_alloc const &)
+ {
+ }
+ SDL_free(temp);
+ }
}
return result;
}
+
+//============================================================
+// osd_set_clipboard_text
+//============================================================
+
+std::error_condition osd_set_clipboard_text(std::string_view text) noexcept
+{
+ try
+ {
+ std::string const clip(text); // need to do this to ensure there's a terminating NUL for SDL
+ if (0 > SDL_SetClipboardText(clip.c_str()))
+ {
+ // SDL_GetError returns a message, can't really convert it to an error condition
+ return std::errc::io_error; // TODO: better error code?
+ }
+
+ return std::error_condition();
+ }
+ catch (std::bad_alloc const &)
+ {
+ return std::errc::not_enough_memory;
+ }
+}
#endif
//============================================================
// osd_getpid
//============================================================
-int osd_getpid(void)
+int osd_getpid() noexcept
{
return getpid();
}
-//============================================================
-// dynamic_module_posix_impl
-//============================================================
namespace osd {
+
+namespace {
+
class dynamic_module_posix_impl : public dynamic_module
{
public:
- dynamic_module_posix_impl(std::vector<std::string> &libraries)
- : m_module(nullptr)
+ dynamic_module_posix_impl(std::vector<std::string> &&libraries) : m_libraries(std::move(libraries))
{
- m_libraries = libraries;
}
virtual ~dynamic_module_posix_impl() override
{
- if (m_module != nullptr)
+ if (m_module)
dlclose(m_module);
- };
+ }
protected:
virtual generic_fptr_t get_symbol_address(char const *symbol) override
@@ -161,19 +233,17 @@ protected:
* one of them, all additional symbols will be loaded from the same library
*/
if (m_module)
- {
return reinterpret_cast<generic_fptr_t>(dlsym(m_module, symbol));
- }
for (auto const &library : m_libraries)
{
- void *module = dlopen(library.c_str(), RTLD_LAZY);
+ void *const module = dlopen(library.c_str(), RTLD_LAZY);
if (module != nullptr)
{
- generic_fptr_t function = reinterpret_cast<generic_fptr_t>(dlsym(module, symbol));
+ generic_fptr_t const function = reinterpret_cast<generic_fptr_t>(dlsym(module, symbol));
- if (function != nullptr)
+ if (function)
{
m_module = module;
return function;
@@ -190,12 +260,81 @@ protected:
private:
std::vector<std::string> m_libraries;
- void * m_module;
+ void * m_module = nullptr;
};
+} // anonymous namespace
+
+
+bool invalidate_instruction_cache(void const *start, std::size_t size) noexcept
+{
+#if !defined(SDLMAME_EMSCRIPTEN)
+ char const *const begin(reinterpret_cast<char const *>(start));
+ char const *const end(begin + size);
+ __builtin___clear_cache(const_cast<char *>(begin), const_cast<char *>(end));
+#endif
+ return true;
+}
+
+
+void *virtual_memory_allocation::do_alloc(std::initializer_list<std::size_t> blocks, unsigned intent, std::size_t &size, std::size_t &page_size) noexcept
+{
+ long const p(sysconf(_SC_PAGE_SIZE));
+ if (0 >= p)
+ return nullptr;
+ std::size_t s(0);
+ for (std::size_t b : blocks)
+ s += (b + p - 1) / p;
+ s *= p;
+ if (!s)
+ return nullptr;
+#if defined __NetBSD__
+ int req((NONE == intent) ? PROT_NONE : 0);
+ if (intent & READ)
+ req |= PROT_READ;
+ if (intent & WRITE)
+ req |= PROT_WRITE;
+ if (intent & EXECUTE)
+ req |= PROT_EXEC;
+ int const prot(PROT_MPROTECT(req));
+#else
+ int const prot(PROT_NONE);
+#endif
+#if defined(SDLMAME_BSD) || defined(SDLMAME_MACOSX) || defined(SDLMAME_EMSCRIPTEN)
+ int const fd(-1);
+#else
+ // TODO: portable applications are supposed to use -1 for anonymous mappings - detect whatever requires 0 specifically
+ int const fd(0);
+#endif
+ void *const result(mmap(nullptr, s, prot, MAP_ANON | MAP_SHARED, fd, 0));
+ if (result == (void *)-1)
+ return nullptr;
+ size = s;
+ page_size = p;
+ return result;
+}
+
+void virtual_memory_allocation::do_free(void *start, std::size_t size) noexcept
+{
+ munmap(reinterpret_cast<char *>(start), size);
+}
+
+bool virtual_memory_allocation::do_set_access(void *start, std::size_t size, unsigned access) noexcept
+{
+ int prot((NONE == access) ? PROT_NONE : 0);
+ if (access & READ)
+ prot |= PROT_READ;
+ if (access & WRITE)
+ prot |= PROT_WRITE;
+ if (access & EXECUTE)
+ prot |= PROT_EXEC;
+ return mprotect(reinterpret_cast<char *>(start), size, prot) == 0;
+}
+
+
dynamic_module::ptr dynamic_module::open(std::vector<std::string> &&names)
{
- return std::make_unique<dynamic_module_posix_impl>(names);
+ return std::make_unique<dynamic_module_posix_impl>(std::move(names));
}
} // namespace osd
diff --git a/src/osd/modules/lib/osdlib_uwp.cpp b/src/osd/modules/lib/osdlib_uwp.cpp
deleted file mode 100644
index 8d20c552cab..00000000000
--- a/src/osd/modules/lib/osdlib_uwp.cpp
+++ /dev/null
@@ -1,190 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:Olivier Galibert, R. Belmont, Brad Hughes
-//============================================================
-//
-// sdlos_*.c - OS specific low level code
-//
-// SDLMAME by Olivier Galibert and R. Belmont
-//
-//============================================================
-
-#include <windows.h>
-#include <mmsystem.h>
-
-#include <stdlib.h>
-
-#include <cstdio>
-#include <memory>
-
-// MAME headers
-#include "osdlib.h"
-#include "osdcomm.h"
-#include "osdcore.h"
-#include "strconv.h"
-
-#include <windows.h>
-#include <wrl\client.h>
-
-#include "strconv.h"
-
-using namespace Platform;
-using namespace Windows::ApplicationModel::DataTransfer;
-using namespace Windows::Foundation;
-
-#include <map>
-
-//============================================================
-// GLOBAL VARIABLES
-//============================================================
-
-std::map<const char *, std::unique_ptr<char>> g_runtime_environment;
-
-//============================================================
-// osd_getenv
-//============================================================
-
-const char *osd_getenv(const char *name)
-{
- for (auto iter = g_runtime_environment.begin(); iter != g_runtime_environment.end(); iter++)
- {
- if (stricmp(iter->first, name) == 0)
- {
- osd_printf_debug("ENVIRONMENT: Get %s = value: '%s'", name, iter->second.get());
- return iter->second.get();
- }
- }
-
- return nullptr;
-}
-
-
-//============================================================
-// osd_setenv
-//============================================================
-
-int osd_setenv(const char *name, const char *value, int overwrite)
-{
- if (!overwrite)
- {
- if (osd_getenv(name) != nullptr)
- return 0;
- }
-
- auto buf = std::make_unique<char>(strlen(name) + strlen(value) + 2);
- sprintf(buf.get(), "%s=%s", name, value);
-
- g_runtime_environment[name] = std::move(buf);
- osd_printf_debug("ENVIRONMENT: Set %s to value: '%s'", name, buf.get());
-
- return 0;
-}
-
-//============================================================
-// osd_process_kill
-//============================================================
-
-void osd_process_kill()
-{
- TerminateProcess(GetCurrentProcess(), -1);
-}
-
-//============================================================
-// osd_alloc_executable
-//
-// allocates "size" bytes of executable memory. this must take
-// things like NX support into account.
-//============================================================
-
-void *osd_alloc_executable(size_t size)
-{
- return nullptr;
-}
-
-
-//============================================================
-// osd_free_executable
-//
-// frees memory allocated with osd_alloc_executable
-//============================================================
-
-void osd_free_executable(void *ptr, size_t size)
-{
-}
-
-
-//============================================================
-// osd_break_into_debugger
-//============================================================
-
-void osd_break_into_debugger(const char *message)
-{
- if (IsDebuggerPresent())
- {
- OutputDebugStringA(message);
- __debugbreak();
- }
-}
-
-//============================================================
-// get_clipboard_text_by_format
-//============================================================
-
-static bool get_clipboard_text_by_format(std::string &result_text, UINT format, std::string (*convert)(LPCVOID data))
-{
- DataPackageView^ dataPackageView;
- IAsyncOperation<String^>^ getTextOp;
- String^ clipboardText;
-
- dataPackageView = Clipboard::GetContent();
- getTextOp = dataPackageView->GetTextAsync();
- clipboardText = getTextOp->GetResults();
-
- result_text = convert(clipboardText->Data());
- return !result_text.empty();
-}
-
-//============================================================
-// convert_wide
-//============================================================
-
-static std::string convert_wide(LPCVOID data)
-{
- return osd::text::from_wstring((LPCWSTR) data);
-}
-
-//============================================================
-// convert_ansi
-//============================================================
-
-static std::string convert_ansi(LPCVOID data)
-{
- return osd::text::from_astring((LPCSTR) data);
-}
-
-//============================================================
-// osd_get_clipboard_text
-//============================================================
-
-std::string osd_get_clipboard_text(void)
-{
- std::string result;
-
- // try to access unicode text
- if (!get_clipboard_text_by_format(result, CF_UNICODETEXT, convert_wide))
- {
- // try to access ANSI text
- get_clipboard_text_by_format(result, CF_TEXT, convert_ansi);
- }
-
- return result;
-}
-
-//============================================================
-// osd_getpid
-//============================================================
-
-int osd_getpid(void)
-{
- return GetCurrentProcessId();
-}
-
diff --git a/src/osd/modules/lib/osdlib_win32.cpp b/src/osd/modules/lib/osdlib_win32.cpp
index 911f95c3bfe..cf3fd7c9320 100644
--- a/src/osd/modules/lib/osdlib_win32.cpp
+++ b/src/osd/modules/lib/osdlib_win32.cpp
@@ -8,27 +8,27 @@
//
//============================================================
-#include <windows.h>
-#include <mmsystem.h>
-
-#include <stdlib.h>
-#ifndef _MSC_VER
-#include <unistd.h>
-#endif
-
-#include <cstdio>
-#include <memory>
-
// MAME headers
#include "osdlib.h"
#include "osdcomm.h"
#include "osdcore.h"
#include "strconv.h"
-#ifdef OSD_WINDOWS
#include "winutf8.h"
+#include "winutil.h"
+
+#include <algorithm>
+#include <cstdio>
+#include <cstdlib>
+
+#include <windows.h>
+#include <memoryapi.h>
+
+#ifndef _MSC_VER
+#include <unistd.h>
#endif
+
//============================================================
// GLOBAL VARIABLES
//============================================================
@@ -82,30 +82,6 @@ void osd_process_kill()
TerminateProcess(GetCurrentProcess(), -1);
}
-//============================================================
-// osd_alloc_executable
-//
-// allocates "size" bytes of executable memory. this must take
-// things like NX support into account.
-//============================================================
-
-void *osd_alloc_executable(size_t size)
-{
- return VirtualAlloc(nullptr, size, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
-}
-
-
-//============================================================
-// osd_free_executable
-//
-// frees memory allocated with osd_alloc_executable
-//============================================================
-
-void osd_free_executable(void *ptr, size_t size)
-{
- VirtualFree(ptr, 0, MEM_RELEASE);
-}
-
//============================================================
// osd_break_into_debugger
@@ -130,6 +106,42 @@ void osd_break_into_debugger(const char *message)
#endif
}
+
+//============================================================
+// osd_get_cache_line_size
+//============================================================
+
+std::pair<std::error_condition, unsigned> osd_get_cache_line_size() noexcept
+{
+ DWORD resultsize = 0;
+ if (GetLogicalProcessorInformation(nullptr, &resultsize) || (ERROR_INSUFFICIENT_BUFFER != GetLastError()) || !resultsize)
+ return std::make_pair(std::errc::operation_not_permitted, 0U);
+
+ auto const result = reinterpret_cast<SYSTEM_LOGICAL_PROCESSOR_INFORMATION *>(std::malloc(resultsize));
+ if (!result)
+ return std::make_pair(std::errc::not_enough_memory, 0U);
+
+ if (!GetLogicalProcessorInformation(result, &resultsize))
+ {
+ std::free(result);
+ return std::make_pair(std::errc::operation_not_permitted, 0U);
+ }
+
+ for (unsigned i = 0; i < (resultsize / sizeof(result[0])); ++i)
+ {
+ if ((RelationCache == result[i].Relationship) && (1 == result[i].Cache.Level))
+ {
+ unsigned const linesize = result[i].Cache.LineSize;
+ std::free(result);
+ return std::make_pair(std::error_condition(), linesize);
+ }
+ }
+
+ std::free(result);
+ return std::make_pair(std::errc::operation_not_permitted, 0U);
+}
+
+
//============================================================
// get_clipboard_text_by_format
//============================================================
@@ -192,25 +204,92 @@ static std::string convert_ansi(LPCVOID data)
// osd_get_clipboard_text
//============================================================
-std::string osd_get_clipboard_text(void)
+std::string osd_get_clipboard_text() noexcept
{
std::string result;
- // try to access unicode text
- if (!get_clipboard_text_by_format(result, CF_UNICODETEXT, convert_wide))
+ // TODO: better error handling
+ try
+ {
+ // try to access unicode text
+ if (!get_clipboard_text_by_format(result, CF_UNICODETEXT, convert_wide))
+ {
+ // try to access ANSI text
+ get_clipboard_text_by_format(result, CF_TEXT, convert_ansi);
+ }
+ }
+ catch (...)
{
- // try to access ANSI text
- get_clipboard_text_by_format(result, CF_TEXT, convert_ansi);
}
return result;
}
//============================================================
+// osd_set_clipboard_text
+//============================================================
+
+std::error_condition osd_set_clipboard_text(std::string_view text) noexcept
+{
+ try
+ {
+ // convert the text to a wide char string and create a moveable global block
+ std::wstring const wtext = osd::text::to_wstring(text);
+ HGLOBAL const clip = GlobalAlloc(GMEM_MOVEABLE, (text.length() + 1) * sizeof(wchar_t));
+ if (!clip)
+ return win_error_to_error_condition(GetLastError());
+ LPWSTR const lock = reinterpret_cast<LPWSTR>(GlobalLock(clip));
+ if (!lock)
+ {
+ DWORD const err(GetLastError());
+ GlobalFree(clip);
+ return win_error_to_error_condition(err);
+ }
+
+ // clear current clipboard contents
+ if (!OpenClipboard(nullptr))
+ {
+ DWORD const err(GetLastError());
+ GlobalUnlock(clip);
+ GlobalFree(clip);
+ return win_error_to_error_condition(err);
+ }
+ if (!EmptyClipboard())
+ {
+ DWORD const err(GetLastError());
+ CloseClipboard();
+ GlobalUnlock(clip);
+ GlobalFree(clip);
+ return win_error_to_error_condition(err);
+ }
+
+ // copy the text (plus NUL terminator) to the moveable block and put it on the clipboard
+ std::copy_n(wtext.c_str(), wtext.length() + 1, lock);
+ GlobalUnlock(clip);
+ if (!SetClipboardData(CF_UNICODETEXT, clip))
+ {
+ DWORD const err(GetLastError());
+ CloseClipboard();
+ GlobalFree(clip);
+ return win_error_to_error_condition(err);
+ }
+
+ // clean up
+ if (!CloseClipboard())
+ return win_error_to_error_condition(GetLastError());
+ return std::error_condition();
+ }
+ catch (std::bad_alloc const &)
+ {
+ return std::errc::not_enough_memory;
+ }
+}
+
+//============================================================
// osd_getpid
//============================================================
-int osd_getpid(void)
+int osd_getpid() noexcept
{
return GetCurrentProcessId();
}
@@ -219,29 +298,25 @@ int osd_getpid(void)
// osd_dynamic_bind
//============================================================
-#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
// for classic desktop applications
#define load_library(filename) LoadLibrary(filename)
-#else
-// for Windows Store universal applications
-#define load_library(filename) LoadPackagedLibrary(filename, 0)
-#endif
namespace osd {
+
+namespace {
+
class dynamic_module_win32_impl : public dynamic_module
{
public:
- dynamic_module_win32_impl(std::vector<std::string> &libraries)
- : m_module(nullptr)
+ dynamic_module_win32_impl(std::vector<std::string> &&libraries) : m_libraries(std::move(libraries))
{
- m_libraries = libraries;
}
virtual ~dynamic_module_win32_impl() override
{
- if (m_module != nullptr)
+ if (m_module)
FreeLibrary(m_module);
- };
+ }
protected:
virtual generic_fptr_t get_symbol_address(char const *symbol) override
@@ -251,20 +326,18 @@ protected:
* one of them, all additional symbols will be loaded from the same library
*/
if (m_module)
- {
return reinterpret_cast<generic_fptr_t>(GetProcAddress(m_module, symbol));
- }
for (auto const &library : m_libraries)
{
- osd::text::tstring tempstr = osd::text::to_tstring(library);
- HMODULE module = load_library(tempstr.c_str());
+ osd::text::tstring const tempstr = osd::text::to_tstring(library);
+ HMODULE const module = load_library(tempstr.c_str());
- if (module != nullptr)
+ if (module)
{
- generic_fptr_t function = reinterpret_cast<generic_fptr_t>(GetProcAddress(module, symbol));
+ auto const function = reinterpret_cast<generic_fptr_t>(GetProcAddress(module, symbol));
- if (function != nullptr)
+ if (function)
{
m_module = module;
return function;
@@ -281,12 +354,56 @@ protected:
private:
std::vector<std::string> m_libraries;
- HMODULE m_module;
+ HMODULE m_module = nullptr;
};
+} // anonymous namespace
+
+
+bool invalidate_instruction_cache(void const *start, std::size_t size) noexcept
+{
+ return FlushInstructionCache(GetCurrentProcess(), start, size) != 0;
+}
+
+
+void *virtual_memory_allocation::do_alloc(std::initializer_list<std::size_t> blocks, unsigned intent, std::size_t &size, std::size_t &page_size) noexcept
+{
+ SYSTEM_INFO info;
+ GetSystemInfo(&info);
+ SIZE_T s(0);
+ for (std::size_t b : blocks)
+ s += (b + info.dwPageSize - 1) / info.dwPageSize;
+ s *= info.dwPageSize;
+ if (!s)
+ return nullptr;
+ LPVOID const result(VirtualAlloc(nullptr, s, MEM_COMMIT, PAGE_NOACCESS));
+ if (result)
+ {
+ size = s;
+ page_size = info.dwPageSize;
+ }
+ return result;
+}
+
+void virtual_memory_allocation::do_free(void *start, std::size_t size) noexcept
+{
+ VirtualFree(start, 0, MEM_RELEASE);
+}
+
+bool virtual_memory_allocation::do_set_access(void *start, std::size_t size, unsigned access) noexcept
+{
+ DWORD p;
+ if (access & EXECUTE)
+ p = (access & WRITE) ? PAGE_EXECUTE_READWRITE : (access & READ) ? PAGE_EXECUTE_READ : PAGE_EXECUTE;
+ else
+ p = (access & WRITE) ? PAGE_READWRITE : (access & READ) ? PAGE_READONLY : PAGE_NOACCESS;
+ return VirtualAlloc(start, size, MEM_COMMIT, p) != nullptr;
+}
+
+
dynamic_module::ptr dynamic_module::open(std::vector<std::string> &&names)
{
- return std::make_unique<dynamic_module_win32_impl>(names);
+ return std::make_unique<dynamic_module_win32_impl>(std::move(names));
}
} // namespace osd
diff --git a/src/osd/modules/lib/osdobj_common.cpp b/src/osd/modules/lib/osdobj_common.cpp
index 51474b810b0..24148889570 100644
--- a/src/osd/modules/lib/osdobj_common.cpp
+++ b/src/osd/modules/lib/osdobj_common.cpp
@@ -2,164 +2,188 @@
// copyright-holders:Aaron Giles
/***************************************************************************
- osdepend.c
+ osdobj_common.h
OS-dependent code interface.
***************************************************************************/
+#include "osdobj_common.h"
+
+#include "modules/osdwindow.h"
+#include "modules/debugger/debug_module.h"
+#include "modules/font/font_module.h"
+#include "modules/input/input_module.h"
+#include "modules/midi/midi_module.h"
+#include "modules/netdev/netdev_module.h"
+#include "modules/monitor/monitor_module.h"
+#include "modules/netdev/netdev_module.h"
+#include "modules/render/render_module.h"
+#include "modules/sound/sound_module.h"
+
+#include "watchdog.h"
#include "emu.h"
-#include "osdepend.h"
-#include "modules/lib/osdobj_common.h"
+#include "../frontend/mame/ui/menuitem.h"
+
+#include <iostream>
+
const options_entry osd_options::s_option_entries[] =
{
- { nullptr, nullptr, OPTION_HEADER, "OSD KEYBOARD MAPPING OPTIONS" },
+ { nullptr, nullptr, core_options::option_type::HEADER, "OSD INPUT MAPPING OPTIONS" },
#if defined(SDLMAME_MACOSX) || defined(OSD_MAC)
- { OSDOPTION_UIMODEKEY, "DEL", OPTION_STRING, "key to enable/disable MAME controls when emulated system has keyboard inputs" },
+ { OSDOPTION_UIMODEKEY, "DEL", core_options::option_type::STRING, "key to enable/disable MAME controls when emulated system has keyboard inputs" },
#else
- { OSDOPTION_UIMODEKEY, "SCRLOCK", OPTION_STRING, "key to enable/disable MAME controls when emulated system has keyboard inputs" },
+ { OSDOPTION_UIMODEKEY, "auto", core_options::option_type::STRING, "key to enable/disable MAME controls when emulated system has keyboard inputs" },
#endif // SDLMAME_MACOSX
-
- { nullptr, nullptr, OPTION_HEADER, "OSD FONT OPTIONS" },
- { OSD_FONT_PROVIDER, OSDOPTVAL_AUTO, OPTION_STRING, "provider for UI font: " },
-
- { nullptr, nullptr, OPTION_HEADER, "OSD OUTPUT OPTIONS" },
- { OSD_OUTPUT_PROVIDER, OSDOPTVAL_AUTO, OPTION_STRING, "provider for output notifications: " },
-
- { nullptr, nullptr, OPTION_HEADER, "OSD INPUT OPTIONS" },
- { OSD_KEYBOARDINPUT_PROVIDER, OSDOPTVAL_AUTO, OPTION_STRING, "provider for keyboard input: " },
- { OSD_MOUSEINPUT_PROVIDER, OSDOPTVAL_AUTO, OPTION_STRING, "provider for mouse input: " },
- { OSD_LIGHTGUNINPUT_PROVIDER, OSDOPTVAL_AUTO, OPTION_STRING, "provider for lightgun input: " },
- { OSD_JOYSTICKINPUT_PROVIDER, OSDOPTVAL_AUTO, OPTION_STRING, "provider for joystick input: " },
-
- { nullptr, nullptr, OPTION_HEADER, "OSD CLI OPTIONS" },
- { OSDCOMMAND_LIST_MIDI_DEVICES ";mlist", "0", OPTION_COMMAND, "list available MIDI I/O devices" },
- { OSDCOMMAND_LIST_NETWORK_ADAPTERS ";nlist", "0", OPTION_COMMAND, "list available network adapters" },
-
- { nullptr, nullptr, OPTION_HEADER, "OSD DEBUGGING OPTIONS" },
- { OSDOPTION_DEBUGGER, OSDOPTVAL_AUTO, OPTION_STRING, "debugger used: " },
- { OSDOPTION_DEBUGGER_PORT, "23946", OPTION_INTEGER, "port to use for gdbstub debugger" },
- { OSDOPTION_DEBUGGER_FONT ";dfont", OSDOPTVAL_AUTO, OPTION_STRING, "font to use for debugger views" },
- { OSDOPTION_DEBUGGER_FONT_SIZE ";dfontsize", "0", OPTION_FLOAT, "font size to use for debugger views" },
- { OSDOPTION_WATCHDOG ";wdog", "0", OPTION_INTEGER, "force the program to terminate if no updates within specified number of seconds" },
-
- { nullptr, nullptr, OPTION_HEADER, "OSD PERFORMANCE OPTIONS" },
- { OSDOPTION_NUMPROCESSORS ";np", OSDOPTVAL_AUTO, OPTION_STRING, "number of processors; this overrides the number the system reports" },
- { OSDOPTION_BENCH, "0", OPTION_INTEGER, "benchmark for the given number of emulated seconds; implies -video none -sound none -nothrottle" },
-
- { nullptr, nullptr, OPTION_HEADER, "OSD VIDEO OPTIONS" },
-// OS X can be trusted to have working hardware OpenGL, so default to it on for the best user experience
- { OSDOPTION_VIDEO, OSDOPTVAL_AUTO, OPTION_STRING, "video output method: " },
- { OSDOPTION_NUMSCREENS "(1-4)", "1", OPTION_INTEGER, "number of output screens/windows to create; usually, you want just one" },
- { OSDOPTION_WINDOW ";w", "0", OPTION_BOOLEAN, "enable window mode; otherwise, full screen mode is assumed" },
- { OSDOPTION_MAXIMIZE ";max", "1", OPTION_BOOLEAN, "default to maximized windows" },
- { OSDOPTION_WAITVSYNC ";vs", "0", OPTION_BOOLEAN, "enable waiting for the start of VBLANK before flipping screens (reduces tearing effects)" },
- { OSDOPTION_SYNCREFRESH ";srf", "0", OPTION_BOOLEAN, "enable using the start of VBLANK for throttling instead of the game time" },
- { OSD_MONITOR_PROVIDER, OSDOPTVAL_AUTO, OPTION_STRING, "monitor discovery method: " },
+ { OSDOPTION_CONTROLLER_MAP_FILE ";ctrlmap", OSDOPTVAL_NONE, core_options::option_type::PATH, "game controller mapping file" },
+ { OSDOPTION_BACKGROUND_INPUT, "0", core_options::option_type::BOOLEAN, "don't ignore input when losing UI focus" },
+
+ { nullptr, nullptr, core_options::option_type::HEADER, "OSD FONT OPTIONS" },
+ { OSD_FONT_PROVIDER, OSDOPTVAL_AUTO, core_options::option_type::STRING, "provider for UI font: " },
+
+ { nullptr, nullptr, core_options::option_type::HEADER, "OSD OUTPUT OPTIONS" },
+ { OSD_OUTPUT_PROVIDER, OSDOPTVAL_AUTO, core_options::option_type::STRING, "provider for output notifications: " },
+
+ { nullptr, nullptr, core_options::option_type::HEADER, "OSD INPUT OPTIONS" },
+ { OSD_KEYBOARDINPUT_PROVIDER, OSDOPTVAL_AUTO, core_options::option_type::STRING, "provider for keyboard input: " },
+ { OSD_MOUSEINPUT_PROVIDER, OSDOPTVAL_AUTO, core_options::option_type::STRING, "provider for mouse input: " },
+ { OSD_LIGHTGUNINPUT_PROVIDER, OSDOPTVAL_AUTO, core_options::option_type::STRING, "provider for lightgun input: " },
+ { OSD_JOYSTICKINPUT_PROVIDER, OSDOPTVAL_AUTO, core_options::option_type::STRING, "provider for joystick input: " },
+
+ { nullptr, nullptr, core_options::option_type::HEADER, "OSD CLI OPTIONS" },
+ { OSDCOMMAND_LIST_MIDI_DEVICES ";mlist", "0", core_options::option_type::COMMAND, "list available MIDI I/O devices" },
+ { OSDCOMMAND_LIST_NETWORK_ADAPTERS ";nlist", "0", core_options::option_type::COMMAND, "list available network adapters" },
+
+ { nullptr, nullptr, core_options::option_type::HEADER, "OSD DEBUGGING OPTIONS" },
+ { OSDOPTION_DEBUGGER, OSDOPTVAL_AUTO, core_options::option_type::STRING, "debugger used: " },
+ { OSDOPTION_DEBUGGER_HOST, "localhost", core_options::option_type::STRING, "address to bind to for gdbstub debugger" },
+ { OSDOPTION_DEBUGGER_PORT, "23946", core_options::option_type::INTEGER, "port to use for gdbstub debugger" },
+ { OSDOPTION_DEBUGGER_FONT ";dfont", OSDOPTVAL_AUTO, core_options::option_type::STRING, "font to use for debugger views" },
+ { OSDOPTION_DEBUGGER_FONT_SIZE ";dfontsize", "0", core_options::option_type::FLOAT, "font size to use for debugger views" },
+ { OSDOPTION_WATCHDOG ";wdog", "0", core_options::option_type::INTEGER, "force the program to terminate if no updates within specified number of seconds" },
+
+ { nullptr, nullptr, core_options::option_type::HEADER, "OSD PERFORMANCE OPTIONS" },
+ { OSDOPTION_NUMPROCESSORS ";np", OSDOPTVAL_AUTO, core_options::option_type::STRING, "number of processors; this overrides the number the system reports" },
+ { OSDOPTION_BENCH, "0", core_options::option_type::INTEGER, "benchmark for the given number of emulated seconds; implies -video none -sound none -nothrottle" },
+
+ { nullptr, nullptr, core_options::option_type::HEADER, "OSD VIDEO OPTIONS" },
+ { OSDOPTION_VIDEO, OSDOPTVAL_AUTO, core_options::option_type::STRING, "video output method: " },
+ { OSDOPTION_NUMSCREENS "(1-4)", "1", core_options::option_type::INTEGER, "number of output screens/windows to create; usually, you want just one" },
+ { OSDOPTION_WINDOW ";w", "0", core_options::option_type::BOOLEAN, "enable window mode; otherwise, full screen mode is assumed" },
+ { OSDOPTION_MAXIMIZE ";max", "1", core_options::option_type::BOOLEAN, "default to maximized windows" },
+ { OSDOPTION_WAITVSYNC ";vs", "0", core_options::option_type::BOOLEAN, "enable waiting for the start of VBLANK before flipping screens (reduces tearing effects)" },
+ { OSDOPTION_SYNCREFRESH ";srf", "0", core_options::option_type::BOOLEAN, "enable using the start of VBLANK for throttling instead of the game time" },
+ { OSD_MONITOR_PROVIDER, OSDOPTVAL_AUTO, core_options::option_type::STRING, "monitor discovery method: " },
// per-window options
- { nullptr, nullptr, OPTION_HEADER, "OSD PER-WINDOW VIDEO OPTIONS" },
- { OSDOPTION_SCREEN, OSDOPTVAL_AUTO, OPTION_STRING, "explicit name of the first screen; 'auto' here will try to make a best guess" },
- { OSDOPTION_ASPECT ";screen_aspect", OSDOPTVAL_AUTO, OPTION_STRING, "aspect ratio for all screens; 'auto' here will try to make a best guess" },
- { OSDOPTION_RESOLUTION ";r", OSDOPTVAL_AUTO, OPTION_STRING, "preferred resolution for all screens; format is <width>x<height>[@<refreshrate>] or 'auto'" },
- { OSDOPTION_VIEW, OSDOPTVAL_AUTO, OPTION_STRING, "preferred view for all screens" },
-
- { OSDOPTION_SCREEN "0", OSDOPTVAL_AUTO, OPTION_STRING, "explicit name of the first screen; 'auto' here will try to make a best guess" },
- { OSDOPTION_ASPECT "0", OSDOPTVAL_AUTO, OPTION_STRING, "aspect ratio of the first screen; 'auto' here will try to make a best guess" },
- { OSDOPTION_RESOLUTION "0;r0", OSDOPTVAL_AUTO, OPTION_STRING, "preferred resolution of the first screen; format is <width>x<height>[@<refreshrate>] or 'auto'" },
- { OSDOPTION_VIEW "0", OSDOPTVAL_AUTO, OPTION_STRING, "preferred view for the first screen" },
-
- { OSDOPTION_SCREEN "1", OSDOPTVAL_AUTO, OPTION_STRING, "explicit name of the second screen; 'auto' here will try to make a best guess" },
- { OSDOPTION_ASPECT "1", OSDOPTVAL_AUTO, OPTION_STRING, "aspect ratio of the second screen; 'auto' here will try to make a best guess" },
- { OSDOPTION_RESOLUTION "1;r1", OSDOPTVAL_AUTO, OPTION_STRING, "preferred resolution of the second screen; format is <width>x<height>[@<refreshrate>] or 'auto'" },
- { OSDOPTION_VIEW "1", OSDOPTVAL_AUTO, OPTION_STRING, "preferred view for the second screen" },
-
- { OSDOPTION_SCREEN "2", OSDOPTVAL_AUTO, OPTION_STRING, "explicit name of the third screen; 'auto' here will try to make a best guess" },
- { OSDOPTION_ASPECT "2", OSDOPTVAL_AUTO, OPTION_STRING, "aspect ratio of the third screen; 'auto' here will try to make a best guess" },
- { OSDOPTION_RESOLUTION "2;r2", OSDOPTVAL_AUTO, OPTION_STRING, "preferred resolution of the third screen; format is <width>x<height>[@<refreshrate>] or 'auto'" },
- { OSDOPTION_VIEW "2", OSDOPTVAL_AUTO, OPTION_STRING, "preferred view for the third screen" },
-
- { OSDOPTION_SCREEN "3", OSDOPTVAL_AUTO, OPTION_STRING, "explicit name of the fourth screen; 'auto' here will try to make a best guess" },
- { OSDOPTION_ASPECT "3", OSDOPTVAL_AUTO, OPTION_STRING, "aspect ratio of the fourth screen; 'auto' here will try to make a best guess" },
- { OSDOPTION_RESOLUTION "3;r3", OSDOPTVAL_AUTO, OPTION_STRING, "preferred resolution of the fourth screen; format is <width>x<height>[@<refreshrate>] or 'auto'" },
- { OSDOPTION_VIEW "3", OSDOPTVAL_AUTO, OPTION_STRING, "preferred view for the fourth screen" },
+ { nullptr, nullptr, core_options::option_type::HEADER, "OSD PER-WINDOW VIDEO OPTIONS" },
+ { OSDOPTION_SCREEN, OSDOPTVAL_AUTO, core_options::option_type::STRING, "explicit name of the first screen; 'auto' here will try to make a best guess" },
+ { OSDOPTION_ASPECT ";screen_aspect", OSDOPTVAL_AUTO, core_options::option_type::STRING, "aspect ratio for all screens; 'auto' here will try to make a best guess" },
+ { OSDOPTION_RESOLUTION ";r", OSDOPTVAL_AUTO, core_options::option_type::STRING, "preferred resolution for all screens; format is <width>x<height>[@<refreshrate>] or 'auto'" },
+ { OSDOPTION_VIEW, OSDOPTVAL_AUTO, core_options::option_type::STRING, "preferred view for all screens" },
+
+ { OSDOPTION_SCREEN "0", OSDOPTVAL_AUTO, core_options::option_type::STRING, "explicit name of the first screen; 'auto' here will try to make a best guess" },
+ { OSDOPTION_ASPECT "0", OSDOPTVAL_AUTO, core_options::option_type::STRING, "aspect ratio of the first screen; 'auto' here will try to make a best guess" },
+ { OSDOPTION_RESOLUTION "0;r0", OSDOPTVAL_AUTO, core_options::option_type::STRING, "preferred resolution of the first screen; format is <width>x<height>[@<refreshrate>] or 'auto'" },
+ { OSDOPTION_VIEW "0", OSDOPTVAL_AUTO, core_options::option_type::STRING, "preferred view for the first screen" },
+
+ { OSDOPTION_SCREEN "1", OSDOPTVAL_AUTO, core_options::option_type::STRING, "explicit name of the second screen; 'auto' here will try to make a best guess" },
+ { OSDOPTION_ASPECT "1", OSDOPTVAL_AUTO, core_options::option_type::STRING, "aspect ratio of the second screen; 'auto' here will try to make a best guess" },
+ { OSDOPTION_RESOLUTION "1;r1", OSDOPTVAL_AUTO, core_options::option_type::STRING, "preferred resolution of the second screen; format is <width>x<height>[@<refreshrate>] or 'auto'" },
+ { OSDOPTION_VIEW "1", OSDOPTVAL_AUTO, core_options::option_type::STRING, "preferred view for the second screen" },
+
+ { OSDOPTION_SCREEN "2", OSDOPTVAL_AUTO, core_options::option_type::STRING, "explicit name of the third screen; 'auto' here will try to make a best guess" },
+ { OSDOPTION_ASPECT "2", OSDOPTVAL_AUTO, core_options::option_type::STRING, "aspect ratio of the third screen; 'auto' here will try to make a best guess" },
+ { OSDOPTION_RESOLUTION "2;r2", OSDOPTVAL_AUTO, core_options::option_type::STRING, "preferred resolution of the third screen; format is <width>x<height>[@<refreshrate>] or 'auto'" },
+ { OSDOPTION_VIEW "2", OSDOPTVAL_AUTO, core_options::option_type::STRING, "preferred view for the third screen" },
+
+ { OSDOPTION_SCREEN "3", OSDOPTVAL_AUTO, core_options::option_type::STRING, "explicit name of the fourth screen; 'auto' here will try to make a best guess" },
+ { OSDOPTION_ASPECT "3", OSDOPTVAL_AUTO, core_options::option_type::STRING, "aspect ratio of the fourth screen; 'auto' here will try to make a best guess" },
+ { OSDOPTION_RESOLUTION "3;r3", OSDOPTVAL_AUTO, core_options::option_type::STRING, "preferred resolution of the fourth screen; format is <width>x<height>[@<refreshrate>] or 'auto'" },
+ { OSDOPTION_VIEW "3", OSDOPTVAL_AUTO, core_options::option_type::STRING, "preferred view for the fourth screen" },
// full screen options
- { nullptr, nullptr, OPTION_HEADER, "OSD FULL SCREEN OPTIONS" },
- { OSDOPTION_SWITCHRES, "0", OPTION_BOOLEAN, "enable resolution switching" },
+ { nullptr, nullptr, core_options::option_type::HEADER, "OSD FULL SCREEN OPTIONS" },
+ { OSDOPTION_SWITCHRES, "0", core_options::option_type::BOOLEAN, "enable resolution switching" },
- { nullptr, nullptr, OPTION_HEADER, "OSD ACCELERATED VIDEO OPTIONS" },
- { OSDOPTION_FILTER ";glfilter;flt", "1", OPTION_BOOLEAN, "use bilinear filtering when scaling emulated video" },
- { OSDOPTION_PRESCALE "(1-3)", "1", OPTION_INTEGER, "scale emulated video by this factor before applying filters/shaders" },
+ { nullptr, nullptr, core_options::option_type::HEADER, "OSD ACCELERATED VIDEO OPTIONS" },
+ { OSDOPTION_FILTER ";glfilter;flt", "1", core_options::option_type::BOOLEAN, "use bilinear filtering when scaling emulated video" },
+ { OSDOPTION_PRESCALE "(1-20)", "1", core_options::option_type::INTEGER, "scale emulated video by this factor before applying filters/shaders" },
#if USE_OPENGL
- { nullptr, nullptr, OPTION_HEADER, "OpenGL-SPECIFIC OPTIONS" },
- { OSDOPTION_GL_FORCEPOW2TEXTURE, "0", OPTION_BOOLEAN, "force power-of-two texture sizes (default no)" },
- { OSDOPTION_GL_NOTEXTURERECT, "0", OPTION_BOOLEAN, "don't use OpenGL GL_ARB_texture_rectangle (default on)" },
- { OSDOPTION_GL_VBO, "1", OPTION_BOOLEAN, "enable OpenGL VBO if available (default on)" },
- { OSDOPTION_GL_PBO, "1", OPTION_BOOLEAN, "enable OpenGL PBO if available (default on)" },
- { OSDOPTION_GL_GLSL, "0", OPTION_BOOLEAN, "enable OpenGL GLSL if available (default off)" },
- { OSDOPTION_GLSL_FILTER, "1", OPTION_STRING, "enable OpenGL GLSL filtering instead of FF filtering 0-plain, 1-bilinear (default), 2-bicubic" },
- { OSDOPTION_SHADER_MAME "0", OSDOPTVAL_NONE, OPTION_STRING, "custom OpenGL GLSL shader set mame bitmap 0" },
- { OSDOPTION_SHADER_MAME "1", OSDOPTVAL_NONE, OPTION_STRING, "custom OpenGL GLSL shader set mame bitmap 1" },
- { OSDOPTION_SHADER_MAME "2", OSDOPTVAL_NONE, OPTION_STRING, "custom OpenGL GLSL shader set mame bitmap 2" },
- { OSDOPTION_SHADER_MAME "3", OSDOPTVAL_NONE, OPTION_STRING, "custom OpenGL GLSL shader set mame bitmap 3" },
- { OSDOPTION_SHADER_MAME "4", OSDOPTVAL_NONE, OPTION_STRING, "custom OpenGL GLSL shader set mame bitmap 4" },
- { OSDOPTION_SHADER_MAME "5", OSDOPTVAL_NONE, OPTION_STRING, "custom OpenGL GLSL shader set mame bitmap 5" },
- { OSDOPTION_SHADER_MAME "6", OSDOPTVAL_NONE, OPTION_STRING, "custom OpenGL GLSL shader set mame bitmap 6" },
- { OSDOPTION_SHADER_MAME "7", OSDOPTVAL_NONE, OPTION_STRING, "custom OpenGL GLSL shader set mame bitmap 7" },
- { OSDOPTION_SHADER_MAME "8", OSDOPTVAL_NONE, OPTION_STRING, "custom OpenGL GLSL shader set mame bitmap 8" },
- { OSDOPTION_SHADER_MAME "9", OSDOPTVAL_NONE, OPTION_STRING, "custom OpenGL GLSL shader set mame bitmap 9" },
- { OSDOPTION_SHADER_SCREEN "0", OSDOPTVAL_NONE, OPTION_STRING, "custom OpenGL GLSL shader screen bitmap 0" },
- { OSDOPTION_SHADER_SCREEN "1", OSDOPTVAL_NONE, OPTION_STRING, "custom OpenGL GLSL shader screen bitmap 1" },
- { OSDOPTION_SHADER_SCREEN "2", OSDOPTVAL_NONE, OPTION_STRING, "custom OpenGL GLSL shader screen bitmap 2" },
- { OSDOPTION_SHADER_SCREEN "3", OSDOPTVAL_NONE, OPTION_STRING, "custom OpenGL GLSL shader screen bitmap 3" },
- { OSDOPTION_SHADER_SCREEN "4", OSDOPTVAL_NONE, OPTION_STRING, "custom OpenGL GLSL shader screen bitmap 4" },
- { OSDOPTION_SHADER_SCREEN "5", OSDOPTVAL_NONE, OPTION_STRING, "custom OpenGL GLSL shader screen bitmap 5" },
- { OSDOPTION_SHADER_SCREEN "6", OSDOPTVAL_NONE, OPTION_STRING, "custom OpenGL GLSL shader screen bitmap 6" },
- { OSDOPTION_SHADER_SCREEN "7", OSDOPTVAL_NONE, OPTION_STRING, "custom OpenGL GLSL shader screen bitmap 7" },
- { OSDOPTION_SHADER_SCREEN "8", OSDOPTVAL_NONE, OPTION_STRING, "custom OpenGL GLSL shader screen bitmap 8" },
- { OSDOPTION_SHADER_SCREEN "9", OSDOPTVAL_NONE, OPTION_STRING, "custom OpenGL GLSL shader screen bitmap 9" },
+ { nullptr, nullptr, core_options::option_type::HEADER, "OpenGL-SPECIFIC OPTIONS" },
+ { OSDOPTION_GL_FORCEPOW2TEXTURE, "0", core_options::option_type::BOOLEAN, "force power-of-two texture sizes (default no)" },
+ { OSDOPTION_GL_NOTEXTURERECT, "0", core_options::option_type::BOOLEAN, "don't use OpenGL GL_ARB_texture_rectangle (default on)" },
+ { OSDOPTION_GL_VBO, "1", core_options::option_type::BOOLEAN, "enable OpenGL VBO if available (default on)" },
+ { OSDOPTION_GL_PBO, "1", core_options::option_type::BOOLEAN, "enable OpenGL PBO if available (default on)" },
+ { OSDOPTION_GL_GLSL, "0", core_options::option_type::BOOLEAN, "enable OpenGL GLSL if available (default off)" },
+ { OSDOPTION_GLSL_FILTER, "1", core_options::option_type::STRING, "enable OpenGL GLSL filtering instead of FF filtering 0-plain, 1-bilinear (default), 2-bicubic" },
+ { OSDOPTION_SHADER_MAME "0", OSDOPTVAL_NONE, core_options::option_type::STRING, "custom OpenGL GLSL shader set mame bitmap 0" },
+ { OSDOPTION_SHADER_MAME "1", OSDOPTVAL_NONE, core_options::option_type::STRING, "custom OpenGL GLSL shader set mame bitmap 1" },
+ { OSDOPTION_SHADER_MAME "2", OSDOPTVAL_NONE, core_options::option_type::STRING, "custom OpenGL GLSL shader set mame bitmap 2" },
+ { OSDOPTION_SHADER_MAME "3", OSDOPTVAL_NONE, core_options::option_type::STRING, "custom OpenGL GLSL shader set mame bitmap 3" },
+ { OSDOPTION_SHADER_MAME "4", OSDOPTVAL_NONE, core_options::option_type::STRING, "custom OpenGL GLSL shader set mame bitmap 4" },
+ { OSDOPTION_SHADER_MAME "5", OSDOPTVAL_NONE, core_options::option_type::STRING, "custom OpenGL GLSL shader set mame bitmap 5" },
+ { OSDOPTION_SHADER_MAME "6", OSDOPTVAL_NONE, core_options::option_type::STRING, "custom OpenGL GLSL shader set mame bitmap 6" },
+ { OSDOPTION_SHADER_MAME "7", OSDOPTVAL_NONE, core_options::option_type::STRING, "custom OpenGL GLSL shader set mame bitmap 7" },
+ { OSDOPTION_SHADER_MAME "8", OSDOPTVAL_NONE, core_options::option_type::STRING, "custom OpenGL GLSL shader set mame bitmap 8" },
+ { OSDOPTION_SHADER_MAME "9", OSDOPTVAL_NONE, core_options::option_type::STRING, "custom OpenGL GLSL shader set mame bitmap 9" },
+ { OSDOPTION_SHADER_SCREEN "0", OSDOPTVAL_NONE, core_options::option_type::STRING, "custom OpenGL GLSL shader screen bitmap 0" },
+ { OSDOPTION_SHADER_SCREEN "1", OSDOPTVAL_NONE, core_options::option_type::STRING, "custom OpenGL GLSL shader screen bitmap 1" },
+ { OSDOPTION_SHADER_SCREEN "2", OSDOPTVAL_NONE, core_options::option_type::STRING, "custom OpenGL GLSL shader screen bitmap 2" },
+ { OSDOPTION_SHADER_SCREEN "3", OSDOPTVAL_NONE, core_options::option_type::STRING, "custom OpenGL GLSL shader screen bitmap 3" },
+ { OSDOPTION_SHADER_SCREEN "4", OSDOPTVAL_NONE, core_options::option_type::STRING, "custom OpenGL GLSL shader screen bitmap 4" },
+ { OSDOPTION_SHADER_SCREEN "5", OSDOPTVAL_NONE, core_options::option_type::STRING, "custom OpenGL GLSL shader screen bitmap 5" },
+ { OSDOPTION_SHADER_SCREEN "6", OSDOPTVAL_NONE, core_options::option_type::STRING, "custom OpenGL GLSL shader screen bitmap 6" },
+ { OSDOPTION_SHADER_SCREEN "7", OSDOPTVAL_NONE, core_options::option_type::STRING, "custom OpenGL GLSL shader screen bitmap 7" },
+ { OSDOPTION_SHADER_SCREEN "8", OSDOPTVAL_NONE, core_options::option_type::STRING, "custom OpenGL GLSL shader screen bitmap 8" },
+ { OSDOPTION_SHADER_SCREEN "9", OSDOPTVAL_NONE, core_options::option_type::STRING, "custom OpenGL GLSL shader screen bitmap 9" },
#endif
- { nullptr, nullptr, OPTION_HEADER, "OSD SOUND OPTIONS" },
- { OSDOPTION_SOUND, OSDOPTVAL_AUTO, OPTION_STRING, "sound output method: " },
- { OSDOPTION_AUDIO_LATENCY "(1-5)", "2", OPTION_INTEGER, "set audio latency (increase to reduce glitches, decrease for responsiveness)" },
+ { nullptr, nullptr, core_options::option_type::HEADER, "OSD SOUND OPTIONS" },
+ { OSDOPTION_SOUND, OSDOPTVAL_AUTO, core_options::option_type::STRING, "sound output method: " },
+ { OSDOPTION_AUDIO_LATENCY "(0-5)", "2", core_options::option_type::INTEGER, "set audio latency (increase to reduce glitches, decrease for responsiveness)" },
#ifndef NO_USE_PORTAUDIO
- { nullptr, nullptr, OPTION_HEADER, "PORTAUDIO OPTIONS" },
- { OSDOPTION_PA_API, OSDOPTVAL_NONE, OPTION_STRING, "PortAudio API" },
- { OSDOPTION_PA_DEVICE, OSDOPTVAL_NONE, OPTION_STRING, "PortAudio device" },
- { OSDOPTION_PA_LATENCY "(0-0.25)", "0", OPTION_FLOAT, "suggested latency in seconds, 0 for default" },
+ { nullptr, nullptr, core_options::option_type::HEADER, "PORTAUDIO OPTIONS" },
+ { OSDOPTION_PA_API, OSDOPTVAL_NONE, core_options::option_type::STRING, "PortAudio API" },
+ { OSDOPTION_PA_DEVICE, OSDOPTVAL_NONE, core_options::option_type::STRING, "PortAudio device" },
+ { OSDOPTION_PA_LATENCY "(0-0.25)", "0", core_options::option_type::FLOAT, "suggested latency in seconds, 0 for default" },
#endif
#ifdef SDLMAME_MACOSX
- { nullptr, nullptr, OPTION_HEADER, "CoreAudio-SPECIFIC OPTIONS" },
- { OSDOPTION_AUDIO_OUTPUT, OSDOPTVAL_AUTO, OPTION_STRING, "audio output device" },
- { OSDOPTION_AUDIO_EFFECT "0", OSDOPTVAL_NONE, OPTION_STRING, "AudioUnit effect 0" },
- { OSDOPTION_AUDIO_EFFECT "1", OSDOPTVAL_NONE, OPTION_STRING, "AudioUnit effect 1" },
- { OSDOPTION_AUDIO_EFFECT "2", OSDOPTVAL_NONE, OPTION_STRING, "AudioUnit effect 2" },
- { OSDOPTION_AUDIO_EFFECT "3", OSDOPTVAL_NONE, OPTION_STRING, "AudioUnit effect 3" },
- { OSDOPTION_AUDIO_EFFECT "4", OSDOPTVAL_NONE, OPTION_STRING, "AudioUnit effect 4" },
- { OSDOPTION_AUDIO_EFFECT "5", OSDOPTVAL_NONE, OPTION_STRING, "AudioUnit effect 5" },
- { OSDOPTION_AUDIO_EFFECT "6", OSDOPTVAL_NONE, OPTION_STRING, "AudioUnit effect 6" },
- { OSDOPTION_AUDIO_EFFECT "7", OSDOPTVAL_NONE, OPTION_STRING, "AudioUnit effect 7" },
- { OSDOPTION_AUDIO_EFFECT "8", OSDOPTVAL_NONE, OPTION_STRING, "AudioUnit effect 8" },
- { OSDOPTION_AUDIO_EFFECT "9", OSDOPTVAL_NONE, OPTION_STRING, "AudioUnit effect 9" },
+ { nullptr, nullptr, core_options::option_type::HEADER, "CoreAudio-SPECIFIC OPTIONS" },
+ { OSDOPTION_AUDIO_OUTPUT, OSDOPTVAL_AUTO, core_options::option_type::STRING, "audio output device" },
+ { OSDOPTION_AUDIO_EFFECT "0", OSDOPTVAL_NONE, core_options::option_type::STRING, "AudioUnit effect 0" },
+ { OSDOPTION_AUDIO_EFFECT "1", OSDOPTVAL_NONE, core_options::option_type::STRING, "AudioUnit effect 1" },
+ { OSDOPTION_AUDIO_EFFECT "2", OSDOPTVAL_NONE, core_options::option_type::STRING, "AudioUnit effect 2" },
+ { OSDOPTION_AUDIO_EFFECT "3", OSDOPTVAL_NONE, core_options::option_type::STRING, "AudioUnit effect 3" },
+ { OSDOPTION_AUDIO_EFFECT "4", OSDOPTVAL_NONE, core_options::option_type::STRING, "AudioUnit effect 4" },
+ { OSDOPTION_AUDIO_EFFECT "5", OSDOPTVAL_NONE, core_options::option_type::STRING, "AudioUnit effect 5" },
+ { OSDOPTION_AUDIO_EFFECT "6", OSDOPTVAL_NONE, core_options::option_type::STRING, "AudioUnit effect 6" },
+ { OSDOPTION_AUDIO_EFFECT "7", OSDOPTVAL_NONE, core_options::option_type::STRING, "AudioUnit effect 7" },
+ { OSDOPTION_AUDIO_EFFECT "8", OSDOPTVAL_NONE, core_options::option_type::STRING, "AudioUnit effect 8" },
+ { OSDOPTION_AUDIO_EFFECT "9", OSDOPTVAL_NONE, core_options::option_type::STRING, "AudioUnit effect 9" },
#endif
- { nullptr, nullptr, OPTION_HEADER, "BGFX POST-PROCESSING OPTIONS" },
- { OSDOPTION_BGFX_PATH, "bgfx", OPTION_STRING, "path to BGFX-related files" },
- { OSDOPTION_BGFX_BACKEND, "auto", OPTION_STRING, "BGFX backend to use (d3d9, d3d11, metal, opengl, gles)" },
- { OSDOPTION_BGFX_DEBUG, "0", OPTION_BOOLEAN, "enable BGFX debugging statistics" },
- { OSDOPTION_BGFX_SCREEN_CHAINS, "default", OPTION_STRING, "comma-delimited list of screen chain JSON names, colon-delimited per-window" },
- { OSDOPTION_BGFX_SHADOW_MASK, "slot-mask.png", OPTION_STRING, "shadow mask texture name" },
- { OSDOPTION_BGFX_LUT, "", OPTION_STRING, "LUT texture name" },
- { OSDOPTION_BGFX_AVI_NAME, OSDOPTVAL_AUTO, OPTION_STRING, "filename for BGFX output logging" },
+ { nullptr, nullptr, core_options::option_type::HEADER, "OSD MIDI OPTIONS" },
+ { OSDOPTION_MIDI_PROVIDER, OSDOPTVAL_AUTO, core_options::option_type::STRING, "MIDI I/O method: " },
+
+ { nullptr, nullptr, core_options::option_type::HEADER, "OSD EMULATED NETWORKING OPTIONS" },
+ { OSDOPTION_NETWORK_PROVIDER, OSDOPTVAL_AUTO, core_options::option_type::STRING, "Emulated networking provider: " },
+
+ { nullptr, nullptr, core_options::option_type::HEADER, "BGFX POST-PROCESSING OPTIONS" },
+ { OSDOPTION_BGFX_PATH, "bgfx", core_options::option_type::PATH, "path to BGFX-related files" },
+ { OSDOPTION_BGFX_BACKEND, "auto", core_options::option_type::STRING, "BGFX backend to use (d3d9, d3d11, d3d12, metal, opengl, gles, vulkan)" },
+ { OSDOPTION_BGFX_DEBUG, "0", core_options::option_type::BOOLEAN, "enable BGFX debugging statistics" },
+ { OSDOPTION_BGFX_SCREEN_CHAINS, "", core_options::option_type::STRING, "comma-delimited list of screen chain JSON names, colon-delimited per-window" },
+ { OSDOPTION_BGFX_SHADOW_MASK, "slot-mask.png", core_options::option_type::STRING, "shadow mask texture name" },
+ { OSDOPTION_BGFX_LUT, "lut-default.png", core_options::option_type::STRING, "LUT texture name" },
+ { OSDOPTION_BGFX_AVI_NAME, OSDOPTVAL_AUTO, core_options::option_type::PATH, "filename for BGFX output logging" },
- // End of list
+ // End of list
{ nullptr }
};
@@ -170,7 +194,7 @@ osd_options::osd_options()
}
// Window list
-std::list<std::shared_ptr<osd_window>> osd_common_t::s_window_list;
+std::list<std::unique_ptr<osd_window> > osd_common_t::s_window_list;
//-------------------------------------------------
// osd_interface - constructor
@@ -184,6 +208,7 @@ osd_common_t::osd_common_t(osd_options &options)
, m_sound(nullptr)
, m_debugger(nullptr)
, m_midi(nullptr)
+ , m_network(nullptr)
, m_keyboard_input(nullptr)
, m_mouse_input(nullptr)
, m_lightgun_input(nullptr)
@@ -205,7 +230,7 @@ osd_common_t::~osd_common_t()
osd_output::pop(this);
}
-#define REGISTER_MODULE(_O, _X ) { extern const module_type _X; _O . register_module( _X ); }
+#define REGISTER_MODULE(O, X) { extern const module_type X; O.register_module(X); }
void osd_common_t::register_options()
{
@@ -215,6 +240,26 @@ void osd_common_t::register_options()
REGISTER_MODULE(m_mod_man, FONT_SDL);
REGISTER_MODULE(m_mod_man, FONT_NONE);
+#if defined(SDLMAME_EMSCRIPTEN)
+ REGISTER_MODULE(m_mod_man, RENDERER_SDL1); // don't bother trying to use video acceleration in browsers
+#endif
+#if defined(OSD_WINDOWS)
+ REGISTER_MODULE(m_mod_man, RENDERER_D3D); // this is only built for OSD=windows, there's no dummy stub
+#endif
+#if defined(OSD_WINDOWS) || defined(SDLMAME_WIN32)
+ REGISTER_MODULE(m_mod_man, RENDERER_BGFX); // try BGFX before GDI on windows to get DirectX 10/11 acceleration
+#endif
+ REGISTER_MODULE(m_mod_man, RENDERER_GDI); // GDI ahead of OpenGL as there's a chance Windows has no OpenGL
+ REGISTER_MODULE(m_mod_man, RENDERER_OPENGL);
+#if !defined(OSD_WINDOWS) && !defined(SDLMAME_WIN32)
+ REGISTER_MODULE(m_mod_man, RENDERER_BGFX); // try BGFX after OpenGL on other operating systems for now
+#endif
+ REGISTER_MODULE(m_mod_man, RENDERER_SDL2);
+#if !defined(SDLMAME_EMSCRIPTEN)
+ REGISTER_MODULE(m_mod_man, RENDERER_SDL1);
+#endif
+ REGISTER_MODULE(m_mod_man, RENDERER_NONE);
+
REGISTER_MODULE(m_mod_man, SOUND_DSOUND);
REGISTER_MODULE(m_mod_man, SOUND_XAUDIO2);
REGISTER_MODULE(m_mod_man, SOUND_COREAUDIO);
@@ -223,6 +268,12 @@ void osd_common_t::register_options()
#ifndef NO_USE_PORTAUDIO
REGISTER_MODULE(m_mod_man, SOUND_PORTAUDIO);
#endif
+#ifndef NO_USE_PULSEAUDIO
+ REGISTER_MODULE(m_mod_man, SOUND_PULSEAUDIO);
+#endif
+#ifndef NO_USE_PIPEWIRE
+ REGISTER_MODULE(m_mod_man, SOUND_PIPEWIRE);
+#endif
REGISTER_MODULE(m_mod_man, SOUND_NONE);
REGISTER_MODULE(m_mod_man, MONITOR_SDL);
@@ -254,7 +305,6 @@ void osd_common_t::register_options()
REGISTER_MODULE(m_mod_man, KEYBOARDINPUT_RAWINPUT);
REGISTER_MODULE(m_mod_man, KEYBOARDINPUT_DINPUT);
REGISTER_MODULE(m_mod_man, KEYBOARDINPUT_WIN32);
- REGISTER_MODULE(m_mod_man, KEYBOARDINPUT_UWP);
REGISTER_MODULE(m_mod_man, KEYBOARD_NONE);
REGISTER_MODULE(m_mod_man, MOUSEINPUT_SDL);
@@ -263,16 +313,17 @@ void osd_common_t::register_options()
REGISTER_MODULE(m_mod_man, MOUSEINPUT_WIN32);
REGISTER_MODULE(m_mod_man, MOUSE_NONE);
+ REGISTER_MODULE(m_mod_man, LIGHTGUNINPUT_SDL);
REGISTER_MODULE(m_mod_man, LIGHTGUN_X11);
REGISTER_MODULE(m_mod_man, LIGHTGUNINPUT_RAWINPUT);
REGISTER_MODULE(m_mod_man, LIGHTGUNINPUT_WIN32);
REGISTER_MODULE(m_mod_man, LIGHTGUN_NONE);
- REGISTER_MODULE(m_mod_man, JOYSTICKINPUT_SDL);
+ REGISTER_MODULE(m_mod_man, JOYSTICKINPUT_SDLGAME);
+ REGISTER_MODULE(m_mod_man, JOYSTICKINPUT_SDLJOY);
REGISTER_MODULE(m_mod_man, JOYSTICKINPUT_WINHYBRID);
REGISTER_MODULE(m_mod_man, JOYSTICKINPUT_DINPUT);
REGISTER_MODULE(m_mod_man, JOYSTICKINPUT_XINPUT);
- REGISTER_MODULE(m_mod_man, JOYSTICKINPUT_UWP);
REGISTER_MODULE(m_mod_man, JOYSTICK_NONE);
REGISTER_MODULE(m_mod_man, OUTPUT_NONE);
@@ -282,95 +333,34 @@ void osd_common_t::register_options()
// after initialization we know which modules are supported
-
- const char *names[20];
- int num;
- std::vector<const char *> dnames;
-
- m_mod_man.get_module_names(OSD_MONITOR_PROVIDER, 20, &num, names);
- for (int i = 0; i < num; i++)
- dnames.push_back(names[i]);
- update_option(OSD_MONITOR_PROVIDER, dnames);
-
- m_mod_man.get_module_names(OSD_FONT_PROVIDER, 20, &num, names);
- dnames.clear();
- for (int i = 0; i < num; i++)
- dnames.push_back(names[i]);
- update_option(OSD_FONT_PROVIDER, dnames);
-
- m_mod_man.get_module_names(OSD_KEYBOARDINPUT_PROVIDER, 20, &num, names);
- dnames.clear();
- for (int i = 0; i < num; i++)
- dnames.push_back(names[i]);
- update_option(OSD_KEYBOARDINPUT_PROVIDER, dnames);
-
- m_mod_man.get_module_names(OSD_MOUSEINPUT_PROVIDER, 20, &num, names);
- dnames.clear();
- for (int i = 0; i < num; i++)
- dnames.push_back(names[i]);
- update_option(OSD_MOUSEINPUT_PROVIDER, dnames);
-
- m_mod_man.get_module_names(OSD_LIGHTGUNINPUT_PROVIDER, 20, &num, names);
- dnames.clear();
- for (int i = 0; i < num; i++)
- dnames.push_back(names[i]);
- update_option(OSD_LIGHTGUNINPUT_PROVIDER, dnames);
-
- m_mod_man.get_module_names(OSD_JOYSTICKINPUT_PROVIDER, 20, &num, names);
- dnames.clear();
- for (int i = 0; i < num; i++)
- dnames.push_back(names[i]);
- update_option(OSD_JOYSTICKINPUT_PROVIDER, dnames);
-
- m_mod_man.get_module_names(OSD_SOUND_PROVIDER, 20, &num, names);
- dnames.clear();
- for (int i = 0; i < num; i++)
- dnames.push_back(names[i]);
- update_option(OSD_SOUND_PROVIDER, dnames);
-
-#if 0
- // Register midi options and update options
- m_mod_man.get_module_names(OSD_MIDI_PROVIDER, 20, &num, names);
- dnames.clear();
- for (int i = 0; i < num; i++)
- dnames.push_back(names[i]);
- update_option(OSD_MIDI_PROVIDER, dnames);
-#endif
-
- // Register debugger options and update options
- m_mod_man.get_module_names(OSD_DEBUG_PROVIDER, 20, &num, names);
- dnames.clear();
- for (int i = 0; i < num; i++)
- dnames.push_back(names[i]);
- update_option(OSD_DEBUG_PROVIDER, dnames);
-
- m_mod_man.get_module_names(OSD_OUTPUT_PROVIDER, 20, &num, names);
- dnames.clear();
- for (int i = 0; i < num; i++)
- dnames.push_back(names[i]);
- update_option(OSD_OUTPUT_PROVIDER, dnames);
-
- // Register video options and update options
- video_options_add("none", nullptr);
- video_register();
- update_option(OSDOPTION_VIDEO, m_video_names);
+ update_option(OSD_FONT_PROVIDER, m_mod_man.get_module_names(OSD_FONT_PROVIDER));
+ update_option(OSD_RENDERER_PROVIDER, m_mod_man.get_module_names(OSD_RENDERER_PROVIDER));
+ update_option(OSD_SOUND_PROVIDER, m_mod_man.get_module_names(OSD_SOUND_PROVIDER));
+ update_option(OSD_MONITOR_PROVIDER, m_mod_man.get_module_names(OSD_MONITOR_PROVIDER));
+ update_option(OSD_KEYBOARDINPUT_PROVIDER, m_mod_man.get_module_names(OSD_KEYBOARDINPUT_PROVIDER));
+ update_option(OSD_MOUSEINPUT_PROVIDER, m_mod_man.get_module_names(OSD_MOUSEINPUT_PROVIDER));
+ update_option(OSD_LIGHTGUNINPUT_PROVIDER, m_mod_man.get_module_names(OSD_LIGHTGUNINPUT_PROVIDER));
+ update_option(OSD_JOYSTICKINPUT_PROVIDER, m_mod_man.get_module_names(OSD_JOYSTICKINPUT_PROVIDER));
+ update_option(OSD_MIDI_PROVIDER, m_mod_man.get_module_names(OSD_MIDI_PROVIDER));
+ update_option(OSD_NETDEV_PROVIDER, m_mod_man.get_module_names(OSD_NETDEV_PROVIDER));
+ update_option(OSD_DEBUG_PROVIDER, m_mod_man.get_module_names(OSD_DEBUG_PROVIDER));
+ update_option(OSD_OUTPUT_PROVIDER, m_mod_man.get_module_names(OSD_OUTPUT_PROVIDER));
}
-void osd_common_t::update_option(const std::string &key, std::vector<const char *> &values)
+void osd_common_t::update_option(const std::string &key, std::vector<std::string_view> const &values)
{
std::string current_value(m_options.description(key.c_str()));
std::string new_option_value("");
for (unsigned int index = 0; index < values.size(); index++)
{
- std::string t(values[index]);
if (new_option_value.length() > 0)
{
- if( index != (values.size()-1))
+ if (index != (values.size() - 1))
new_option_value.append(", ");
else
new_option_value.append(" or ");
}
- new_option_value.append(t);
+ new_option_value.append(values[index]);
}
m_option_descs[key] = current_value + new_option_value;
@@ -381,28 +371,28 @@ void osd_common_t::update_option(const std::string &key, std::vector<const char
//-------------------------------------------------
// output_callback - callback for osd_printf_...
//-------------------------------------------------
-void osd_common_t::output_callback(osd_output_channel channel, const char *msg, va_list args)
+void osd_common_t::output_callback(osd_output_channel channel, const util::format_argument_pack<char> &args)
{
switch (channel)
{
- case OSD_OUTPUT_CHANNEL_ERROR:
- case OSD_OUTPUT_CHANNEL_WARNING:
- vfprintf(stderr, msg, args);
- break;
- case OSD_OUTPUT_CHANNEL_INFO:
- case OSD_OUTPUT_CHANNEL_LOG:
- vfprintf(stdout, msg, args);
- break;
- case OSD_OUTPUT_CHANNEL_VERBOSE:
- if (verbose()) vfprintf(stdout, msg, args);
- break;
- case OSD_OUTPUT_CHANNEL_DEBUG:
+ case OSD_OUTPUT_CHANNEL_ERROR:
+ case OSD_OUTPUT_CHANNEL_WARNING:
+ util::stream_format(std::cerr, args);
+ break;
+ case OSD_OUTPUT_CHANNEL_INFO:
+ case OSD_OUTPUT_CHANNEL_LOG:
+ util::stream_format(std::cout, args);
+ break;
+ case OSD_OUTPUT_CHANNEL_VERBOSE:
+ if (verbose()) util::stream_format(std::cout, args);
+ break;
+ case OSD_OUTPUT_CHANNEL_DEBUG:
#ifdef MAME_DEBUG
- vfprintf(stdout, msg, args);
+ util::stream_format(std::cout, args);
#endif
- break;
- default:
- break;
+ break;
+ default:
+ break;
}
}
@@ -442,7 +432,7 @@ void osd_common_t::init(running_machine &machine)
m_machine = &machine;
- osd_options &options = downcast<osd_options &>(machine.options());
+ auto &options = downcast<osd_options &>(machine.options());
// extract the verbose printing option
if (options.verbose())
set_verbose(true);
@@ -478,9 +468,6 @@ void osd_common_t::update(bool skip_redraw)
//
if (m_watchdog != nullptr)
m_watchdog->reset();
-
- update_slider_list();
-
}
@@ -522,46 +509,65 @@ void osd_common_t::debugger_update()
}
-//-------------------------------------------------
-// update_audio_stream - update the stereo audio
-// stream
-//-------------------------------------------------
+bool osd_common_t::sound_external_per_channel_volume()
+{
+ return m_sound->external_per_channel_volume();
+}
-void osd_common_t::update_audio_stream(const int16_t *buffer, int samples_this_frame)
+bool osd_common_t::sound_split_streams_per_source()
{
- //
- // This method is called whenever the system has new audio data to stream.
- // It provides an array of stereo samples in L-R order which should be
- // output at the configured sample_rate.
- //
- m_sound->update_audio_stream(m_machine->video().throttled(), buffer,samples_this_frame);
+ return m_sound->split_streams_per_source();
}
+uint32_t osd_common_t::sound_get_generation()
+{
+ return m_sound->get_generation();
+}
-//-------------------------------------------------
-// set_mastervolume - set the system volume
-//-------------------------------------------------
+osd::audio_info osd_common_t::sound_get_information()
+{
+ return m_sound->get_information();
+}
-void osd_common_t::set_mastervolume(int attenuation)
+uint32_t osd_common_t::sound_stream_sink_open(uint32_t node, std::string name, uint32_t rate)
{
- //
- // Attenuation is the attenuation in dB (a negative number).
- // To convert from dB to a linear volume scale do the following:
- // volume = MAX_VOLUME;
- // while (attenuation++ < 0)
- // volume /= 1.122018454; // = (10 ^ (1/20)) = 1dB
- //
- if (m_sound != nullptr)
- m_sound->set_mastervolume(attenuation);
+ return m_sound->stream_sink_open(node, name, rate);
}
+uint32_t osd_common_t::sound_stream_source_open(uint32_t node, std::string name, uint32_t rate)
+{
+ return m_sound->stream_source_open(node, name, rate);
+}
+
+void osd_common_t::sound_stream_set_volumes(uint32_t id, const std::vector<float> &db)
+{
+ m_sound->stream_set_volumes(id, db);
+}
+
+void osd_common_t::sound_stream_close(uint32_t id)
+{
+ m_sound->stream_close(id);
+}
+
+void osd_common_t::sound_stream_sink_update(uint32_t id, const int16_t *buffer, int samples_this_frame)
+{
+ m_sound->stream_sink_update(id, buffer, samples_this_frame);
+}
+
+void osd_common_t::sound_stream_source_update(uint32_t id, int16_t *buffer, int samples_this_frame)
+{
+ m_sound->stream_source_update(id, buffer, samples_this_frame);
+}
+
+
+
//-------------------------------------------------
// customize_input_type_list - provide OSD
// additions/modifications to the input list
//-------------------------------------------------
-void osd_common_t::customize_input_type_list(simple_list<input_type_entry> &typelist)
+void osd_common_t::customize_input_type_list(std::vector<input_type_entry> &typelist)
{
//
// inptport.c defines some general purpose defaults for key and joystick bindings.
@@ -583,6 +589,31 @@ void osd_common_t::customize_input_type_list(simple_list<input_type_entry> &type
std::vector<ui::menu_item> osd_common_t::get_slider_list()
{
+ // check if any window has dirty sliders
+ bool dirty = false;
+ for (const auto &window : window_list())
+ {
+ if (window->has_renderer() && window->renderer().sliders_dirty())
+ {
+ dirty = true;
+ break;
+ }
+ }
+
+ if (dirty)
+ {
+ m_sliders.clear();
+
+ for (const auto &window : osd_common_t::window_list())
+ {
+ if (window->has_renderer())
+ {
+ std::vector<ui::menu_item> window_sliders = window->renderer().get_slider_list();
+ m_sliders.insert(m_sliders.end(), window_sliders.begin(), window_sliders.end());
+ }
+ }
+ }
+
return m_sliders;
}
@@ -607,28 +638,50 @@ bool osd_common_t::execute_command(const char *command)
{
if (strcmp(command, OSDCOMMAND_LIST_NETWORK_ADAPTERS) == 0)
{
- osd_module *om = select_module_options(options(), OSD_NETDEV_PROVIDER);
-
- if (om->probe())
+ auto &om = select_module_options<netdev_module>(OSD_NETDEV_PROVIDER);
+ auto const interfaces = om.list_devices();
+ if (interfaces.empty())
{
- om->init(options());
- osd_list_network_adapters();
- om->exit();
+ printf("No supported network interfaces were found\n");
}
+ else
+ {
+ printf("Available network interfaces:\n");
+ for (auto &entry : interfaces)
+ {
+ printf(" %.*s\n", int(entry.description.length()), entry.description.data());
+ }
+ }
+ dynamic_cast<osd_module &>(om).exit();
return true;
}
else if (strcmp(command, OSDCOMMAND_LIST_MIDI_DEVICES) == 0)
{
- osd_module *om = select_module_options(options(), OSD_MIDI_PROVIDER);
- midi_module *pm = select_module_options<midi_module *>(options(), OSD_MIDI_PROVIDER);
-
- if (om->probe())
+ auto &om = select_module_options<midi_module>(OSD_MIDI_PROVIDER);
+ auto const ports = om.list_midi_ports();
+ if (ports.empty())
+ {
+ printf("No MIDI ports were found\n");
+ }
+ else
{
- om->init(options());
- pm->list_midi_devices();
- om->exit();
+ printf("MIDI input ports:\n");
+ for (auto const &port : ports)
+ {
+ if (port.input)
+ printf(port.default_input ? "%s (default)\n" : "%s\n", port.name.c_str());
+ }
+
+ printf("\nMIDI output ports:\n");
+ for (auto const &port : ports)
+ {
+ if (port.output)
+ printf(port.default_output ? "%s (default)\n" : "%s\n", port.name.c_str());
+ }
}
+ dynamic_cast<osd_module &>(om).exit();
+
return true;
}
@@ -644,10 +697,10 @@ static void output_notifier_callback(const char *outname, int32_t value, void *p
void osd_common_t::init_subsystems()
{
// monitors have to be initialized before video init
- m_monitor_module = select_module_options<monitor_module *>(options(), OSD_MONITOR_PROVIDER);
- assert(m_monitor_module != nullptr);
- m_monitor_module->init(options());
+ m_monitor_module = &select_module_options<monitor_module>(OSD_MONITOR_PROVIDER);
+ // various modules depend on having a window handle
+ m_render = &select_module_options<render_module>(OSD_RENDERER_PROVIDER);
if (!video_init())
{
video_exit();
@@ -657,32 +710,24 @@ void osd_common_t::init_subsystems()
exit(-1);
}
- m_keyboard_input = select_module_options<input_module *>(options(), OSD_KEYBOARDINPUT_PROVIDER);
- m_mouse_input = select_module_options<input_module *>(options(), OSD_MOUSEINPUT_PROVIDER);
- m_lightgun_input = select_module_options<input_module *>(options(), OSD_LIGHTGUNINPUT_PROVIDER);
- m_joystick_input = select_module_options<input_module *>(options(), OSD_JOYSTICKINPUT_PROVIDER);
-
- m_font_module = select_module_options<font_module *>(options(), OSD_FONT_PROVIDER);
- m_sound = select_module_options<sound_module *>(options(), OSD_SOUND_PROVIDER);
- m_sound->m_sample_rate = options().sample_rate();
- m_sound->m_audio_latency = options().audio_latency();
+ m_keyboard_input = &select_module_options<input_module>(OSD_KEYBOARDINPUT_PROVIDER);
+ m_mouse_input = &select_module_options<input_module>(OSD_MOUSEINPUT_PROVIDER);
+ m_lightgun_input = &select_module_options<input_module>(OSD_LIGHTGUNINPUT_PROVIDER);
+ m_joystick_input = &select_module_options<input_module>(OSD_JOYSTICKINPUT_PROVIDER);
- m_debugger = select_module_options<debug_module *>(options(), OSD_DEBUG_PROVIDER);
+ m_font_module = &select_module_options<font_module>(OSD_FONT_PROVIDER);
+ m_sound = &select_module_options<sound_module>(OSD_SOUND_PROVIDER);
- select_module_options<netdev_module *>(options(), OSD_NETDEV_PROVIDER);
+ m_debugger = &select_module_options<debug_module>(OSD_DEBUG_PROVIDER);
- m_midi = select_module_options<midi_module *>(options(), OSD_MIDI_PROVIDER);
+ m_midi = &select_module_options<midi_module>(OSD_MIDI_PROVIDER);
- m_output = select_module_options<output_module *>(options(), OSD_OUTPUT_PROVIDER);
- m_output->set_machine(&machine());
- machine().output().set_notifier(nullptr, output_notifier_callback, this);
+ m_network = &select_module_options<netdev_module>(OSD_NETDEV_PROVIDER);
- m_mod_man.init(options());
+ m_output = &select_module_options<output_module>(OSD_OUTPUT_PROVIDER);
+ machine().output().set_global_notifier(output_notifier_callback, this);
input_init();
- // we need pause callbacks
- machine().add_notifier(MACHINE_NOTIFY_PAUSE, machine_notify_delegate(&osd_common_t::input_pause, this));
- machine().add_notifier(MACHINE_NOTIFY_RESUME, machine_notify_delegate(&osd_common_t::input_resume, this));
}
bool osd_common_t::video_init()
@@ -700,10 +745,6 @@ bool osd_common_t::no_sound()
return (strcmp(options().sound(),"none")==0) ? true : false;
}
-void osd_common_t::video_register()
-{
-}
-
bool osd_common_t::input_init()
{
m_keyboard_input->input_init(machine());
@@ -713,20 +754,12 @@ bool osd_common_t::input_init()
return true;
}
-void osd_common_t::input_pause()
+void osd_common_t::poll_input_modules(bool relative_reset)
{
- m_keyboard_input->pause();
- m_mouse_input->pause();
- m_lightgun_input->pause();
- m_joystick_input->pause();
-}
-
-void osd_common_t::input_resume()
-{
- m_keyboard_input->resume();
- m_mouse_input->resume();
- m_lightgun_input->resume();
- m_joystick_input->resume();
+ m_keyboard_input->poll_if_necessary(relative_reset);
+ m_mouse_input->poll_if_necessary(relative_reset);
+ m_lightgun_input->poll_if_necessary(relative_reset);
+ m_joystick_input->poll_if_necessary(relative_reset);
}
void osd_common_t::exit_subsystems()
@@ -744,13 +777,46 @@ void osd_common_t::window_exit()
void osd_common_t::osd_exit()
{
+ // destroy the renderers before shutting down their parent module
+ for (auto it = window_list().rbegin(); window_list().rend() != it; ++it)
+ (*it)->renderer_reset();
+
m_mod_man.exit();
exit_subsystems();
}
-void osd_common_t::video_options_add(const char *name, void *type)
+osd_font::ptr osd_common_t::font_alloc()
+{
+ return m_font_module->font_alloc();
+}
+
+bool osd_common_t::get_font_families(std::string const &font_path, std::vector<std::pair<std::string, std::string> > &result)
+{
+ return m_font_module->get_font_families(font_path, result);
+}
+
+std::unique_ptr<osd::midi_input_port> osd_common_t::create_midi_input(std::string_view name)
+{
+ return m_midi->create_input(name);
+}
+
+std::unique_ptr<osd::midi_output_port> osd_common_t::create_midi_output(std::string_view name)
+{
+ return m_midi->create_output(name);
+}
+
+std::vector<osd::midi_port_info> osd_common_t::list_midi_ports()
+{
+ return m_midi->list_midi_ports();
+}
+
+std::unique_ptr<osd::network_device> osd_common_t::open_network_device(int id, osd::network_handler &handler)
+{
+ return m_network->open_device(id, handler);
+}
+
+std::vector<osd::network_device_info> osd_common_t::list_network_devices()
{
- //m_video_options.add(name, type, false);
- m_video_names.push_back(name);
+ return m_network->list_devices();
}
diff --git a/src/osd/modules/lib/osdobj_common.h b/src/osd/modules/lib/osdobj_common.h
index 37e043f53ad..ff0d0b9a6dd 100644
--- a/src/osd/modules/lib/osdobj_common.h
+++ b/src/osd/modules/lib/osdobj_common.h
@@ -2,41 +2,48 @@
// copyright-holders:Aaron Giles
/***************************************************************************
- osdepend.h
+ osdobj_common.h
OS-dependent code interface.
*******************************************************************c********/
-
-#pragma once
-
#ifndef MAME_OSD_LIB_OSDOBJ_COMMON_H
#define MAME_OSD_LIB_OSDOBJ_COMMON_H
+#pragma once
+
+#include "osdcore.h"
#include "osdepend.h"
-#include "watchdog.h"
+
#include "modules/osdmodule.h"
-#include "modules/font/font_module.h"
-#include "modules/input/input_module.h"
-#include "modules/sound/sound_module.h"
-#include "modules/debugger/debug_module.h"
-#include "modules/netdev/netdev_module.h"
-#include "modules/midi/midi_module.h"
#include "modules/output/output_module.h"
-#include "modules/monitor/monitor_module.h"
+
#include "emuopts.h"
-#include "../frontend/mame/ui/menuitem.h"
+
+#include "strformat.h"
+
+#include <iosfwd>
+#include <list>
+#include <memory>
+#include <string>
+#include <string_view>
+#include <unordered_map>
+#include <vector>
+
//============================================================
// Defines
//============================================================
#define OSDOPTION_UIMODEKEY "uimodekey"
+#define OSDOPTION_CONTROLLER_MAP_FILE "controller_map"
+#define OSDOPTION_BACKGROUND_INPUT "background_input"
#define OSDCOMMAND_LIST_MIDI_DEVICES "listmidi"
#define OSDCOMMAND_LIST_NETWORK_ADAPTERS "listnetwork"
#define OSDOPTION_DEBUGGER "debugger"
+#define OSDOPTION_DEBUGGER_HOST "debugger_host"
#define OSDOPTION_DEBUGGER_PORT "debugger_port"
#define OSDOPTION_DEBUGGER_FONT "debugger_font"
#define OSDOPTION_DEBUGGER_FONT_SIZE "debugger_font_size"
@@ -81,8 +88,9 @@
#define OSDOPTION_AUDIO_OUTPUT "audio_output"
#define OSDOPTION_AUDIO_EFFECT "audio_effect"
-#define OSDOPTVAL_AUTO "auto"
-#define OSDOPTVAL_NONE "none"
+#define OSDOPTION_MIDI_PROVIDER "midiprovider"
+
+#define OSDOPTION_NETWORK_PROVIDER "networkprovider"
#define OSDOPTION_BGFX_PATH "bgfx_path"
#define OSDOPTION_BGFX_BACKEND "bgfx_backend"
@@ -92,6 +100,9 @@
#define OSDOPTION_BGFX_LUT "bgfx_lut"
#define OSDOPTION_BGFX_AVI_NAME "bgfx_avi_name"
+#define OSDOPTVAL_AUTO "auto"
+#define OSDOPTVAL_NONE "none"
+
//============================================================
// TYPE DEFINITIONS
//============================================================
@@ -104,9 +115,12 @@ public:
// keyboard mapping
const char *ui_mode_key() const { return value(OSDOPTION_UIMODEKEY); }
+ const char *controller_mapping_file() const { return value(OSDOPTION_CONTROLLER_MAP_FILE); }
+ bool background_input() const { return bool_value(OSDOPTION_BACKGROUND_INPUT); }
// debugging options
const char *debugger() const { return value(OSDOPTION_DEBUGGER); }
+ const char *debugger_host() const { return value(OSDOPTION_DEBUGGER_HOST); }
int debugger_port() const { return int_value(OSDOPTION_DEBUGGER_PORT); }
const char *debugger_font() const { return value(OSDOPTION_DEBUGGER_FONT); }
float debugger_font_size() const { return float_value(OSDOPTION_DEBUGGER_FONT_SIZE); }
@@ -129,10 +143,10 @@ public:
const char *aspect() const { return value(OSDOPTION_ASPECT); }
const char *resolution() const { return value(OSDOPTION_RESOLUTION); }
const char *view() const { return value(OSDOPTION_VIEW); }
- const char *screen(int index) const { return value(string_format("%s%d", OSDOPTION_SCREEN, index).c_str()); }
- const char *aspect(int index) const { return value(string_format("%s%d", OSDOPTION_ASPECT, index).c_str()); }
- const char *resolution(int index) const { return value(string_format("%s%d", OSDOPTION_RESOLUTION, index).c_str()); }
- const char *view(int index) const { return value(string_format("%s%d", OSDOPTION_VIEW, index).c_str()); }
+ const char *screen(int index) const { return value(util::string_format("%s%d", OSDOPTION_SCREEN, index)); }
+ const char *aspect(int index) const { return value(util::string_format("%s%d", OSDOPTION_ASPECT, index)); }
+ const char *resolution(int index) const { return value(util::string_format("%s%d", OSDOPTION_RESOLUTION, index)); }
+ const char *view(int index) const { return value(util::string_format("%s%d", OSDOPTION_VIEW, index)); }
// full screen options
bool switch_res() const { return bool_value(OSDOPTION_SWITCHRES); }
@@ -148,8 +162,8 @@ public:
bool gl_pbo() const { return bool_value(OSDOPTION_GL_PBO); }
bool gl_glsl() const { return bool_value(OSDOPTION_GL_GLSL); }
int glsl_filter() const { return int_value(OSDOPTION_GLSL_FILTER); }
- const char *shader_mame(int index) const { return value(string_format("%s%d", OSDOPTION_SHADER_MAME, index).c_str()); }
- const char *shader_screen(int index) const { return value(string_format("%s%d", OSDOPTION_SHADER_SCREEN, index).c_str()); }
+ const char *shader_mame(int index) const { return value(util::string_format("%s%d", OSDOPTION_SHADER_MAME, index)); }
+ const char *shader_screen(int index) const { return value(util::string_format("%s%d", OSDOPTION_SHADER_SCREEN, index)); }
// sound options
const char *sound() const { return value(OSDOPTION_SOUND); }
@@ -157,7 +171,7 @@ public:
// CoreAudio specific options
const char *audio_output() const { return value(OSDOPTION_AUDIO_OUTPUT); }
- const char *audio_effect(int index) const { return value(string_format("%s%d", OSDOPTION_AUDIO_EFFECT, index).c_str()); }
+ const char *audio_effect(int index) const { return value(util::string_format("%s%d", OSDOPTION_AUDIO_EFFECT, index)); }
// BGFX specific options
const char *bgfx_path() const { return value(OSDOPTION_BGFX_PATH); }
@@ -171,13 +185,24 @@ public:
// PortAudio options
const char *pa_api() const { return value(OSDOPTION_PA_API); }
const char *pa_device() const { return value(OSDOPTION_PA_DEVICE); }
- const float pa_latency() const { return float_value(OSDOPTION_PA_LATENCY); }
+ float pa_latency() const { return float_value(OSDOPTION_PA_LATENCY); }
static const options_entry s_option_entries[];
};
// ======================> osd_interface
+
+class debug_module;
+class font_module;
+class input_module;
+class midi_module;
+class monitor_module;
+class netdev_module;
+class osd_watchdog;
class osd_window;
+class output_module;
+class render_module;
+class sound_module;
// description of the currently-running machine
class osd_common_t : public osd_interface, osd_output
@@ -199,24 +224,40 @@ public:
virtual void wait_for_debugger(device_t &device, bool firststop) override;
// audio overridables
- virtual void update_audio_stream(const int16_t *buffer, int samples_this_frame) override;
- virtual void set_mastervolume(int attenuation) override;
virtual bool no_sound() override;
+ virtual bool sound_external_per_channel_volume() override;
+ virtual bool sound_split_streams_per_source() override;
+ virtual uint32_t sound_get_generation() override;
+ virtual osd::audio_info sound_get_information() override;
+ virtual uint32_t sound_stream_sink_open(uint32_t node, std::string name, uint32_t rate) override;
+ virtual uint32_t sound_stream_source_open(uint32_t node, std::string name, uint32_t rate) override;
+ virtual void sound_stream_set_volumes(uint32_t id, const std::vector<float> &db) override;
+ virtual void sound_stream_close(uint32_t id) override;
+ virtual void sound_stream_sink_update(uint32_t id, const int16_t *buffer, int samples_this_frame) override;
+ virtual void sound_stream_source_update(uint32_t id, int16_t *buffer, int samples_this_frame) override;
// input overridables
- virtual void customize_input_type_list(simple_list<input_type_entry> &typelist) override;
+ virtual void customize_input_type_list(std::vector<input_type_entry> &typelist) override;
// video overridables
virtual void add_audio_to_recording(const int16_t *buffer, int samples_this_frame) override;
virtual std::vector<ui::menu_item> get_slider_list() override;
+ // font interface
+ virtual osd_font::ptr font_alloc() override;
+ virtual bool get_font_families(std::string const &font_path, std::vector<std::pair<std::string, std::string> > &result) override;
+
// command option overrides
virtual bool execute_command(const char *command) override;
- virtual osd_font::ptr font_alloc() override { return m_font_module->font_alloc(); }
- virtual bool get_font_families(std::string const &font_path, std::vector<std::pair<std::string, std::string> > &result) override { return m_font_module->get_font_families(font_path, result); }
+ // MIDI interface
+ virtual std::unique_ptr<osd::midi_input_port> create_midi_input(std::string_view name) override;
+ virtual std::unique_ptr<osd::midi_output_port> create_midi_output(std::string_view name) override;
+ virtual std::vector<osd::midi_port_info> list_midi_ports() override;
- virtual osd_midi_device *create_midi_device() override { return m_midi->create_midi_device(); }
+ // network interface
+ virtual std::unique_ptr<osd::network_device> open_network_device(int id, osd::network_handler &handler) override;
+ virtual std::vector<osd::network_device_info> list_network_devices() override;
// FIXME: everything below seems to be osd specific and not part of
// this INTERFACE but part of the osd IMPLEMENTATION
@@ -229,36 +270,34 @@ public:
virtual void init_subsystems();
virtual bool video_init();
- virtual void video_register();
virtual bool window_init();
- virtual void input_resume();
-
virtual void exit_subsystems();
virtual void video_exit();
virtual void window_exit();
virtual void osd_exit();
- virtual void video_options_add(const char *name, void *type);
-
virtual osd_options &options() { return m_options; }
// osd_output interface ...
- virtual void output_callback(osd_output_channel channel, const char *msg, va_list args) override;
+ virtual void output_callback(osd_output_channel channel, const util::format_argument_pack<char> &args) override;
bool verbose() const { return m_print_verbose; }
virtual void set_verbose(bool print_verbose) override { m_print_verbose = print_verbose; }
void notify(const char *outname, int32_t value) const { m_output->notify(outname, value); }
- static std::list<std::shared_ptr<osd_window>> s_window_list;
+ virtual void process_events() = 0;
+ virtual bool has_focus() const = 0;
+
+ static const std::list<std::unique_ptr<osd_window> > &window_list() { return s_window_list; }
protected:
virtual bool input_init();
- virtual void input_pause();
- virtual void build_slider_list() { }
- virtual void update_slider_list() { }
+ void poll_input_modules(bool relative_reset);
+
+ static std::list<std::unique_ptr<osd_window> > s_window_list;
private:
// internal state
@@ -270,31 +309,30 @@ private:
osd_module_manager m_mod_man;
font_module *m_font_module;
- void update_option(const std::string &key, std::vector<const char *> &values);
+ void update_option(const std::string &key, std::vector<std::string_view> const &values);
// FIXME: should be elsewhere
- osd_module *select_module_options(const core_options &opts, const std::string &opt_name)
+ template<class C>
+ C &select_module_options(const std::string &opt_name)
{
- std::string opt_val = opts.exists(opt_name) ? opts.value(opt_name.c_str()) : "";
- if (opt_val.compare("auto")==0)
+ std::string opt_val = options().exists(opt_name) ? options().value(opt_name) : "";
+ if (opt_val == "auto")
+ {
opt_val = "";
+ }
else if (!m_mod_man.type_has_name(opt_name.c_str(), opt_val.c_str()))
{
- osd_printf_warning("Value %s not supported for option %s - falling back to auto\n", opt_val.c_str(), opt_name.c_str());
+ osd_printf_warning("Value %s not supported for option %s - falling back to auto\n", opt_val, opt_name);
opt_val = "";
}
- return m_mod_man.select_module(opt_name.c_str(), opt_val.c_str());
- }
-
- template<class C>
- C select_module_options(const core_options &opts, const std::string &opt_name)
- {
- return dynamic_cast<C>(select_module_options(opts, opt_name));
+ return m_mod_man.select_module<C>(*this, options(), opt_name.c_str(), opt_val.c_str());
}
protected:
+ render_module* m_render;
sound_module* m_sound;
debug_module* m_debugger;
midi_module* m_midi;
+ netdev_module* m_network;
input_module* m_keyboard_input;
input_module* m_mouse_input;
input_module* m_lightgun_input;
@@ -305,16 +343,7 @@ protected:
std::vector<ui::menu_item> m_sliders;
private:
- std::vector<const char *> m_video_names;
std::unordered_map<std::string, std::string> m_option_descs;
};
-
-// this template function creates a stub which constructs a debugger
-template<class _DeviceClass>
-debug_module *osd_debugger_creator()
-{
- return global_alloc(_DeviceClass());
-}
-
#endif // MAME_OSD_LIB_OSDOBJ_COMMON_H