summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rwxr-xr-xplugins/discord/init.lua106
-rw-r--r--plugins/discord/plugin.json10
-rw-r--r--scripts/src/osd/sdl.lua1
-rw-r--r--src/frontend/mame/luaengine.cpp1
-rw-r--r--src/osd/modules/file/posixdomain.cpp207
-rw-r--r--src/osd/modules/file/posixfile.cpp2
-rw-r--r--src/osd/modules/file/posixfile.h3
-rw-r--r--src/osd/modules/file/winptty.cpp13
-rw-r--r--src/osd/modules/lib/osdlib.h1
-rw-r--r--src/osd/modules/lib/osdlib_macosx.cpp9
-rw-r--r--src/osd/modules/lib/osdlib_unix.cpp9
-rw-r--r--src/osd/modules/lib/osdlib_uwp.cpp10
-rw-r--r--src/osd/modules/lib/osdlib_win32.cpp9
-rw-r--r--src/osd/osdcore.h8
14 files changed, 386 insertions, 3 deletions
diff --git a/plugins/discord/init.lua b/plugins/discord/init.lua
new file mode 100755
index 00000000000..2b534b98377
--- /dev/null
+++ b/plugins/discord/init.lua
@@ -0,0 +1,106 @@
+-- license:BSD-3-Clause
+-- copyright-holders:Carl
+local exports = {}
+exports.name = "discord"
+exports.version = "0.0.1"
+exports.description = "Discord presence"
+exports.license = "The BSD 3-Clause License"
+exports.author = { name = "Carl" }
+
+local discord = exports
+
+function discord.startplugin()
+ local pipe = emu.file("rw")
+ local json = require("json")
+ local nonce = 1
+ local starttime = 0
+
+ local function init()
+ local path
+ if package.config:sub(1,1) == '\\' then
+ path = "\\\\.\\pipe\\discord-ipc-0"
+ else
+ path = os.getenv("XDG_RUNTIME_DIR") or os.getenv("TMPDIR") or os.getenv("TMP") or os.getenv("TEMP") or '/tmp'
+ path = "domain." .. path .. "/discord-ipc-0"
+ end
+ local err = pipe:open(path)
+ if err then
+ error("discord: unable to connect, " .. err .. "\n")
+ end
+ local output = json.stringify({v = 1, client_id = "453309506152169472"})
+ --print(output)
+ pipe:write(string.pack("<I4I4", 0, #output) .. output)
+ local time = os.time()
+ local data = ""
+ repeat
+ local res = pipe:read(100)
+ data = data .. res
+ until #res == 0 and #data > 0 or time + 1 < os.time()
+ --print(data)
+ if data:find("code", 1, true) then
+ error("discord: bad RPC reply, " .. data:sub(8) .. "\n")
+ end
+ end
+
+ local function update(status)
+ local running = emu.romname() ~= "___empty"
+ local state = not running and "In menu" or status
+ local details = running and manager:machine():system().description or nil
+ if emu.softname() ~= "" then
+ for name, dev in pairs(manager:machine().images) do
+ if dev:longname() then
+ details = details .. " (" .. dev:longname() .. ")"
+ break
+ end
+ end
+ end
+ local status = {
+ cmd = "SET_ACTIVITY",
+ args = {
+ pid = emu.pid(),
+ activity = {
+ state = state,
+ details = details,
+ timestamps = {
+ start = starttime
+ }
+ }
+ },
+ nonce = nonce
+ }
+ nonce = nonce + 1
+ local output = json.stringify(status)
+ --print(output)
+ pipe:write(string.pack("<I4I4", 1, #output) .. output)
+ local time = os.time()
+ local data = ""
+ repeat
+ local res = pipe:read(100)
+ data = data .. res
+ until #res == 0 and #data > 0 or time + 1 < os.time()
+ --print(data)
+ end
+
+ do
+ local stat, err = pcall(init)
+ if not stat then
+ emu.print_error(err)
+ return
+ end
+ end
+
+ emu.register_start(function()
+ starttime = os.time()
+ update("Playing")
+ end)
+
+ emu.register_pause(function()
+ update("Paused")
+ end)
+
+ emu.register_resume(function()
+ update("Playing")
+ end)
+end
+
+return exports
diff --git a/plugins/discord/plugin.json b/plugins/discord/plugin.json
new file mode 100644
index 00000000000..df2eb695158
--- /dev/null
+++ b/plugins/discord/plugin.json
@@ -0,0 +1,10 @@
+{
+ "plugin": {
+ "name": "discord",
+ "description": "Discord presence",
+ "version": "0.0.1",
+ "author": "Carl",
+ "type": "plugin",
+ "start": "false"
+ }
+}
diff --git a/scripts/src/osd/sdl.lua b/scripts/src/osd/sdl.lua
index 718ca6e551e..9ef57e0ba7c 100644
--- a/scripts/src/osd/sdl.lua
+++ b/scripts/src/osd/sdl.lua
@@ -462,6 +462,7 @@ project ("ocore_" .. _OPTIONS["osd"])
if BASE_TARGETOS=="unix" then
files {
MAME_DIR .. "src/osd/modules/file/posixdir.cpp",
+ MAME_DIR .. "src/osd/modules/file/posixdomain.cpp",
MAME_DIR .. "src/osd/modules/file/posixfile.cpp",
MAME_DIR .. "src/osd/modules/file/posixfile.h",
MAME_DIR .. "src/osd/modules/file/posixptty.cpp",
diff --git a/src/frontend/mame/luaengine.cpp b/src/frontend/mame/luaengine.cpp
index 846d24dbbd0..c4e7bbbbfdd 100644
--- a/src/frontend/mame/luaengine.cpp
+++ b/src/frontend/mame/luaengine.cpp
@@ -807,6 +807,7 @@ void lua_engine::initialize()
return lua_yield(L, 0);
});
emu["lang_translate"] = &lang_translate;
+ emu["pid"] = &osd_getpid;
/*
* emu.file([opt] searchpath, flags) - flags can be as in osdcore "OPEN_FLAG_*" or lua style with 'rwc' with addtional c for create *and truncate* (be careful)
diff --git a/src/osd/modules/file/posixdomain.cpp b/src/osd/modules/file/posixdomain.cpp
new file mode 100644
index 00000000000..633187819a7
--- /dev/null
+++ b/src/osd/modules/file/posixdomain.cpp
@@ -0,0 +1,207 @@
+// license:BSD-3-Clause
+// copyright-holders:Olivier Galibert, R. Belmont, Vas Crabb
+//============================================================
+//
+// sdldomain.c - SDL socket (unix) access functions
+//
+// SDLMAME by Olivier Galibert and R. Belmont
+//
+//============================================================
+
+#include "posixfile.h"
+
+#include <cassert>
+#include <cerrno>
+#include <cstdio>
+
+#include <sys/select.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <sys/time.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+
+namespace {
+char const *const posixfile_domain_identifier = "domain.";
+
+
+class posix_osd_domain : public osd_file
+{
+public:
+ posix_osd_domain(posix_osd_domain const &) = delete;
+ posix_osd_domain(posix_osd_domain &&) = delete;
+ posix_osd_domain& operator=(posix_osd_domain const &) = delete;
+ posix_osd_domain& operator=(posix_osd_domain &&) = delete;
+
+ posix_osd_domain(int sock, bool listening)
+ : m_sock(sock)
+ , m_listening(listening)
+ {
+ assert(m_sock >= 0);
+ }
+
+ virtual ~posix_osd_domain()
+ {
+ ::close(m_sock);
+ }
+
+ virtual error read(void *buffer, std::uint64_t offset, std::uint32_t count, std::uint32_t &actual) override
+ {
+ fd_set readfds;
+ FD_ZERO(&readfds);
+ FD_SET(m_sock, &readfds);
+
+ struct timeval timeout;
+ timeout.tv_sec = timeout.tv_usec = 0;
+
+ if (select(m_sock + 1, &readfds, nullptr, nullptr, &timeout) < 0)
+ {
+ char line[80];
+ std::sprintf(line, "%s : %s : %d ", __func__, __FILE__, __LINE__);
+ std::perror(line);
+ return errno_to_file_error(errno);
+ }
+ else if (FD_ISSET(m_sock, &readfds))
+ {
+ if (!m_listening)
+ {
+ // connected socket
+ ssize_t const result = ::read(m_sock, buffer, count);
+ if (result < 0)
+ {
+ return errno_to_file_error(errno);
+ }
+ else
+ {
+ actual = std::uint32_t(size_t(result));
+ return error::NONE;
+ }
+ }
+ else
+ {
+ // listening socket
+ int const accepted = ::accept(m_sock, nullptr, nullptr);
+ if (accepted < 0)
+ {
+ return errno_to_file_error(errno);
+ }
+ else
+ {
+ ::close(m_sock);
+ m_sock = accepted;
+ m_listening = false;
+ actual = 0;
+
+ return error::NONE;
+ }
+ }
+ }
+ else
+ {
+ return error::FAILURE;
+ }
+ }
+
+ virtual error write(void const *buffer, std::uint64_t offset, std::uint32_t count, std::uint32_t &actual) override
+ {
+ ssize_t const result = ::write(m_sock, buffer, count);
+ if (result < 0)
+ return errno_to_file_error(errno);
+
+ actual = std::uint32_t(size_t(result));
+ return error::NONE;
+ }
+
+ virtual error truncate(std::uint64_t offset) override
+ {
+ // doesn't make sense on socket
+ return error::INVALID_ACCESS;
+ }
+
+ virtual error flush() override
+ {
+ // there's no simple way to flush buffers on a socket anyway
+ return error::NONE;
+ }
+
+private:
+ int m_sock;
+ bool m_listening;
+};
+
+} // anonymous namespace
+
+
+bool posix_check_domain_path(std::string const &path)
+{
+ if (strncmp(path.c_str(), posixfile_domain_identifier, strlen(posixfile_domain_identifier)) == 0)
+ return true;
+ return false;
+}
+
+
+osd_file::error posix_open_domain(std::string const &path, std::uint32_t openflags, osd_file::ptr &file, std::uint64_t &filesize)
+{
+ struct sockaddr_un sau;
+ memset(&sau, 0, sizeof(sau));
+ sau.sun_family = AF_UNIX;
+ strncpy(sau.sun_path, &path.c_str()[strlen(posixfile_domain_identifier)], sizeof(sau.sun_path)-1);
+
+ int const sock = ::socket(AF_UNIX, SOCK_STREAM, 0);
+ if (sock < 0)
+ return errno_to_file_error(errno);
+
+ fcntl(sock, F_SETFL, O_NONBLOCK);
+
+ // listening socket support
+ if (openflags & OPEN_FLAG_CREATE)
+ {
+ if (::bind(sock, reinterpret_cast<struct sockaddr const *>(&sau), sizeof(struct sockaddr_un)) < 0)
+ {
+ int const err = errno;
+ ::close(sock);
+ return errno_to_file_error(err);
+ }
+
+ // start to listen...
+ if (::listen(sock, 1) < 0)
+ {
+ int const err = errno;
+ ::close(sock);
+ return errno_to_file_error(err);
+ }
+
+ // mark socket as "listening"
+ try
+ {
+ file = std::make_unique<posix_osd_domain>(sock, true);
+ filesize = 0;
+ return osd_file::error::NONE;
+ }
+ catch (...)
+ {
+ ::close(sock);
+ return osd_file::error::OUT_OF_MEMORY;
+ }
+ }
+ else
+ {
+ if (::connect(sock, reinterpret_cast<struct sockaddr const *>(&sau), sizeof(struct sockaddr_un)) < 0)
+ {
+ ::close(sock);
+ return osd_file::error::ACCESS_DENIED; // have to return this value or bitb won't try to bind on connect failure
+ }
+ try
+ {
+ file = std::make_unique<posix_osd_domain>(sock, false);
+ filesize = 0;
+ return osd_file::error::NONE;
+ }
+ catch (...)
+ {
+ ::close(sock);
+ return osd_file::error::OUT_OF_MEMORY;
+ }
+ }
+}
diff --git a/src/osd/modules/file/posixfile.cpp b/src/osd/modules/file/posixfile.cpp
index 967202eb61c..832b6810db4 100644
--- a/src/osd/modules/file/posixfile.cpp
+++ b/src/osd/modules/file/posixfile.cpp
@@ -217,6 +217,8 @@ osd_file::error osd_file::open(std::string const &path, std::uint32_t openflags,
return posix_open_socket(path, openflags, file, filesize);
else if (posix_check_ptty_path(path))
return posix_open_ptty(openflags, file, filesize, dst);
+ else if (posix_check_domain_path(path))
+ return posix_open_domain(path, openflags, file, filesize);
// select the file open modes
int access;
diff --git a/src/osd/modules/file/posixfile.h b/src/osd/modules/file/posixfile.h
index 2339a52ceec..6f585ff827a 100644
--- a/src/osd/modules/file/posixfile.h
+++ b/src/osd/modules/file/posixfile.h
@@ -22,6 +22,9 @@
bool posix_check_socket_path(std::string const &path);
osd_file::error posix_open_socket(std::string const &path, std::uint32_t openflags, osd_file::ptr &file, std::uint64_t &filesize);
+bool posix_check_domain_path(std::string const &path);
+osd_file::error posix_open_domain(std::string const &path, std::uint32_t openflags, osd_file::ptr &file, std::uint64_t &filesize);
+
bool posix_check_ptty_path(std::string const &path);
osd_file::error posix_open_ptty(std::uint32_t openflags, osd_file::ptr &file, std::uint64_t &filesize, std::string &name);
diff --git a/src/osd/modules/file/winptty.cpp b/src/osd/modules/file/winptty.cpp
index ab0efae37ff..943f1fbaa52 100644
--- a/src/osd/modules/file/winptty.cpp
+++ b/src/osd/modules/file/winptty.cpp
@@ -88,10 +88,19 @@ osd_file::error win_open_ptty(std::string const &path, std::uint32_t openflags,
{
osd::text::tstring t_name = osd::text::to_tstring(path);
- HANDLE pipe = CreateNamedPipe(t_name.c_str(), PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_NOWAIT, 1, 32, 32, 0, nullptr);
+ HANDLE pipe = CreateFileW(t_name.c_str(), GENERIC_READ | GENERIC_WRITE, 0, nullptr, OPEN_EXISTING, 0, nullptr);
if (INVALID_HANDLE_VALUE == pipe)
- return osd_file::error::ACCESS_DENIED;
+ {
+ pipe = CreateNamedPipe(t_name.c_str(), PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_NOWAIT, 1, 32, 32, 0, nullptr);
+ if (INVALID_HANDLE_VALUE == pipe)
+ return osd_file::error::ACCESS_DENIED;
+ }
+ else
+ {
+ DWORD state = PIPE_NOWAIT;
+ SetNamedPipeHandleState(pipe, &state, NULL, NULL);
+ }
try
{
diff --git a/src/osd/modules/lib/osdlib.h b/src/osd/modules/lib/osdlib.h
index afcc5229371..d080d1edd85 100644
--- a/src/osd/modules/lib/osdlib.h
+++ b/src/osd/modules/lib/osdlib.h
@@ -63,7 +63,6 @@ int osd_setenv(const char *name, const char *value, int overwrite);
char *osd_get_clipboard_text(void);
-
/*-----------------------------------------------------------------------------
dynamic_module: load functions from optional shared libraries
diff --git a/src/osd/modules/lib/osdlib_macosx.cpp b/src/osd/modules/lib/osdlib_macosx.cpp
index 1f6dec46c76..b476261df41 100644
--- a/src/osd/modules/lib/osdlib_macosx.cpp
+++ b/src/osd/modules/lib/osdlib_macosx.cpp
@@ -191,6 +191,15 @@ char *osd_get_clipboard_text(void)
}
//============================================================
+// osd_getpid
+//============================================================
+
+int osd_getpid(void)
+{
+ return getpid();
+}
+
+//============================================================
// dynamic_module_posix_impl
//============================================================
diff --git a/src/osd/modules/lib/osdlib_unix.cpp b/src/osd/modules/lib/osdlib_unix.cpp
index da3ddc24dea..0bcf34d04b2 100644
--- a/src/osd/modules/lib/osdlib_unix.cpp
+++ b/src/osd/modules/lib/osdlib_unix.cpp
@@ -126,6 +126,15 @@ char *osd_get_clipboard_text(void)
#endif
//============================================================
+// osd_getpid
+//============================================================
+
+int osd_getpid(void)
+{
+ return getpid();
+}
+
+//============================================================
// dynamic_module_posix_impl
//============================================================
diff --git a/src/osd/modules/lib/osdlib_uwp.cpp b/src/osd/modules/lib/osdlib_uwp.cpp
index 864177d9544..dcf995fbd7f 100644
--- a/src/osd/modules/lib/osdlib_uwp.cpp
+++ b/src/osd/modules/lib/osdlib_uwp.cpp
@@ -175,3 +175,13 @@ char *osd_get_clipboard_text(void)
return result;
}
+
+//============================================================
+// osd_getpid
+//============================================================
+
+int osd_getpid(void)
+{
+ return -1;
+}
+
diff --git a/src/osd/modules/lib/osdlib_win32.cpp b/src/osd/modules/lib/osdlib_win32.cpp
index d4dc3327f17..fb4b29e62af 100644
--- a/src/osd/modules/lib/osdlib_win32.cpp
+++ b/src/osd/modules/lib/osdlib_win32.cpp
@@ -209,6 +209,15 @@ char *osd_get_clipboard_text(void)
}
//============================================================
+// osd_getpid
+//============================================================
+
+int osd_getpid(void)
+{
+ return GetCurrentProcessId();
+}
+
+//============================================================
// osd_dynamic_bind
//============================================================
diff --git a/src/osd/osdcore.h b/src/osd/osdcore.h
index 2bfc7cb5950..ac1571f2dd2 100644
--- a/src/osd/osdcore.h
+++ b/src/osd/osdcore.h
@@ -243,6 +243,14 @@ public:
-----------------------------------------------------------------------------*/
const char *osd_getenv(const char *name);
+/*-----------------------------------------------------------------------------
+ osd_getpid: gets process id
+
+ Return value:
+
+ process id
+-----------------------------------------------------------------------------*/
+int osd_getpid();
/*-----------------------------------------------------------------------------
osd_get_physical_drive_geometry: if the given path points to a physical