summaryrefslogtreecommitdiffstatshomepage
path: root/src/osd
diff options
context:
space:
mode:
Diffstat (limited to 'src/osd')
-rw-r--r--src/osd/mac/window.cpp45
-rw-r--r--src/osd/modules/debugger/debuggdbstub.cpp1
-rw-r--r--src/osd/modules/debugger/debugimgui.cpp11
-rw-r--r--src/osd/modules/debugger/osx/debugview.mm2
-rw-r--r--src/osd/modules/debugger/qt/mainwindow.cpp6
-rw-r--r--src/osd/modules/debugger/win/consolewininfo.cpp4
-rw-r--r--src/osd/modules/input/input_common.h10
-rw-r--r--src/osd/modules/input/input_dinput.cpp8
-rw-r--r--src/osd/modules/input/input_dinput.h4
-rw-r--r--src/osd/modules/input/input_rawinput.cpp271
-rw-r--r--src/osd/modules/input/input_sdl.cpp302
-rw-r--r--src/osd/modules/input/input_sdlcommon.cpp2
-rw-r--r--src/osd/modules/input/input_sdlcommon.h44
-rw-r--r--src/osd/modules/input/input_win32.cpp14
-rw-r--r--src/osd/modules/input/input_windows.cpp22
-rw-r--r--src/osd/modules/input/input_x11.cpp12
-rw-r--r--src/osd/modules/input/input_xinput.cpp14
-rw-r--r--src/osd/modules/lib/osdlib.h2
-rw-r--r--src/osd/modules/lib/osdobj_common.cpp2
-rw-r--r--src/osd/modules/osdhelper.h4
-rw-r--r--src/osd/modules/osdwindow.h8
-rw-r--r--src/osd/modules/output/output_module.h2
-rw-r--r--src/osd/modules/render/aviwrite.cpp1
-rw-r--r--src/osd/modules/render/bgfx/chainentryreader.cpp5
-rw-r--r--src/osd/modules/render/bgfx/chainmanager.cpp13
-rw-r--r--src/osd/modules/render/bgfx/effect.cpp1
-rw-r--r--src/osd/modules/render/bgfx/effect.h3
-rw-r--r--src/osd/modules/render/bgfx/effectmanager.cpp96
-rw-r--r--src/osd/modules/render/bgfx/effectmanager.h8
-rw-r--r--src/osd/modules/render/bgfx/effectreader.cpp129
-rw-r--r--src/osd/modules/render/bgfx/effectreader.h9
-rw-r--r--src/osd/modules/render/bgfx/shadermanager.cpp59
-rw-r--r--src/osd/modules/render/bgfx/shadermanager.h9
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/crt-geom/vs_gaussx.sc2
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/misc/fs_blit_yuy16.sc9
-rw-r--r--src/osd/modules/render/bgfx/shaders/chains/misc/fs_lut.sc13
-rw-r--r--src/osd/modules/render/bgfx/texturemanager.cpp5
-rw-r--r--src/osd/modules/render/bgfx/uniform.cpp12
-rw-r--r--src/osd/modules/render/bgfx/uniform.h2
-rw-r--r--src/osd/modules/render/bgfx/view.cpp7
-rw-r--r--src/osd/modules/render/bgfx/windowparameter.h2
-rw-r--r--src/osd/modules/render/d3d/d3dhlsl.cpp5
-rw-r--r--src/osd/modules/render/d3d/d3dhlsl.h156
-rw-r--r--src/osd/modules/render/drawbgfx.cpp376
-rw-r--r--src/osd/modules/render/drawbgfx.h9
-rw-r--r--src/osd/modules/render/drawd3d.cpp23
-rw-r--r--src/osd/modules/render/drawgdi.h6
-rw-r--r--src/osd/modules/render/drawogl.cpp25
-rw-r--r--src/osd/osdnet.cpp2
-rw-r--r--src/osd/osdnet.h2
-rw-r--r--src/osd/osdsync.cpp25
-rw-r--r--src/osd/osdsync.h12
-rw-r--r--src/osd/sdl/sdlmain.cpp17
-rw-r--r--src/osd/sdl/video.cpp8
-rw-r--r--src/osd/sdl/window.cpp69
-rw-r--r--src/osd/strconv.cpp7
-rw-r--r--src/osd/windows/window.cpp46
-rw-r--r--src/osd/windows/window.h2
-rw-r--r--src/osd/windows/winmain.cpp4
-rw-r--r--src/osd/windows/winmain.h2
60 files changed, 1179 insertions, 792 deletions
diff --git a/src/osd/mac/window.cpp b/src/osd/mac/window.cpp
index 4056958b0d9..ea2adbb631f 100644
--- a/src/osd/mac/window.cpp
+++ b/src/osd/mac/window.cpp
@@ -20,6 +20,7 @@
#include "emu.h"
#include "emuopts.h"
#include "render.h"
+#include "screen.h"
#include "ui/uimain.h"
// OSD headers
@@ -68,17 +69,43 @@ bool mac_osd_interface::window_init()
{
osd_printf_verbose("Enter macwindow_init\n");
- // initialize the drawers
-
- switch (video_config.mode)
- {
- case VIDEO_MODE_BGFX:
- renderer_bgfx::init(machine());
- break;
- case VIDEO_MODE_OPENGL:
- renderer_ogl::init(machine());
+ // initialize the renderer
+ const int fallbacks[VIDEO_MODE_COUNT] = {
+ -1, // NONE -> no fallback
+ -1, // No GDI on macOS
+ VIDEO_MODE_OPENGL, // BGFX -> OpenGL
+ -1, // OpenGL -> no fallback
+ -1, // No SDL2ACCEL on macOS
+ -1, // No D3D on macOS
+ -1 // No SOFT on macOS
+ };
+
+ int current_mode = video_config.mode;
+ while (current_mode != VIDEO_MODE_NONE)
+ {
+ bool error = false;
+ switch(current_mode)
+ {
+ case VIDEO_MODE_BGFX:
+ error = renderer_bgfx::init(machine());
+ break;
+ case VIDEO_MODE_OPENGL:
+ renderer_ogl::init(machine());
+ break;
+ default:
+ fatalerror("Unknown video mode.");
+ break;
+ }
+ if (error)
+ {
+ current_mode = fallbacks[current_mode];
+ }
+ else
+ {
break;
+ }
}
+ video_config.mode = current_mode;
// set up the window list
osd_printf_verbose("Leave macwindow_init\n");
diff --git a/src/osd/modules/debugger/debuggdbstub.cpp b/src/osd/modules/debugger/debuggdbstub.cpp
index 9f26fb2c778..5e477200dc2 100644
--- a/src/osd/modules/debugger/debuggdbstub.cpp
+++ b/src/osd/modules/debugger/debuggdbstub.cpp
@@ -13,6 +13,7 @@
#include "debug/textbuf.h"
#include "debug_module.h"
#include "debugger.h"
+#include "fileio.h"
#include "modules/lib/osdobj_common.h"
#include "modules/osdmodule.h"
diff --git a/src/osd/modules/debugger/debugimgui.cpp b/src/osd/modules/debugger/debugimgui.cpp
index 6271adf97a5..944ed203b79 100644
--- a/src/osd/modules/debugger/debugimgui.cpp
+++ b/src/osd/modules/debugger/debugimgui.cpp
@@ -142,7 +142,7 @@ private:
struct image_type_entry
{
- floppy_image_format_t* format;
+ const floppy_image_format_t* format;
std::string shortname;
std::string longname;
};
@@ -987,9 +987,9 @@ void debug_imgui::create_image()
{
image_init_result res;
- if(m_dialog_image->image_type() == IO_FLOPPY)
+ auto *fd = dynamic_cast<floppy_image_device *>(m_dialog_image);
+ if(fd != nullptr)
{
- auto *fd = static_cast<floppy_image_device *>(m_dialog_image);
res = fd->create(m_path,nullptr,nullptr);
if(res == image_init_result::PASS)
fd->setup_write(m_typelist.at(m_format_sel).format);
@@ -1061,7 +1061,7 @@ void debug_imgui::refresh_typelist()
if(fd == nullptr)
return;
- for(floppy_image_format_t* flist : fd->get_formats())
+ for(const floppy_image_format_t* flist : fd->get_formats())
{
if(flist->supports_save())
{
@@ -1199,7 +1199,8 @@ void debug_imgui::draw_create_dialog(const char* label)
}
// format combo box for floppy devices
- if(m_dialog_image->image_type() == IO_FLOPPY)
+ auto *fd = dynamic_cast<floppy_image_device *>(m_dialog_image);
+ if(fd != nullptr)
{
std::string combo_str;
combo_str.clear();
diff --git a/src/osd/modules/debugger/osx/debugview.mm b/src/osd/modules/debugger/osx/debugview.mm
index df7c4dbcc01..8853be80622 100644
--- a/src/osd/modules/debugger/osx/debugview.mm
+++ b/src/osd/modules/debugger/osx/debugview.mm
@@ -675,7 +675,7 @@ static void debugwin_view_update(debug_view &view, void *osdprivate)
NSUInteger start = 0, length = 0;
for (uint32_t col = origin.x; col < origin.x + size.x; col++)
{
- [[text mutableString] appendFormat:@"%c", data[col - origin.x].byte];
+ [[text mutableString] appendFormat:@"%C", unichar(data[col - origin.x].byte)];
if ((start < length) && (attr != data[col - origin.x].attrib))
{
NSRange const run = NSMakeRange(start, length - start);
diff --git a/src/osd/modules/debugger/qt/mainwindow.cpp b/src/osd/modules/debugger/qt/mainwindow.cpp
index b0043c06dee..afea2e07919 100644
--- a/src/osd/modules/debugger/qt/mainwindow.cpp
+++ b/src/osd/modules/debugger/qt/mainwindow.cpp
@@ -220,7 +220,7 @@ void MainWindow::toggleBreakpointAtCursor(bool changedTo)
command = string_format("bpset 0x%X", address);
else
command = string_format("bpclear 0x%X", bp->index());
- m_machine.debugger().console().execute_command(command.c_str(), true);
+ m_machine.debugger().console().execute_command(command, true);
}
refreshAll();
@@ -242,7 +242,7 @@ void MainWindow::enableBreakpointAtCursor(bool changedTo)
{
int32_t const bpindex = bp->index();
std::string command = string_format(bp->enabled() ? "bpdisable 0x%X" : "bpenable 0x%X", bpindex);
- m_machine.debugger().console().execute_command(command.c_str(), true);
+ m_machine.debugger().console().execute_command(command, true);
}
}
@@ -257,7 +257,7 @@ void MainWindow::runToCursor(bool changedTo)
{
offs_t address = downcast<debug_view_disasm*>(dasmView)->selected_address();
std::string command = string_format("go 0x%X", address);
- m_machine.debugger().console().execute_command(command.c_str(), true);
+ m_machine.debugger().console().execute_command(command, true);
}
}
diff --git a/src/osd/modules/debugger/win/consolewininfo.cpp b/src/osd/modules/debugger/win/consolewininfo.cpp
index 1265417c61f..afddcf31d6c 100644
--- a/src/osd/modules/debugger/win/consolewininfo.cpp
+++ b/src/osd/modules/debugger/win/consolewininfo.cpp
@@ -2,7 +2,7 @@
// copyright-holders:Aaron Giles, Vas Crabb
//============================================================
//
-// consolewininfo.c - Win32 debug window handling
+// consolewininfo.cpp - Win32 debug window handling
//
//============================================================
@@ -20,6 +20,8 @@
#include "strconv.h"
#include "winutf8.h"
+#include "softlist_dev.h"
+
consolewin_info::consolewin_info(debugger_windows_interface &debugger) :
disasmbasewin_info(debugger, true, "Debug", nullptr),
diff --git a/src/osd/modules/input/input_common.h b/src/osd/modules/input/input_common.h
index 49c4e768dcf..a26d6f5375e 100644
--- a/src/osd/modules/input/input_common.h
+++ b/src/osd/modules/input/input_common.h
@@ -295,7 +295,8 @@ private:
std::vector<std::unique_ptr<device_info>> m_list;
public:
- size_t size() const { return m_list.size(); }
+ auto size() const { return m_list.size(); }
+ auto empty() const { return m_list.empty(); }
auto begin() { return m_list.begin(); }
auto end() { return m_list.end(); }
@@ -318,7 +319,8 @@ public:
m_list.erase(std::remove_if(std::begin(m_list), std::end(m_list), device_matches), m_list.end());
}
- void for_each_device(std::function<void (device_info*)> action)
+ template <typename T>
+ void for_each_device(T &&action)
{
for (auto &device: m_list)
action(device.get());
@@ -445,7 +447,7 @@ protected:
public:
const osd_options * options() const { return m_options; }
- input_device_list * devicelist() { return &m_devicelist; }
+ input_device_list & devicelist() { return m_devicelist; }
bool input_enabled() const { return m_input_enabled; }
bool input_paused() const { return m_input_paused; }
bool mouse_enabled() const { return m_mouse_enabled; }
@@ -502,7 +504,7 @@ public:
virtual void exit() override
{
- devicelist()->free_all_devices();
+ devicelist().free_all_devices();
}
protected:
diff --git a/src/osd/modules/input/input_dinput.cpp b/src/osd/modules/input/input_dinput.cpp
index 8ceb29e21f4..7295b23de12 100644
--- a/src/osd/modules/input/input_dinput.cpp
+++ b/src/osd/modules/input/input_dinput.cpp
@@ -238,7 +238,7 @@ public:
result = dinput_set_dword_property(devinfo->dinput.device, DIPROP_AXISMODE, 0, DIPH_DEVICE, DIPROPAXISMODE_REL);
if (result != DI_OK && result != DI_PROPNOEFFECT)
{
- osd_printf_error("DirectInput: Unable to set relative mode for mouse %u (%s)\n", static_cast<unsigned int>(devicelist()->size()), devinfo->name());
+ osd_printf_error("DirectInput: Unable to set relative mode for mouse %u (%s)\n", static_cast<unsigned int>(devicelist().size()), devinfo->name());
goto error;
}
@@ -277,7 +277,7 @@ public:
error:
if (devinfo)
- devicelist()->free_device(*devinfo);
+ devicelist().free_device(*devinfo);
goto exit;
}
};
@@ -449,10 +449,10 @@ void dinput_joystick_device::poll()
int dinput_joystick_device::configure()
{
HRESULT result;
- auto devicelist = static_cast<input_module_base&>(module()).devicelist();
+ auto &devicelist = static_cast<input_module_base&>(module()).devicelist();
// temporary approximation of index
- int devindex = devicelist->size();
+ int devindex = devicelist.size();
// set absolute mode
result = dinput_set_dword_property(dinput.device, DIPROP_AXISMODE, 0, DIPH_DEVICE, DIPROPAXISMODE_ABS);
diff --git a/src/osd/modules/input/input_dinput.h b/src/osd/modules/input/input_dinput.h
index 8600e73a04d..20bced84883 100644
--- a/src/osd/modules/input/input_dinput.h
+++ b/src/osd/modules/input/input_dinput.h
@@ -72,7 +72,7 @@ public:
std::string utf8_instance_id = utf8_instance_name + " product_" + guid_to_string(instance->guidProduct) + " instance_" + guid_to_string(instance->guidInstance);
// allocate memory for the device object
- TDevice &devinfo = module.devicelist()->create_device<TDevice>(machine, std::move(utf8_instance_name), std::move(utf8_instance_id), module);
+ TDevice &devinfo = module.devicelist().create_device<TDevice>(machine, std::move(utf8_instance_name), std::move(utf8_instance_id), module);
// attempt to create a device
result = m_dinput->CreateDevice(instance->guidInstance, devinfo.dinput.device.GetAddressOf(), nullptr);
@@ -133,7 +133,7 @@ public:
return &devinfo;
error:
- module.devicelist()->free_device(devinfo);
+ module.devicelist().free_device(devinfo);
return nullptr;
}
diff --git a/src/osd/modules/input/input_rawinput.cpp b/src/osd/modules/input/input_rawinput.cpp
index 248b7bb48ab..6424a0d1099 100644
--- a/src/osd/modules/input/input_rawinput.cpp
+++ b/src/osd/modules/input/input_rawinput.cpp
@@ -19,6 +19,7 @@
#include <algorithm>
#include <functional>
#include <mutex>
+#include <new>
// MAME headers
#include "emu.h"
@@ -35,12 +36,6 @@
namespace {
-// Typedefs for dynamically loaded functions
-typedef UINT (WINAPI *get_rawinput_device_list_ptr)(PRAWINPUTDEVICELIST, PUINT, UINT);
-typedef UINT (WINAPI *get_rawinput_data_ptr)( HRAWINPUT, UINT, LPVOID, PUINT, UINT);
-typedef UINT (WINAPI *get_rawinput_device_info_ptr)(HANDLE, UINT, LPVOID, PUINT);
-typedef BOOL (WINAPI *register_rawinput_devices_ptr)(PCRAWINPUTDEVICE, UINT, UINT);
-
class safe_regkey
{
private:
@@ -294,7 +289,7 @@ public:
rawinput_keyboard_device(running_machine &machine, std::string &&name, std::string &&id, input_module &module) :
rawinput_device(machine, std::move(name), std::move(id), DEVICE_CLASS_KEYBOARD, module),
- keyboard({{0}})
+ keyboard({ { 0 } })
{
}
@@ -326,7 +321,7 @@ class rawinput_mouse_device : public rawinput_device
private:
std::mutex m_device_lock;
public:
- mouse_state mouse;
+ mouse_state mouse;
rawinput_mouse_device(running_machine &machine, std::string &&name, std::string &&id, input_module &module) :
rawinput_device(machine, std::move(name), std::move(id), DEVICE_CLASS_MOUSE, module),
@@ -442,12 +437,7 @@ public:
class rawinput_module : public wininput_module
{
private:
- osd::dynamic_module::ptr m_user32_dll;
- get_rawinput_device_list_ptr get_rawinput_device_list = nullptr;
- get_rawinput_data_ptr get_rawinput_data = nullptr;
- get_rawinput_device_info_ptr get_rawinput_device_info = nullptr;
- register_rawinput_devices_ptr register_rawinput_devices = nullptr;
- std::mutex m_module_lock;
+ std::mutex m_module_lock;
public:
rawinput_module(const char *type, const char *name) : wininput_module(type, name)
@@ -456,163 +446,234 @@ public:
bool probe() override
{
- m_user32_dll = osd::dynamic_module::open({ "user32.dll" });
-
- get_rawinput_device_list = m_user32_dll->bind<get_rawinput_device_list_ptr>("GetRawInputDeviceList");
- get_rawinput_data = m_user32_dll->bind<get_rawinput_data_ptr>("GetRawInputData");
- get_rawinput_device_info = m_user32_dll->bind<get_rawinput_device_info_ptr>("GetRawInputDeviceInfoW");
- register_rawinput_devices = m_user32_dll->bind<register_rawinput_devices_ptr>("RegisterRawInputDevices");
-
- return get_rawinput_device_list && get_rawinput_data && get_rawinput_device_info && register_rawinput_devices;
+ return true;
}
void input_init(running_machine &machine) override
{
- // get the number of devices, allocate a device list, and fetch it
+ // get initial number of devices
UINT device_count = 0;
- if ((*get_rawinput_device_list)(nullptr, &device_count, sizeof(RAWINPUTDEVICELIST)) != 0)
+ if (GetRawInputDeviceList(nullptr, &device_count, sizeof(RAWINPUTDEVICELIST)) != 0)
+ {
+ osd_printf_error("Error getting initial number of RawInput devices.\n");
return;
-
- if (device_count == 0)
+ }
+ if (!device_count)
return;
- auto rawinput_devices = std::make_unique<RAWINPUTDEVICELIST[]>(device_count);
- if ((*get_rawinput_device_list)(rawinput_devices.get(), &device_count, sizeof(RAWINPUTDEVICELIST)) == UINT(-1))
+ std::unique_ptr<RAWINPUTDEVICELIST []> rawinput_devices;
+ UINT retrieved;
+ do
+ {
+ rawinput_devices.reset(new (std::nothrow) RAWINPUTDEVICELIST [device_count]);
+ if (!rawinput_devices)
+ {
+ osd_printf_error("Error allocating buffer for RawInput device list.\n");
+ return;
+ }
+ retrieved = GetRawInputDeviceList(rawinput_devices.get(), &device_count, sizeof(RAWINPUTDEVICELIST));
+ }
+ while ((UINT(-1) == retrieved) && (GetLastError() == ERROR_INSUFFICIENT_BUFFER));
+ if (UINT(-1) == retrieved)
+ {
+ osd_printf_error("Error listing RawInput devices.\n");
return;
+ }
// iterate backwards through devices; new devices are added at the head
- for (int devnum = device_count - 1; devnum >= 0; devnum--)
- {
- RAWINPUTDEVICELIST *device = &rawinput_devices[devnum];
- add_rawinput_device(machine, device);
- }
+ for (int devnum = retrieved - 1; devnum >= 0; devnum--)
+ add_rawinput_device(machine, rawinput_devices[devnum]);
// don't enable global inputs when debugging
if (!machine.options().debug())
- {
m_global_inputs_enabled = downcast<windows_options &>(machine.options()).global_inputs();
- }
// If we added no devices, no need to register for notifications
- if (devicelist()->size() == 0)
+ if (devicelist().empty())
return;
// finally, register to receive raw input WM_INPUT messages if we found devices
RAWINPUTDEVICE registration;
registration.usUsagePage = usagepage();
registration.usUsage = usage();
- registration.dwFlags = m_global_inputs_enabled ? 0x00000100 : 0;
+ registration.dwFlags = RIDEV_DEVNOTIFY;
+ if (m_global_inputs_enabled)
+ registration.dwFlags |= RIDEV_INPUTSINK;
registration.hwndTarget = std::static_pointer_cast<win_window_info>(osd_common_t::s_window_list.front())->platform_window();
// register the device
- (*register_rawinput_devices)(&registration, 1, sizeof(registration));
+ RegisterRawInputDevices(&registration, 1, sizeof(registration));
}
protected:
- virtual void add_rawinput_device(running_machine &machine, RAWINPUTDEVICELIST *device) = 0;
+ virtual void add_rawinput_device(running_machine &machine, RAWINPUTDEVICELIST const &device) = 0;
virtual USHORT usagepage() = 0;
virtual USHORT usage() = 0;
int init_internal() override
{
- if (!get_rawinput_device_list || !get_rawinput_data ||
- !get_rawinput_device_info || !register_rawinput_devices )
- {
- return 1;
- }
-
- osd_printf_verbose("RawInput: APIs detected\n");
return 0;
}
template<class TDevice>
- TDevice *create_rawinput_device(running_machine &machine, PRAWINPUTDEVICELIST rawinputdevice)
+ TDevice *create_rawinput_device(running_machine &machine, RAWINPUTDEVICELIST const &rawinputdevice)
{
// determine the length of the device name, allocate it, and fetch it if not nameless
UINT name_length = 0;
- if ((*get_rawinput_device_info)(rawinputdevice->hDevice, RIDI_DEVICENAME, nullptr, &name_length) != 0)
+ if (GetRawInputDeviceInfoW(rawinputdevice.hDevice, RIDI_DEVICENAME, nullptr, &name_length) != 0)
return nullptr;
std::unique_ptr<WCHAR []> tname = std::make_unique<WCHAR []>(name_length + 1);
- if (name_length > 1 && (*get_rawinput_device_info)(rawinputdevice->hDevice, RIDI_DEVICENAME, tname.get(), &name_length) == UINT(-1))
+ if (name_length > 1 && GetRawInputDeviceInfoW(rawinputdevice.hDevice, RIDI_DEVICENAME, tname.get(), &name_length) == UINT(-1))
return nullptr;
// if this is an RDP name, skip it
- if (_tcsstr(tname.get(), TEXT("Root#RDP_")) != nullptr)
+ if (wcsstr(tname.get(), L"Root#RDP_") != nullptr)
return nullptr;
// improve the name and then allocate a device
- std::wstring name = rawinput_device_improve_name(tname.get());
-
- // convert name to utf8
- std::string utf8_name = osd::text::from_wstring(name);
+ std::string utf8_name = osd::text::from_wstring(rawinput_device_improve_name(tname.get()));
- // set device id to raw input name
+ // set device ID to raw input name
std::string utf8_id = osd::text::from_wstring(tname.get());
- TDevice &devinfo = devicelist()->create_device<TDevice>(machine, std::move(utf8_name), std::move(utf8_id), *this);
+ tname.reset();
+
+ TDevice &devinfo = devicelist().create_device<TDevice>(machine, std::move(utf8_name), std::move(utf8_id), *this);
// Add the handle
- devinfo.set_handle(rawinputdevice->hDevice);
+ devinfo.set_handle(rawinputdevice.hDevice);
return &devinfo;
}
bool handle_input_event(input_event eventid, void *eventdata) override
{
- // Only handle raw input data
- if (!input_enabled() || eventid != INPUT_EVENT_RAWINPUT)
- return false;
-
- HRAWINPUT rawinputdevice = *static_cast<HRAWINPUT*>(eventdata);
-
- BYTE small_buffer[4096];
- std::unique_ptr<BYTE[]> larger_buffer;
- LPBYTE data = small_buffer;
- UINT size;
+ switch (eventid)
+ {
+ // handle raw input data
+ case INPUT_EVENT_RAWINPUT:
+ {
+ // ignore if not enabled
+ if (!input_enabled())
+ return false;
+
+ HRAWINPUT rawinputdevice = *static_cast<HRAWINPUT *>(eventdata);
+
+ BYTE small_buffer[4096];
+ std::unique_ptr<BYTE []> larger_buffer;
+ LPBYTE data = small_buffer;
+ UINT size;
+
+ // determine the size of data buffer we need
+ if (GetRawInputData(rawinputdevice, RID_INPUT, nullptr, &size, sizeof(RAWINPUTHEADER)) != 0)
+ return false;
+
+ // if necessary, allocate a temporary buffer and fetch the data
+ if (size > sizeof(small_buffer))
+ {
+ larger_buffer.reset(new (std::nothrow) BYTE [size]);
+ data = larger_buffer.get();
+ if (!data)
+ return false;
+ }
+
+ // fetch the data and process the appropriate message types
+ UINT result = GetRawInputData(rawinputdevice, RID_INPUT, data, &size, sizeof(RAWINPUTHEADER));
+ if (UINT(-1) == result)
+ {
+ return false;
+ }
+ else if (result)
+ {
+ std::lock_guard<std::mutex> scope_lock(m_module_lock);
+
+ auto *input = reinterpret_cast<RAWINPUT *>(data);
+ if (!input->header.hDevice)
+ return false;
+
+ // find the device in the list and update
+ auto target_device = std::find_if(
+ devicelist().begin(),
+ devicelist().end(),
+ [input] (auto const &device)
+ {
+ auto devinfo = dynamic_cast<rawinput_device *>(device.get());
+ return devinfo && (input->header.hDevice == devinfo->device_handle());
+ });
+ if (devicelist().end() == target_device)
+ return false;
+
+ static_cast<rawinput_device *>(target_device->get())->queue_events(input, 1);
+ return true;
+ }
+ }
+ break;
- // ignore if not enabled
- if (!input_enabled())
- return false;
+ case INPUT_EVENT_ARRIVAL:
+ {
+ HRAWINPUT rawinputdevice = *static_cast<HRAWINPUT *>(eventdata);
+
+ // determine the length of the device name, allocate it, and fetch it if not nameless
+ UINT name_length = 0;
+ if (GetRawInputDeviceInfoW(rawinputdevice, RIDI_DEVICENAME, nullptr, &name_length) != 0)
+ return false;
+
+ std::unique_ptr<WCHAR []> tname = std::make_unique<WCHAR []>(name_length + 1);
+ if (name_length > 1 && GetRawInputDeviceInfoW(rawinputdevice, RIDI_DEVICENAME, tname.get(), &name_length) == UINT(-1))
+ return false;
+ std::string utf8_id = osd::text::from_wstring(tname.get());
+ tname.reset();
+
+ std::lock_guard<std::mutex> scope_lock(m_module_lock);
+
+ // find the device in the list and update
+ auto target_device = std::find_if(
+ devicelist().begin(),
+ devicelist().end(),
+ [&utf8_id] (auto const &device)
+ {
+ auto devinfo = dynamic_cast<rawinput_device *>(device.get());
+ return devinfo && !devinfo->device_handle() && (devinfo->id() == utf8_id);
+ });
+ if (devicelist().end() == target_device)
+ return false;
- // determine the size of databuffer we need
- if ((*get_rawinput_data)(rawinputdevice, RID_INPUT, nullptr, &size, sizeof(RAWINPUTHEADER)) != 0)
- return false;
+ static_cast<rawinput_device *>(target_device->get())->set_handle(rawinputdevice);
+ return true;
+ }
+ break;
- // if necessary, allocate a temporary buffer and fetch the data
- if (size > sizeof(small_buffer))
- {
- larger_buffer = std::make_unique<BYTE[]>(size);
- data = larger_buffer.get();
- if (data == nullptr)
- return false;
- }
+ case INPUT_EVENT_REMOVAL:
+ {
+ HRAWINPUT rawinputdevice = *static_cast<HRAWINPUT *>(eventdata);
- // fetch the data and process the appropriate message types
- bool result = (*get_rawinput_data)(static_cast<HRAWINPUT>(rawinputdevice), RID_INPUT, data, &size, sizeof(RAWINPUTHEADER));
- if (result)
- {
- std::lock_guard<std::mutex> scope_lock(m_module_lock);
+ std::lock_guard<std::mutex> scope_lock(m_module_lock);
- auto *input = reinterpret_cast<RAWINPUT*>(data);
+ // find the device in the list and update
+ auto target_device = std::find_if(
+ devicelist().begin(),
+ devicelist().end(),
+ [rawinputdevice] (auto const &device)
+ {
+ auto devinfo = dynamic_cast<rawinput_device *>(device.get());
+ return devinfo && (rawinputdevice == devinfo->device_handle());
+ });
- // find the device in the list and update
- auto target_device = std::find_if(
- devicelist()->begin(),
- devicelist()->end(),
- [input] (auto const &device)
- {
- auto devinfo = dynamic_cast<rawinput_device *>(device.get());
- return devinfo && (input->header.hDevice == devinfo->device_handle());
- });
+ if (devicelist().end() == target_device)
+ return false;
- if (target_device != devicelist()->end())
- {
- static_cast<rawinput_device *>((*target_device).get())->queue_events(input, 1);
+ (*target_device)->reset();
+ static_cast<rawinput_device *>(target_device->get())->set_handle(nullptr);
return true;
}
+ break;
+
+ default:
+ break;
}
+ // must have been unhandled
return false;
}
};
@@ -633,10 +694,10 @@ protected:
USHORT usagepage() override { return 1; }
USHORT usage() override { return 6; }
- void add_rawinput_device(running_machine &machine, RAWINPUTDEVICELIST *device) override
+ void add_rawinput_device(running_machine &machine, RAWINPUTDEVICELIST const &device) override
{
// make sure this is a keyboard
- if (device->dwType != RIM_TYPEKEYBOARD)
+ if (device.dwType != RIM_TYPEKEYBOARD)
return;
// allocate and link in a new device
@@ -679,10 +740,10 @@ protected:
USHORT usagepage() override { return 1; }
USHORT usage() override { return 2; }
- void add_rawinput_device(running_machine &machine, RAWINPUTDEVICELIST *device) override
+ void add_rawinput_device(running_machine &machine, RAWINPUTDEVICELIST const &device) override
{
// make sure this is a mouse
- if (device->dwType != RIM_TYPEMOUSE)
+ if (device.dwType != RIM_TYPEMOUSE)
return;
// allocate and link in a new device
@@ -728,11 +789,11 @@ protected:
USHORT usagepage() override { return 1; }
USHORT usage() override { return 2; }
- void add_rawinput_device(running_machine &machine, RAWINPUTDEVICELIST *device) override
+ void add_rawinput_device(running_machine &machine, RAWINPUTDEVICELIST const &device) override
{
// make sure this is a mouse
- if (device->dwType != RIM_TYPEMOUSE)
+ if (device.dwType != RIM_TYPEMOUSE)
return;
// allocate and link in a new device
diff --git a/src/osd/modules/input/input_sdl.cpp b/src/osd/modules/input/input_sdl.cpp
index 58901627bcf..8937e4cb2a6 100644
--- a/src/osd/modules/input/input_sdl.cpp
+++ b/src/osd/modules/input/input_sdl.cpp
@@ -20,12 +20,13 @@
#include <SDL2/SDL.h>
#include <cctype>
// ReSharper disable once CppUnusedIncludeDirective
+#include <algorithm>
#include <cstddef>
-#include <mutex>
+#include <iterator>
#include <memory>
+#include <mutex>
+#include <optional>
#include <queue>
-#include <iterator>
-#include <algorithm>
// MAME headers
#include "emu.h"
@@ -373,6 +374,14 @@ protected:
class sdl_keyboard_device : public sdl_device
{
public:
+ // state information for a keyboard
+ struct keyboard_state
+ {
+ int32_t state[0x3ff]; // must be int32_t!
+ int8_t oldkey[MAX_KEYS];
+ int8_t currkey[MAX_KEYS];
+ };
+
keyboard_state keyboard;
sdl_keyboard_device(running_machine &machine, std::string &&name, std::string &&id, input_module &module) :
@@ -483,6 +492,13 @@ private:
int last_y;
public:
+ // state information for a mouse
+ struct mouse_state
+ {
+ int32_t lX, lY;
+ int32_t buttons[MAX_BUTTONS];
+ };
+
mouse_state mouse;
sdl_mouse_device(running_machine &machine, std::string &&name, std::string &&id, input_module &module) :
@@ -602,40 +618,40 @@ public:
// sdl_joystick_device
//============================================================
-// state information for a joystick
-struct sdl_joystick_state
-{
- int32_t axes[MAX_AXES];
- int32_t buttons[MAX_BUTTONS];
- int32_t hatsU[MAX_HATS], hatsD[MAX_HATS], hatsL[MAX_HATS], hatsR[MAX_HATS];
- int32_t balls[MAX_AXES];
-};
-
-struct sdl_api_state
-{
- SDL_Joystick *device;
- SDL_Haptic *hapdevice;
- SDL_JoystickID joystick_id;
-};
-
class sdl_joystick_device : public sdl_device
{
public:
+ // state information for a joystick
+ struct sdl_joystick_state
+ {
+ int32_t axes[MAX_AXES];
+ int32_t buttons[MAX_BUTTONS];
+ int32_t hatsU[MAX_HATS], hatsD[MAX_HATS], hatsL[MAX_HATS], hatsR[MAX_HATS];
+ int32_t balls[MAX_AXES];
+ };
+
+ struct sdl_api_state
+ {
+ SDL_Joystick *device = nullptr;
+ SDL_Haptic *hapdevice = nullptr;
+ SDL_JoystickID joystick_id;
+ std::optional<std::string> serial;
+ };
+
sdl_joystick_state joystick;
sdl_api_state sdl_state;
sdl_joystick_device(running_machine &machine, std::string &&name, std::string &&id, input_module &module) :
sdl_device(machine, std::move(name), std::move(id), DEVICE_CLASS_JOYSTICK, module),
- joystick({{0}}),
- sdl_state({ nullptr })
+ joystick({{0}})
{
}
~sdl_joystick_device()
{
- if (sdl_state.device != nullptr)
+ if (sdl_state.device)
{
- if (sdl_state.hapdevice != nullptr)
+ if (sdl_state.hapdevice)
{
SDL_HapticClose(sdl_state.hapdevice);
sdl_state.hapdevice = nullptr;
@@ -665,38 +681,10 @@ public:
break;
case SDL_JOYHATMOTION:
- if (sdlevent.jhat.value & SDL_HAT_UP)
- {
- joystick.hatsU[sdlevent.jhat.hat] = 0x80;
- }
- else
- {
- joystick.hatsU[sdlevent.jhat.hat] = 0;
- }
- if (sdlevent.jhat.value & SDL_HAT_DOWN)
- {
- joystick.hatsD[sdlevent.jhat.hat] = 0x80;
- }
- else
- {
- joystick.hatsD[sdlevent.jhat.hat] = 0;
- }
- if (sdlevent.jhat.value & SDL_HAT_LEFT)
- {
- joystick.hatsL[sdlevent.jhat.hat] = 0x80;
- }
- else
- {
- joystick.hatsL[sdlevent.jhat.hat] = 0;
- }
- if (sdlevent.jhat.value & SDL_HAT_RIGHT)
- {
- joystick.hatsR[sdlevent.jhat.hat] = 0x80;
- }
- else
- {
- joystick.hatsR[sdlevent.jhat.hat] = 0;
- }
+ joystick.hatsU[sdlevent.jhat.hat] = (sdlevent.jhat.value & SDL_HAT_UP) ? 0x80 : 0;
+ joystick.hatsD[sdlevent.jhat.hat] = (sdlevent.jhat.value & SDL_HAT_DOWN) ? 0x80 : 0;
+ joystick.hatsL[sdlevent.jhat.hat] = (sdlevent.jhat.value & SDL_HAT_LEFT) ? 0x80 : 0;
+ joystick.hatsR[sdlevent.jhat.hat] = (sdlevent.jhat.value & SDL_HAT_RIGHT) ? 0x80 : 0;
break;
case SDL_JOYBUTTONDOWN:
@@ -704,6 +692,21 @@ public:
if (sdlevent.jbutton.button < MAX_BUTTONS)
joystick.buttons[sdlevent.jbutton.button] = (sdlevent.jbutton.state == SDL_PRESSED) ? 0x80 : 0;
break;
+
+ case SDL_JOYDEVICEREMOVED:
+ osd_printf_verbose("Joystick: %s [GUID %s] disconnected\n", name(), id());
+ reset();
+ if (sdl_state.device)
+ {
+ if (sdl_state.hapdevice)
+ {
+ SDL_HapticClose(sdl_state.hapdevice);
+ sdl_state.hapdevice = nullptr;
+ }
+ SDL_JoystickClose(sdl_state.device);
+ sdl_state.device = nullptr;
+ }
+ break;
}
}
};
@@ -786,9 +789,10 @@ public:
void handle_event(SDL_Event &sdlevent) override
{
// By default dispatch event to every device
- devicelist()->for_each_device([&sdlevent](auto device) {
- downcast<sdl_device*>(device)->queue_events(&sdlevent, 1);
- });
+ devicelist().for_each_device(
+ [&sdlevent](auto device) {
+ downcast<sdl_device*>(device)->queue_events(&sdlevent, 1);
+ });
}
};
@@ -810,13 +814,12 @@ public:
{
sdl_input_module::input_init(machine);
- static int event_types[] = {
- static_cast<int>(SDL_KEYDOWN),
- static_cast<int>(SDL_KEYUP),
- static_cast<int>(SDL_TEXTINPUT)
- };
+ static int const event_types[] = {
+ int(SDL_KEYDOWN),
+ int(SDL_KEYUP),
+ int(SDL_TEXTINPUT) };
- sdl_event_manager::instance().subscribe(event_types, std::size(event_types), this);
+ sdl_event_manager::instance().subscribe(event_types, this);
// Read our keymap and store a pointer to our table
m_key_trans_table = sdlinput_read_keymap(machine);
@@ -826,7 +829,7 @@ public:
osd_printf_verbose("Keyboard: Start initialization\n");
// SDL only has 1 keyboard add it now
- auto &devinfo = devicelist()->create_device<sdl_keyboard_device>(machine, "System keyboard", "System keyboard", *this);
+ auto &devinfo = devicelist().create_device<sdl_keyboard_device>(machine, "System keyboard", "System keyboard", *this);
// populate it
for (int keynum = 0; local_table[keynum].mame_key != ITEM_ID_INVALID; keynum++)
@@ -942,19 +945,18 @@ public:
{
sdl_input_module::input_init(machine);
- static int event_types[] = {
- static_cast<int>(SDL_MOUSEMOTION),
- static_cast<int>(SDL_MOUSEBUTTONDOWN),
- static_cast<int>(SDL_MOUSEBUTTONUP),
- static_cast<int>(SDL_MOUSEWHEEL)
- };
+ static int const event_types[] = {
+ int(SDL_MOUSEMOTION),
+ int(SDL_MOUSEBUTTONDOWN),
+ int(SDL_MOUSEBUTTONUP),
+ int(SDL_MOUSEWHEEL) };
- sdl_event_manager::instance().subscribe(event_types, std::size(event_types), this);
+ sdl_event_manager::instance().subscribe(event_types, this);
osd_printf_verbose("Mouse: Start initialization\n");
// SDL currently only supports one mouse
- auto &devinfo = devicelist()->create_device<sdl_mouse_device>(machine, "System mouse", "System mouse", *this);
+ auto &devinfo = devicelist().create_device<sdl_mouse_device>(machine, "System mouse", "System mouse", *this);
// add the axes
devinfo.device()->add_item("X", ITEM_ID_XAXIS, generic_axis_get_state<std::int32_t>, &devinfo.mouse.lX);
@@ -981,12 +983,15 @@ void devmap_register(device_map_t &devmap, int physical_idx, const std::string &
auto entry = std::find_if(
std::begin(devmap.map),
std::end(devmap.map),
- [&name] (auto &item) { return (item.name == name) && (item.physical < 0); });
+ [&name] (auto const &item) { return (item.name == name) && (item.physical < 0); });
// If we didn't find it by name, find the first free slot
if (entry == std::end(devmap.map))
{
- entry = std::find_if(std::begin(devmap.map), std::end(devmap.map), [] (auto &item) { return item.name.empty(); });
+ entry = std::find_if(
+ std::begin(devmap.map),
+ std::end(devmap.map),
+ [] (auto const &item) { return item.name.empty(); });
}
if (entry != std::end(devmap.map))
@@ -1054,13 +1059,12 @@ public:
char tempname[512];
- m_sixaxis_mode = downcast<const sdl_options*>(options())->sixaxis();
+ m_sixaxis_mode = downcast<const sdl_options *>(options())->sixaxis();
devmap_init(machine, &m_joy_map, SDLOPTION_JOYINDEX, 8, "Joystick mapping");
osd_printf_verbose("Joystick: Start initialization\n");
- int physical_stick;
- for (physical_stick = 0; physical_stick < SDL_NumJoysticks(); physical_stick++)
+ for (int physical_stick = 0; physical_stick < SDL_NumJoysticks(); physical_stick++)
{
std::string joy_name = remove_spaces(SDL_JoystickNameForIndex(physical_stick));
devmap_register(m_joy_map, physical_stick, joy_name);
@@ -1073,28 +1077,40 @@ public:
if (!devinfo)
continue;
- physical_stick = m_joy_map.map[stick].physical;
- SDL_Joystick *joy = SDL_JoystickOpen(physical_stick);
+ int const physical_stick = m_joy_map.map[stick].physical;
+ SDL_Joystick *const joy = SDL_JoystickOpen(physical_stick);
SDL_JoystickGUID guid = SDL_JoystickGetGUID(joy);
char guid_str[256];
guid_str[0] = '\0';
- SDL_JoystickGetGUIDString(guid, guid_str, sizeof(guid_str)-1);
+ SDL_JoystickGetGUIDString(guid, guid_str, sizeof(guid_str) - 1);
devinfo->sdl_state.device = joy;
devinfo->sdl_state.joystick_id = SDL_JoystickInstanceID(joy);
devinfo->sdl_state.hapdevice = SDL_HapticOpenFromJoystick(joy);
-
- osd_printf_verbose("Joystick: %s [GUID %s]\n", SDL_JoystickNameForIndex(physical_stick), guid_str);
- osd_printf_verbose("Joystick: ... %d axes, %d buttons %d hats %d balls\n", SDL_JoystickNumAxes(joy), SDL_JoystickNumButtons(joy), SDL_JoystickNumHats(joy), SDL_JoystickNumBalls(joy));
+#if SDL_VERSION_ATLEAST(2, 0, 14)
+ char const *const serial = SDL_JoystickGetSerial(joy);
+ if (serial)
+ devinfo->sdl_state.serial = serial;
+ else
+#endif // SDL_VERSION_ATLEAST(2, 0, 14)
+ devinfo->sdl_state.serial = std::nullopt;
+
+ osd_printf_verbose("Joystick: %s [GUID %s] Vendor ID %04X, Product ID %04X, Revision %04X\n",
+ SDL_JoystickNameForIndex(physical_stick),
+ guid_str,
+ SDL_JoystickGetVendor(joy),
+ SDL_JoystickGetProduct(joy),
+ SDL_JoystickGetProductVersion(joy));
+ osd_printf_verbose("Joystick: ... %d axes, %d buttons %d hats %d balls\n",
+ SDL_JoystickNumAxes(joy),
+ SDL_JoystickNumButtons(joy),
+ SDL_JoystickNumHats(joy),
+ SDL_JoystickNumBalls(joy));
osd_printf_verbose("Joystick: ... Physical id %d mapped to logical id %d\n", physical_stick, stick + 1);
- if (devinfo->sdl_state.hapdevice != nullptr)
- {
+ if (devinfo->sdl_state.hapdevice)
osd_printf_verbose("Joystick: ... Has haptic capability\n");
- }
else
- {
osd_printf_verbose("Joystick: ... Does not have haptic capability\n");
- }
// loop over all axes
for (int axis = 0; axis < SDL_JoystickNumAxes(joy); axis++)
@@ -1108,7 +1124,7 @@ public:
else
itemid = ITEM_ID_OTHER_AXIS_ABSOLUTE;
- snprintf(tempname, sizeof(tempname), "A%d %s", axis, devinfo->name().c_str());
+ snprintf(tempname, sizeof(tempname), "A%d", axis + 1);
devinfo->device()->add_item(tempname, itemid, generic_axis_get_state<std::int32_t>, &devinfo->joystick.axes[axis]);
}
@@ -1128,7 +1144,7 @@ public:
else
itemid = ITEM_ID_OTHER_SWITCH;
- snprintf(tempname, sizeof(tempname), "button %d", button);
+ snprintf(tempname, sizeof(tempname), "Button %d", button + 1);
devinfo->device()->add_item(tempname, itemid, generic_button_get_state<std::int32_t>, &devinfo->joystick.buttons[button]);
}
@@ -1137,16 +1153,16 @@ public:
{
input_item_id itemid;
- snprintf(tempname, sizeof(tempname), "hat %d Up", hat);
+ snprintf(tempname, sizeof(tempname), "Hat %d Up", hat + 1);
itemid = (input_item_id)((hat < INPUT_MAX_HATS) ? ITEM_ID_HAT1UP + 4 * hat : ITEM_ID_OTHER_SWITCH);
devinfo->device()->add_item(tempname, itemid, generic_button_get_state<std::int32_t>, &devinfo->joystick.hatsU[hat]);
- snprintf(tempname, sizeof(tempname), "hat %d Down", hat);
+ snprintf(tempname, sizeof(tempname), "Hat %d Down", hat + 1);
itemid = (input_item_id)((hat < INPUT_MAX_HATS) ? ITEM_ID_HAT1DOWN + 4 * hat : ITEM_ID_OTHER_SWITCH);
devinfo->device()->add_item(tempname, itemid, generic_button_get_state<std::int32_t>, &devinfo->joystick.hatsD[hat]);
- snprintf(tempname, sizeof(tempname), "hat %d Left", hat);
+ snprintf(tempname, sizeof(tempname), "Hat %d Left", hat + 1);
itemid = (input_item_id)((hat < INPUT_MAX_HATS) ? ITEM_ID_HAT1LEFT + 4 * hat : ITEM_ID_OTHER_SWITCH);
devinfo->device()->add_item(tempname, itemid, generic_button_get_state<std::int32_t>, &devinfo->joystick.hatsL[hat]);
- snprintf(tempname, sizeof(tempname), "hat %d Right", hat);
+ snprintf(tempname, sizeof(tempname), "Hat %d Right", hat + 1);
itemid = (input_item_id)((hat < INPUT_MAX_HATS) ? ITEM_ID_HAT1RIGHT + 4 * hat : ITEM_ID_OTHER_SWITCH);
devinfo->device()->add_item(tempname, itemid, generic_button_get_state<std::int32_t>, &devinfo->joystick.hatsR[hat]);
}
@@ -1161,46 +1177,90 @@ public:
else
itemid = ITEM_ID_OTHER_AXIS_RELATIVE;
- snprintf(tempname, sizeof(tempname), "R%d %s", ball * 2, devinfo->name().c_str());
+ snprintf(tempname, sizeof(tempname), "R%d X", ball + 1);
devinfo->device()->add_item(tempname, (input_item_id)itemid, generic_axis_get_state<std::int32_t>, &devinfo->joystick.balls[ball * 2]);
- snprintf(tempname, sizeof(tempname), "R%d %s", ball * 2 + 1, devinfo->name().c_str());
+ snprintf(tempname, sizeof(tempname), "R%d Y", ball + 1);
devinfo->device()->add_item(tempname, (input_item_id)(itemid + 1), generic_axis_get_state<std::int32_t>, &devinfo->joystick.balls[ball * 2 + 1]);
}
}
- static int event_types[] = {
- static_cast<int>(SDL_JOYAXISMOTION),
- static_cast<int>(SDL_JOYBALLMOTION),
- static_cast<int>(SDL_JOYHATMOTION),
- static_cast<int>(SDL_JOYBUTTONDOWN),
- static_cast<int>(SDL_JOYBUTTONUP)
- };
+ static int const event_types[] = {
+ int(SDL_JOYAXISMOTION),
+ int(SDL_JOYBALLMOTION),
+ int(SDL_JOYHATMOTION),
+ int(SDL_JOYBUTTONDOWN),
+ int(SDL_JOYBUTTONUP),
+ int(SDL_JOYDEVICEADDED),
+ int(SDL_JOYDEVICEREMOVED) };
- sdl_event_manager::instance().subscribe(event_types, std::size(event_types), this);
+ sdl_event_manager::instance().subscribe(event_types, this);
osd_printf_verbose("Joystick: End initialization\n");
}
virtual void handle_event(SDL_Event &sdlevent) override
{
- // Figure out which joystick this event id destined for
- auto target_device = std::find_if(
- devicelist()->begin(),
- devicelist()->end(),
- [&sdlevent] (auto &device)
+ if (SDL_JOYDEVICEADDED == sdlevent.type)
+ {
+ SDL_Joystick *const joy = SDL_JoystickOpen(sdlevent.jdevice.which);
+ if (joy)
+ {
+ SDL_JoystickGUID guid = SDL_JoystickGetGUID(joy);
+ char guid_str[256];
+ guid_str[0] = '\0';
+ SDL_JoystickGetGUIDString(guid, guid_str, sizeof(guid_str) - 1);
+ char const *serial = nullptr;
+#if SDL_VERSION_ATLEAST(2, 0, 14)
+ serial = SDL_JoystickGetSerial(joy);
+#endif
+ auto target_device = std::find_if(
+ devicelist().begin(),
+ devicelist().end(),
+ [&guid_str, &serial] (auto const &device)
+ {
+ auto &devinfo = downcast<sdl_joystick_device &>(*device);
+ return
+ !devinfo.sdl_state.device &&
+ (devinfo.id() == guid_str) &&
+ ((serial && devinfo.sdl_state.serial && (*devinfo.sdl_state.serial == serial)) || (!serial && !devinfo.sdl_state.serial));
+ });
+ if (devicelist().end() != target_device)
{
- std::unique_ptr<device_info> &ptr = device;
- return downcast<sdl_joystick_device*>(ptr.get())->sdl_state.joystick_id == sdlevent.jdevice.which;
- });
-
- // If we find a matching joystick, dispatch the event to the joystick
- if (target_device != devicelist()->end())
+ auto &devinfo = downcast<sdl_joystick_device &>(**target_device);
+ devinfo.sdl_state.device = joy;
+ devinfo.sdl_state.joystick_id = SDL_JoystickInstanceID(joy);
+ devinfo.sdl_state.hapdevice = SDL_HapticOpenFromJoystick(joy);
+ osd_printf_verbose("Joystick: %s [GUID %s] reconnected\n", devinfo.name(), guid_str);
+ }
+ else
+ {
+ SDL_JoystickClose(joy);
+ }
+ }
+ }
+ else
{
- downcast<sdl_joystick_device*>((*target_device).get())->queue_events(&sdlevent, 1);
+ // Figure out which joystick this event id destined for
+ sdl_joystick_device *const target_device = find_joystick(sdlevent.jdevice.which); // FIXME: this depends on SDL_JoystickID being the same size as Sint32
+
+ // If we find a matching joystick, dispatch the event to the joystick
+ if (target_device)
+ target_device->queue_events(&sdlevent, 1);
}
}
private:
+ sdl_joystick_device *find_joystick(SDL_JoystickID instance)
+ {
+ for (auto &ptr : devicelist())
+ {
+ sdl_joystick_device *const device = downcast<sdl_joystick_device *>(ptr.get());
+ if (device->sdl_state.device && (device->sdl_state.joystick_id == instance))
+ return device;
+ }
+ return nullptr;
+ }
+
sdl_joystick_device *create_joystick_device(running_machine &machine, device_map_t *devmap, int index, input_device_class devclass)
{
char tempname[20];
@@ -1215,16 +1275,16 @@ private:
{
snprintf(tempname, std::size(tempname), "NC%d", index);
m_sixaxis_mode
- ? devicelist()->create_device<sdl_sixaxis_joystick_device>(machine, tempname, guid_str, *this)
- : devicelist()->create_device<sdl_joystick_device>(machine, tempname, guid_str, *this);
+ ? devicelist().create_device<sdl_sixaxis_joystick_device>(machine, tempname, guid_str, *this)
+ : devicelist().create_device<sdl_joystick_device>(machine, tempname, guid_str, *this);
}
return nullptr;
}
return m_sixaxis_mode
- ? &devicelist()->create_device<sdl_sixaxis_joystick_device>(machine, std::string(devmap->map[index].name), guid_str, *this)
- : &devicelist()->create_device<sdl_joystick_device>(machine, std::string(devmap->map[index].name), guid_str, *this);
+ ? &devicelist().create_device<sdl_sixaxis_joystick_device>(machine, std::string(devmap->map[index].name), guid_str, *this)
+ : &devicelist().create_device<sdl_joystick_device>(machine, std::string(devmap->map[index].name), guid_str, *this);
}
};
diff --git a/src/osd/modules/input/input_sdlcommon.cpp b/src/osd/modules/input/input_sdlcommon.cpp
index 92e3653e4d1..1f84e28f2f6 100644
--- a/src/osd/modules/input/input_sdlcommon.cpp
+++ b/src/osd/modules/input/input_sdlcommon.cpp
@@ -267,7 +267,7 @@ void sdl_osd_interface::release_keys()
{
auto keybd = dynamic_cast<input_module_base*>(m_keyboard_input);
if (keybd != nullptr)
- keybd->devicelist()->reset_devices();
+ keybd->devicelist().reset_devices();
}
bool sdl_osd_interface::should_hide_mouse()
diff --git a/src/osd/modules/input/input_sdlcommon.h b/src/osd/modules/input/input_sdlcommon.h
index 030a8ca4bd7..74b12a875ba 100644
--- a/src/osd/modules/input/input_sdlcommon.h
+++ b/src/osd/modules/input/input_sdlcommon.h
@@ -8,40 +8,17 @@
//
//============================================================
-#ifndef INPUT_SDLCOMMON_H_
-#define INPUT_SDLCOMMON_H_
+#ifndef MAME_OSD_INPUT_INPUT_SDLCOMMON_H
+#define MAME_OSD_INPUT_INPUT_SDLCOMMON_H
+
+#pragma once
-#include <unordered_map>
#include <algorithm>
+#include <unordered_map>
#define MAX_DEVMAP_ENTRIES 16
#define SDL_MODULE_EVENT_BUFFER_SIZE 5
-// state information for a keyboard
-struct keyboard_state
-{
- int32_t state[0x3ff]; // must be int32_t!
- int8_t oldkey[MAX_KEYS];
- int8_t currkey[MAX_KEYS];
-};
-
-// state information for a mouse
-struct mouse_state
-{
- int32_t lX, lY;
- int32_t buttons[MAX_BUTTONS];
-};
-
-
-// state information for a joystick; DirectInput state must be first element
-struct joystick_state
-{
- SDL_Joystick *device;
- int32_t axes[MAX_AXES];
- int32_t buttons[MAX_BUTTONS];
- int32_t hatsU[MAX_HATS], hatsD[MAX_HATS], hatsL[MAX_HATS], hatsR[MAX_HATS];
- int32_t balls[MAX_AXES];
-};
struct device_map_t
{
@@ -79,15 +56,14 @@ public:
{
}
- void subscribe(int* event_types, int num_event_types, TSubscriber *subscriber)
+ template <size_t N>
+ void subscribe(int const (&event_types)[N], TSubscriber *subscriber)
{
std::lock_guard<std::mutex> scope_lock(m_lock);
// Add the subscription
- for (int i = 0; i < num_event_types; i++)
- {
- m_subscription_index.emplace(event_types[i], subscriber);
- }
+ for (int i : event_types)
+ m_subscription_index.emplace(i, subscriber);
}
void unsubscribe(TSubscriber *subscriber)
@@ -199,4 +175,4 @@ static inline void devmap_init(running_machine &machine, device_map_t *devmap, c
}
}
-#endif
+#endif // MAME_OSD_INPUT_INPUT_SDLCOMMON_H
diff --git a/src/osd/modules/input/input_win32.cpp b/src/osd/modules/input/input_win32.cpp
index ff154140f7f..a02b2ee426e 100644
--- a/src/osd/modules/input/input_win32.cpp
+++ b/src/osd/modules/input/input_win32.cpp
@@ -74,7 +74,7 @@ public:
virtual void input_init(running_machine &machine) override
{
// Add a single win32 keyboard device that we'll monitor using Win32
- auto &devinfo = devicelist()->create_device<win32_keyboard_device>(machine, "Win32 Keyboard 1", "Win32 Keyboard 1", *this);
+ auto &devinfo = devicelist().create_device<win32_keyboard_device>(machine, "Win32 Keyboard 1", "Win32 Keyboard 1", *this);
keyboard_trans_table &table = keyboard_trans_table::instance();
@@ -106,7 +106,7 @@ public:
case INPUT_EVENT_KEYDOWN:
case INPUT_EVENT_KEYUP:
args = static_cast<KeyPressEventArgs*>(eventdata);
- devicelist()->for_each_device([args](auto device)
+ devicelist().for_each_device([args](auto device)
{
auto keyboard = dynamic_cast<win32_keyboard_device*>(device);
if (keyboard != nullptr)
@@ -206,7 +206,7 @@ public:
return;
// allocate a device
- auto &devinfo = devicelist()->create_device<win32_mouse_device>(machine, "Win32 Mouse 1", "Win32 Mouse 1", *this);
+ auto &devinfo = devicelist().create_device<win32_mouse_device>(machine, "Win32 Mouse 1", "Win32 Mouse 1", *this);
// populate the axes
for (int axisnum = 0; axisnum < 2; axisnum++)
@@ -235,7 +235,7 @@ public:
return false;
auto args = static_cast<MouseButtonEventArgs*>(eventdata);
- devicelist()->for_each_device([args](auto device)
+ devicelist().for_each_device([args](auto device)
{
auto mouse = dynamic_cast<win32_mouse_device*>(device);
if (mouse != nullptr)
@@ -268,7 +268,7 @@ public:
m_lightgun_shared_axis_mode = downcast<windows_options &>(machine.options()).dual_lightgun();
// Since we are about to be added to the list, the current size is the zero-based index of where we will be
- m_gun_index = downcast<wininput_module&>(module).devicelist()->size();
+ m_gun_index = downcast<wininput_module&>(module).devicelist().size();
}
void poll() override
@@ -391,7 +391,7 @@ public:
static const char *const gun_names[] = { "Win32 Gun 1", "Win32 Gun 2" };
// allocate a device
- auto &devinfo = devicelist()->create_device<win32_lightgun_device>(machine, gun_names[gunnum], gun_names[gunnum], *this);
+ auto &devinfo = devicelist().create_device<win32_lightgun_device>(machine, gun_names[gunnum], gun_names[gunnum], *this);
// populate the axes
for (int axisnum = 0; axisnum < 2; axisnum++)
@@ -421,7 +421,7 @@ public:
return false;
auto args = static_cast<MouseButtonEventArgs*>(eventdata);
- devicelist()->for_each_device([args](auto device)
+ devicelist().for_each_device([args](auto device)
{
auto lightgun = dynamic_cast<win32_lightgun_device*>(device);
if (lightgun != nullptr)
diff --git a/src/osd/modules/input/input_windows.cpp b/src/osd/modules/input/input_windows.cpp
index bbe109eb53a..4415e71f3a4 100644
--- a/src/osd/modules/input/input_windows.cpp
+++ b/src/osd/modules/input/input_windows.cpp
@@ -27,39 +27,39 @@
bool windows_osd_interface::should_hide_mouse() const
{
bool hidemouse = false;
- wininput_module* mod;
+ wininput_module *mod;
- mod = dynamic_cast<wininput_module*>(m_keyboard_input);
+ mod = dynamic_cast<wininput_module *>(m_keyboard_input);
if (mod) hidemouse |= mod->should_hide_mouse();
- mod = dynamic_cast<wininput_module*>(m_mouse_input);
+ mod = dynamic_cast<wininput_module *>(m_mouse_input);
if (mod) hidemouse |= mod->should_hide_mouse();
- mod = dynamic_cast<wininput_module*>(m_lightgun_input);
+ mod = dynamic_cast<wininput_module *>(m_lightgun_input);
if (mod) hidemouse |= mod->should_hide_mouse();
- mod = dynamic_cast<wininput_module*>(m_joystick_input);
+ mod = dynamic_cast<wininput_module *>(m_joystick_input);
if (mod) hidemouse |= mod->should_hide_mouse();
return hidemouse;
}
-bool windows_osd_interface::handle_input_event(input_event eventid, void* eventdata) const
+bool windows_osd_interface::handle_input_event(input_event eventid, void *eventdata) const
{
bool handled = false;
- wininput_module* mod;
+ wininput_module *mod;
- mod = dynamic_cast<wininput_module*>(m_keyboard_input);
+ mod = dynamic_cast<wininput_module *>(m_keyboard_input);
if (mod) handled |= mod->handle_input_event(eventid, eventdata);
- mod = dynamic_cast<wininput_module*>(m_mouse_input);
+ mod = dynamic_cast<wininput_module *>(m_mouse_input);
if (mod) handled |= mod->handle_input_event(eventid, eventdata);
- mod = dynamic_cast<wininput_module*>(m_lightgun_input);
+ mod = dynamic_cast<wininput_module *>(m_lightgun_input);
if (mod) handled |= mod->handle_input_event(eventid, eventdata);
- mod = dynamic_cast<wininput_module*>(m_joystick_input);
+ mod = dynamic_cast<wininput_module *>(m_joystick_input);
if (mod) handled |= mod->handle_input_event(eventid, eventdata);
return handled;
diff --git a/src/osd/modules/input/input_x11.cpp b/src/osd/modules/input/input_x11.cpp
index e7481d6470e..0657e99fd2d 100644
--- a/src/osd/modules/input/input_x11.cpp
+++ b/src/osd/modules/input/input_x11.cpp
@@ -538,9 +538,9 @@ public:
osd_printf_verbose("Device %i: Registered %i events.\n", static_cast<int>(info->id), events_registered);
// register ourself to handle events from event manager
- int event_types[] = { motion_type, button_press_type, button_release_type };
+ int const event_types[] = { motion_type, button_press_type, button_release_type };
osd_printf_verbose("Events types to register: motion:%d, press:%d, release:%d\n", motion_type, button_press_type, button_release_type);
- x11_event_manager::instance().subscribe(event_types, std::size(event_types), this);
+ x11_event_manager::instance().subscribe(event_types, this);
}
osd_printf_verbose("Lightgun: End initialization\n");
@@ -582,14 +582,14 @@ public:
}
// Figure out which lightgun this event id destined for
- auto target_device = std::find_if(devicelist()->begin(), devicelist()->end(), [deviceid](auto &device)
+ auto target_device = std::find_if(devicelist().begin(), devicelist().end(), [deviceid](auto &device)
{
std::unique_ptr<device_info> &ptr = device;
return downcast<x11_input_device*>(ptr.get())->x11_state.deviceid == deviceid;
});
// If we find a matching lightgun, dispatch the event to the lightgun
- if (target_device != devicelist()->end())
+ if (target_device != devicelist().end())
{
downcast<x11_input_device*>((*target_device).get())->queue_events(&xevent, 1);
}
@@ -604,7 +604,7 @@ private:
{
char tempname[20];
snprintf(tempname, std::size(tempname), "NC%d", index);
- return &devicelist()->create_device<x11_lightgun_device>(machine, tempname, tempname, *this);
+ return &devicelist().create_device<x11_lightgun_device>(machine, tempname, tempname, *this);
}
else
{
@@ -612,7 +612,7 @@ private:
}
}
- return &devicelist()->create_device<x11_lightgun_device>(machine, std::string(m_lightgun_map.map[index].name), std::string(m_lightgun_map.map[index].name), *this);
+ return &devicelist().create_device<x11_lightgun_device>(machine, std::string(m_lightgun_map.map[index].name), std::string(m_lightgun_map.map[index].name), *this);
}
void add_lightgun_buttons(XAnyClassPtr first_info_class, int num_classes, x11_lightgun_device &devinfo) const
diff --git a/src/osd/modules/input/input_xinput.cpp b/src/osd/modules/input/input_xinput.cpp
index dd4c418aacd..152e16b4e81 100644
--- a/src/osd/modules/input/input_xinput.cpp
+++ b/src/osd/modules/input/input_xinput.cpp
@@ -186,7 +186,7 @@ xinput_joystick_device * xinput_api_helper::create_xinput_device(running_machine
snprintf(device_name, sizeof(device_name), "XInput Player %u", index + 1);
// allocate the device object
- auto &devinfo = module.devicelist()->create_device<xinput_joystick_device>(machine, device_name, device_name, module, shared_from_this());
+ auto &devinfo = module.devicelist().create_device<xinput_joystick_device>(machine, device_name, device_name, module, shared_from_this());
// Set the player ID
devinfo.xinput_state.player_index = index;
@@ -201,12 +201,12 @@ xinput_joystick_device * xinput_api_helper::create_xinput_device(running_machine
// xinput_joystick_device
//============================================================
-xinput_joystick_device::xinput_joystick_device(running_machine &machine, std::string &&name, std::string &&id, input_module &module, std::shared_ptr<xinput_api_helper> helper)
- : device_info(machine, std::string(name), std::string(id), DEVICE_CLASS_JOYSTICK, module),
- gamepad({{0}}),
- xinput_state({0}),
- m_xinput_helper(helper),
- m_configured(false)
+xinput_joystick_device::xinput_joystick_device(running_machine &machine, std::string &&name, std::string &&id, input_module &module, std::shared_ptr<xinput_api_helper> helper) :
+ device_info(machine, std::string(name), std::string(id), DEVICE_CLASS_JOYSTICK, module),
+ gamepad({ { 0 } }),
+ xinput_state({ 0 }),
+ m_xinput_helper(helper),
+ m_configured(false)
{
}
diff --git a/src/osd/modules/lib/osdlib.h b/src/osd/modules/lib/osdlib.h
index 4a06b7052f5..8ca4762a111 100644
--- a/src/osd/modules/lib/osdlib.h
+++ b/src/osd/modules/lib/osdlib.h
@@ -163,7 +163,7 @@ public:
static ptr open(std::vector<std::string> &&libraries);
- virtual ~dynamic_module() { };
+ virtual ~dynamic_module() { }
template <typename T>
typename std::enable_if_t<std::is_pointer_v<T>, T> bind(char const *symbol)
diff --git a/src/osd/modules/lib/osdobj_common.cpp b/src/osd/modules/lib/osdobj_common.cpp
index be06da29767..52ddca76ca0 100644
--- a/src/osd/modules/lib/osdobj_common.cpp
+++ b/src/osd/modules/lib/osdobj_common.cpp
@@ -159,7 +159,7 @@ const options_entry osd_options::s_option_entries[] =
{ 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_LUT, "lut-default.png", OPTION_STRING, "LUT texture name" },
{ OSDOPTION_BGFX_AVI_NAME, OSDOPTVAL_AUTO, OPTION_STRING, "filename for BGFX output logging" },
// End of list
diff --git a/src/osd/modules/osdhelper.h b/src/osd/modules/osdhelper.h
index 093c392e249..85cbfc906c1 100644
--- a/src/osd/modules/osdhelper.h
+++ b/src/osd/modules/osdhelper.h
@@ -20,8 +20,8 @@ public:
constexpr int width() const { return m_w; }
constexpr int height() const { return m_h; }
- constexpr bool operator!=(const osd_dim &other) { return (m_w != other.width()) || (m_h != other.height()); }
- constexpr bool operator==(const osd_dim &other) { return (m_w == other.width()) && (m_h == other.height()); }
+ constexpr bool operator!=(const osd_dim &other) const { return (m_w != other.width()) || (m_h != other.height()); }
+ constexpr bool operator==(const osd_dim &other) const { return (m_w == other.width()) && (m_h == other.height()); }
private:
int m_w;
diff --git a/src/osd/modules/osdwindow.h b/src/osd/modules/osdwindow.h
index 730e8a67894..9cd05c29d17 100644
--- a/src/osd/modules/osdwindow.h
+++ b/src/osd/modules/osdwindow.h
@@ -225,10 +225,10 @@ public:
virtual void add_audio_to_recording(const int16_t *buffer, int samples_this_frame) { }
virtual std::vector<ui::menu_item> get_slider_list() { return m_sliders; }
virtual int draw(const int update) = 0;
- virtual int xy_to_render_target(const int x, const int y, int *xt, int *yt) { return 0; };
- virtual void save() { };
- virtual void record() { };
- virtual void toggle_fsfx() { };
+ virtual int xy_to_render_target(const int x, const int y, int *xt, int *yt) { return 0; }
+ virtual void save() { }
+ virtual void record() { }
+ virtual void toggle_fsfx() { }
virtual bool sliders_dirty() { return m_sliders_dirty; }
static std::unique_ptr<osd_renderer> make_for_type(int mode, std::shared_ptr<osd_window> window, int extra_flags = FLAG_NONE);
diff --git a/src/osd/modules/output/output_module.h b/src/osd/modules/output/output_module.h
index 9046fda3252..36194e356ea 100644
--- a/src/osd/modules/output/output_module.h
+++ b/src/osd/modules/output/output_module.h
@@ -29,7 +29,7 @@ public:
virtual void notify(const char *outname, int32_t value) = 0;
- void set_machine(running_machine *machine) { m_machine = machine; };
+ void set_machine(running_machine *machine) { m_machine = machine; }
running_machine &machine() const { return *m_machine; }
private:
running_machine *m_machine;
diff --git a/src/osd/modules/render/aviwrite.cpp b/src/osd/modules/render/aviwrite.cpp
index ec6ce21c543..9148244111b 100644
--- a/src/osd/modules/render/aviwrite.cpp
+++ b/src/osd/modules/render/aviwrite.cpp
@@ -10,6 +10,7 @@
#include "aviwrite.h"
#include "modules/lib/osdobj_common.h"
+#include "fileio.h"
#include "screen.h"
diff --git a/src/osd/modules/render/bgfx/chainentryreader.cpp b/src/osd/modules/render/bgfx/chainentryreader.cpp
index ba3ae1c9e67..5ac97fd1d45 100644
--- a/src/osd/modules/render/bgfx/chainentryreader.cpp
+++ b/src/osd/modules/render/bgfx/chainentryreader.cpp
@@ -9,6 +9,7 @@
#include <string>
#include "emu.h"
+#include "fileio.h"
#include "rendutil.h"
#include <modules/render/copyutil.h>
@@ -34,11 +35,11 @@ bgfx_chain_entry* chain_entry_reader::read_from_value(const Value& value, std::s
{
if (!validate_parameters(value, prefix))
{
- printf("Failed validation\n");
+ osd_printf_error("Chain entry failed validation.\n");
return nullptr;
}
- bgfx_effect* effect = chains.effects().effect(value["effect"].GetString());
+ bgfx_effect* effect = chains.effects().get_or_load_effect(chains.options(), value["effect"].GetString());
if (effect == nullptr)
{
return nullptr;
diff --git a/src/osd/modules/render/bgfx/chainmanager.cpp b/src/osd/modules/render/bgfx/chainmanager.cpp
index 73128c12a0b..afbb7a99500 100644
--- a/src/osd/modules/render/bgfx/chainmanager.cpp
+++ b/src/osd/modules/render/bgfx/chainmanager.cpp
@@ -61,11 +61,11 @@ chain_manager::~chain_manager()
void chain_manager::init_texture_converters()
{
m_converters.push_back(nullptr);
- m_converters.push_back(m_effects.effect("misc/texconv_palette16"));
- m_converters.push_back(m_effects.effect("misc/texconv_rgb32"));
+ m_converters.push_back(m_effects.get_or_load_effect(m_options, "misc/texconv_palette16"));
+ m_converters.push_back(m_effects.get_or_load_effect(m_options, "misc/texconv_rgb32"));
m_converters.push_back(nullptr);
- m_converters.push_back(m_effects.effect("misc/texconv_yuy16"));
- m_adjuster = m_effects.effect("misc/bcg_adjust");
+ m_converters.push_back(m_effects.get_or_load_effect(m_options, "misc/texconv_yuy16"));
+ m_adjuster = m_effects.get_or_load_effect(m_options, "misc/bcg_adjust");
}
void chain_manager::refresh_available_chains()
@@ -468,7 +468,10 @@ uint32_t chain_manager::update_screen_textures(uint32_t view, render_primitive *
if (texture == nullptr)
{
- bgfx_texture *texture = new bgfx_texture(full_name, dst_format, tex_width, tex_height, mem, BGFX_SAMPLER_U_CLAMP | BGFX_SAMPLER_V_CLAMP | BGFX_SAMPLER_MIN_POINT | BGFX_SAMPLER_MAG_POINT | BGFX_SAMPLER_MIP_POINT, pitch, prim.m_rowpixels, width_div_factor, width_mul_factor);
+ uint32_t flags = BGFX_SAMPLER_MIN_POINT | BGFX_SAMPLER_MAG_POINT | BGFX_SAMPLER_MIP_POINT;
+ if (!PRIMFLAG_GET_TEXWRAP(prim.m_flags))
+ flags |= BGFX_SAMPLER_U_CLAMP | BGFX_SAMPLER_V_CLAMP;
+ bgfx_texture *texture = new bgfx_texture(full_name, dst_format, tex_width, tex_height, mem, flags, pitch, prim.m_rowpixels, width_div_factor, width_mul_factor);
m_textures.add_provider(full_name, texture);
if (prim.m_prim->texture.palette)
diff --git a/src/osd/modules/render/bgfx/effect.cpp b/src/osd/modules/render/bgfx/effect.cpp
index 6707b5cfc43..06fddee66ad 100644
--- a/src/osd/modules/render/bgfx/effect.cpp
+++ b/src/osd/modules/render/bgfx/effect.cpp
@@ -25,6 +25,7 @@ bgfx_effect::bgfx_effect(uint64_t state, bgfx::ShaderHandle vertex_shader, bgfx:
delete uniforms[i];
continue;
}
+ uniforms[i]->create();
m_uniforms[uniforms[i]->name()] = uniforms[i];
}
}
diff --git a/src/osd/modules/render/bgfx/effect.h b/src/osd/modules/render/bgfx/effect.h
index 02ef9fd4f54..ca1be77c73d 100644
--- a/src/osd/modules/render/bgfx/effect.h
+++ b/src/osd/modules/render/bgfx/effect.h
@@ -26,7 +26,8 @@ public:
~bgfx_effect();
void submit(int view, uint64_t blend = 0L);
- bgfx_uniform* uniform(std::string name);
+ bgfx_uniform *uniform(std::string name);
+ bool is_valid() { return m_program_handle.idx != bgfx::kInvalidHandle; }
private:
uint64_t m_state;
diff --git a/src/osd/modules/render/bgfx/effectmanager.cpp b/src/osd/modules/render/bgfx/effectmanager.cpp
index 6462ae75f72..98bc9a72097 100644
--- a/src/osd/modules/render/bgfx/effectmanager.cpp
+++ b/src/osd/modules/render/bgfx/effectmanager.cpp
@@ -23,68 +23,79 @@
#include "effectreader.h"
#include "effect.h"
-using namespace rapidjson;
-
-effect_manager::~effect_manager()
-{
- for (std::pair<std::string, bgfx_effect*> effect : m_effects)
- {
- delete effect.second;
- }
- m_effects.clear();
-}
-
-bgfx_effect* effect_manager::effect(std::string name)
-{
- std::map<std::string, bgfx_effect*>::iterator iter = m_effects.find(name);
- if (iter != m_effects.end())
- {
- return iter->second;
- }
-
- return load_effect(name);
-}
-
-bgfx_effect* effect_manager::load_effect(std::string name)
+static bool prepare_effect_document(std::string &name, osd_options &options, rapidjson::Document &document)
{
std::string full_name = name;
- if (full_name.length() < 5 || (full_name.compare(full_name.length() - 5, 5, ".json") != 0)) {
+ if (full_name.length() < 5 || (full_name.compare(full_name.length() - 5, 5, ".json") != 0))
+ {
full_name = full_name + ".json";
}
+
std::string path;
- osd_subst_env(path, util::string_format("%s" PATH_SEPARATOR "effects" PATH_SEPARATOR, m_options.bgfx_path()));
+ osd_subst_env(path, util::string_format("%s" PATH_SEPARATOR "effects" PATH_SEPARATOR, options.bgfx_path()));
path += full_name;
bx::FileReader reader;
if (!bx::open(&reader, path.c_str()))
{
- printf("Unable to open effect file %s\n", path.c_str());
- return nullptr;
+ osd_printf_error("Unable to open effect file %s\n", path.c_str());
+ return false;
}
int32_t size (bx::getSize(&reader));
-
char* data = new char[size + 1];
bx::read(&reader, reinterpret_cast<void*>(data), size);
bx::close(&reader);
data[size] = 0;
- Document document;
- document.Parse<kParseCommentsFlag>(data);
+ document.Parse<rapidjson::kParseCommentsFlag>(data);
delete [] data;
- if (document.HasParseError()) {
- std::string error(GetParseError_En(document.GetParseError()));
- printf("Unable to parse effect %s. Errors returned:\n", path.c_str());
- printf("%s\n", error.c_str());
+ if (document.HasParseError())
+ {
+ std::string error(rapidjson::GetParseError_En(document.GetParseError()));
+ osd_printf_error("Unable to parse effect %s. Errors returned:\n", path.c_str());
+ osd_printf_error("%s\n", error.c_str());
+ return false;
+ }
+
+ return true;
+}
+
+effect_manager::~effect_manager()
+{
+ for (std::pair<std::string, bgfx_effect*> effect : m_effects)
+ {
+ delete effect.second;
+ }
+ m_effects.clear();
+}
+
+bgfx_effect* effect_manager::get_or_load_effect(osd_options &options, std::string name)
+{
+ std::map<std::string, bgfx_effect*>::iterator iter = m_effects.find(name);
+ if (iter != m_effects.end())
+ {
+ return iter->second;
+ }
+
+ return load_effect(options, name);
+}
+
+bgfx_effect* effect_manager::load_effect(osd_options &options, std::string name)
+{
+ rapidjson::Document document;
+ if (!prepare_effect_document(name, options, document))
+ {
return nullptr;
}
- bgfx_effect* effect = effect_reader::read_from_value(document, "Effect '" + name + "': ", m_shaders);
+ bgfx_effect* effect = effect_reader::read_from_value(document, "Effect '" + name + "': ", options, m_shaders);
- if (effect == nullptr) {
- printf("Unable to load effect %s\n", path.c_str());
+ if (effect == nullptr)
+ {
+ osd_printf_error("Unable to load effect %s\n", name.c_str());
return nullptr;
}
@@ -92,3 +103,14 @@ bgfx_effect* effect_manager::load_effect(std::string name)
return effect;
}
+
+bool effect_manager::validate_effect(osd_options &options, std::string name)
+{
+ rapidjson::Document document;
+ if (!prepare_effect_document(name, options, document))
+ {
+ return false;
+ }
+
+ return effect_reader::validate_value(document, "Effect '" + name + "': ", options);
+}
diff --git a/src/osd/modules/render/bgfx/effectmanager.h b/src/osd/modules/render/bgfx/effectmanager.h
index 8125741c7ff..5d8bf3f5c93 100644
--- a/src/osd/modules/render/bgfx/effectmanager.h
+++ b/src/osd/modules/render/bgfx/effectmanager.h
@@ -25,16 +25,16 @@ class bgfx_effect;
class effect_manager {
public:
- effect_manager(osd_options& options, shader_manager& shaders) : m_options(options), m_shaders(shaders) { }
+ effect_manager(shader_manager& shaders) : m_shaders(shaders) { }
~effect_manager();
// Getters
- bgfx_effect* effect(std::string name);
+ bgfx_effect* get_or_load_effect(osd_options &options, std::string name);
+ static bool validate_effect(osd_options &options, std::string name);
private:
- bgfx_effect* load_effect(std::string name);
+ bgfx_effect* load_effect(osd_options& options, std::string name);
- osd_options& m_options;
shader_manager& m_shaders;
std::map<std::string, bgfx_effect*> m_effects;
};
diff --git a/src/osd/modules/render/bgfx/effectreader.cpp b/src/osd/modules/render/bgfx/effectreader.cpp
index 3e51cb9d9dc..fd59b0bde44 100644
--- a/src/osd/modules/render/bgfx/effectreader.cpp
+++ b/src/osd/modules/render/bgfx/effectreader.cpp
@@ -23,13 +23,77 @@
#include "effectreader.h"
-bgfx_effect* effect_reader::read_from_value(const Value& value, std::string prefix, shader_manager& shaders)
+bgfx_effect *effect_reader::read_from_value(const Value& value, std::string prefix, osd_options &options, shader_manager& shaders)
{
- if (!validate_parameters(value, prefix))
+ uint64_t flags = 0;
+ std::string vertex_name;
+ std::string fragment_name;
+ bgfx::ShaderHandle vertex_shader = BGFX_INVALID_HANDLE;
+ bgfx::ShaderHandle fragment_shader = BGFX_INVALID_HANDLE;
+ std::vector<bgfx_uniform *> uniforms;
+
+ if (!get_base_effect_data(value, prefix, flags, vertex_name, fragment_name, uniforms))
+ {
+ return nullptr;
+ }
+
+ if (!get_shader_data(value, options, shaders, vertex_name, vertex_shader, fragment_name, fragment_shader))
{
+ clear_uniform_list(uniforms);
return nullptr;
}
+ bgfx_effect *effect = new bgfx_effect(flags, vertex_shader, fragment_shader, uniforms);
+ if (effect->is_valid())
+ {
+ return effect;
+ }
+
+ delete effect;
+
+ return nullptr;
+}
+
+bool effect_reader::validate_value(const Value& value, std::string prefix, osd_options &options)
+{
+ if (!validate_parameters(value, prefix))
+ {
+ return false;
+ }
+
+ uint64_t flags = 0;
+ std::string vertex_name;
+ std::string fragment_name;
+ std::vector<bgfx_uniform *> uniforms;
+
+ if (!get_base_effect_data(value, prefix, flags, vertex_name, fragment_name, uniforms))
+ {
+ return false;
+ }
+
+ if (!shader_manager::is_shader_present(options, vertex_name))
+ {
+ clear_uniform_list(uniforms);
+ return false;
+ }
+
+ if (!shader_manager::is_shader_present(options, fragment_name))
+ {
+ clear_uniform_list(uniforms);
+ return false;
+ }
+
+ return true;
+}
+
+bool effect_reader::get_base_effect_data(const Value& value, std::string &prefix, uint64_t &flags, std::string &vertex_name, std::string &fragment_name,
+ std::vector<bgfx_uniform *> &uniforms)
+{
+ if (!validate_parameters(value, prefix))
+ {
+ return false;
+ }
+
uint64_t blend = 0;
if (value.HasMember("blend"))
{
@@ -38,34 +102,21 @@ bgfx_effect* effect_reader::read_from_value(const Value& value, std::string pref
uint64_t depth = depth_reader::read_from_value(value["depth"], prefix + "depth: ");
uint64_t cull = cull_reader::read_from_value(value["cull"]);
uint64_t write = write_reader::read_from_value(value["write"]);
+ flags = blend | depth | cull | write;
- std::vector<bgfx_uniform*> uniforms;
const Value& uniform_array = value["uniforms"];
for (uint32_t i = 0; i < uniform_array.Size(); i++)
{
- bgfx_uniform* uniform = uniform_reader::read_from_value(uniform_array[i], prefix + "uniforms[" + std::to_string(i) + "]: ");
+ bgfx_uniform *uniform = uniform_reader::read_from_value(uniform_array[i], prefix + "uniforms[" + std::to_string(i) + "]: ");
if (uniform == nullptr)
{
- return nullptr;
+ return false;
}
uniforms.push_back(uniform);
}
- std::string vertex_name(value["vertex"].GetString());
- bgfx::ShaderHandle vertex_shader = shaders.shader(vertex_name);
- if (vertex_shader.idx == 0xffff)
- {
- for (bgfx_uniform* uniform : uniforms)
- {
- if (uniform != nullptr)
- {
- delete uniform;
- }
- }
- return nullptr;
- }
+ vertex_name = value["vertex"].GetString();
- std::string fragment_name("");
if (value.HasMember("fragment"))
{
fragment_name = value["fragment"].GetString();
@@ -74,20 +125,38 @@ bgfx_effect* effect_reader::read_from_value(const Value& value, std::string pref
{
fragment_name = value["pixel"].GetString();
}
- bgfx::ShaderHandle fragment_shader = shaders.shader(fragment_name);
- if (fragment_shader.idx == 0xffff)
+ else
{
- for (bgfx_uniform* uniform : uniforms)
- {
- if (uniform != nullptr)
- {
- delete uniform;
- }
- }
- return nullptr;
+ fragment_name = "";
}
- return new bgfx_effect(blend | depth | cull | write, vertex_shader, fragment_shader, uniforms);
+ return true;
+}
+
+bool effect_reader::get_shader_data(const Value& value, osd_options &options, shader_manager &shaders, std::string &vertex_name, bgfx::ShaderHandle &vertex_shader,
+ std::string &fragment_name, bgfx::ShaderHandle &fragment_shader)
+{
+ vertex_shader = shaders.load_shader(options, vertex_name);
+ if (vertex_shader.idx == bgfx::kInvalidHandle)
+ {
+ return false;
+ }
+
+ fragment_shader = shaders.load_shader(options, fragment_name);
+ if (fragment_shader.idx == bgfx::kInvalidHandle)
+ {
+ return false;
+ }
+
+ return true;
+}
+
+void effect_reader::clear_uniform_list(std::vector<bgfx_uniform *> &uniforms)
+{
+ for (bgfx_uniform *uniform : uniforms)
+ {
+ delete uniform;
+ }
}
bool effect_reader::validate_parameters(const Value& value, std::string prefix)
diff --git a/src/osd/modules/render/bgfx/effectreader.h b/src/osd/modules/render/bgfx/effectreader.h
index 0bc1b334435..d632c7326c2 100644
--- a/src/osd/modules/render/bgfx/effectreader.h
+++ b/src/osd/modules/render/bgfx/effectreader.h
@@ -16,14 +16,21 @@
#include "statereader.h"
class bgfx_effect;
+class bgfx_uniform;
class shader_manager;
class effect_reader : public state_reader
{
public:
- static bgfx_effect* read_from_value(const Value& value, std::string prefix, shader_manager& shaders);
+ static bgfx_effect *read_from_value(const Value& value, std::string prefix, osd_options &options, shader_manager& shaders);
+ static bool validate_value(const Value& value, std::string prefix, osd_options &options);
private:
+ static bool get_base_effect_data(const Value& value, std::string &prefix, uint64_t &flags, std::string &vertex_name, std::string &fragment_name,
+ std::vector<bgfx_uniform *> &uniforms);
+ static bool get_shader_data(const Value& value, osd_options &options, shader_manager &shaders, std::string &vertex_name, bgfx::ShaderHandle &vertex_shader,
+ std::string &fragment_name, bgfx::ShaderHandle &fragment_shader);
+ static void clear_uniform_list(std::vector<bgfx_uniform *> &uniforms);
static bool validate_parameters(const Value& value, std::string prefix);
};
diff --git a/src/osd/modules/render/bgfx/shadermanager.cpp b/src/osd/modules/render/bgfx/shadermanager.cpp
index 7583b58dec5..dd131e719a5 100644
--- a/src/osd/modules/render/bgfx/shadermanager.cpp
+++ b/src/osd/modules/render/bgfx/shadermanager.cpp
@@ -28,7 +28,7 @@ shader_manager::~shader_manager()
m_shaders.clear();
}
-bgfx::ShaderHandle shader_manager::shader(std::string name)
+bgfx::ShaderHandle shader_manager::get_or_load_shader(osd_options &options, std::string name)
{
std::map<std::string, bgfx::ShaderHandle>::iterator iter = m_shaders.find(name);
if (iter != m_shaders.end())
@@ -36,12 +36,49 @@ bgfx::ShaderHandle shader_manager::shader(std::string name)
return iter->second;
}
- return load_shader(name);
+ bgfx::ShaderHandle handle = load_shader(options, name);
+ if (handle.idx != bgfx::kInvalidHandle)
+ {
+ m_shaders[name] = handle;
+ }
+
+ return handle;
+}
+
+bgfx::ShaderHandle shader_manager::load_shader(osd_options &options, std::string name)
+{
+ std::string shader_path = make_path_string(options, name);
+ const bgfx::Memory* mem = load_mem(shader_path + name + ".bin");
+ if (mem != nullptr)
+ {
+ return bgfx::createShader(mem);
+ }
+
+ return BGFX_INVALID_HANDLE;
}
-bgfx::ShaderHandle shader_manager::load_shader(std::string name)
+bool shader_manager::is_shader_present(osd_options &options, std::string name)
{
- std::string shader_path(m_options.bgfx_path());
+ std::string shader_path = make_path_string(options, name);
+ std::string file_name = shader_path + name + ".bin";
+ bx::FileReader reader;
+ if (bx::open(&reader, file_name.c_str()))
+ {
+ uint32_t expected_size(bx::getSize(&reader));
+ uint8_t *data = new uint8_t[expected_size];
+ uint32_t read_size = (uint32_t)bx::read(&reader, data, expected_size);
+ delete [] data;
+ bx::close(&reader);
+
+ return expected_size == read_size;
+ }
+
+ return false;
+}
+
+std::string shader_manager::make_path_string(osd_options &options, std::string name)
+{
+ std::string shader_path(options.bgfx_path());
shader_path += PATH_SEPARATOR "shaders" PATH_SEPARATOR;
switch (bgfx::getRendererType())
{
@@ -81,17 +118,7 @@ bgfx::ShaderHandle shader_manager::load_shader(std::string name)
shader_path += PATH_SEPARATOR;
osd_subst_env(shader_path, shader_path);
- const bgfx::Memory* mem = load_mem(shader_path + name + ".bin");
- if (mem != nullptr)
- {
- bgfx::ShaderHandle handle = bgfx::createShader(mem);
-
- m_shaders[name] = handle;
-
- return handle;
- }
-
- return BGFX_INVALID_HANDLE;
+ return shader_path;
}
const bgfx::Memory* shader_manager::load_mem(std::string name)
@@ -109,7 +136,7 @@ const bgfx::Memory* shader_manager::load_mem(std::string name)
}
else
{
- printf("Unable to load shader %s\n", name.c_str());
+ osd_printf_error("Unable to load shader %s\n", name.c_str());
}
return nullptr;
}
diff --git a/src/osd/modules/render/bgfx/shadermanager.h b/src/osd/modules/render/bgfx/shadermanager.h
index bee48dcea81..d58a669f22f 100644
--- a/src/osd/modules/render/bgfx/shadermanager.h
+++ b/src/osd/modules/render/bgfx/shadermanager.h
@@ -24,18 +24,19 @@
class shader_manager {
public:
- shader_manager(osd_options& options) : m_options(options) { }
+ shader_manager() { }
~shader_manager();
// Getters
- bgfx::ShaderHandle shader(std::string name);
+ bgfx::ShaderHandle get_or_load_shader(osd_options &options, std::string name);
+ static bgfx::ShaderHandle load_shader(osd_options &options, std::string name);
+ static bool is_shader_present(osd_options &options, std::string name);
private:
- bgfx::ShaderHandle load_shader(std::string name);
+ static std::string make_path_string(osd_options &options, std::string name);
static const bgfx::Memory* load_mem(std::string name);
std::map<std::string, bgfx::ShaderHandle> m_shaders;
- osd_options& m_options;
};
#endif // __DRAWBGFX_SHADER_MANAGER__
diff --git a/src/osd/modules/render/bgfx/shaders/chains/crt-geom/vs_gaussx.sc b/src/osd/modules/render/bgfx/shaders/chains/crt-geom/vs_gaussx.sc
index 4bd5a57e3ef..c91a8948bf1 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/crt-geom/vs_gaussx.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/crt-geom/vs_gaussx.sc
@@ -9,7 +9,7 @@ uniform vec4 u_aspect;
void main()
{
- float wid = u_width.x*u_tex_size0.x/(320.*u_aspect.x);;
+ float wid = u_width.x*u_tex_size0.x/(320.*u_aspect.x);
v_coeffs = exp(vec4(1.,4.,9.,16.)*vec4_splat(-1.0/wid/wid));
// Do the standard vertex processing.
diff --git a/src/osd/modules/render/bgfx/shaders/chains/misc/fs_blit_yuy16.sc b/src/osd/modules/render/bgfx/shaders/chains/misc/fs_blit_yuy16.sc
index 91e3c3ed462..af3eb3e3954 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/misc/fs_blit_yuy16.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/misc/fs_blit_yuy16.sc
@@ -13,9 +13,10 @@ uniform vec4 u_inv_tex_size0;
vec3 ycc_to_rgb(float y, float cb, float cr)
{
- float r = saturate(y + 1.40200 * (cr - 0.5));
- float g = saturate(y - 0.34414 * (cb - 0.5) - 0.71414 * (cr - 0.5));
- float b = saturate(y + 1.77200 * (cb - 0.5));
+ float common = 1.168627 * (y - 0.062745);
+ float r = saturate(common + 1.603922 * (cr - 0.5));
+ float g = saturate(common - 0.392157 * (cb - 0.5) - 0.815686 * (cr - 0.5));
+ float b = saturate(common + 2.023529 * (cb - 0.5));
return vec3(r, g, b);
}
@@ -27,7 +28,7 @@ void main()
float mod_val = mod(original_uv.x, 2.0);
vec2 rounded_uv = vec2(original_uv.x - mod_val, original_uv.y);
vec4 srcpix = texture2D(s_tex, rounded_uv * u_inv_tex_size0.xy + half_texel.x);
-
+
float cr = srcpix.r;
float cb = srcpix.b;
if (mod_val < 1.0)
diff --git a/src/osd/modules/render/bgfx/shaders/chains/misc/fs_lut.sc b/src/osd/modules/render/bgfx/shaders/chains/misc/fs_lut.sc
index 2c8cffab7e1..6b00e4a1934 100644
--- a/src/osd/modules/render/bgfx/shaders/chains/misc/fs_lut.sc
+++ b/src/osd/modules/render/bgfx/shaders/chains/misc/fs_lut.sc
@@ -5,9 +5,9 @@ $input v_color0, v_texcoord0
#include "common.sh"
-#define LUT_TEXTURE_WIDTH 4096.0f
-#define LUT_SIZE 64.0f
-#define LUT_SCALE vec2(1.0f / LUT_TEXTURE_WIDTH, 1.0f / LUT_SIZE)
+// Autos
+uniform vec4 u_tex_size1;
+uniform vec4 u_inv_tex_size1;
SAMPLER2D(s_tex, 0);
SAMPLER2D(s_3dlut, 1);
@@ -17,13 +17,12 @@ void main()
vec4 bp = texture2D(s_tex, v_texcoord0);
vec3 color = bp.rgb;
// NOTE: Do not change the order of parameters here.
- vec3 lutcoord = vec3(color.rg * ((LUT_SIZE - 1.0f) + 0.5f) *
- LUT_SCALE, (LUT_SIZE - 1.0f) * color.b);
+ vec3 lutcoord = vec3(color.rg * ((u_tex_size1.y - 1.0) + 0.5) * u_inv_tex_size1.xy, (u_tex_size1.y - 1.0) * color.b);
float shift = floor(lutcoord.z);
- lutcoord.x += shift * LUT_SCALE.y;
+ lutcoord.x += shift * u_inv_tex_size1.y;
color.rgb = mix(texture2D(s_3dlut, lutcoord.xy).rgb,
- texture2D(s_3dlut, vec2(lutcoord.x + LUT_SCALE.y,
+ texture2D(s_3dlut, vec2(lutcoord.x + u_inv_tex_size1.y,
lutcoord.y)).rgb, lutcoord.z - shift);
gl_FragColor = vec4(color, bp.a) * v_color0;
}
diff --git a/src/osd/modules/render/bgfx/texturemanager.cpp b/src/osd/modules/render/bgfx/texturemanager.cpp
index 1fe6fe13b60..af960707523 100644
--- a/src/osd/modules/render/bgfx/texturemanager.cpp
+++ b/src/osd/modules/render/bgfx/texturemanager.cpp
@@ -14,6 +14,7 @@
#include "texturemanager.h"
#include "texture.h"
#include "bgfxutil.h"
+#include "fileio.h"
#include "rendutil.h"
#include "modules/render/copyutil.h"
@@ -67,7 +68,7 @@ bgfx_texture* texture_manager::create_png_texture(std::string path, std::string
if (bitmap.width() == 0 || bitmap.height() == 0)
{
- printf("Unable to load PNG '%s' from path '%s'\n", file_name.c_str(), path.c_str());
+ osd_printf_error("Unable to load PNG '%s' from path '%s'\n", file_name.c_str(), path.c_str());
return nullptr;
}
@@ -80,7 +81,7 @@ bgfx_texture* texture_manager::create_png_texture(std::string path, std::string
auto* base = reinterpret_cast<uint32_t *>(bitmap.raw_pixptr(0));
for (int y = 0; y < height; y++)
{
- copy_util::copyline_argb32(data32 + y * width, base + y * rowpixels, width, nullptr);
+ copy_util::copyline_argb32_to_bgra(data32 + y * width, base + y * rowpixels, width, nullptr);
}
if (screen >= 0)
diff --git a/src/osd/modules/render/bgfx/uniform.cpp b/src/osd/modules/render/bgfx/uniform.cpp
index dc81475ad59..36f68b7a9c7 100644
--- a/src/osd/modules/render/bgfx/uniform.cpp
+++ b/src/osd/modules/render/bgfx/uniform.cpp
@@ -13,7 +13,7 @@ bgfx_uniform::bgfx_uniform(std::string name, bgfx::UniformType::Enum type)
: m_name(name)
, m_type(type)
{
- m_handle = bgfx::createUniform(m_name.c_str(), m_type);
+ m_handle = BGFX_INVALID_HANDLE;
m_data_size = get_size_for_type(type);
if (m_data_size > 0)
{
@@ -23,10 +23,18 @@ bgfx_uniform::bgfx_uniform(std::string name, bgfx::UniformType::Enum type)
bgfx_uniform::~bgfx_uniform()
{
- bgfx::destroy(m_handle);
+ if (m_handle.idx != bgfx::kInvalidHandle)
+ {
+ bgfx::destroy(m_handle);
+ }
delete [] m_data;
}
+void bgfx_uniform::create()
+{
+ m_handle = bgfx::createUniform(m_name.c_str(), m_type);
+}
+
void bgfx_uniform::upload()
{
if (m_type != bgfx::UniformType::Sampler)
diff --git a/src/osd/modules/render/bgfx/uniform.h b/src/osd/modules/render/bgfx/uniform.h
index aa4c2cc097a..f7873f400a9 100644
--- a/src/osd/modules/render/bgfx/uniform.h
+++ b/src/osd/modules/render/bgfx/uniform.h
@@ -23,6 +23,8 @@ public:
virtual void upload();
+ void create();
+
// Getters
std::string name() { return m_name; }
bgfx::UniformType::Enum type() const { return m_type; }
diff --git a/src/osd/modules/render/bgfx/view.cpp b/src/osd/modules/render/bgfx/view.cpp
index 4385500edb1..1e3b2a6000d 100644
--- a/src/osd/modules/render/bgfx/view.cpp
+++ b/src/osd/modules/render/bgfx/view.cpp
@@ -26,11 +26,14 @@ void bgfx_view::update() {
}
void bgfx_ortho_view::setup() {
- if (m_window_index != 0)
+ if (m_window_index == 0)
+ {
+ bgfx::setViewFrameBuffer(m_index, BGFX_INVALID_HANDLE);
+ }
+ else
{
bgfx::setViewFrameBuffer(m_index, m_backbuffer->target());
}
-
bgfx::setViewRect(m_index, 0, 0, m_view_width, m_view_height);
while ((m_index + 1) > m_seen_views.size())
diff --git a/src/osd/modules/render/bgfx/windowparameter.h b/src/osd/modules/render/bgfx/windowparameter.h
index a30b928b817..0ba4224de40 100644
--- a/src/osd/modules/render/bgfx/windowparameter.h
+++ b/src/osd/modules/render/bgfx/windowparameter.h
@@ -24,7 +24,7 @@ public:
virtual ~bgfx_window_parameter() { }
virtual float value() override { return float(m_index); }
- virtual void tick(double delta) override { };
+ virtual void tick(double delta) override { }
private:
uint32_t m_index;
diff --git a/src/osd/modules/render/d3d/d3dhlsl.cpp b/src/osd/modules/render/d3d/d3dhlsl.cpp
index eabcd5bcb81..22a6b5af508 100644
--- a/src/osd/modules/render/d3d/d3dhlsl.cpp
+++ b/src/osd/modules/render/d3d/d3dhlsl.cpp
@@ -13,6 +13,7 @@
#include "rendlay.h"
#include "rendutil.h"
#include "emuopts.h"
+#include "fileio.h"
#include "aviio.h"
#include "png.h"
#include "screen.h"
@@ -504,7 +505,7 @@ bool shaders::init(d3d_base *d3dintf, running_machine *machine, renderer_d3d9 *r
snap_width = winoptions.d3d_snap_width();
snap_height = winoptions.d3d_snap_height();
- this->options = make_unique_clear<hlsl_options>().release();
+ this->options = new hlsl_options;
this->options->params_init = false;
// copy last options if initialized
@@ -2318,7 +2319,7 @@ void shaders::init_slider_list()
}
internal_sliders.clear();
- const screen_device *first_screen = screen_device_enumerator(machine->root_device()).first();;
+ const screen_device *first_screen = screen_device_enumerator(machine->root_device()).first();
if (first_screen == nullptr)
{
return;
diff --git a/src/osd/modules/render/d3d/d3dhlsl.h b/src/osd/modules/render/d3d/d3dhlsl.h
index 5a34d9830df..f72197cb7b1 100644
--- a/src/osd/modules/render/d3d/d3dhlsl.h
+++ b/src/osd/modules/render/d3d/d3dhlsl.h
@@ -175,92 +175,92 @@ class movie_recorder;
/* in the future this will be moved into an OSD/emu shared buffer */
struct hlsl_options
{
- bool params_init;
- bool params_dirty;
- int shadow_mask_tile_mode;
- float shadow_mask_alpha;
- char shadow_mask_texture[1024];
- int shadow_mask_count_x;
- int shadow_mask_count_y;
- float shadow_mask_u_size;
- float shadow_mask_v_size;
- float shadow_mask_u_offset;
- float shadow_mask_v_offset;
- float distortion;
- float cubic_distortion;
- float distort_corner;
- float round_corner;
- float smooth_border;
- float reflection;
- float vignetting;
- float scanline_alpha;
- float scanline_scale;
- float scanline_height;
- float scanline_variation;
- float scanline_bright_scale;
- float scanline_bright_offset;
- float scanline_jitter;
- float hum_bar_alpha;
- float defocus[2];
- float converge_x[3];
- float converge_y[3];
- float radial_converge_x[3];
- float radial_converge_y[3];
- float red_ratio[3];
- float grn_ratio[3];
- float blu_ratio[3];
- float offset[3];
- float scale[3];
- float power[3];
- float floor[3];
- float phosphor[3];
- float saturation;
- int chroma_mode;
- float chroma_a[2];
- float chroma_b[2];
- float chroma_c[2];
- float chroma_conversion_gain[3];
- float chroma_y_gain[3];
+ bool params_init = false;
+ bool params_dirty = false;
+ int shadow_mask_tile_mode = 0;
+ float shadow_mask_alpha = 0.0;
+ char shadow_mask_texture[1024]{ 0 };
+ int shadow_mask_count_x = 0;
+ int shadow_mask_count_y = 0;
+ float shadow_mask_u_size = 0.0;
+ float shadow_mask_v_size = 0.0;
+ float shadow_mask_u_offset = 0.0;
+ float shadow_mask_v_offset = 0.0;
+ float distortion = 0.0;
+ float cubic_distortion = 0.0;
+ float distort_corner = 0.0;
+ float round_corner = 0.0;
+ float smooth_border = 0.0;
+ float reflection = 0.0;
+ float vignetting = 0.0;
+ float scanline_alpha = 0.0;
+ float scanline_scale = 0.0;
+ float scanline_height = 0.0;
+ float scanline_variation = 0.0;
+ float scanline_bright_scale = 0.0;
+ float scanline_bright_offset = 0.0;
+ float scanline_jitter = 0.0;
+ float hum_bar_alpha = 0.0;
+ float defocus[2]{ 0.0 };
+ float converge_x[3]{ 0.0 };
+ float converge_y[3]{ 0.0 };
+ float radial_converge_x[3]{ 0.0 };
+ float radial_converge_y[3]{ 0.0 };
+ float red_ratio[3]{ 0.0 };
+ float grn_ratio[3]{ 0.0 };
+ float blu_ratio[3]{ 0.0 };
+ float offset[3]{ 0.0 };
+ float scale[3]{ 0.0 };
+ float power[3]{ 0.0 };
+ float floor[3]{ 0.0 };
+ float phosphor[3]{ 0.0 };
+ float saturation = 0.0;
+ int chroma_mode = 0;
+ float chroma_a[2]{ 0.0 };
+ float chroma_b[2]{ 0.0 };
+ float chroma_c[2]{ 0.0 };
+ float chroma_conversion_gain[3]{ 0.0 };
+ float chroma_y_gain[3]{ 0.0 };
// NTSC
- int yiq_enable;
- float yiq_jitter;
- float yiq_cc;
- float yiq_a;
- float yiq_b;
- float yiq_o;
- float yiq_p;
- float yiq_n;
- float yiq_y;
- float yiq_i;
- float yiq_q;
- float yiq_scan_time;
- int yiq_phase_count;
+ int yiq_enable = 0;
+ float yiq_jitter = 0.0;
+ float yiq_cc = 0.0;
+ float yiq_a = 0.0;
+ float yiq_b = 0.0;
+ float yiq_o = 0.0;
+ float yiq_p = 0.0;
+ float yiq_n = 0.0;
+ float yiq_y = 0.0;
+ float yiq_i = 0.0;
+ float yiq_q = 0.0;
+ float yiq_scan_time = 0.0;
+ int yiq_phase_count = 0;
// Vectors
- float vector_beam_smooth;
- float vector_length_scale;
- float vector_length_ratio;
+ float vector_beam_smooth = 0.0;
+ float vector_length_scale = 0.0;
+ float vector_length_ratio = 0.0;
// Bloom
- int bloom_blend_mode;
- float bloom_scale;
- float bloom_overdrive[3];
- float bloom_level0_weight;
- float bloom_level1_weight;
- float bloom_level2_weight;
- float bloom_level3_weight;
- float bloom_level4_weight;
- float bloom_level5_weight;
- float bloom_level6_weight;
- float bloom_level7_weight;
- float bloom_level8_weight;
+ int bloom_blend_mode = 0;
+ float bloom_scale = 0.0;
+ float bloom_overdrive[3]{ 0.0 };
+ float bloom_level0_weight = 0.0;
+ float bloom_level1_weight = 0.0;
+ float bloom_level2_weight = 0.0;
+ float bloom_level3_weight = 0.0;
+ float bloom_level4_weight = 0.0;
+ float bloom_level5_weight = 0.0;
+ float bloom_level6_weight = 0.0;
+ float bloom_level7_weight = 0.0;
+ float bloom_level8_weight = 0.0;
// Final
- char lut_texture[1024];
- int lut_enable;
- char ui_lut_texture[1024];
- int ui_lut_enable;
+ char lut_texture[1024]{ 0 };
+ int lut_enable = 0;
+ char ui_lut_texture[1024]{ 0 };
+ int ui_lut_enable = 0;
};
struct slider_desc
diff --git a/src/osd/modules/render/drawbgfx.cpp b/src/osd/modules/render/drawbgfx.cpp
index 29cb8deda00..07570882ec0 100644
--- a/src/osd/modules/render/drawbgfx.cpp
+++ b/src/osd/modules/render/drawbgfx.cpp
@@ -75,8 +75,10 @@ char const *const renderer_bgfx::WINDOW_PREFIX = "Window 0, ";
// STATICS
//============================================================
-bool renderer_bgfx::s_window_set = false;
uint32_t renderer_bgfx::s_current_view = 0;
+bool renderer_bgfx::s_bgfx_library_initialized = false;
+uint32_t renderer_bgfx::s_width[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+uint32_t renderer_bgfx::s_height[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
//============================================================
// renderer_bgfx - constructor
@@ -134,31 +136,96 @@ renderer_bgfx::~renderer_bgfx()
delete m_targets;
}
+
+
//============================================================
-// renderer_bgfx::create
+// renderer_bgfx::init_bgfx_library
+//============================================================
+
+void renderer_bgfx::init_bgfx_library()
+{
+ std::string backend(m_options.bgfx_backend());
+
+ bgfx::Init init;
+ init.type = bgfx::RendererType::Count;
+ init.vendorId = BGFX_PCI_ID_NONE;
+ init.resolution.width = s_width[0];
+ init.resolution.height = s_height[0];
+ init.resolution.numBackBuffers = 1;
+ init.resolution.reset = BGFX_RESET_NONE;
+ init.platformData = m_platform_data;
+ if (backend == "auto")
+ {
+ }
+ else if (backend == "dx9" || backend == "d3d9")
+ {
+ init.type = bgfx::RendererType::Direct3D9;
+ }
+ else if (backend == "dx11" || backend == "d3d11")
+ {
+ init.type = bgfx::RendererType::Direct3D11;
+ }
+ else if (backend == "dx12" || backend == "d3d12")
+ {
+ init.type = bgfx::RendererType::Direct3D12;
+ }
+ else if (backend == "gles")
+ {
+ init.type = bgfx::RendererType::OpenGLES;
+ }
+ else if (backend == "glsl" || backend == "opengl")
+ {
+ init.type = bgfx::RendererType::OpenGL;
+ }
+ else if (backend == "vulkan")
+ {
+ init.type = bgfx::RendererType::Vulkan;
+ }
+ else if (backend == "metal")
+ {
+ init.type = bgfx::RendererType::Metal;
+ }
+ else
+ {
+ osd_printf_verbose("Unknown backend type '%s', going with auto-detection.\n", backend.c_str());
+ }
+
+ bgfx::init(init);
+ bgfx::reset(s_width[0], s_height[0], video_config.waitvsync ? BGFX_RESET_VSYNC : BGFX_RESET_NONE);
+ // Enable debug text if requested.
+ bool bgfx_debug = m_options.bgfx_debug();
+ bgfx::setDebug(bgfx_debug ? BGFX_DEBUG_STATS : BGFX_DEBUG_TEXT);
+
+ ScreenVertex::init();
+
+ imguiCreate();
+}
+
+
+
+//============================================================
+// Utilities for setting up window handles
//============================================================
#ifdef OSD_WINDOWS
-inline void winSetHwnd(::HWND _window)
+inline void winSetHwnd(bgfx::PlatformData &platform_data, ::HWND _window)
{
- bgfx::PlatformData pd;
- pd.ndt = NULL;
- pd.nwh = _window;
- pd.context = NULL;
- pd.backBuffer = NULL;
- pd.backBufferDS = NULL;
- bgfx::setPlatformData(pd);
+ platform_data.ndt = NULL;
+ platform_data.nwh = _window;
+ platform_data.context = NULL;
+ platform_data.backBuffer = NULL;
+ platform_data.backBufferDS = NULL;
+ bgfx::setPlatformData(platform_data);
}
#elif defined(OSD_MAC)
-inline void macSetWindow(void *_window)
+inline void macSetWindow(bgfx::PlatformData &platform_data, void *_window)
{
- bgfx::PlatformData pd;
- pd.ndt = NULL;
- pd.nwh = GetOSWindow(_window);
- pd.context = NULL;
- pd.backBuffer = NULL;
- pd.backBufferDS = NULL;
- bgfx::setPlatformData(pd);
+ platform_data.ndt = NULL;
+ platform_data.nwh = GetOSWindow(_window);
+ platform_data.context = NULL;
+ platform_data.backBuffer = NULL;
+ platform_data.backBufferDS = NULL;
+ bgfx::setPlatformData(platform_data);
}
#elif defined(OSD_SDL)
static void* sdlNativeWindowHandle(SDL_Window* _window)
@@ -181,7 +248,7 @@ static void* sdlNativeWindowHandle(SDL_Window* _window)
# endif // BX_PLATFORM_
}
-inline bool sdlSetWindow(SDL_Window* _window)
+inline bool sdlSetWindow(bgfx::PlatformData &platform_data, SDL_Window* _window)
{
SDL_SysWMinfo wmi;
SDL_VERSION(&wmi.version);
@@ -190,117 +257,83 @@ inline bool sdlSetWindow(SDL_Window* _window)
return false;
}
- bgfx::PlatformData pd;
# if BX_PLATFORM_LINUX || BX_PLATFORM_BSD
- pd.ndt = wmi.info.x11.display;
- pd.nwh = (void*)(uintptr_t)wmi.info.x11.window;
+ platform_data.ndt = wmi.info.x11.display;
+ platform_data.nwh = (void*)(uintptr_t)wmi.info.x11.window;
# elif BX_PLATFORM_OSX
- pd.ndt = NULL;
- pd.nwh = wmi.info.cocoa.window;
+ platform_data.ndt = NULL;
+ platform_data.nwh = wmi.info.cocoa.window;
# elif BX_PLATFORM_WINDOWS
- pd.ndt = NULL;
- pd.nwh = wmi.info.win.window;
+ platform_data.ndt = NULL;
+ platform_data.nwh = wmi.info.win.window;
# endif // BX_PLATFORM_
- pd.context = NULL;
- pd.backBuffer = NULL;
- pd.backBufferDS = NULL;
- bgfx::setPlatformData(pd);
+ platform_data.context = NULL;
+ platform_data.backBuffer = NULL;
+ platform_data.backBufferDS = NULL;
+ bgfx::setPlatformData(platform_data);
return true;
}
#endif
+
+
+//============================================================
+// renderer_bgfx::create
+//============================================================
+
int renderer_bgfx::create()
{
- // create renderer
std::shared_ptr<osd_window> win = assert_window();
osd_dim wdim = win->get_size();
- m_width[win->index()] = wdim.width();
- m_height[win->index()] = wdim.height();
+ s_width[win->index()] = wdim.width();
+ s_height[win->index()] = wdim.height();
+ m_dimensions = wdim;
+
+ if (s_bgfx_library_initialized)
+ {
+ exit();
+ }
+
if (win->index() == 0)
{
- if (!s_window_set)
- {
- s_window_set = true;
- ScreenVertex::init();
- }
- else
- {
- bgfx::shutdown();
- bgfx::PlatformData blank_pd;
- memset(&blank_pd, 0, sizeof(bgfx::PlatformData));
- bgfx::setPlatformData(blank_pd);
- }
#ifdef OSD_WINDOWS
- winSetHwnd(std::static_pointer_cast<win_window_info>(win)->platform_window());
+ winSetHwnd(m_platform_data, std::static_pointer_cast<win_window_info>(win)->platform_window());
#elif defined(OSD_MAC)
- macSetWindow(std::static_pointer_cast<mac_window_info>(win)->platform_window());
+ macSetWindow(m_platform_data, std::static_pointer_cast<mac_window_info>(win)->platform_window());
#else
- sdlSetWindow(std::dynamic_pointer_cast<sdl_window_info>(win)->platform_window());
+ sdlSetWindow(m_platform_data, std::dynamic_pointer_cast<sdl_window_info>(win)->platform_window());
#endif
- std::string backend(m_options.bgfx_backend());
- bgfx::Init init;
- init.type = bgfx::RendererType::Count;
- init.vendorId = BGFX_PCI_ID_NONE;
- init.resolution.width = wdim.width();
- init.resolution.height = wdim.height();
- init.resolution.reset = BGFX_RESET_NONE;
- if (backend == "auto")
- {
- }
- else if (backend == "dx9" || backend == "d3d9")
- {
- init.type = bgfx::RendererType::Direct3D9;
- }
- else if (backend == "dx11" || backend == "d3d11")
- {
- init.type = bgfx::RendererType::Direct3D11;
- }
- else if (backend == "dx12" || backend == "d3d12")
- {
- init.type = bgfx::RendererType::Direct3D12;
- }
- else if (backend == "gles")
- {
- init.type = bgfx::RendererType::OpenGLES;
- }
- else if (backend == "glsl" || backend == "opengl")
- {
- init.type = bgfx::RendererType::OpenGL;
- }
- else if (backend == "vulkan")
- {
- init.type = bgfx::RendererType::Vulkan;
- }
- else if (backend == "metal")
- {
- init.type = bgfx::RendererType::Metal;
- }
- else
- {
- printf("Unknown backend type '%s', going with auto-detection\n", backend.c_str());
- }
- bgfx::init(init);
- bgfx::reset(m_width[win->index()], m_height[win->index()], video_config.waitvsync ? BGFX_RESET_VSYNC : BGFX_RESET_NONE);
- // Enable debug text.
- bgfx::setDebug(m_options.bgfx_debug() ? BGFX_DEBUG_STATS : BGFX_DEBUG_TEXT);
- m_dimensions = osd_dim(m_width[0], m_height[0]);
+
+ init_bgfx_library();
}
+ // finish creating the renderer
m_textures = new texture_manager();
m_targets = new target_manager(*m_textures);
- m_shaders = new shader_manager(m_options);
- m_effects = new effect_manager(m_options, *m_shaders);
+ m_shaders = new shader_manager();
+ m_effects = new effect_manager(*m_shaders);
+
+ // Create program from shaders.
+ m_gui_effect[0] = m_effects->get_or_load_effect(m_options, "gui_opaque");
+ m_gui_effect[1] = m_effects->get_or_load_effect(m_options, "gui_blend");
+ m_gui_effect[2] = m_effects->get_or_load_effect(m_options, "gui_multiply");
+ m_gui_effect[3] = m_effects->get_or_load_effect(m_options, "gui_add");
+
+ m_screen_effect[0] = m_effects->get_or_load_effect(m_options, "screen_opaque");
+ m_screen_effect[1] = m_effects->get_or_load_effect(m_options, "screen_blend");
+ m_screen_effect[2] = m_effects->get_or_load_effect(m_options, "screen_multiply");
+ m_screen_effect[3] = m_effects->get_or_load_effect(m_options, "screen_add");
if (win->index() != 0)
{
#ifdef OSD_WINDOWS
- m_framebuffer = m_targets->create_backbuffer(std::static_pointer_cast<win_window_info>(win)->platform_window(), m_width[win->index()], m_height[win->index()]);
+ m_framebuffer = m_targets->create_backbuffer(std::static_pointer_cast<win_window_info>(win)->platform_window(), s_width[win->index()], s_height[win->index()]);
#elif defined(OSD_MAC)
- m_framebuffer = m_targets->create_backbuffer(GetOSWindow(std::static_pointer_cast<mac_window_info>(win)->platform_window()), m_width[win->index()], m_height[win->index()]);
+ m_framebuffer = m_targets->create_backbuffer(GetOSWindow(std::static_pointer_cast<mac_window_info>(win)->platform_window()), s_width[win->index()], s_height[win->index()]);
#else
- m_framebuffer = m_targets->create_backbuffer(sdlNativeWindowHandle(std::dynamic_pointer_cast<sdl_window_info>(win)->platform_window()), m_width[win->index()], m_height[win->index()]);
+ m_framebuffer = m_targets->create_backbuffer(sdlNativeWindowHandle(std::dynamic_pointer_cast<sdl_window_info>(win)->platform_window()), s_width[win->index()], s_height[win->index()]);
#endif
bgfx::touch(win->index());
@@ -309,23 +342,6 @@ int renderer_bgfx::create()
}
}
- // Create program from shaders.
- m_gui_effect[0] = m_effects->effect("gui_opaque");
- m_gui_effect[1] = m_effects->effect("gui_blend");
- m_gui_effect[2] = m_effects->effect("gui_multiply");
- m_gui_effect[3] = m_effects->effect("gui_add");
-
- m_screen_effect[0] = m_effects->effect("screen_opaque");
- m_screen_effect[1] = m_effects->effect("screen_blend");
- m_screen_effect[2] = m_effects->effect("screen_multiply");
- m_screen_effect[3] = m_effects->effect("screen_add");
-
- if ( m_gui_effect[0] == nullptr || m_gui_effect[1] == nullptr || m_gui_effect[2] == nullptr || m_gui_effect[3] == nullptr ||
- m_screen_effect[0] == nullptr || m_screen_effect[1] == nullptr || m_screen_effect[2] == nullptr || m_screen_effect[3] == nullptr)
- {
- fatalerror("BGFX: Unable to load required shaders. Please check and reinstall the %s folder\n", m_options.bgfx_path());
- }
-
m_chains = new chain_manager(win->machine(), m_options, *m_textures, *m_targets, *m_effects, win->index(), *this);
m_sliders_dirty = true;
@@ -335,11 +351,11 @@ int renderer_bgfx::create()
memset(m_white, 0xff, sizeof(uint32_t) * 16 * 16);
m_texinfo.push_back(rectangle_packer::packable_rectangle(WHITE_HASH, PRIMFLAG_TEXFORMAT(TEXFORMAT_ARGB32), 16, 16, 16, nullptr, m_white));
- imguiCreate();
-
return 0;
}
+
+
//============================================================
// renderer_bgfx::record
//============================================================
@@ -355,9 +371,9 @@ void renderer_bgfx::record()
if (m_avi_writer == nullptr)
{
- m_avi_writer = new avi_write(win->machine(), m_width[0], m_height[0]);
- m_avi_data = new uint8_t[m_width[0] * m_height[0] * 4];
- m_avi_bitmap.allocate(m_width[0], m_height[0]);
+ m_avi_writer = new avi_write(win->machine(), s_width[0], s_height[0]);
+ m_avi_data = new uint8_t[s_width[0] * s_height[0] * 4];
+ m_avi_bitmap.allocate(s_width[0], s_height[0]);
}
if (m_avi_writer->recording())
@@ -372,8 +388,8 @@ void renderer_bgfx::record()
else
{
m_avi_writer->record(m_options.bgfx_avi_name());
- m_avi_target = m_targets->create_target("avibuffer", bgfx::TextureFormat::BGRA8, m_width[0], m_height[0], TARGET_STYLE_CUSTOM, false, true, 1, 0);
- m_avi_texture = bgfx::createTexture2D(m_width[0], m_height[0], false, 1, bgfx::TextureFormat::BGRA8, BGFX_TEXTURE_BLIT_DST | BGFX_TEXTURE_READ_BACK);
+ m_avi_target = m_targets->create_target("avibuffer", bgfx::TextureFormat::BGRA8, s_width[0], s_height[0], TARGET_STYLE_CUSTOM, false, true, 1, 0);
+ m_avi_texture = bgfx::createTexture2D(s_width[0], s_height[0], false, 1, bgfx::TextureFormat::BGRA8, BGFX_TEXTURE_BLIT_DST | BGFX_TEXTURE_READ_BACK);
if (m_avi_view == nullptr)
{
@@ -384,12 +400,32 @@ void renderer_bgfx::record()
bool renderer_bgfx::init(running_machine &machine)
{
- const char *bgfx_path = downcast<osd_options &>(machine.options()).bgfx_path();
+ osd_options &options = downcast<osd_options &>(machine.options());
+ const char *bgfx_path = options.bgfx_path();
osd::directory::ptr directory = osd::directory::open(bgfx_path);
if (directory == nullptr)
{
- osd_printf_verbose("Unable to find the %s folder. Please reinstall it to use the BGFX renderer\n", bgfx_path);
+ osd_printf_error("Unable to find the BGFX path %s, please install it or fix the bgfx_path setting to use the BGFX renderer.\n", bgfx_path);
+ return true;
+ }
+
+ // Verify baseline shaders.
+ const bool gui_opaque_valid = effect_manager::validate_effect(options, "gui_opaque");
+ const bool gui_blend_valid = effect_manager::validate_effect(options, "gui_blend");
+ const bool gui_multiply_valid = effect_manager::validate_effect(options, "gui_multiply");
+ const bool gui_add_valid = effect_manager::validate_effect(options, "gui_add");
+ const bool all_gui_valid = gui_opaque_valid && gui_blend_valid && gui_multiply_valid && gui_add_valid;
+
+ const bool screen_opaque_valid = effect_manager::validate_effect(options, "screen_opaque");
+ const bool screen_blend_valid = effect_manager::validate_effect(options, "screen_blend");
+ const bool screen_multiply_valid = effect_manager::validate_effect(options, "screen_multiply");
+ const bool screen_add_valid = effect_manager::validate_effect(options, "screen_add");
+ const bool all_screen_valid = screen_opaque_valid && screen_blend_valid && screen_multiply_valid && screen_add_valid;
+
+ if (!all_gui_valid || !all_screen_valid)
+ {
+ osd_printf_error("BGFX: Unable to load required shaders. Please update the %s folder or adjust your bgfx_path setting.\n", options.bgfx_path());
return true;
}
@@ -399,9 +435,8 @@ bool renderer_bgfx::init(running_machine &machine)
void renderer_bgfx::exit()
{
imguiDestroy();
-
bgfx::shutdown();
- s_window_set = false;
+ s_bgfx_library_initialized = false;
}
//============================================================
@@ -507,11 +542,11 @@ void renderer_bgfx::render_post_screen_quad(int view, render_primitive* prim, bg
vertex(&vertices[4], x[2], y[2], 0, 0xffffffff, u[2], v[2]);
vertex(&vertices[5], x[0], y[0], 0, 0xffffffff, u[0], v[0]);
- uint32_t texture_flags = BGFX_SAMPLER_U_CLAMP | BGFX_SAMPLER_V_CLAMP;
+ uint32_t texture_flags = 0U;
+ if (!PRIMFLAG_GET_TEXWRAP(prim->flags))
+ texture_flags |= BGFX_SAMPLER_U_CLAMP | BGFX_SAMPLER_V_CLAMP;
if (video_config.filter == 0)
- {
texture_flags |= BGFX_SAMPLER_MIN_POINT | BGFX_SAMPLER_MAG_POINT | BGFX_SAMPLER_MIP_POINT;
- }
uint32_t blend = PRIMFLAG_GET_BLENDMODE(prim->flags);
bgfx::setVertexBuffer(0,buffer);
@@ -524,15 +559,15 @@ void renderer_bgfx::render_avi_quad()
m_avi_view->set_index(s_current_view);
m_avi_view->setup();
- bgfx::setViewRect(s_current_view, 0, 0, m_width[0], m_height[0]);
+ bgfx::setViewRect(s_current_view, 0, 0, s_width[0], s_height[0]);
bgfx::setViewClear(s_current_view, BGFX_CLEAR_COLOR | BGFX_CLEAR_DEPTH, 0x00000000, 1.0f, 0);
bgfx::TransientVertexBuffer buffer;
bgfx::allocTransientVertexBuffer(&buffer, 6, ScreenVertex::ms_decl);
auto* vertices = reinterpret_cast<ScreenVertex*>(buffer.data);
- float x[4] = { 0.0f, float(m_width[0]), 0.0f, float(m_width[0]) };
- float y[4] = { 0.0f, 0.0f, float(m_height[0]), float(m_height[0]) };
+ float x[4] = { 0.0f, float(s_width[0]), 0.0f, float(s_width[0]) };
+ float y[4] = { 0.0f, 0.0f, float(s_height[0]), float(s_height[0]) };
float u[4] = { 0.0f, 1.0f, 0.0f, 1.0f };
float v[4] = { 0.0f, 0.0f, 1.0f, 1.0f };
uint32_t rgba = 0xffffffff;
@@ -567,11 +602,11 @@ void renderer_bgfx::render_textured_quad(render_primitive* prim, bgfx::Transient
vertex(&vertices[4], x[2], y[2], 0, rgba, u[2], v[2]);
vertex(&vertices[5], x[0], y[0], 0, rgba, u[0], v[0]);
- uint32_t texture_flags = BGFX_SAMPLER_U_CLAMP | BGFX_SAMPLER_V_CLAMP;
+ uint32_t texture_flags = 0U;
+ if (!PRIMFLAG_GET_TEXWRAP(prim->flags))
+ texture_flags |= BGFX_SAMPLER_U_CLAMP | BGFX_SAMPLER_V_CLAMP;
if (video_config.filter == 0)
- {
texture_flags |= BGFX_SAMPLER_MIN_POINT | BGFX_SAMPLER_MAG_POINT | BGFX_SAMPLER_MIP_POINT;
- }
const bool is_screen = PRIMFLAG_GET_SCREENTEX(prim->flags);
uint16_t tex_width(prim->texture.width);
@@ -824,8 +859,8 @@ int renderer_bgfx::draw(int update)
}
osd_dim wdim = win->get_size();
- m_width[window_index] = wdim.width();
- m_height[window_index] = wdim.height();
+ s_width[window_index] = wdim.width();
+ s_height[window_index] = wdim.height();
// Set view 0 default viewport.
if (window_index == 0)
@@ -837,17 +872,18 @@ int renderer_bgfx::draw(int update)
uint32_t num_screens = m_chains->update_screen_textures(s_current_view, win->m_primlist->first(), *win.get());
win->m_primlist->release_lock();
- if (num_screens)
- {
- s_current_view += m_chains->process_screen_chains(s_current_view, *win.get());
- }
-
bool skip_frame = update_dimensions();
if (skip_frame)
{
return 0;
}
+ if (num_screens)
+ {
+ uint32_t chain_view_count = m_chains->process_screen_chains(s_current_view, *win.get());
+ s_current_view += chain_view_count;
+ }
+
if (s_current_view > m_max_view)
{
m_max_view = s_current_view;
@@ -906,7 +942,7 @@ int renderer_bgfx::draw(int update)
// This dummy draw call is here to make sure that view 0 is cleared
// if no other draw calls are submitted to view 0.
- bgfx::touch(s_current_view > 0 ? s_current_view - 1 : 0);
+ //bgfx::touch(s_current_view > 0 ? s_current_view - 1 : 0);
// Advance to next frame. Rendering thread will be kicked to
// process submitted rendering primitives.
@@ -918,7 +954,10 @@ int renderer_bgfx::draw(int update)
bgfx::touch(s_current_view);
update_recording();
}
+ }
+ if (win->index() == osd_common_t::s_window_list.size() - 1)
+ {
bgfx::frame();
}
@@ -959,24 +998,16 @@ bool renderer_bgfx::update_dimensions()
std::shared_ptr<osd_window> win = assert_window();
const uint32_t window_index = win->index();
- const uint32_t width = m_width[window_index];
- const uint32_t height = m_height[window_index];
+ const uint32_t width = s_width[window_index];
+ const uint32_t height = s_height[window_index];
- if (window_index == 0)
+ if (m_dimensions != osd_dim(width, height))
{
- if ((m_dimensions != osd_dim(width, height)))
- {
- bgfx::reset(width, height, video_config.waitvsync ? BGFX_RESET_VSYNC : BGFX_RESET_NONE);
- m_dimensions = osd_dim(width, height);
- }
- }
- else
- {
- if ((m_dimensions != osd_dim(width, height)))
- {
- bgfx::reset(win->main_window()->get_size().width(), win->main_window()->get_size().height(), video_config.waitvsync ? BGFX_RESET_VSYNC : BGFX_RESET_NONE);
- m_dimensions = osd_dim(width, height);
+ bgfx::reset(width, height, video_config.waitvsync ? BGFX_RESET_VSYNC : BGFX_RESET_NONE);
+ m_dimensions = osd_dim(width, height);
+ if (win->index() != 0)
+ {
delete m_framebuffer;
#ifdef OSD_WINDOWS
m_framebuffer = m_targets->create_backbuffer(std::static_pointer_cast<win_window_info>(win)->platform_window(), width, height);
@@ -986,15 +1017,17 @@ bool renderer_bgfx::update_dimensions()
m_framebuffer = m_targets->create_backbuffer(sdlNativeWindowHandle(std::dynamic_pointer_cast<sdl_window_info>(win)->platform_window()), width, height);
#endif
if (m_ortho_view)
+ {
m_ortho_view->set_backbuffer(m_framebuffer);
-
+ }
bgfx::setViewFrameBuffer(s_current_view, m_framebuffer->target());
- bgfx::setViewClear(s_current_view, BGFX_CLEAR_COLOR | BGFX_CLEAR_DEPTH, 0x00000000, 1.0f, 0);
- bgfx::setViewMode(s_current_view, bgfx::ViewMode::Sequential);
- bgfx::touch(s_current_view);
- bgfx::frame();
- return true;
}
+
+ bgfx::setViewClear(s_current_view, BGFX_CLEAR_COLOR | BGFX_CLEAR_DEPTH, 0x00000000, 1.0f, 0);
+ bgfx::setViewMode(s_current_view, bgfx::ViewMode::Sequential);
+ bgfx::touch(s_current_view);
+ bgfx::frame();
+ return true;
}
return false;
}
@@ -1003,14 +1036,15 @@ void renderer_bgfx::setup_ortho_view()
{
if (!m_ortho_view)
{
- m_ortho_view = new bgfx_ortho_view(this, s_current_view, m_framebuffer, m_seen_views);
+ m_ortho_view = new bgfx_ortho_view(this, 0, m_framebuffer, m_seen_views);
}
- m_ortho_view->update();
- if (m_ortho_view->get_index() == UINT_MAX) {
+ if (m_ortho_view->get_index() == UINT_MAX)
+ {
m_ortho_view->set_index(s_current_view);
m_ortho_view->setup();
s_current_view++;
}
+ m_ortho_view->update();
}
renderer_bgfx::buffer_status renderer_bgfx::buffer_primitives(bool atlas_valid, render_primitive** prim, bgfx::TransientVertexBuffer* buffer, int32_t screen)
@@ -1279,10 +1313,10 @@ void renderer_bgfx::set_sliders_dirty()
}
uint32_t renderer_bgfx::get_window_width(uint32_t index) const {
- return m_width[index];
+ return s_width[index];
}
uint32_t renderer_bgfx::get_window_height(uint32_t index) const {
- return m_height[index];
+ return s_height[index];
}
diff --git a/src/osd/modules/render/drawbgfx.h b/src/osd/modules/render/drawbgfx.h
index e7e648c27d1..6cbf2631b9d 100644
--- a/src/osd/modules/render/drawbgfx.h
+++ b/src/osd/modules/render/drawbgfx.h
@@ -85,6 +85,8 @@ public:
static char const *const WINDOW_PREFIX;
private:
+ void init_bgfx_library();
+
void vertex(ScreenVertex* vertex, float x, float y, float z, uint32_t rgba, float u, float v);
void render_avi_quad();
void update_recording();
@@ -122,6 +124,7 @@ private:
uint32_t get_texture_hash(render_primitive *prim);
osd_options& m_options;
+ bgfx::PlatformData m_platform_data;
bgfx_target *m_framebuffer;
bgfx_texture *m_texture_cache;
@@ -143,8 +146,6 @@ private:
std::vector<rectangle_packer::packable_rectangle> m_texinfo;
rectangle_packer m_packer;
- uint32_t m_width[16];
- uint32_t m_height[16];
uint32_t m_white[16*16];
bgfx_view *m_ortho_view;
uint32_t m_max_view;
@@ -160,8 +161,10 @@ private:
static const uint32_t PACKABLE_SIZE;
static const uint32_t WHITE_HASH;
- static bool s_window_set;
static uint32_t s_current_view;
+ static bool s_bgfx_library_initialized;
+ static uint32_t s_width[16];
+ static uint32_t s_height[16];
};
#endif // RENDER_BGFX
diff --git a/src/osd/modules/render/drawd3d.cpp b/src/osd/modules/render/drawd3d.cpp
index a279034ef7d..cfc494a2be9 100644
--- a/src/osd/modules/render/drawd3d.cpp
+++ b/src/osd/modules/render/drawd3d.cpp
@@ -8,10 +8,11 @@
// MAME headers
#include "emu.h"
+#include "emuopts.h"
#include "render.h"
-
#include "rendutil.h"
-#include "emuopts.h"
+#include "screen.h"
+
#include "aviio.h"
// MAMEOS headers
@@ -1522,15 +1523,10 @@ void renderer_d3d9::batch_vector(const render_primitive &prim)
}
// compute the effective width based on the direction of the line
- float effwidth = prim.width;
- if (effwidth < 2.0f)
- {
- effwidth = 2.0f;
- }
+ float effwidth = std::max(prim.width, 2.0f);
// determine the bounds of a quad to draw this line
- render_bounds b0, b1;
- render_line_to_quad(&prim.bounds, effwidth, effwidth, &b0, &b1);
+ auto [b0, b1] = render_line_to_quad(prim.bounds, effwidth, effwidth);
float lx = b1.x1 - b0.x1;
float ly = b1.y1 - b0.y1;
@@ -1629,15 +1625,10 @@ void renderer_d3d9::draw_line(const render_primitive &prim)
}
// compute the effective width based on the direction of the line
- float effwidth = prim.width;
- if (effwidth < 1.0f)
- {
- effwidth = 1.0f;
- }
+ float effwidth = std::max(prim.width, 1.0f);
// determine the bounds of a quad to draw this line
- render_bounds b0, b1;
- render_line_to_quad(&prim.bounds, effwidth, 0.0f, &b0, &b1);
+ auto [b0, b1] = render_line_to_quad(prim.bounds, effwidth, 0.0f);
vertex[0].x = b0.x0;
vertex[0].y = b0.y0;
diff --git a/src/osd/modules/render/drawgdi.h b/src/osd/modules/render/drawgdi.h
index 7984998f4bc..0dfc4bf2641 100644
--- a/src/osd/modules/render/drawgdi.h
+++ b/src/osd/modules/render/drawgdi.h
@@ -42,9 +42,9 @@ public:
virtual int create() override;
virtual render_primitive_list *get_primitives() override;
virtual int draw(const int update) override;
- virtual void save() override {};
- virtual void record() override {};
- virtual void toggle_fsfx() override {};
+ virtual void save() override {}
+ virtual void record() override {}
+ virtual void toggle_fsfx() override {}
private:
BITMAPINFO m_bminfo;
diff --git a/src/osd/modules/render/drawogl.cpp b/src/osd/modules/render/drawogl.cpp
index 7cf99ccfb5f..9e200f3817c 100644
--- a/src/osd/modules/render/drawogl.cpp
+++ b/src/osd/modules/render/drawogl.cpp
@@ -1253,11 +1253,6 @@ int renderer_ogl::draw(const int update)
}
#else
{
- const line_aa_step *step = line_aa_4step;
- render_bounds b0, b1;
- float r, g, b, a;
- float effwidth;
-
// we're not gonna play fancy here. close anything pending and let's go.
if (pendingPrimitive!=GL_NO_PRIMITIVE && pendingPrimitive!=curPrimitive)
{
@@ -1268,12 +1263,10 @@ int renderer_ogl::draw(const int update)
set_blendmode(sdl, PRIMFLAG_GET_BLENDMODE(prim.flags));
// compute the effective width based on the direction of the line
- effwidth = prim.width();
- if (effwidth < 0.5f)
- effwidth = 0.5f;
+ float effwidth = std::max(prim.width(), 0.5f);
// determine the bounds of a quad to draw this line
- render_line_to_quad(&prim.bounds, effwidth, 0.0f, &b0, &b1);
+ auto [b0, b1] = render_line_to_quad(prim.bounds, effwidth, 0.0f);
// fix window position
b0.x0 += hofs;
@@ -1286,7 +1279,7 @@ int renderer_ogl::draw(const int update)
b1.y1 += vofs;
// iterate over AA steps
- for (step = PRIMFLAG_GET_ANTIALIAS(prim.flags) ? line_aa_4step : line_aa_1step; step->weight != 0; step++)
+ for (const line_aa_step *step = PRIMFLAG_GET_ANTIALIAS(prim.flags) ? line_aa_4step : line_aa_1step; step->weight != 0; step++)
{
glBegin(GL_TRIANGLE_STRIP);
@@ -1303,14 +1296,10 @@ int renderer_ogl::draw(const int update)
glVertex2f(b1.x1 + step->xoffs, b1.y1 + step->yoffs);
// determine the color of the line
- r = (prim.color.r * step->weight);
- g = (prim.color.g * step->weight);
- b = (prim.color.b * step->weight);
- a = (prim.color.a * 255.0f);
- if (r > 1.0) r = 1.0;
- if (g > 1.0) g = 1.0;
- if (b > 1.0) b = 1.0;
- if (a > 1.0) a = 1.0;
+ float r = std::min(prim.color.r * step->weight, 1.0f);
+ float g = std::min(prim.color.g * step->weight, 1.0f);
+ float b = std::min(prim.color.b * step->weight, 1.0f);
+ float a = std::min(prim.color.a * 255.0f, 1.0f);
glColor4f(r, g, b, a);
// texture = texture_update(window, &prim, 0);
diff --git a/src/osd/osdnet.cpp b/src/osd/osdnet.cpp
index b90a139731c..97b37366a4d 100644
--- a/src/osd/osdnet.cpp
+++ b/src/osd/osdnet.cpp
@@ -61,7 +61,7 @@ int osd_netdev::send(uint8_t *buf, int len)
return 0;
}
-void osd_netdev::recv(void *ptr, int param)
+void osd_netdev::recv(int param)
{
uint8_t *buf;
int len;
diff --git a/src/osd/osdnet.h b/src/osd/osdnet.h
index 32e41663dcc..f18d7c5fea7 100644
--- a/src/osd/osdnet.h
+++ b/src/osd/osdnet.h
@@ -44,7 +44,7 @@ protected:
virtual int recv_dev(uint8_t **buf);
private:
- void recv(void *ptr, int param);
+ void recv(int param);
class device_network_interface *m_dev;
emu_timer *m_timer;
diff --git a/src/osd/osdsync.cpp b/src/osd/osdsync.cpp
index 85950b33093..6c6fec4dedf 100644
--- a/src/osd/osdsync.cpp
+++ b/src/osd/osdsync.cpp
@@ -85,14 +85,15 @@ static void spin_while_not(const volatile _AtomType * volatile atom, const _Main
// osd_num_processors
//============================================================
-int osd_get_num_processors()
+int osd_get_num_processors(bool heavy_mt)
{
#if defined(SDLMAME_EMSCRIPTEN)
// multithreading is not supported at this time
return 1;
#else
+ unsigned int threads = std::thread::hardware_concurrency();
// max out at 4 for now since scaling above that seems to do poorly
- return std::min(std::thread::hardware_concurrency(), 4U);
+ return heavy_mt ? threads : std::min(std::thread::hardware_concurrency(), 4U);
#endif
}
@@ -105,8 +106,7 @@ struct work_thread_info
work_thread_info(uint32_t aid, osd_work_queue &aqueue)
: queue(aqueue)
, handle(nullptr)
- , wakeevent(false, false) // auto-reset, not signalled
- , active(0)
+ , wakeevent(true, false) // manual reset, not signalled
, id(aid)
#if KEEP_STATISTICS
, itemsdone(0)
@@ -120,7 +120,6 @@ struct work_thread_info
osd_work_queue & queue; // pointer back to the queue
std::thread * handle; // handle to the thread
osd_event wakeevent; // wake event for the thread
- std::atomic<int32_t> active; // are we actively processing work?
uint32_t id;
#if KEEP_STATISTICS
@@ -211,7 +210,7 @@ int osd_num_processors = 0;
// FUNCTION PROTOTYPES
//============================================================
-static int effective_num_processors();
+static int effective_num_processors(bool heavy_mt);
static void * worker_thread_entry(void *param);
static void worker_thread_process(osd_work_queue *queue, work_thread_info *thread);
static bool queue_has_list_items(osd_work_queue *queue);
@@ -251,7 +250,7 @@ int thread_adjust_priority(std::thread *thread, int adjust)
osd_work_queue *osd_work_queue_alloc(int flags)
{
int threadnum;
- int numprocs = effective_num_processors();
+ int numprocs = effective_num_processors(!(flags & WORK_QUEUE_FLAG_HIGH_FREQ));
osd_work_queue *queue;
int osdthreadnum = 0;
int allocthreadnum;
@@ -544,10 +543,9 @@ osd_work_item *osd_work_item_queue_multiple(osd_work_queue *queue, osd_work_call
{
work_thread_info *thread = queue->thread[threadnum];
- // if this thread is not active, wake him up
- if (!thread->active)
+ // Attempt to wake the thread
+ if (thread->wakeevent.set())
{
- thread->wakeevent.set();
add_to_stat(queue->setevents, 1);
// for non-shared, the first one we find is good enough
@@ -639,9 +637,9 @@ void osd_work_item_release(osd_work_item *item)
// effective_num_processors
//============================================================
-static int effective_num_processors()
+static int effective_num_processors(bool heavy_mt)
{
- int physprocs = osd_get_num_processors();
+ int physprocs = osd_get_num_processors(heavy_mt);
// osd_num_processors == 0 for 'auto'
if (osd_num_processors > 0)
@@ -692,7 +690,6 @@ static void *worker_thread_entry(void *param)
break;
// indicate that we are live
- thread->active = true;
++queue.livethreads;
// process work items
@@ -717,7 +714,7 @@ static void *worker_thread_entry(void *param)
}
// decrement the live thread count
- thread->active = false;
+ thread->wakeevent.reset();
--queue.livethreads;
}
diff --git a/src/osd/osdsync.h b/src/osd/osdsync.h
index 3a286b60afa..cd8a6604c21 100644
--- a/src/osd/osdsync.h
+++ b/src/osd/osdsync.h
@@ -136,16 +136,17 @@ public:
Return value:
- None
+ Whether or not the event was actually signalled (false if the event had already been signalled)
Notes:
All threads waiting for the event will be signalled.
-----------------------------------------------------------------------------*/
- void set()
+ bool set()
{
m_mutex.lock();
- if (m_signalled == false)
+ bool needs_signal = !m_signalled;
+ if (needs_signal)
{
m_signalled = true;
if (m_autoreset)
@@ -154,13 +155,14 @@ public:
m_cond.notify_all();
}
m_mutex.unlock();
+ return needs_signal;
}
private:
std::mutex m_mutex;
std::condition_variable m_cond;
- std::atomic<int32_t> m_autoreset;
- std::atomic<int32_t> m_signalled;
+ int32_t m_autoreset;
+ int32_t m_signalled;
};
diff --git a/src/osd/sdl/sdlmain.cpp b/src/osd/sdl/sdlmain.cpp
index 1a65e48a846..3c57faeddbb 100644
--- a/src/osd/sdl/sdlmain.cpp
+++ b/src/osd/sdl/sdlmain.cpp
@@ -437,10 +437,21 @@ void sdl_osd_interface::init(running_machine &machine)
}
stemp = options().video_driver();
- if (stemp != nullptr && strcmp(stemp, OSDOPTVAL_AUTO) != 0)
+ if (stemp != nullptr)
{
- osd_printf_verbose("Setting SDL videodriver '%s' ...\n", stemp);
- osd_setenv(SDLENV_VIDEODRIVER, stemp, 1);
+ if (strcmp(stemp, OSDOPTVAL_AUTO) != 0)
+ {
+ osd_printf_verbose("Setting SDL videodriver '%s' ...\n", stemp);
+ osd_setenv(SDLENV_VIDEODRIVER, stemp, 1);
+ }
+ else
+ {
+#if defined(__linux__)
+ // bgfx does not work with wayland
+ osd_printf_verbose("Setting SDL videodriver '%s' ...\n", "x11");
+ osd_setenv(SDLENV_VIDEODRIVER, "x11", 1);
+#endif
+ }
}
stemp = options().render_driver();
diff --git a/src/osd/sdl/video.cpp b/src/osd/sdl/video.cpp
index 5bb3910d8f9..8212e0a4586 100644
--- a/src/osd/sdl/video.cpp
+++ b/src/osd/sdl/video.cpp
@@ -191,12 +191,10 @@ void sdl_osd_interface::extract_video_config()
stemp = options().video();
if (strcmp(stemp, "auto") == 0)
{
-#if (defined SDLMAME_WIN32)
- stemp = "opengl";
-#elif (defined SDLMAME_MACOSX)
- stemp = "bgfx";
-#else
+#if (defined SDLMAME_EMSCRIPTEN)
stemp = "soft";
+#else
+ stemp = "bgfx";
#endif
}
if (strcmp(stemp, SDLOPTVAL_SOFT) == 0)
diff --git a/src/osd/sdl/window.cpp b/src/osd/sdl/window.cpp
index 29ed4b920eb..0bf11ddfa9a 100644
--- a/src/osd/sdl/window.cpp
+++ b/src/osd/sdl/window.cpp
@@ -29,6 +29,7 @@
#include "emu.h"
#include "emuopts.h"
#include "render.h"
+#include "screen.h"
#include "ui/uimain.h"
// OSD headers
@@ -91,25 +92,55 @@ bool sdl_osd_interface::window_init()
{
osd_printf_verbose("Enter sdlwindow_init\n");
- // initialize the drawers
+ // initialize the renderer
+ const int fallbacks[VIDEO_MODE_COUNT] = {
+ -1, // NONE -> no fallback
+ -1, // No GDI on Linux
+#if defined(USE_OPENGL) && USE_OPENGL
+ VIDEO_MODE_OPENGL, // BGFX -> OpenGL
+ -1, // OpenGL -> no fallback
+#else
+ VIDEO_MODE_SDL2ACCEL, // BGFX -> SDL2Accel
+#endif
+ -1, // SDL2ACCEL -> no fallback
+ -1, // No D3D on Linux
+ -1, // SOFT -> no fallback
+ };
- switch (video_config.mode)
+ int current_mode = video_config.mode;
+ while (current_mode != VIDEO_MODE_NONE)
{
- case VIDEO_MODE_BGFX:
- renderer_bgfx::init(machine());
- break;
-#if (USE_OPENGL)
- case VIDEO_MODE_OPENGL:
- renderer_ogl::init(machine());
- break;
+ bool error = false;
+ switch(current_mode)
+ {
+ case VIDEO_MODE_BGFX:
+ error = renderer_bgfx::init(machine());
+ break;
+#if defined(USE_OPENGL) && USE_OPENGL
+ case VIDEO_MODE_OPENGL:
+ renderer_ogl::init(machine());
+ break;
#endif
- case VIDEO_MODE_SDL2ACCEL:
- renderer_sdl2::init(machine());
- break;
- case VIDEO_MODE_SOFT:
- renderer_sdl1::init(machine());
+ case VIDEO_MODE_SDL2ACCEL:
+ renderer_sdl2::init(machine());
+ break;
+ case VIDEO_MODE_SOFT:
+ renderer_sdl1::init(machine());
+ break;
+ default:
+ fatalerror("Unknown video mode.");
+ break;
+ }
+ if (error)
+ {
+ current_mode = fallbacks[current_mode];
+ }
+ else
+ {
break;
+ }
}
+ video_config.mode = current_mode;
/* We may want to set a number of the hints SDL2 provides.
* The code below will document which hints were set.
@@ -966,6 +997,10 @@ osd_rect sdl_window_info::constrain_to_aspect_ratio(const osd_rect &rect, int ad
// compute the visible area based on the proposed rectangle
target()->compute_visible_area(propwidth, propheight, pixel_aspect, target()->orientation(), viswidth, visheight);
+ // clamp visable area to the proposed rectangle
+ viswidth = std::min(viswidth, propwidth);
+ visheight = std::min(visheight, propheight);
+
// compute the adjustments we need to make
adjwidth = (viswidth + extrawidth) - rect.width();
adjheight = (visheight + extraheight) - rect.height();
@@ -1014,6 +1049,12 @@ osd_dim sdl_window_info::get_min_bounds(int constrain)
// get the minimum target size
target()->compute_minimum_size(minwidth, minheight);
+ // check if visible area is bigger
+ int32_t viswidth, visheight;
+ target()->compute_visible_area(minwidth, minheight, monitor()->aspect(), target()->orientation(), viswidth, visheight);
+ minwidth = std::max(viswidth, minwidth);
+ minheight = std::max(visheight, minheight);
+
// expand to our minimum dimensions
if (minwidth < MIN_WINDOW_DIM)
minwidth = MIN_WINDOW_DIM;
diff --git a/src/osd/strconv.cpp b/src/osd/strconv.cpp
index 4dafeddd398..737cb9fc1dc 100644
--- a/src/osd/strconv.cpp
+++ b/src/osd/strconv.cpp
@@ -254,6 +254,11 @@ std::string from_wstring(const WCHAR *s)
int osd_uchar_from_osdchar(char32_t *uchar, const char *osdchar, size_t count)
{
+ // FIXME: Does not handle charsets that use variable lengths encodings such
+ // as example GB18030 or UTF-8.
+ // FIXME: Assumes all characters can be converted into a single wchar_t
+ // which may not always be the case such as with surrogate pairs.
+
WCHAR wch;
CPINFO cp;
@@ -261,7 +266,7 @@ int osd_uchar_from_osdchar(char32_t *uchar, const char *osdchar, size_t count)
goto error;
// The multibyte char can't be bigger than the max character size
- count = std::min(count, size_t(cp.MaxCharSize));
+ count = std::min(count, size_t(IsDBCSLeadByte(*osdchar) ? cp.MaxCharSize : 1));
if (MultiByteToWideChar(CP_ACP, 0, osdchar, static_cast<DWORD>(count), &wch, 1) == 0)
goto error;
diff --git a/src/osd/windows/window.cpp b/src/osd/windows/window.cpp
index c5166d67a11..e8eaa39256a 100644
--- a/src/osd/windows/window.cpp
+++ b/src/osd/windows/window.cpp
@@ -8,9 +8,6 @@
#define LOG_TEMP_PAUSE 0
-// Needed for RAW Input
-#define WM_INPUT 0x00FF
-
// standard C headers
#include <process.h>
@@ -133,12 +130,13 @@ bool windows_osd_interface::window_init()
window_thread = GetCurrentThread();
window_threadid = main_threadid;
+ // initialize the renderer
const int fallbacks[VIDEO_MODE_COUNT] = {
-1, // NONE -> no fallback
VIDEO_MODE_NONE, // GDI -> NONE
VIDEO_MODE_D3D, // BGFX -> D3D
#if (USE_OPENGL)
- VIDEO_MODE_GDI, // OPENGL -> GDI
+ -1, // OPENGL -> no fallback
#endif
-1, // No SDL2ACCEL on Windows OSD
#if (USE_OPENGL)
@@ -154,7 +152,7 @@ bool windows_osd_interface::window_init()
{
bool error = false;
switch(current_mode)
- {
+ {
case VIDEO_MODE_NONE:
error = renderer_none::init(machine());
break;
@@ -304,6 +302,8 @@ win_window_info::win_window_info(
, m_targetview(0)
, m_targetorient(0)
, m_targetvismask(0)
+ , m_targetscalemode(0)
+ , m_targetkeepaspect(machine.options().keep_aspect())
, m_lastclicktime(std::chrono::steady_clock::time_point::min())
, m_lastclickx(0)
, m_lastclicky(0)
@@ -783,12 +783,17 @@ void win_window_info::update()
int const targetorient = target()->orientation();
render_layer_config const targetlayerconfig = target()->layer_config();
u32 const targetvismask = target()->visibility_mask();
- if (targetview != m_targetview || targetorient != m_targetorient || targetlayerconfig != m_targetlayerconfig || targetvismask != m_targetvismask)
+ int const targetscalemode = target()->scale_mode();
+ bool const targetkeepaspect = target()->keepaspect();
+ if (targetview != m_targetview || targetorient != m_targetorient || targetlayerconfig != m_targetlayerconfig || targetvismask != m_targetvismask ||
+ targetscalemode != m_targetscalemode || targetkeepaspect != m_targetkeepaspect)
{
m_targetview = targetview;
m_targetorient = targetorient;
m_targetlayerconfig = targetlayerconfig;
m_targetvismask = targetvismask;
+ m_targetscalemode = targetscalemode;
+ m_targetkeepaspect = targetkeepaspect;
// in window mode, reminimize/maximize
if (!fullscreen())
@@ -1105,6 +1110,21 @@ LRESULT CALLBACK win_window_info::video_window_proc(HWND wnd, UINT message, WPAR
return DefWindowProc(wnd, message, wparam, lparam);
break;
+ // input device change: handle RawInput device connection/disconnection
+ case WM_INPUT_DEVICE_CHANGE:
+ switch (wparam)
+ {
+ case GIDC_ARRIVAL:
+ downcast<windows_osd_interface&>(window->machine().osd()).handle_input_event(INPUT_EVENT_ARRIVAL, &lparam);
+ break;
+ case GIDC_REMOVAL:
+ downcast<windows_osd_interface&>(window->machine().osd()).handle_input_event(INPUT_EVENT_REMOVAL, &lparam);
+ break;
+ default:
+ return DefWindowProc(wnd, message, wparam, lparam);
+ }
+ break;
+
// input: handle the raw input
case WM_INPUT:
downcast<windows_osd_interface&>(window->machine().osd()).handle_input_event(INPUT_EVENT_RAWINPUT, &lparam);
@@ -1480,6 +1500,10 @@ osd_rect win_window_info::constrain_to_aspect_ratio(const osd_rect &rect, int ad
// compute the visible area based on the proposed rectangle
target()->compute_visible_area(propwidth, propheight, pixel_aspect, target()->orientation(), viswidth, visheight);
+ // clamp visable area to the proposed rectangle
+ viswidth = std::min(viswidth, propwidth);
+ visheight = std::min(visheight, propheight);
+
// compute the adjustments we need to make
adjwidth = (viswidth + extrawidth) - rect.width();
adjheight = (visheight + extraheight) - rect.height();
@@ -1528,6 +1552,12 @@ osd_dim win_window_info::get_min_bounds(int constrain)
// get the minimum target size
target()->compute_minimum_size(minwidth, minheight);
+ // check if visible area is bigger
+ int32_t viswidth, visheight;
+ target()->compute_visible_area(minwidth, minheight, monitor()->aspect(), target()->orientation(), viswidth, visheight);
+ minwidth = std::max(viswidth, minwidth);
+ minheight = std::max(visheight, minheight);
+
// expand to our minimum dimensions
if (minwidth < MIN_WINDOW_DIMX)
minwidth = MIN_WINDOW_DIMX;
@@ -1631,6 +1661,10 @@ void win_window_info::update_minmax_state()
(rect_height(&bounds) == minbounds.height());
m_ismaximized = (rect_width(&bounds) == maxbounds.width()) ||
(rect_height(&bounds) == maxbounds.height());
+
+ // We can't be maximized and minimized simultaneously
+ if (m_ismaximized)
+ m_isminimized = FALSE;
}
else
{
diff --git a/src/osd/windows/window.h b/src/osd/windows/window.h
index 6586420df66..ac7ccf3277d 100644
--- a/src/osd/windows/window.h
+++ b/src/osd/windows/window.h
@@ -107,6 +107,8 @@ public:
int m_targetorient;
render_layer_config m_targetlayerconfig;
u32 m_targetvismask;
+ int m_targetscalemode;
+ bool m_targetkeepaspect;
// input info
std::chrono::steady_clock::time_point m_lastclicktime;
diff --git a/src/osd/windows/winmain.cpp b/src/osd/windows/winmain.cpp
index ba66380f71e..77eeeaf476e 100644
--- a/src/osd/windows/winmain.cpp
+++ b/src/osd/windows/winmain.cpp
@@ -262,9 +262,9 @@ const options_entry windows_options::s_option_entries[] =
{ WINOPTION_BLOOM_LEVEL6_WEIGHT, "0.04", OPTION_FLOAT, "bloom level 6 weight (1/4 smaller that level 5 target)" },
{ WINOPTION_BLOOM_LEVEL7_WEIGHT, "0.02", OPTION_FLOAT, "bloom level 7 weight (1/4 smaller that level 6 target)" },
{ WINOPTION_BLOOM_LEVEL8_WEIGHT, "0.01", OPTION_FLOAT, "bloom level 8 weight (1/4 smaller that level 7 target)" },
- { WINOPTION_LUT_TEXTURE, "", OPTION_STRING, "3D LUT texture filename for screen, PNG format" },
+ { WINOPTION_LUT_TEXTURE, "lut-default.png", OPTION_STRING, "3D LUT texture filename for screen, PNG format" },
{ WINOPTION_LUT_ENABLE, "0", OPTION_BOOLEAN, "Enables 3D LUT to be applied to screen after post-processing" },
- { WINOPTION_UI_LUT_TEXTURE, "", OPTION_STRING, "3D LUT texture filename of UI, PNG format" },
+ { WINOPTION_UI_LUT_TEXTURE, "lut-default.png", OPTION_STRING, "3D LUT texture filename of UI, PNG format" },
{ WINOPTION_UI_LUT_ENABLE, "0", OPTION_BOOLEAN, "enable 3D LUT to be applied to UI and artwork after post-processing" },
// full screen options
diff --git a/src/osd/windows/winmain.h b/src/osd/windows/winmain.h
index ef1cd1aff4f..7c1689cff9f 100644
--- a/src/osd/windows/winmain.h
+++ b/src/osd/windows/winmain.h
@@ -243,6 +243,8 @@ enum input_event
INPUT_EVENT_KEYDOWN,
INPUT_EVENT_KEYUP,
INPUT_EVENT_RAWINPUT,
+ INPUT_EVENT_ARRIVAL,
+ INPUT_EVENT_REMOVAL,
INPUT_EVENT_MOUSE_BUTTON
};