summaryrefslogtreecommitdiffstatshomepage
path: root/src/osd/modules
diff options
context:
space:
mode:
author Giuseppe Gorgoglione <gorgogsp@gmail.com>2016-05-28 04:14:15 +0200
committer Giuseppe Gorgoglione <gorgogsp@gmail.com>2016-06-11 20:14:09 +0200
commit58dc78b6eba373d88fe7ef68f9ce3c2c43e635d6 (patch)
tree90af8c2c2323070c2c336153de8376d83a3f1f44 /src/osd/modules
parentea1b66f146e4c6663e06b124f8665f878c43ce0c (diff)
Introduce dynamic_module
This is a central cross-platform facility to dynamically bind functions from shared libraries. Updated all OSD modules to use it.
Diffstat (limited to 'src/osd/modules')
-rw-r--r--src/osd/modules/diagnostics/diagnostics_win32.cpp84
-rw-r--r--src/osd/modules/font/font_dwrite.cpp53
-rw-r--r--src/osd/modules/input/input_dinput.cpp18
-rw-r--r--src/osd/modules/input/input_dinput.h10
-rw-r--r--src/osd/modules/input/input_rawinput.cpp88
-rw-r--r--src/osd/modules/input/input_winhybrid.cpp2
-rw-r--r--src/osd/modules/input/input_xinput.cpp46
-rw-r--r--src/osd/modules/input/input_xinput.h40
-rw-r--r--src/osd/modules/lib/osdlib.h46
-rw-r--r--src/osd/modules/lib/osdlib_macosx.cpp74
-rw-r--r--src/osd/modules/lib/osdlib_unix.cpp75
-rw-r--r--src/osd/modules/lib/osdlib_win32.cpp84
-rw-r--r--src/osd/modules/netdev/pcap.cpp181
-rw-r--r--src/osd/modules/render/d3d/d3d9intf.cpp63
-rw-r--r--src/osd/modules/render/d3d/d3dcomm.h29
-rw-r--r--src/osd/modules/render/d3d/d3dhlsl.cpp208
-rw-r--r--src/osd/modules/render/d3d/d3dhlsl.h58
-rw-r--r--src/osd/modules/render/drawd3d.cpp576
-rw-r--r--src/osd/modules/render/drawd3d.h38
-rw-r--r--src/osd/modules/render/drawogl.cpp8
-rw-r--r--src/osd/modules/render/winglcontext.h94
-rwxr-xr-x[-rw-r--r--]src/osd/modules/sound/xaudio2_sound.cpp62
22 files changed, 1061 insertions, 876 deletions
diff --git a/src/osd/modules/diagnostics/diagnostics_win32.cpp b/src/osd/modules/diagnostics/diagnostics_win32.cpp
index d24bffe75a7..437b2b3ddb5 100644
--- a/src/osd/modules/diagnostics/diagnostics_win32.cpp
+++ b/src/osd/modules/diagnostics/diagnostics_win32.cpp
@@ -22,30 +22,21 @@
#include <memory>
#include <vector>
-#include <windows/winutil.h>
-template<typename _FunctionPtr>
-class dynamic_bind
-{
-public:
- // constructor which looks up the function
- dynamic_bind(const TCHAR *dll, const char *symbol)
- : m_function(nullptr)
- {
- HMODULE module = LoadLibrary(dll);
- if (module != nullptr)
- m_function = reinterpret_cast<_FunctionPtr>(GetProcAddress(module, symbol));
- }
+#include "modules/lib/osdlib.h"
- // bool to test if the function is nullptr or not
- operator bool() const { return (m_function != nullptr); }
+#include <windows/winutil.h>
- // dereference to get the underlying pointer
- _FunctionPtr operator *() const { return m_function; }
-
-private:
- _FunctionPtr m_function;
-};
+// Typedefs for dynamically loaded functions
+typedef BOOL WINAPI (*StackWalk64_fn)(DWORD, HANDLE, HANDLE, LPSTACKFRAME64, PVOID, PREAD_PROCESS_MEMORY_ROUTINE64, PFUNCTION_TABLE_ACCESS_ROUTINE64, PGET_MODULE_BASE_ROUTINE64, PTRANSLATE_ADDRESS_ROUTINE64);
+typedef BOOL WINAPI (*SymInitialize_fn)(HANDLE, LPCTSTR, BOOL);
+typedef PVOID WINAPI (*SymFunctionTableAccess64_fn)(HANDLE, DWORD64);
+typedef DWORD64 WINAPI (*SymGetModuleBase64_fn)(HANDLE, DWORD64);
+typedef BOOL WINAPI (*SymFromAddr_fn)(HANDLE, DWORD64, PDWORD64, PSYMBOL_INFO);
+typedef BOOL WINAPI (*SymGetLineFromAddr64_fn)(HANDLE, DWORD64, PDWORD, PIMAGEHLP_LINE64);
+typedef PIMAGE_SECTION_HEADER WINAPI (*ImageRvaToSection_fn)(PIMAGE_NT_HEADERS, PVOID, ULONG);
+typedef PIMAGE_NT_HEADERS WINAPI (*ImageNtHeader_fn)(PVOID);
+typedef VOID WINAPI (*RtlCaptureContext_fn)(PCONTEXT);
class stack_walker
{
@@ -67,12 +58,14 @@ private:
CONTEXT m_context;
bool m_first;
- dynamic_bind<BOOL(WINAPI *)(DWORD, HANDLE, HANDLE, LPSTACKFRAME64, PVOID, PREAD_PROCESS_MEMORY_ROUTINE64, PFUNCTION_TABLE_ACCESS_ROUTINE64, PGET_MODULE_BASE_ROUTINE64, PTRANSLATE_ADDRESS_ROUTINE64)>
- m_stack_walk_64;
- dynamic_bind<BOOL(WINAPI *)(HANDLE, LPCTSTR, BOOL)> m_sym_initialize;
- dynamic_bind<PVOID(WINAPI *)(HANDLE, DWORD64)> m_sym_function_table_access_64;
- dynamic_bind<DWORD64(WINAPI *)(HANDLE, DWORD64)> m_sym_get_module_base_64;
- dynamic_bind<VOID(WINAPI *)(PCONTEXT)> m_rtl_capture_context;
+ osd::dynamic_module::ptr m_dbghelp_dll;
+ osd::dynamic_module::ptr m_kernel32_dll;
+
+ StackWalk64_fn m_stack_walk_64;
+ SymInitialize_fn m_sym_initialize;
+ SymFunctionTableAccess64_fn m_sym_function_table_access_64;
+ SymGetModuleBase64_fn m_sym_get_module_base_64;
+ RtlCaptureContext_fn m_rtl_capture_context;
static bool s_initialized;
};
@@ -126,8 +119,10 @@ private:
FPTR m_last_base;
FPTR m_text_base;
- dynamic_bind<BOOL(WINAPI *)(HANDLE, DWORD64, PDWORD64, PSYMBOL_INFO)> m_sym_from_addr;
- dynamic_bind<BOOL(WINAPI *)(HANDLE, DWORD64, PDWORD, PIMAGEHLP_LINE64)> m_sym_get_line_from_addr_64;
+ osd::dynamic_module::ptr m_dbghelp_dll;
+
+ SymFromAddr_fn m_sym_from_addr;
+ SymGetLineFromAddr64_fn m_sym_get_line_from_addr_64;
};
class sampling_profiler
@@ -176,17 +171,21 @@ bool stack_walker::s_initialized = false;
stack_walker::stack_walker()
: m_process(GetCurrentProcess()),
m_thread(GetCurrentThread()),
- m_first(true),
- m_stack_walk_64(TEXT("dbghelp.dll"), "StackWalk64"),
- m_sym_initialize(TEXT("dbghelp.dll"), "SymInitialize"),
- m_sym_function_table_access_64(TEXT("dbghelp.dll"), "SymFunctionTableAccess64"),
- m_sym_get_module_base_64(TEXT("dbghelp.dll"), "SymGetModuleBase64"),
- m_rtl_capture_context(TEXT("kernel32.dll"), "RtlCaptureContext")
+ m_first(true)
{
// zap the structs
memset(&m_stackframe, 0, sizeof(m_stackframe));
memset(&m_context, 0, sizeof(m_context));
+ m_dbghelp_dll = osd::dynamic_module::open({ "dbghelp.dll" });
+ m_kernel32_dll = osd::dynamic_module::open({ "kernel32.dll" });
+
+ m_stack_walk_64 = m_dbghelp_dll->bind<StackWalk64_fn>("StackWalk64");
+ m_sym_initialize = m_dbghelp_dll->bind<SymInitialize_fn>("SymInitialize");
+ m_sym_function_table_access_64 = m_dbghelp_dll->bind<SymFunctionTableAccess64_fn>("SymFunctionTableAccess64");
+ m_sym_get_module_base_64 = m_dbghelp_dll->bind<SymGetModuleBase64_fn>("SymGetModuleBase64");
+ m_rtl_capture_context = m_kernel32_dll->bind<RtlCaptureContext_fn>("RtlCaptureContext");
+
// initialize the symbols
if (!s_initialized && m_sym_initialize && m_stack_walk_64 && m_sym_function_table_access_64 && m_sym_get_module_base_64)
{
@@ -294,9 +293,7 @@ symbol_manager::symbol_manager(const char *argv0)
m_symfile(argv0),
m_process(GetCurrentProcess()),
m_last_base(0),
- m_text_base(0),
- m_sym_from_addr(TEXT("dbghelp.dll"), "SymFromAddr"),
- m_sym_get_line_from_addr_64(TEXT("dbghelp.dll"), "SymGetLineFromAddr64")
+ m_text_base(0)
{
#ifdef __GNUC__
// compute the name of the mapfile
@@ -317,6 +314,11 @@ symbol_manager::symbol_manager(const char *argv0)
// expand the buffer to be decently large up front
m_buffer = string_format("%500s", "");
+
+ m_dbghelp_dll = osd::dynamic_module::open({ "dbghelp.dll" });
+
+ m_sym_from_addr = m_dbghelp_dll->bind<SymFromAddr_fn>("SymFromAddr");
+ m_sym_get_line_from_addr_64 = m_dbghelp_dll->bind<SymGetLineFromAddr64_fn>("SymGetLineFromAddr64");
}
@@ -603,8 +605,10 @@ void symbol_manager::format_symbol(const char *name, UINT32 displacement, const
FPTR symbol_manager::get_text_section_base()
{
- dynamic_bind<PIMAGE_SECTION_HEADER(WINAPI *)(PIMAGE_NT_HEADERS, PVOID, ULONG)> image_rva_to_section(TEXT("dbghelp.dll"), "ImageRvaToSection");
- dynamic_bind<PIMAGE_NT_HEADERS(WINAPI *)(PVOID)> image_nt_header(TEXT("dbghelp.dll"), "ImageNtHeader");
+ osd::dynamic_module::ptr m_dbghelp_dll = osd::dynamic_module::open({ "dbghelp.dll" });
+
+ ImageRvaToSection_fn image_rva_to_section = m_dbghelp_dll->bind<ImageRvaToSection_fn>("ImageRvaToSection");
+ ImageNtHeader_fn image_nt_header = m_dbghelp_dll->bind<ImageNtHeader_fn>("ImageNtHeader");
// start with the image base
PVOID base = reinterpret_cast<PVOID>(GetModuleHandleUni());
diff --git a/src/osd/modules/font/font_dwrite.cpp b/src/osd/modules/font/font_dwrite.cpp
index f119be4523d..e816f296294 100644
--- a/src/osd/modules/font/font_dwrite.cpp
+++ b/src/osd/modules/font/font_dwrite.cpp
@@ -7,6 +7,7 @@
#include "font_module.h"
#include "modules/osdmodule.h"
+#include "modules/lib/osdlib.h"
// We take dependencies on WRL client headers and
// we can only build with a high enough version
@@ -78,8 +79,8 @@ struct osd_deleter
typedef std::unique_ptr<char, osd_deleter> osd_utf8_ptr;
// Typedefs for dynamically loaded functions
-typedef lazy_loaded_function_p4<HRESULT, D2D1_FACTORY_TYPE, REFIID, const D2D1_FACTORY_OPTIONS*, void**> d2d_create_factory_fn;
-typedef lazy_loaded_function_p3<HRESULT, DWRITE_FACTORY_TYPE, REFIID, IUnknown**> dwrite_create_factory_fn;
+typedef HRESULT WINAPI (*d2d_create_factory_fn)(D2D1_FACTORY_TYPE, REFIID, const D2D1_FACTORY_OPTIONS *, void **);
+typedef HRESULT (*dwrite_create_factory_fn)(DWRITE_FACTORY_TYPE, REFIID, IUnknown **);
// Debugging functions
#ifdef DWRITE_DEBUGGING
@@ -96,13 +97,17 @@ HRESULT SaveBitmap(IWICBitmap* bitmap, GUID pixelFormat, const WCHAR *filename)
ComPtr<IDWriteFactory> dwriteFactory;
ComPtr<IWICImagingFactory> wicFactory;
- d2d_create_factory_fn pfn_D2D1CreateFactory("D2D1CreateFactory", L"D2d1.dll");
- dwrite_create_factory_fn pfn_DWriteCreateFactory("DWriteCreateFactory", L"Dwrite.dll");
- HR_RETHR(pfn_D2D1CreateFactory.initialize());
- HR_RETHR(pfn_DWriteCreateFactory.initialize());
+ osd::dynamic_module::ptr d2d1_dll = osd::dynamic_module::open({ "d2d1.dll" });
+ osd::dynamic_module::ptr dwrite_dll = osd::dynamic_module::open({ "dwrite.dll" });
+
+ d2d_create_factory_fn pfn_D2D1CreateFactory = d2d1_dll->bind<d2d_create_factory_fn>("D2D1CreateFactory");
+ dwrite_create_factory_fn pfn_DWriteCreateFactory = dwrite_dll->bind<dwrite_create_factory_fn>("DWriteCreateFactory");
+
+ if (!pfn_D2D1CreateFactory || !pfn_DWriteCreateFactory)
+ return ERROR_DLL_NOT_FOUND;
// Create a Direct2D factory
- HR_RETHR(pfn_D2D1CreateFactory(
+ HR_RETHR((*pfn_D2D1CreateFactory)(
D2D1_FACTORY_TYPE_SINGLE_THREADED,
__uuidof(ID2D1Factory1),
nullptr,
@@ -112,7 +117,7 @@ HRESULT SaveBitmap(IWICBitmap* bitmap, GUID pixelFormat, const WCHAR *filename)
CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED);
// Create a DirectWrite factory.
- HR_RETHR(pfn_DWriteCreateFactory(
+ HR_RETHR((*pfn_DWriteCreateFactory)(
DWRITE_FACTORY_TYPE_SHARED,
__uuidof(IDWriteFactory),
reinterpret_cast<IUnknown **>(dwriteFactory.GetAddressOf())));
@@ -652,18 +657,18 @@ private:
class font_dwrite : public osd_module, public font_module
{
private:
- d2d_create_factory_fn m_pfnD2D1CreateFactory;
- dwrite_create_factory_fn m_pfnDWriteCreateFactory;
- ComPtr<ID2D1Factory> m_d2dfactory;
- ComPtr<IDWriteFactory> m_dwriteFactory;
- ComPtr<IWICImagingFactory> m_wicFactory;
+ osd::dynamic_module::ptr m_d2d1_dll;
+ osd::dynamic_module::ptr m_dwrite_dll;
+ d2d_create_factory_fn m_pfnD2D1CreateFactory;
+ dwrite_create_factory_fn m_pfnDWriteCreateFactory;
+ ComPtr<ID2D1Factory> m_d2dfactory;
+ ComPtr<IDWriteFactory> m_dwriteFactory;
+ ComPtr<IWICImagingFactory> m_wicFactory;
public:
font_dwrite() :
osd_module(OSD_FONT_PROVIDER, "dwrite"),
font_module(),
- m_pfnD2D1CreateFactory("D2D1CreateFactory", L"D2d1.dll"),
- m_pfnDWriteCreateFactory("DWriteCreateFactory", L"Dwrite.dll"),
m_d2dfactory(nullptr),
m_dwriteFactory(nullptr),
m_wicFactory(nullptr)
@@ -672,12 +677,15 @@ public:
virtual bool probe() override
{
+ m_d2d1_dll = osd::dynamic_module::open({ "d2d1.dll" });
+ m_dwrite_dll = osd::dynamic_module::open({ "dwrite.dll" });
+
+ m_pfnD2D1CreateFactory = m_d2d1_dll->bind<d2d_create_factory_fn>("D2D1CreateFactory");
+ m_pfnDWriteCreateFactory = m_dwrite_dll->bind<dwrite_create_factory_fn>("DWriteCreateFactory");
+
// This module is available if it can load the expected API Functions
- if (m_pfnD2D1CreateFactory.initialize() != 0
- || m_pfnDWriteCreateFactory.initialize() != 0)
- {
+ if (!m_pfnD2D1CreateFactory || !m_pfnDWriteCreateFactory)
return false;
- }
return true;
}
@@ -689,15 +697,14 @@ public:
osd_printf_verbose("FontProvider: Initializing DirectWrite\n");
// Make sure we can initialize our api functions
- if (m_pfnD2D1CreateFactory.initialize()
- || m_pfnDWriteCreateFactory.initialize())
+ if (!m_pfnD2D1CreateFactory || !m_pfnDWriteCreateFactory)
{
osd_printf_error("ERROR: FontProvider: Failed to load DirectWrite functions.\n");
return -1;
}
// Create a Direct2D factory.
- HR_RET1(m_pfnD2D1CreateFactory(
+ HR_RET1((*m_pfnD2D1CreateFactory)(
D2D1_FACTORY_TYPE_SINGLE_THREADED,
__uuidof(ID2D1Factory),
nullptr,
@@ -707,7 +714,7 @@ public:
CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED);
// Create a DirectWrite factory.
- HR_RET1(m_pfnDWriteCreateFactory(
+ HR_RET1((*m_pfnDWriteCreateFactory)(
DWRITE_FACTORY_TYPE_SHARED,
__uuidof(IDWriteFactory),
reinterpret_cast<IUnknown **>(m_dwriteFactory.GetAddressOf())));
diff --git a/src/osd/modules/input/input_dinput.cpp b/src/osd/modules/input/input_dinput.cpp
index 5ce00b93a06..21874cbbe95 100644
--- a/src/osd/modules/input/input_dinput.cpp
+++ b/src/osd/modules/input/input_dinput.cpp
@@ -136,8 +136,7 @@ void dinput_keyboard_device::reset()
dinput_api_helper::dinput_api_helper(int version)
: m_dinput(nullptr),
- m_dinput_version(version),
- m_pfn_DirectInputCreate("DirectInputCreateW", L"dinput.dll")
+ m_dinput_version(version)
{
}
@@ -163,18 +162,23 @@ int dinput_api_helper::initialize()
else
#endif
{
- result = m_pfn_DirectInputCreate.initialize();
- if (result != DI_OK)
- return result;
+ m_dinput_dll = osd::dynamic_module::open({ "dinput.dll" });
+
+ m_dinput_create_prt = m_dinput_dll->bind<dinput_create_fn>("DirectInputCreateW");
+ if (m_dinput_create_prt == nullptr)
+ {
+ osd_printf_verbose("Legacy DirectInput library dinput.dll is not available\n");
+ return ERROR_DLL_NOT_FOUND;
+ }
// first attempt to initialize DirectInput at v7
m_dinput_version = 0x0700;
- result = m_pfn_DirectInputCreate(GetModuleHandleUni(), m_dinput_version, m_dinput.GetAddressOf(), nullptr);
+ result = (*m_dinput_create_prt)(GetModuleHandleUni(), m_dinput_version, m_dinput.GetAddressOf(), nullptr);
if (result != DI_OK)
{
// if that fails, try version 5
m_dinput_version = 0x0500;
- result = m_pfn_DirectInputCreate(GetModuleHandleUni(), m_dinput_version, m_dinput.GetAddressOf(), nullptr);
+ result = (*m_dinput_create_prt)(GetModuleHandleUni(), m_dinput_version, m_dinput.GetAddressOf(), nullptr);
if (result != DI_OK)
{
m_dinput_version = 0;
diff --git a/src/osd/modules/input/input_dinput.h b/src/osd/modules/input/input_dinput.h
index 6a8eba3e24a..7005ed0a305 100644
--- a/src/osd/modules/input/input_dinput.h
+++ b/src/osd/modules/input/input_dinput.h
@@ -2,7 +2,7 @@
#define INPUT_DINPUT_H_
#include "input_common.h"
-#include "winutil.h"
+#include "modules/lib/osdlib.h"
//============================================================
// dinput_device - base directinput device
@@ -43,10 +43,11 @@ public:
virtual BOOL device_enum_callback(LPCDIDEVICEINSTANCE instance, LPVOID ref) = 0;
};
+// Typedef for dynamically loaded function
#if DIRECTINPUT_VERSION >= 0x0800
-typedef lazy_loaded_function_p4<HRESULT, HMODULE, int, IDirectInput8 **, LPUNKNOWN> pfn_dinput_create;
+typedef HRESULT WINAPI (*dinput_create_fn)(HINSTANCE, DWORD, LPDIRECTINPUT8 *, LPUNKNOWN);
#else
-typedef lazy_loaded_function_p4<HRESULT, HMODULE, int, IDirectInput **, LPUNKNOWN> pfn_dinput_create;
+typedef HRESULT WINAPI (*dinput_create_fn)(HINSTANCE, DWORD, LPDIRECTINPUT *, LPUNKNOWN);
#endif
class dinput_api_helper
@@ -58,7 +59,8 @@ private:
Microsoft::WRL::ComPtr<IDirectInput> m_dinput;
#endif
int m_dinput_version;
- pfn_dinput_create m_pfn_DirectInputCreate;
+ osd::dynamic_module::ptr m_dinput_dll;
+ dinput_create_fn m_dinput_create_prt;
public:
dinput_api_helper(int version);
diff --git a/src/osd/modules/input/input_rawinput.cpp b/src/osd/modules/input/input_rawinput.cpp
index ecfae316d41..cfab7dcdb5a 100644
--- a/src/osd/modules/input/input_rawinput.cpp
+++ b/src/osd/modules/input/input_rawinput.cpp
@@ -26,7 +26,7 @@
#include "strconv.h"
// MAMEOS headers
-#include "winutil.h"
+#include "modules/lib/osdlib.h"
#include "winmain.h"
#include "window.h"
@@ -37,17 +37,11 @@
// MACROS
//============================================================
-#ifdef UNICODE
-#define UNICODE_SUFFIX "W"
-#else
-#define UNICODE_SUFFIX "A"
-#endif
-
-// RawInput APIs
-typedef lazy_loaded_function_p3<INT, PRAWINPUTDEVICELIST, PINT, UINT> get_rawinput_device_list_ptr;
-typedef lazy_loaded_function_p5<INT, HRAWINPUT, UINT, LPVOID, PINT, UINT> get_rawinput_data_ptr;
-typedef lazy_loaded_function_p4<INT, HANDLE, UINT, LPVOID, PINT> get_rawinput_device_info_ptr;
-typedef lazy_loaded_function_p3<BOOL, PCRAWINPUTDEVICE, UINT, UINT> register_rawinput_devices_ptr;
+// 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
{
@@ -395,13 +389,6 @@ public:
}
};
-/*
-register_rawinput_devices = (register_rawinput_devices_ptr)GetProcAddress(user32, "RegisterRawInputDevices");
-get_rawinput_device_list = (get_rawinput_device_list_ptr)GetProcAddress(user32, "GetRawInputDeviceList");
-get_rawinput_device_info = (get_rawinput_device_info_ptr)GetProcAddress(user32, "GetRawInputDeviceInfo" UNICODE_SUFFIX);
-get_rawinput_data = (get_rawinput_data_ptr)GetProcAddress(user32, "GetRawInputData");
-*/
-
//============================================================
// rawinput_module - base class for rawinput modules
//============================================================
@@ -409,32 +396,33 @@ get_rawinput_data = (get_rawinput_data_ptr)GetProcAddress(user32, "GetRawInputDa
class rawinput_module : public wininput_module
{
private:
- // RawInput variables
- get_rawinput_device_list_ptr get_rawinput_device_list;
- get_rawinput_data_ptr get_rawinput_data;
- get_rawinput_device_info_ptr get_rawinput_device_info;
- register_rawinput_devices_ptr register_rawinput_devices;
- std::mutex m_module_lock;
+ osd::dynamic_module::ptr m_user32_dll;
+ get_rawinput_device_list_ptr get_rawinput_device_list;
+ get_rawinput_data_ptr get_rawinput_data;
+ get_rawinput_device_info_ptr get_rawinput_device_info;
+ register_rawinput_devices_ptr register_rawinput_devices;
+ std::mutex m_module_lock;
public:
rawinput_module(const char *type, const char* name)
- : wininput_module(type, name),
- get_rawinput_device_list("GetRawInputDeviceList", L"user32.dll"),
- get_rawinput_data("GetRawInputData", L"user32.dll"),
- get_rawinput_device_info("GetRawInputDeviceInfoW", L"user32.dll"),
- register_rawinput_devices("RegisterRawInputDevices", L"user32.dll")
+ : wininput_module(type, name)
{
}
bool probe() override
{
- int status = get_rawinput_device_list.initialize();
- status |= get_rawinput_data.initialize();
- status |= get_rawinput_device_info.initialize();
- status |= register_rawinput_devices.initialize();
+ 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");
- if (status != 0)
+ if (!get_rawinput_device_list || !get_rawinput_data ||
+ !get_rawinput_device_info || !register_rawinput_devices )
+ {
return false;
+ }
return true;
}
@@ -442,15 +430,15 @@ public:
void input_init(running_machine &machine) override
{
// get the number of devices, allocate a device list, and fetch it
- int device_count = 0;
- if (get_rawinput_device_list(nullptr, &device_count, sizeof(RAWINPUTDEVICELIST)) != 0)
+ UINT device_count = 0;
+ if ((*get_rawinput_device_list)(nullptr, &device_count, sizeof(RAWINPUTDEVICELIST)) != 0)
return;
if (device_count == 0)
return;
auto rawinput_devices = std::make_unique<RAWINPUTDEVICELIST[]>(device_count);
- if (get_rawinput_device_list(rawinput_devices.get(), &device_count, sizeof(RAWINPUTDEVICELIST)) == -1)
+ if ((*get_rawinput_device_list)(rawinput_devices.get(), &device_count, sizeof(RAWINPUTDEVICELIST)) == -1)
return;
// iterate backwards through devices; new devices are added at the head
@@ -478,7 +466,7 @@ public:
registration.hwndTarget = osd_common_t::s_window_list.front()->platform_window<HWND>();
// register the device
- register_rawinput_devices(&registration, 1, sizeof(registration));
+ (*register_rawinput_devices)(&registration, 1, sizeof(registration));
}
protected:
@@ -488,13 +476,11 @@ protected:
int init_internal() override
{
- // look up the entry points
- int status = get_rawinput_device_list.initialize();
- status |= get_rawinput_data.initialize();
- status |= get_rawinput_device_info.initialize();
- status |= register_rawinput_devices.initialize();
- if (status != 0)
+ 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;
@@ -504,13 +490,13 @@ protected:
TDevice* create_rawinput_device(running_machine &machine, PRAWINPUTDEVICELIST rawinputdevice)
{
TDevice* devinfo;
- INT name_length = 0;
+ UINT name_length = 0;
// determine the length of the device name, allocate it, and fetch it if not nameless
- if (get_rawinput_device_info(rawinputdevice->hDevice, RIDI_DEVICENAME, nullptr, &name_length) != 0)
+ if ((*get_rawinput_device_info)(rawinputdevice->hDevice, RIDI_DEVICENAME, nullptr, &name_length) != 0)
return nullptr;
std::unique_ptr<TCHAR[]> tname = std::make_unique<TCHAR[]>(name_length + 1);
- if (name_length > 1 && get_rawinput_device_info(rawinputdevice->hDevice, RIDI_DEVICENAME, tname.get(), &name_length) == -1)
+ if (name_length > 1 && (*get_rawinput_device_info)(rawinputdevice->hDevice, RIDI_DEVICENAME, tname.get(), &name_length) == -1)
return nullptr;
// if this is an RDP name, skip it
@@ -544,14 +530,14 @@ protected:
std::unique_ptr<BYTE[]> larger_buffer;
LPBYTE data = small_buffer;
BOOL result;
- int size;
+ UINT size;
// ignore if not enabled
if (!input_enabled())
return FALSE;
// determine the size of databuffer we need
- if (get_rawinput_data(rawinputdevice, RID_INPUT, nullptr, &size, sizeof(RAWINPUTHEADER)) != 0)
+ if ((*get_rawinput_data)(rawinputdevice, RID_INPUT, nullptr, &size, sizeof(RAWINPUTHEADER)) != 0)
return FALSE;
// if necessary, allocate a temporary buffer and fetch the data
@@ -564,7 +550,7 @@ protected:
}
// fetch the data and process the appropriate message types
- result = get_rawinput_data(static_cast<HRAWINPUT>(rawinputdevice), RID_INPUT, data, &size, sizeof(RAWINPUTHEADER));
+ 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);
diff --git a/src/osd/modules/input/input_winhybrid.cpp b/src/osd/modules/input/input_winhybrid.cpp
index 968edbf1624..a7453d59cf8 100644
--- a/src/osd/modules/input/input_winhybrid.cpp
+++ b/src/osd/modules/input/input_winhybrid.cpp
@@ -218,7 +218,7 @@ protected:
{
XINPUT_STATE state = { 0 };
- if (m_xinput_helper->XInputGetState(i, &state) == ERROR_SUCCESS)
+ if (m_xinput_helper->xinput_get_state(i, &state) == ERROR_SUCCESS)
{
// allocate and link in a new device
devinfo = m_xinput_helper->create_xinput_device(machine, i, *this);
diff --git a/src/osd/modules/input/input_xinput.cpp b/src/osd/modules/input/input_xinput.cpp
index 593cf16fc28..2d01b702bd8 100644
--- a/src/osd/modules/input/input_xinput.cpp
+++ b/src/osd/modules/input/input_xinput.cpp
@@ -32,50 +32,28 @@
#include "input_windows.h"
#include "input_xinput.h"
-
-xinput_api_helper::xinput_api_helper()
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
- : XInputGetState("XInputGetState", xinput_dll_names, ARRAY_LENGTH(xinput_dll_names))
- , XInputGetCapabilities("XInputGetCapabilities", xinput_dll_names, ARRAY_LENGTH(xinput_dll_names))
+#define XINPUT_LIBRARIES { "xinput1_4.dll", "xinput9_1_0.dll" }
+#else
+#define XINPUT_LIBRARIES { "xinput1_4.dll" }
#endif
-{
-}
int xinput_api_helper::initialize()
{
-#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
- int status;
- status = XInputGetState.initialize();
- if (status != 0)
- {
- osd_printf_verbose("Failed to initialize function pointer for %s. Error: %d\n", XInputGetState.name(), status);
- return -1;
- }
+ m_xinput_dll = osd::dynamic_module::open(XINPUT_LIBRARIES);
- status = XInputGetCapabilities.initialize();
- if (status != 0)
+ XInputGetState = m_xinput_dll->bind<xinput_get_state_fn>("XInputGetState");
+ XInputGetCapabilities = m_xinput_dll->bind<xinput_get_caps_fn>("XInputGetCapabilities");
+
+ if (!XInputGetState || !XInputGetCapabilities)
{
- osd_printf_verbose("Failed to initialize function pointer for %s. Error: %d\n", XInputGetCapabilities.name(), status);
+ osd_printf_verbose("Could not find XInput. Please try to reinstall DirectX runtime package.\n");
return -1;
}
-#endif
return 0;
}
-#if !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
-// Pass-through functions for Universal Windows
-inline DWORD xinput_api_helper::XInputGetState(DWORD dwUserindex, XINPUT_STATE *pState)
-{
- return ::XInputGetState(dwUserindex, pState);
-}
-
-inline DWORD xinput_api_helper::XInputGetCapabilities(DWORD dwUserindex, DWORD dwFlags, XINPUT_CAPABILITIES* pCapabilities)
-{
- return ::XInputGetCapabilities(dwUserindex, dwFlags, pCapabilities);
-}
-#endif
-
//============================================================
// create_xinput_device
//============================================================
@@ -85,7 +63,7 @@ xinput_joystick_device * xinput_api_helper::create_xinput_device(running_machine
xinput_joystick_device *devinfo;
XINPUT_CAPABILITIES caps = { 0 };
- if (FAILED(XInputGetCapabilities(index, 0, &caps)))
+ if (FAILED(xinput_get_capabilities(index, 0, &caps)))
{
// If we can't get the capabilities skip this device
return nullptr;
@@ -125,7 +103,7 @@ void xinput_joystick_device::poll()
return;
// poll the device first
- HRESULT result = m_xinput_helper->XInputGetState(xinput_state.player_index, &xinput_state.xstate);
+ HRESULT result = m_xinput_helper->xinput_get_state(xinput_state.player_index, &xinput_state.xstate);
// If we can't poll the device, skip
if (FAILED(result))
@@ -262,7 +240,7 @@ protected:
{
XINPUT_STATE state = {0};
- if (m_xinput_helper->XInputGetState(i, &state) == ERROR_SUCCESS)
+ if (m_xinput_helper->xinput_get_state(i, &state) == ERROR_SUCCESS)
{
// allocate and link in a new device
devinfo = m_xinput_helper->create_xinput_device(machine, i, *this);
diff --git a/src/osd/modules/input/input_xinput.h b/src/osd/modules/input/input_xinput.h
index 791fc36f310..575f6d3fe34 100644
--- a/src/osd/modules/input/input_xinput.h
+++ b/src/osd/modules/input/input_xinput.h
@@ -3,6 +3,8 @@
#include <mutex>
+#include "modules/lib/osdlib.h"
+
#define XINPUT_MAX_POV 4
#define XINPUT_MAX_BUTTONS 10
#define XINPUT_MAX_AXIS 4
@@ -88,34 +90,30 @@ struct xinput_api_state
XINPUT_CAPABILITIES caps;
};
-#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
-// Typedef for pointers to XInput Functions
-typedef lazy_loaded_function_p2<DWORD, DWORD, XINPUT_STATE*> xinput_get_state_fn;
-typedef lazy_loaded_function_p3<DWORD, DWORD, DWORD, XINPUT_CAPABILITIES*> xinput_get_caps_fn;
-#endif
+// Typedefs for dynamically loaded functions
+typedef DWORD (*xinput_get_state_fn)(DWORD, XINPUT_STATE *);
+typedef DWORD (*xinput_get_caps_fn)(DWORD, DWORD, XINPUT_CAPABILITIES *);
class xinput_api_helper : public std::enable_shared_from_this<xinput_api_helper>
{
-#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
-private:
- const wchar_t* xinput_dll_names[2] = { L"xinput1_4.dll", L"xinput9_1_0.dll" };
-
-public:
- xinput_get_state_fn XInputGetState;
- xinput_get_caps_fn XInputGetCapabilities;
-#endif
-
public:
- xinput_api_helper();
-
int initialize();
xinput_joystick_device * create_xinput_device(running_machine &machine, UINT index, wininput_module &module);
-#if !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
- // Pass-through functions for Universal Windows
- inline DWORD XInputGetState(DWORD dwUserindex, XINPUT_STATE *pState);
- inline DWORD XInputGetCapabilities(DWORD dwUserindex, DWORD dwFlags, XINPUT_CAPABILITIES* pCapabilities);
-#endif
+ inline DWORD xinput_get_state(DWORD dwUserindex, XINPUT_STATE *pState)
+ {
+ return (*XInputGetState)(dwUserindex, pState);
+ }
+
+ inline DWORD xinput_get_capabilities(DWORD dwUserindex, DWORD dwFlags, XINPUT_CAPABILITIES* pCapabilities)
+ {
+ return (*XInputGetCapabilities)(dwUserindex, dwFlags, pCapabilities);
+ }
+
+private:
+ osd::dynamic_module::ptr m_xinput_dll;
+ xinput_get_state_fn XInputGetState;
+ xinput_get_caps_fn XInputGetCapabilities;
};
class xinput_joystick_device : public device_info
diff --git a/src/osd/modules/lib/osdlib.h b/src/osd/modules/lib/osdlib.h
index f4a632dbbd1..64bd556cd3c 100644
--- a/src/osd/modules/lib/osdlib.h
+++ b/src/osd/modules/lib/osdlib.h
@@ -19,6 +19,10 @@
#ifndef __OSDLIB__
#define __OSDLIB__
+#include <string>
+#include <type_traits>
+#include <vector>
+
/*-----------------------------------------------------------------------------
osd_process_kill: kill the current process
@@ -30,8 +34,10 @@
None.
-----------------------------------------------------------------------------*/
+
void osd_process_kill(void);
+
/*-----------------------------------------------------------------------------
osd_setenv: set environment variable
@@ -48,14 +54,52 @@ void osd_process_kill(void);
int osd_setenv(const char *name, const char *value, int overwrite);
+
/*-----------------------------------------------------------------------------
osd_get_clipboard_text: retrieves text from the clipboard
Return value:
the returned string needs to be osd_free()-ed!
-
-----------------------------------------------------------------------------*/
+
char *osd_get_clipboard_text(void);
+
+/*-----------------------------------------------------------------------------
+ dynamic_module: load functions from optional shared libraries
+
+ Notes:
+
+ - Supports Mac OS X, Unix and Windows (both desktop and Windows
+ Store universal applications)
+ - A symbol can be searched in a list of libraries (e.g. more
+ revisions of a same library)
+-----------------------------------------------------------------------------*/
+
+namespace osd {
+
+class dynamic_module
+{
+public:
+ typedef std::unique_ptr<dynamic_module> ptr;
+
+ static ptr open(std::vector<std::string> &&libraries);
+
+ virtual ~dynamic_module() { };
+
+ template <typename T>
+ typename std::enable_if<std::is_pointer<T>::value, T>::type bind(char const *symbol)
+ {
+ return reinterpret_cast<T>(get_symbol_address(symbol));
+ }
+
+protected:
+ typedef void (*generic_fptr_t)();
+
+ virtual generic_fptr_t get_symbol_address(char const *symbol) = 0;
+};
+
+} // namespace osd
+
#endif /* __OSDLIB__ */
diff --git a/src/osd/modules/lib/osdlib_macosx.cpp b/src/osd/modules/lib/osdlib_macosx.cpp
index 07cfa05226a..b3a7ed642e3 100644
--- a/src/osd/modules/lib/osdlib_macosx.cpp
+++ b/src/osd/modules/lib/osdlib_macosx.cpp
@@ -13,6 +13,12 @@
#include <sys/mman.h>
#include <sys/types.h>
#include <signal.h>
+#include <dlfcn.h>
+
+#include <codecvt>
+#include <iomanip>
+#include <memory>
+
#include <mach/mach.h>
#include <mach/mach_time.h>
@@ -215,3 +221,71 @@ char *osd_get_clipboard_text(void)
return result;
}
+
+//============================================================
+// dynamic_module_posix_impl
+//============================================================
+
+namespace osd {
+
+class dynamic_module_posix_impl : public dynamic_module
+{
+public:
+ dynamic_module_posix_impl(std::vector<std::string> &libraries)
+ : m_module(nullptr)
+ {
+ m_libraries = libraries;
+ }
+
+ virtual ~dynamic_module_posix_impl() override
+ {
+ if (m_module != nullptr)
+ dlclose(m_module);
+ };
+
+protected:
+ virtual generic_fptr_t get_symbol_address(char const *symbol) override
+ {
+ /*
+ * given a list of libraries, if a first symbol is successfully loaded from
+ * one of them, all additional symbols will be loaded from the same library
+ */
+ if (m_module)
+ {
+ return reinterpret_cast<generic_fptr_t>(dlsym(m_module, symbol));
+ }
+
+ for (auto const &library : m_libraries)
+ {
+ void *module = dlopen(library.c_str(), RTLD_LAZY);
+
+ if (module != nullptr)
+ {
+ generic_fptr_t function = reinterpret_cast<generic_fptr_t>(dlsym(module, symbol));
+
+ if (function != nullptr)
+ {
+ m_module = module;
+ return function;
+ }
+ else
+ {
+ dlclose(module);
+ }
+ }
+ }
+
+ return nullptr;
+ }
+
+private:
+ std::vector<std::string> m_libraries;
+ void * m_module;
+};
+
+dynamic_module::ptr dynamic_module::open(std::vector<std::string> &&names)
+{
+ return std::make_unique<dynamic_module_posix_impl>(names);
+}
+
+} // namespace osd
diff --git a/src/osd/modules/lib/osdlib_unix.cpp b/src/osd/modules/lib/osdlib_unix.cpp
index 52999835a1c..81d9967ff64 100644
--- a/src/osd/modules/lib/osdlib_unix.cpp
+++ b/src/osd/modules/lib/osdlib_unix.cpp
@@ -13,12 +13,19 @@
#include <sys/mman.h>
#include <sys/types.h>
#include <signal.h>
+#include <dlfcn.h>
+
+#include <codecvt>
+#include <iomanip>
+#include <memory>
+
// MAME headers
#include "osdcore.h"
#include "osdlib.h"
#include <SDL2/SDL.h>
+
//============================================================
// osd_getenv
//============================================================
@@ -159,3 +166,71 @@ char *osd_get_clipboard_text(void)
}
#endif
+
+//============================================================
+// dynamic_module_posix_impl
+//============================================================
+
+namespace osd {
+
+class dynamic_module_posix_impl : public dynamic_module
+{
+public:
+ dynamic_module_posix_impl(std::vector<std::string> &libraries)
+ : m_module(nullptr)
+ {
+ m_libraries = libraries;
+ }
+
+ virtual ~dynamic_module_posix_impl() override
+ {
+ if (m_module != nullptr)
+ dlclose(m_module);
+ };
+
+protected:
+ virtual generic_fptr_t get_symbol_address(char const *symbol) override
+ {
+ /*
+ * given a list of libraries, if a first symbol is successfully loaded from
+ * one of them, all additional symbols will be loaded from the same library
+ */
+ if (m_module)
+ {
+ return reinterpret_cast<generic_fptr_t>(dlsym(m_module, symbol));
+ }
+
+ for (auto const &library : m_libraries)
+ {
+ void *module = dlopen(library.c_str(), RTLD_LAZY);
+
+ if (module != nullptr)
+ {
+ generic_fptr_t function = reinterpret_cast<generic_fptr_t>(dlsym(module, symbol));
+
+ if (function != nullptr)
+ {
+ m_module = module;
+ return function;
+ }
+ else
+ {
+ dlclose(module);
+ }
+ }
+ }
+
+ return nullptr;
+ }
+
+private:
+ std::vector<std::string> m_libraries;
+ void * m_module;
+};
+
+dynamic_module::ptr dynamic_module::open(std::vector<std::string> &&names)
+{
+ return std::make_unique<dynamic_module_posix_impl>(names);
+}
+
+} // namespace osd
diff --git a/src/osd/modules/lib/osdlib_win32.cpp b/src/osd/modules/lib/osdlib_win32.cpp
index f778977614a..e65509cc436 100644
--- a/src/osd/modules/lib/osdlib_win32.cpp
+++ b/src/osd/modules/lib/osdlib_win32.cpp
@@ -17,6 +17,8 @@
#include <unistd.h>
#endif
+#include <memory>
+
// MAME headers
#include "osdlib.h"
#include "osdcomm.h"
@@ -314,3 +316,85 @@ char *osd_get_clipboard_text(void)
return result;
}
+
+//============================================================
+// osd_dynamic_bind
+//============================================================
+
+#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
+// for classic desktop applications
+#define load_library(filename) LoadLibrary(filename)
+#else
+// for Windows Store universal applications
+#define load_library(filename) LoadPackagedLibrary(filename, 0)
+#endif
+
+namespace osd {
+
+class dynamic_module_win32_impl : public dynamic_module
+{
+public:
+ dynamic_module_win32_impl(std::vector<std::string> &libraries)
+ : m_module(nullptr)
+ {
+ m_libraries = libraries;
+ }
+
+ virtual ~dynamic_module_win32_impl() override
+ {
+ if (m_module != nullptr)
+ FreeLibrary(m_module);
+ };
+
+protected:
+ virtual generic_fptr_t get_symbol_address(char const *symbol) override
+ {
+ /*
+ * given a list of libraries, if a first symbol is successfully loaded from
+ * one of them, all additional symbols will be loaded from the same library
+ */
+ if (m_module)
+ {
+ return reinterpret_cast<generic_fptr_t>(GetProcAddress(m_module, symbol));
+ }
+
+ for (auto const &library : m_libraries)
+ {
+ TCHAR *tempstr = tstring_from_utf8(library.c_str());
+ if (!tempstr)
+ return nullptr;
+
+ HMODULE module = load_library(tempstr);
+
+ osd_free(tempstr);
+
+ if (module != nullptr)
+ {
+ generic_fptr_t function = reinterpret_cast<generic_fptr_t>(GetProcAddress(module, symbol));
+
+ if (function != nullptr)
+ {
+ m_module = module;
+ return function;
+ }
+ else
+ {
+ FreeLibrary(module);
+ }
+ }
+ }
+
+ return nullptr;
+ }
+
+private:
+ std::vector<std::string> m_libraries;
+ HMODULE m_module;
+};
+
+dynamic_module::ptr dynamic_module::open(std::vector<std::string> &&names)
+{
+ return std::make_unique<dynamic_module_win32_impl>(names);
+}
+
+} // namespace osd
diff --git a/src/osd/modules/netdev/pcap.cpp b/src/osd/modules/netdev/pcap.cpp
index 541ed422d8a..1cd7ae3bfa8 100644
--- a/src/osd/modules/netdev/pcap.cpp
+++ b/src/osd/modules/netdev/pcap.cpp
@@ -1,61 +1,47 @@
// license:BSD-3-Clause
// copyright-holders:Carl
-#if defined(OSD_NET_USE_PCAP)
-#if defined(SDLMAME_WIN32) || defined(OSD_WINDOWS)
-#ifdef UNICODE
-#define LIB_NAME L"wpcap.dll"
-#define LoadDynamicLibrary LoadLibraryW
-#else
-#define LIB_NAME "wpcap.dll"
-#define LoadDynamicLibrary LoadLibraryA
-#endif
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-#endif
-
-#include <pcap.h>
+#if defined(OSD_NET_USE_PCAP)
#include "emu.h"
#include "osdnet.h"
#include "netdev_module.h"
#include "modules/osdmodule.h"
+#include "modules/lib/osdlib.h"
#if defined(SDLMAME_WIN32) || defined(OSD_WINDOWS)
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#undef interface
+#define LIB_NAME "wpcap.dll"
-#define LIB_ERROR_STR "Unable to load winpcap: %lx\n"
-typedef DWORD except_type;
-
-#else
-
-#include <dlfcn.h>
-#ifdef SDLMAME_MACOSX
+#elif defined(SDLMAME_MACOSX)
#include <pthread.h>
#include <libkern/OSAtomic.h>
-#endif
-
-#ifdef SDLMAME_MACOSX
#define LIB_NAME "libpcap.dylib"
+
#else
#define LIB_NAME "libpcap.so"
#endif
-#define LIB_ERROR_STR "Unable to load pcap: %s\n"
-typedef void *HMODULE;
-typedef const char *except_type;
-#define FreeLibrary(x) dlclose(x)
-#define GetLastError() dlerror()
-#define GetProcAddress(x, y) dlsym(x, y)
-#define LoadDynamicLibrary(x) dlopen(x, RTLD_LAZY)
+#include <pcap.h>
-#endif
+// Typedefs for dynamically loaded functions
+typedef int (*pcap_findalldevs_fn)(pcap_if_t **, char *);
+typedef pcap_t *(*pcap_open_live_fn)(const char *, int, int, int, char *);
+typedef int (*pcap_next_ex_fn)(pcap_t *, struct pcap_pkthdr **, const u_char **);
+typedef int (*pcap_compile_fn)(pcap_t *, struct bpf_program *, const char *, int, bpf_u_int32);
+typedef void (*pcap_close_fn)(pcap_t *);
+typedef int (*pcap_setfilter_fn)(pcap_t *, struct bpf_program *);
+typedef int (*pcap_sendpacket_fn)(pcap_t *, const u_char *, int);
+typedef int (*pcap_set_datalink_fn)(pcap_t *, int);
+typedef int (*pcap_dispatch_fn)(pcap_t *, int, pcap_handler, u_char *);
class pcap_module : public osd_module, public netdev_module
{
public:
-
pcap_module()
- : osd_module(OSD_NETDEV_PROVIDER, "pcap"), netdev_module(), handle(nullptr)
+ : osd_module(OSD_NETDEV_PROVIDER, "pcap"), netdev_module()
{
}
virtual ~pcap_module() { }
@@ -63,32 +49,46 @@ public:
virtual int init(const osd_options &options) override;
virtual void exit() override;
- virtual bool probe() override;
+ virtual bool probe() override
+ {
+ pcap_dll = osd::dynamic_module::open({ LIB_NAME });
+
+ pcap_findalldevs_dl = pcap_dll->bind<pcap_findalldevs_fn>("pcap_findalldevs");
+ pcap_open_live_dl = pcap_dll->bind<pcap_open_live_fn>("pcap_open_live");
+ pcap_next_ex_dl = pcap_dll->bind<pcap_next_ex_fn>("pcap_next_ex");
+ pcap_compile_dl = pcap_dll->bind<pcap_compile_fn>("pcap_compile");
+ pcap_close_dl = pcap_dll->bind<pcap_close_fn>("pcap_close");
+ pcap_setfilter_dl = pcap_dll->bind<pcap_setfilter_fn>("pcap_setfilter");
+ pcap_sendpacket_dl = pcap_dll->bind<pcap_sendpacket_fn>("pcap_sendpacket");
+ pcap_set_datalink_dl = pcap_dll->bind<pcap_set_datalink_fn>("pcap_set_datalink");
+ pcap_dispatch_dl = pcap_dll->bind<pcap_dispatch_fn>("pcap_dispatch");
+
+ if (!pcap_findalldevs_dl || !pcap_open_live_dl || !pcap_next_ex_dl ||
+ !pcap_compile_dl || !pcap_close_dl || !pcap_setfilter_dl ||
+ !pcap_sendpacket_dl || !pcap_set_datalink_dl || !pcap_dispatch_dl)
+ {
+ osd_printf_error("Unable to load the PCAP library\n");
+ return false;
+ }
+
+ return true;
+ }
- HMODULE handle;
+ osd::dynamic_module::ptr pcap_dll;
+
+ pcap_findalldevs_fn pcap_findalldevs_dl;
+ pcap_open_live_fn pcap_open_live_dl;
+ pcap_next_ex_fn pcap_next_ex_dl;
+ pcap_compile_fn pcap_compile_dl;
+ pcap_close_fn pcap_close_dl;
+ pcap_setfilter_fn pcap_setfilter_dl;
+ pcap_sendpacket_fn pcap_sendpacket_dl;
+ pcap_set_datalink_fn pcap_set_datalink_dl;
+ pcap_dispatch_fn pcap_dispatch_dl;
};
-static int (*pcap_compile_dl)(pcap_t *, struct bpf_program *, char *, int, bpf_u_int32) = nullptr;
-static int (*pcap_findalldevs_dl)(pcap_if_t **, char *) = nullptr;
-static pcap_t *(*pcap_open_live_dl)(const char *name, int, int, int, char *) = nullptr;
-static int (*pcap_next_ex_dl)(pcap_t *, struct pcap_pkthdr **, const u_char **) = nullptr;
-static void (*pcap_close_dl)(pcap_t *) = nullptr;
-static int (*pcap_setfilter_dl)(pcap_t *, struct bpf_program *) = nullptr;
-static int (*pcap_sendpacket_dl)(pcap_t *, u_char *, int) = nullptr;
-static int (*pcap_set_datalink_dl)(pcap_t *, int) = nullptr;
-static int (*pcap_dispatch_dl)(pcap_t *, int, pcap_handler callback, u_char *) = nullptr;
-
-
-#if 0
-#define pcap_compile_dl pcap_compile
-#define pcap_findalldevs_dl pcap_findalldevs
-#define pcap_open_live_dl pcap_open_live
-#define pcap_next_ex_dl pcap_next_ex
-#define pcap_close_dl pcap_close
-#define pcap_setfilter_dl pcap_setfilter
-#define pcap_sendpacket_dl pcap_sendpacket
-#define pcap_set_datalink_dl pcap_set_datalink
-#endif
+// FIXME: bridge between pcap_module and netdev_pcap
+static pcap_module *module = nullptr;
#ifdef SDLMAME_MACOSX
struct netdev_pcap_context {
@@ -140,7 +140,7 @@ static void *netdev_pcap_blocker(void *arg) {
struct netdev_pcap_context *ctx = (struct netdev_pcap_context*)arg;
while(ctx && ctx->p) {
- pcap_dispatch_dl(ctx->p, 1, netdev_pcap_handler, (u_char*)ctx);
+ (*module->pcap_dispatch_dl)(ctx->p, 1, netdev_pcap_handler, (u_char*)ctx);
}
return 0;
@@ -152,19 +152,19 @@ netdev_pcap::netdev_pcap(const char *name, class device_network_interface *ifdev
{
char errbuf[PCAP_ERRBUF_SIZE];
#if defined(SDLMAME_WIN32) || defined(OSD_WINDOWS)
- m_p = pcap_open_live_dl(name, 65535, 1, -1, errbuf);
+ m_p = (*module->pcap_open_live_dl)(name, 65535, 1, -1, errbuf);
#else
- m_p = pcap_open_live_dl(name, 65535, 1, 1, errbuf);
+ m_p = (*module->pcap_open_live_dl)(name, 65535, 1, 1, errbuf);
#endif
if(!m_p)
{
osd_printf_error("Unable to open %s: %s\n", name, errbuf);
return;
}
- if(pcap_set_datalink_dl(m_p, DLT_EN10MB) == -1)
+ if ((*module->pcap_set_datalink_dl)(m_p, DLT_EN10MB) == -1)
{
osd_printf_error("Unable to set %s to ethernet", name);
- pcap_close_dl(m_p);
+ (*module->pcap_close_dl)(m_p);
m_p = nullptr;
return;
}
@@ -188,10 +188,10 @@ void netdev_pcap::set_mac(const char *mac)
#else
sprintf(filter, "ether dst %.2X:%.2X:%.2X:%.2X:%.2X:%.2X or ether multicast or ether broadcast", (unsigned char)mac[0], (unsigned char)mac[1], (unsigned char)mac[2],(unsigned char)mac[3], (unsigned char)mac[4], (unsigned char)mac[5]);
#endif
- if(pcap_compile_dl(m_p, &fp, filter, 1, 0) == -1) {
+ if ((*module->pcap_compile_dl)(m_p, &fp, filter, 1, 0) == -1) {
osd_printf_error("Error with pcap_compile\n");
}
- if(pcap_setfilter_dl(m_p, &fp) == -1) {
+ if ((*module->pcap_setfilter_dl)(m_p, &fp) == -1) {
osd_printf_error("Error with pcap_setfilter\n");
}
}
@@ -203,7 +203,7 @@ int netdev_pcap::send(UINT8 *buf, int len)
printf("send invoked, but no pcap context\n");
return 0;
}
- ret = pcap_sendpacket_dl(m_p, buf, len);
+ ret = (*module->pcap_sendpacket_dl)(m_p, buf, len);
printf("sent packet length %d, returned %d\n", len, ret);
return ret ? len : 0;
//return (!pcap_sendpacket_dl(m_p, buf, len))?len:0;
@@ -228,7 +228,7 @@ int netdev_pcap::recv_dev(UINT8 **buf)
#else
struct pcap_pkthdr *header;
if(!m_p) return 0;
- return (pcap_next_ex_dl(m_p, &header, (const u_char **)buf) == 1)?header->len:0;
+ return ((*module->pcap_next_ex_dl)(m_p, &header, (const u_char **)buf) == 1)?header->len:0;
#endif
}
@@ -239,7 +239,7 @@ netdev_pcap::~netdev_pcap()
pthread_cancel(m_thread);
pthread_join(m_thread, nullptr);
#endif
- if(m_p) pcap_close_dl(m_p);
+ if(m_p) (*module->pcap_close_dl)(m_p);
m_p = nullptr;
}
@@ -249,52 +249,16 @@ static CREATE_NETDEV(create_pcap)
return dynamic_cast<osd_netdev *>(dev);
}
-bool pcap_module::probe()
-{
- if (handle == nullptr)
- {
- handle = LoadDynamicLibrary(LIB_NAME);
- return (handle != nullptr);
- }
- return true;
-}
-
-
int pcap_module::init(const osd_options &options)
{
pcap_if_t *devs;
char errbuf[PCAP_ERRBUF_SIZE];
- try
- {
- if(!(pcap_findalldevs_dl = (int (*)(pcap_if_t **, char *))GetProcAddress(handle, "pcap_findalldevs")))
- throw GetLastError();
- if(!(pcap_open_live_dl = (pcap_t* (*)(const char *, int, int, int, char *))GetProcAddress(handle, "pcap_open_live")))
- throw GetLastError();
- if(!(pcap_next_ex_dl = (int (*)(pcap_t *, struct pcap_pkthdr **, const u_char **))GetProcAddress(handle, "pcap_next_ex")))
- throw GetLastError();
- if(!(pcap_compile_dl = (int (*)(pcap_t *, struct bpf_program *, char *, int, bpf_u_int32))GetProcAddress(handle, "pcap_compile")))
- throw GetLastError();
- if(!(pcap_close_dl = (void (*)(pcap_t *))GetProcAddress(handle, "pcap_close")))
- throw GetLastError();
- if(!(pcap_setfilter_dl = (int (*)(pcap_t *, struct bpf_program *))GetProcAddress(handle, "pcap_setfilter")))
- throw GetLastError();
- if(!(pcap_sendpacket_dl = (int (*)(pcap_t *, u_char *, int))GetProcAddress(handle, "pcap_sendpacket")))
- throw GetLastError();
- if(!(pcap_set_datalink_dl = (int (*)(pcap_t *, int))GetProcAddress(handle, "pcap_set_datalink")))
- throw GetLastError();
- if(!(pcap_dispatch_dl = (int (*)(pcap_t *, int, pcap_handler callback, u_char *))GetProcAddress(handle, "pcap_dispatch")))
- throw GetLastError();
- }
- catch (except_type e)
- {
- FreeLibrary(handle);
- osd_printf_error(LIB_ERROR_STR, e);
- return 1;
- }
- if(pcap_findalldevs_dl(&devs, errbuf) == -1)
+ // FIXME: bridge between pcap_module and netdev_pcap
+ module = this;
+
+ if ((*pcap_findalldevs_dl)(&devs, errbuf) == -1)
{
- FreeLibrary(handle);
osd_printf_error("Unable to get network devices: %s\n", errbuf);
return 1;
}
@@ -314,9 +278,8 @@ int pcap_module::init(const osd_options &options)
void pcap_module::exit()
{
clear_netdev();
- //FreeLibrary(handle);
- //handle = nullptr;
}
+
#else
#include "modules/osdmodule.h"
#include "netdev_module.h"
diff --git a/src/osd/modules/render/d3d/d3d9intf.cpp b/src/osd/modules/render/d3d/d3d9intf.cpp
index 435ec7ef64c..08eaaff0c7b 100644
--- a/src/osd/modules/render/d3d/d3d9intf.cpp
+++ b/src/osd/modules/render/d3d/d3d9intf.cpp
@@ -64,65 +64,27 @@ static inline void convert_present_params(const present_parameters *params, D3DP
d3d_base *drawd3d9_init(void)
{
- bool post_available = true;
+ // allocate an object to hold our data
+ d3d_base *d3dptr = global_alloc(d3d_base);
- // dynamically grab the create function from d3d9.dll
- HINSTANCE dllhandle = LoadLibrary(TEXT("d3d9.dll"));
- if (dllhandle == nullptr)
- {
- osd_printf_verbose("Direct3D: Unable to access d3d9.dll\n");
- return nullptr;
- }
+ d3dptr->d3d9_dll = osd::dynamic_module::open({ "d3d9.dll" });
- // import the create function
- direct3dcreate9_ptr direct3dcreate9 = (direct3dcreate9_ptr)GetProcAddress(dllhandle, "Direct3DCreate9");
- if (direct3dcreate9 == nullptr)
+ d3d9_create_fn d3d9_create_ptr = d3dptr->d3d9_dll->bind<d3d9_create_fn>("Direct3DCreate9");
+ if (d3d9_create_ptr == nullptr)
{
- osd_printf_verbose("Direct3D: Unable to find Direct3DCreate9\n");
- FreeLibrary(dllhandle);
- return nullptr;
+ osd_printf_verbose("Direct3D: Unable to find Direct3D 9 runtime library\n");
+ return true;
}
- // create our core direct 3d object
- IDirect3D9 *d3d9 = (*direct3dcreate9)(D3D_SDK_VERSION);
- if (d3d9 == nullptr)
+ d3dptr->d3dobj = (*d3d9_create_ptr)(D3D_SDK_VERSION);
+ if (d3dptr->d3dobj == nullptr)
{
- osd_printf_verbose("Direct3D: Error attempting to initialize Direct3D9\n");
- FreeLibrary(dllhandle);
- return nullptr;
+ osd_printf_verbose("Direct3D: Unable to initialize Direct3D 9\n");
+ return true;
}
- // dynamically grab the shader load function from d3dx9.dll
- HINSTANCE fxhandle = nullptr;
- for (int idx = 99; idx >= 0; idx--) // a shameful moogle
- {
- #ifdef UNICODE
- wchar_t dllbuf[13];
- wsprintf(dllbuf, TEXT("d3dx9_%d.dll"), idx);
- fxhandle = LoadLibrary(dllbuf);
- #else
- char dllbuf[13];
- sprintf(dllbuf, "d3dx9_%d.dll", idx);
- fxhandle = LoadLibraryA(dllbuf);
- #endif
- if (fxhandle != nullptr)
- {
- break;
- }
- }
- if (fxhandle == nullptr)
- {
- osd_printf_verbose("Direct3D: Warning - Unable find any D3D9 DLLs; disabling post-effect rendering\n");
- post_available = false;
- }
-
- // allocate an object to hold our data
- auto d3dptr = global_alloc(d3d_base);
d3dptr->version = 9;
- d3dptr->d3dobj = d3d9;
- d3dptr->dllhandle = dllhandle;
- d3dptr->post_fx_available = post_available;
- d3dptr->libhandle = fxhandle;
+ d3dptr->post_fx_available = true;
set_interfaces(d3dptr);
osd_printf_verbose("Direct3D: Using Direct3D 9\n");
@@ -239,7 +201,6 @@ static ULONG release(d3d_base *d3dptr)
{
IDirect3D9 *d3d9 = (IDirect3D9 *)d3dptr->d3dobj;
ULONG result = IDirect3D9_Release(d3d9);
- FreeLibrary(d3dptr->dllhandle);
global_free(d3dptr);
return result;
}
diff --git a/src/osd/modules/render/d3d/d3dcomm.h b/src/osd/modules/render/d3d/d3dcomm.h
index 89a7f33a8e8..ebd2294a203 100644
--- a/src/osd/modules/render/d3d/d3dcomm.h
+++ b/src/osd/modules/render/d3d/d3dcomm.h
@@ -64,7 +64,6 @@ public:
{ }
d3d_texture_manager(renderer_d3d9 *d3d);
- ~d3d_texture_manager();
void update_textures();
@@ -142,9 +141,9 @@ public:
int get_cur_frame() const { return m_cur_frame; }
int get_prev_frame() const { return m_prev_frame; }
- texture * get_tex() const { return m_d3dtex; }
- surface * get_surface() const { return m_d3dsurface; }
- texture * get_finaltex() const { return m_d3dfinaltex; }
+ IDirect3DTexture9 * get_tex() const { return m_d3dtex; }
+ IDirect3DSurface9 * get_surface() const { return m_d3dsurface; }
+ IDirect3DTexture9 * get_finaltex() const { return m_d3dfinaltex; }
vec2f & get_uvstart() { return m_start; }
vec2f & get_uvstop() { return m_stop; }
@@ -173,9 +172,9 @@ private:
int m_xprescale, m_yprescale; // X/Y prescale factor
int m_cur_frame; // what is our current frame?
int m_prev_frame; // what was our last frame? (used to determine pause state)
- texture * m_d3dtex; // Direct3D texture pointer
- surface * m_d3dsurface; // Direct3D offscreen plain surface pointer
- texture * m_d3dfinaltex; // Direct3D final (post-scaled) texture
+ IDirect3DTexture9 * m_d3dtex; // Direct3D texture pointer
+ IDirect3DSurface9 * m_d3dsurface; // Direct3D offscreen plain surface pointer
+ IDirect3DTexture9 * m_d3dfinaltex; // Direct3D final (post-scaled) texture
};
/* poly_info holds information about a single polygon/d3d primitive */
@@ -254,8 +253,8 @@ public:
bool init(renderer_d3d9 *d3d, d3d_base *d3dintf, int source_width, int source_height, int target_width, int target_height);
- surface *last_target;
- texture *last_texture;
+ IDirect3DSurface9 *last_target;
+ IDirect3DTexture9 *last_texture;
int target_width;
int target_height;
@@ -293,16 +292,16 @@ public:
int screen_index;
int page_index;
- surface *target_surface[2];
- texture *target_texture[2];
- surface *source_surface[2];
- texture *source_texture[2];
+ IDirect3DSurface9 *target_surface[2];
+ IDirect3DTexture9 *target_texture[2];
+ IDirect3DSurface9 *source_surface[2];
+ IDirect3DTexture9 *source_texture[2];
d3d_render_target *next;
d3d_render_target *prev;
- surface *bloom_surface[MAX_BLOOM_COUNT];
- texture *bloom_texture[MAX_BLOOM_COUNT];
+ IDirect3DSurface9 *bloom_surface[MAX_BLOOM_COUNT];
+ IDirect3DTexture9 *bloom_texture[MAX_BLOOM_COUNT];
float bloom_dims[MAX_BLOOM_COUNT][2];
diff --git a/src/osd/modules/render/d3d/d3dhlsl.cpp b/src/osd/modules/render/d3d/d3dhlsl.cpp
index 5c1bef296cf..9c06e99bcbd 100644
--- a/src/osd/modules/render/d3d/d3dhlsl.cpp
+++ b/src/osd/modules/render/d3d/d3dhlsl.cpp
@@ -2,18 +2,10 @@
// copyright-holders:Aaron Giles
//============================================================
//
-// d3dhlsl.c - Win32 Direct3D HLSL implementation
+// d3dhlsl.cpp - Win32 Direct3D HLSL implementation
//
//============================================================
-// Useful info:
-// Windows XP/2003 shipped with DirectX 8.1
-// Windows 2000 shipped with DirectX 7a
-// Windows 98SE shipped with DirectX 6.1a
-// Windows 98 shipped with DirectX 5
-// Windows NT shipped with DirectX 3.0a
-// Windows 95 shipped with DirectX 2
-
// MAME headers
#include "emu.h"
#include "drivenum.h"
@@ -47,14 +39,6 @@ static void get_vector(const char *data, int count, float *out, bool report_erro
//============================================================
-// TYPE DEFINITIONS
-//============================================================
-
-typedef HRESULT (WINAPI *direct3dx9_loadeffect_ptr)(LPDIRECT3DDEVICE9 pDevice, LPCTSTR pSrcFile, const D3DXMACRO *pDefines, LPD3DXINCLUDE pInclude, DWORD Flags, LPD3DXEFFECTPOOL pPool, LPD3DXEFFECT *ppEffect, LPD3DXBUFFER *ppCompilationErrors);
-static direct3dx9_loadeffect_ptr g_load_effect = nullptr;
-
-
-//============================================================
// shader manager constructor
//============================================================
@@ -119,21 +103,21 @@ void shaders::window_save()
return;
}
- HRESULT result = (*d3dintf->device.create_texture)(d3d->get_device(), snap_width, snap_height, 1, D3DUSAGE_DYNAMIC, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &snap_copy_texture);
- if (result != D3D_OK)
+ HRESULT result = d3d->get_device()->CreateTexture(snap_width, snap_height, 1, D3DUSAGE_DYNAMIC, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &snap_copy_texture, nullptr);
+ if (FAILED(result))
{
osd_printf_verbose("Direct3D: Unable to init system-memory target for HLSL snapshot (%08x), bailing\n", (UINT32)result);
return;
}
- (*d3dintf->texture.get_surface_level)(snap_copy_texture, 0, &snap_copy_target);
+ snap_copy_texture->GetSurfaceLevel(0, &snap_copy_target);
- result = (*d3dintf->device.create_texture)(d3d->get_device(), snap_width, snap_height, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &snap_texture);
- if (result != D3D_OK)
+ result = d3d->get_device()->CreateTexture(snap_width, snap_height, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &snap_texture, nullptr);
+ if (FAILED(result))
{
osd_printf_verbose("Direct3D: Unable to init video-memory target for HLSL snapshot (%08x), bailing\n", (UINT32)result);
return;
}
- (*d3dintf->texture.get_surface_level)(snap_texture, 0, &snap_target);
+ snap_texture->GetSurfaceLevel(0, &snap_target);
render_snap = true;
snap_rendered = false;
@@ -169,7 +153,7 @@ void shaders::window_record()
// shaders::avi_update_snap
//============================================================
-void shaders::avi_update_snap(surface *surface)
+void shaders::avi_update_snap(IDirect3DSurface9 *surface)
{
if (!master_enable || !d3dintf->post_fx_available)
{
@@ -185,15 +169,15 @@ void shaders::avi_update_snap(surface *surface)
}
// copy the texture
- HRESULT result = (*d3dintf->device.get_render_target_data)(d3d->get_device(), surface, avi_copy_surface);
- if (result != D3D_OK)
+ HRESULT result = d3d->get_device()->GetRenderTargetData(surface, avi_copy_surface);
+ if (FAILED(result))
{
return;
}
// lock the texture
- result = (*d3dintf->surface.lock_rect)(avi_copy_surface, &rect, nullptr, D3DLOCK_DISCARD);
- if (result != D3D_OK)
+ result = avi_copy_surface->LockRect(&rect, nullptr, D3DLOCK_DISCARD);
+ if (FAILED(result))
{
return;
}
@@ -211,11 +195,9 @@ void shaders::avi_update_snap(surface *surface)
}
// unlock
- result = (*d3dintf->surface.unlock_rect)(avi_copy_surface);
- if (result != D3D_OK)
- {
- osd_printf_verbose("Direct3D: Error %08X during texture unlock_rect call\n", (int)result);
- }
+ result = avi_copy_surface->UnlockRect();
+ if (FAILED(result))
+ osd_printf_verbose("Direct3D: Error %08lX during texture UnlockRect call\n", result);
}
@@ -224,7 +206,7 @@ void shaders::avi_update_snap(surface *surface)
// hlsl_render_snapshot
//============================================================
-void shaders::render_snapshot(surface *surface)
+void shaders::render_snapshot(IDirect3DSurface9 *surface)
{
if (!master_enable || !d3dintf->post_fx_available)
{
@@ -242,15 +224,15 @@ void shaders::render_snapshot(surface *surface)
}
// copy the texture
- HRESULT result = (*d3dintf->device.get_render_target_data)(d3d->get_device(), surface, snap_copy_target);
- if (result != D3D_OK)
+ HRESULT result = d3d->get_device()->GetRenderTargetData(surface, snap_copy_target);
+ if (FAILED(result))
{
return;
}
// lock the texture
- result = (*d3dintf->surface.lock_rect)(snap_copy_target, &rect, nullptr, D3DLOCK_DISCARD);
- if (result != D3D_OK)
+ result = snap_copy_target->LockRect(&rect, nullptr, D3DLOCK_DISCARD);
+ if (FAILED(result))
{
return;
}
@@ -292,30 +274,31 @@ void shaders::render_snapshot(surface *surface)
png_free(&pnginfo);
// unlock
- result = (*d3dintf->surface.unlock_rect)(snap_copy_target);
- if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during texture unlock_rect call\n", (int)result);
+ result = snap_copy_target->UnlockRect();
+ if (FAILED(result))
+ osd_printf_verbose("Direct3D: Error %08lX during texture UnlockRect call\n", result);
if (snap_texture != nullptr)
{
- (*d3dintf->texture.release)(snap_texture);
+ snap_texture->Release();
snap_texture = nullptr;
}
if (snap_target != nullptr)
{
- (*d3dintf->surface.release)(snap_target);
+ snap_target->Release();
snap_target = nullptr;
}
if (snap_copy_texture != nullptr)
{
- (*d3dintf->texture.release)(snap_copy_texture);
+ snap_copy_texture->Release();
snap_copy_texture = nullptr;
}
if (snap_copy_target != nullptr)
{
- (*d3dintf->surface.release)(snap_copy_target);
+ snap_copy_target->Release();
snap_copy_target = nullptr;
}
}
@@ -332,7 +315,7 @@ void shaders::record_texture()
return;
}
- surface *surface = avi_final_target;
+ IDirect3DSurface9 *surface = avi_final_target;
// ignore if nothing to do
if (avi_output_file == nullptr || surface == nullptr)
@@ -621,20 +604,17 @@ void shaders::set_texture(texture_info *texture)
void shaders::init(d3d_base *d3dintf, running_machine *machine, renderer_d3d9 *renderer)
{
- if (!d3dintf->post_fx_available)
- {
- return;
- }
+ d3dx9_dll = osd::dynamic_module::open({ "d3dx9_43.dll" });
- g_load_effect = (direct3dx9_loadeffect_ptr)GetProcAddress(d3dintf->libhandle, "D3DXCreateEffectFromFileW");
- if (g_load_effect == nullptr)
+ d3dx_create_effect_from_file_ptr = d3dx9_dll->bind<d3dx_create_effect_from_file_fn>("D3DXCreateEffectFromFileW");
+ if (!d3dx_create_effect_from_file_ptr)
{
printf("Direct3D: Unable to find D3DXCreateEffectFromFileW\n");
d3dintf->post_fx_available = false;
-
return;
}
+ d3dintf->post_fx_available = true;
this->d3dintf = d3dintf;
this->machine = machine;
this->d3d = renderer;
@@ -837,41 +817,44 @@ int shaders::create_resources(bool reset, std::vector<ui::menu_item>& sliders)
options = &last_options;
}
- HRESULT result = (*d3dintf->device.get_render_target)(d3d->get_device(), 0, &backbuffer);
- if (result != D3D_OK)
+ HRESULT result = d3d->get_device()->GetRenderTarget(0, &backbuffer);
+ if (FAILED(result))
{
- osd_printf_verbose("Direct3D: Error %08X during device get_render_target call\n", (int)result);
+ osd_printf_verbose("Direct3D: Error %08lX during device GetRenderTarget call\n", result);
}
- result = (*d3dintf->device.create_texture)(d3d->get_device(), 4, 4, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &black_texture);
- if (result != D3D_OK)
+ result = d3d->get_device()->CreateTexture(4, 4, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &black_texture, nullptr);
+ if (FAILED(result))
{
osd_printf_verbose("Direct3D: Unable to init video-memory target for black texture (%08x)\n", (UINT32)result);
return 1;
}
- (*d3dintf->texture.get_surface_level)(black_texture, 0, &black_surface);
- result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, black_surface);
- if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_render_target call\n", (int)result);
- result = (*d3dintf->device.clear)(d3d->get_device(), 0, nullptr, D3DCLEAR_TARGET, D3DCOLOR_ARGB(0,0,0,0), 0, 0);
- if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device clear call\n", (int)result);
- result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, backbuffer);
- if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_render_target call\n", (int)result);
+ black_texture->GetSurfaceLevel(0, &black_surface);
+ result = d3d->get_device()->SetRenderTarget(0, black_surface);
+ if (FAILED(result))
+ osd_printf_verbose("Direct3D: Error %08lX during device SetRenderTarget call\n", result);
+ result = d3d->get_device()->Clear(0, nullptr, D3DCLEAR_TARGET, D3DCOLOR_ARGB(0,0,0,0), 0, 0);
+ if (FAILED(result))
+ osd_printf_verbose("Direct3D: Error %08lX during device clear call\n", result);
+ result = d3d->get_device()->SetRenderTarget(0, backbuffer);
+ if (FAILED(result))
+ osd_printf_verbose("Direct3D: Error %08lX during device SetRenderTarget call\n", result);
- result = (*d3dintf->device.create_texture)(d3d->get_device(), (int)snap_width, (int)snap_height, 1, D3DUSAGE_DYNAMIC, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &avi_copy_texture);
- if (result != D3D_OK)
+ result = d3d->get_device()->CreateTexture((int)snap_width, (int)snap_height, 1, D3DUSAGE_DYNAMIC, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &avi_copy_texture, nullptr);
+ if (FAILED(result))
{
osd_printf_verbose("Direct3D: Unable to init system-memory target for HLSL AVI dumping (%08x)\n", (UINT32)result);
return 1;
}
- (*d3dintf->texture.get_surface_level)(avi_copy_texture, 0, &avi_copy_surface);
+ avi_copy_texture->GetSurfaceLevel(0, &avi_copy_surface);
- result = (*d3dintf->device.create_texture)(d3d->get_device(), (int)snap_width, (int)snap_height, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &avi_final_texture);
- if (result != D3D_OK)
+ result = d3d->get_device()->CreateTexture((int)snap_width, (int)snap_height, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &avi_final_texture, nullptr);
+ if (FAILED(result))
{
osd_printf_verbose("Direct3D: Unable to init video-memory target for HLSL AVI dumping (%08x)\n", (UINT32)result);
return 1;
}
- (*d3dintf->texture.get_surface_level)(avi_final_texture, 0, &avi_final_target);
+ avi_final_texture->GetSurfaceLevel(0, &avi_final_target);
emu_file file(machine->options().art_path(), OPEN_FLAG_READ);
render_load_png(shadow_bitmap, file, nullptr, options->shadow_mask_texture);
@@ -890,7 +873,7 @@ int shaders::create_resources(bool reset, std::vector<ui::menu_item>& sliders)
texture.seqid = 0;
// now create it (no prescale, no wrap)
- shadow_texture = new texture_info(d3d->get_texture_manager(), &texture, 1, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXFORMAT(TEXFORMAT_ARGB32));
+ shadow_texture = global_alloc(texture_info(d3d->get_texture_manager(), &texture, 1, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXFORMAT(TEXFORMAT_ARGB32)));
}
const char *fx_dir = downcast<windows_options &>(machine->options()).screen_post_fx_dir();
@@ -1035,10 +1018,10 @@ void shaders::begin_draw()
downsample_effect->set_technique("DefaultTechnique");
vector_effect->set_technique("DefaultTechnique");
- HRESULT result = (*d3dintf->device.get_render_target)(d3d->get_device(), 0, &backbuffer);
- if (result != D3D_OK)
+ HRESULT result = d3d->get_device()->GetRenderTarget(0, &backbuffer);
+ if (FAILED(result))
{
- osd_printf_verbose("Direct3D: Error %08X during device get_render_target call\n", (int)result);
+ osd_printf_verbose("Direct3D: Error %08lX during device GetRenderTarget call\n", result);
}
}
@@ -1058,7 +1041,7 @@ void shaders::begin_frame()
//============================================================
void shaders::blit(
- surface *dst,
+ IDirect3DSurface9 *dst,
bool clear_dst,
D3DPRIMITIVETYPE prim_type,
UINT32 prim_index,
@@ -1068,18 +1051,18 @@ void shaders::blit(
if (dst != nullptr)
{
- result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, dst);
- if (result != D3D_OK)
+ result = d3d->get_device()->SetRenderTarget(0, dst);
+ if (FAILED(result))
{
- osd_printf_verbose("Direct3D: Error %08X during device set_render_target call\n", (int)result);
+ osd_printf_verbose("Direct3D: Error %08lX during device SetRenderTarget call\n", result);
}
if (clear_dst)
{
- result = (*d3dintf->device.clear)(d3d->get_device(), 0, nullptr, D3DCLEAR_TARGET, D3DCOLOR_ARGB(1,0,0,0), 0, 0);
- if (result != D3D_OK)
+ result = d3d->get_device()->Clear(0, nullptr, D3DCLEAR_TARGET, D3DCOLOR_ARGB(1,0,0,0), 0, 0);
+ if (FAILED(result))
{
- osd_printf_verbose("Direct3D: Error %08X during device clear call\n", (int)result);
+ osd_printf_verbose("Direct3D: Error %08lX during device clear call\n", result);
}
}
}
@@ -1092,10 +1075,10 @@ void shaders::blit(
curr_effect->begin_pass(pass);
// add the primitives
- result = (*d3dintf->device.draw_primitive)(d3d->get_device(), prim_type, prim_index, prim_count);
- if (result != D3D_OK)
+ result = d3d->get_device()->DrawPrimitive(prim_type, prim_index, prim_count);
+ if (FAILED(result))
{
- osd_printf_verbose("Direct3D: Error %08X during device draw_primitive call\n", (int)result);
+ osd_printf_verbose("Direct3D: Error %08lX during device DrawPrimitive call\n", result);
}
curr_effect->end_pass();
@@ -1565,10 +1548,10 @@ int shaders::screen_pass(d3d_render_target *rt, int source_index, poly_info *pol
{
blit(avi_final_target, false, poly->get_type(), vertnum, poly->get_count());
- HRESULT result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, backbuffer);
- if (result != D3D_OK)
+ HRESULT result = d3d->get_device()->SetRenderTarget(0, backbuffer);
+ if (FAILED(result))
{
- osd_printf_verbose("Direct3D: Error %08X during device set_render_target call\n", (int)result);
+ osd_printf_verbose("Direct3D: Error %08lX during device SetRenderTarget call\n", result);
}
}
@@ -1576,10 +1559,10 @@ int shaders::screen_pass(d3d_render_target *rt, int source_index, poly_info *pol
{
blit(snap_target, false, poly->get_type(), vertnum, poly->get_count());
- HRESULT result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, backbuffer);
- if (result != D3D_OK)
+ HRESULT result = d3d->get_device()->SetRenderTarget(0, backbuffer);
+ if (FAILED(result))
{
- osd_printf_verbose("Direct3D: Error %08X during device set_render_target call\n", (int)result);
+ osd_printf_verbose("Direct3D: Error %08lX during device SetRenderTarget call\n", result);
}
snap_rendered = true;
@@ -1684,10 +1667,10 @@ void shaders::render_quad(poly_info *poly, int vertnum)
next_index = vector_pass(rt, next_index, poly, vertnum);
- HRESULT result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, backbuffer);
- if (result != D3D_OK)
+ HRESULT result = d3d->get_device()->SetRenderTarget(0, backbuffer);
+ if (FAILED(result))
{
- osd_printf_verbose("Direct3D: Error %08X during device set_render_target call\n", (int)result);
+ osd_printf_verbose("Direct3D: Error %08lX during device SetRenderTarget call\n", result);
}
}
else if (PRIMFLAG_GET_VECTORBUF(poly->get_flags()) && vector_enable)
@@ -1736,10 +1719,10 @@ void shaders::render_quad(poly_info *poly, int vertnum)
next_index = screen_pass(rt, next_index, poly, vertnum);
d3d->set_wrap(PRIMFLAG_GET_TEXWRAP(curr_texture->get_flags()) ? D3DTADDRESS_WRAP : D3DTADDRESS_CLAMP);
- HRESULT result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, backbuffer);
- if (result != D3D_OK)
+ HRESULT result = d3d->get_device()->SetRenderTarget(0, backbuffer);
+ if (FAILED(result))
{
- osd_printf_verbose("Direct3D: Error %08X during device set_render_target call\n", (int)result);
+ osd_printf_verbose("Direct3D: Error %08lX during device SetRenderTarget call\n", result);
}
lines_pending = false;
@@ -1770,13 +1753,14 @@ void shaders::end_draw()
return;
}
- (*d3dintf->surface.release)(backbuffer);
+ backbuffer->Release();
}
//============================================================
// shaders::add_cache_target - register a cache target
//============================================================
+
bool shaders::add_cache_target(renderer_d3d9* d3d, texture_info* texture, int source_width, int source_height, int target_width, int target_height, int screen_index)
{
cache_target* target = (cache_target*)global_alloc_clear<cache_target>();
@@ -1803,6 +1787,7 @@ bool shaders::add_cache_target(renderer_d3d9* d3d, texture_info* texture, int so
//============================================================
// shaders::get_texture_target(render_primitive::prim, texture_info::texture)
//============================================================
+
d3d_render_target* shaders::get_texture_target(render_primitive *prim, texture_info *texture)
{
auto win = d3d->assert_window();
@@ -2108,42 +2093,42 @@ void shaders::delete_resources(bool reset)
if (backbuffer != nullptr)
{
- (*d3dintf->surface.release)(backbuffer);
+ backbuffer->Release();
backbuffer = nullptr;
}
if (black_surface != nullptr)
{
- (*d3dintf->surface.release)(black_surface);
+ black_surface->Release();
black_surface = nullptr;
}
if (black_texture != nullptr)
{
- (*d3dintf->texture.release)(black_texture);
+ black_texture->Release();
black_texture = nullptr;
}
if (avi_copy_texture != nullptr)
{
- (*d3dintf->texture.release)(avi_copy_texture);
+ avi_copy_texture->Release();
avi_copy_texture = nullptr;
}
if (avi_copy_surface != nullptr)
{
- (*d3dintf->surface.release)(avi_copy_surface);
+ avi_copy_surface->Release();
avi_copy_surface = nullptr;
}
if (avi_final_texture != nullptr)
{
- (*d3dintf->texture.release)(avi_final_texture);
+ avi_final_texture->Release();
avi_final_texture = nullptr;
}
if (avi_final_target != nullptr)
{
- (*d3dintf->surface.release)(avi_final_target);
+ avi_final_target->Release();
avi_final_target = nullptr;
}
@@ -2909,12 +2894,12 @@ void uniform::set(bool x)
m_bval = x;
}
-void uniform::set(matrix *mat)
+void uniform::set(D3DMATRIX *mat)
{
m_mval = mat;
}
-void uniform::set(texture *tex)
+void uniform::set(IDirect3DTexture9 *tex)
{
m_texture = tex;
}
@@ -2951,9 +2936,8 @@ void uniform::upload()
// effect functions
//============================================================
-effect::effect(shaders *shadersys, device *dev, const char *name, const char *path)
+effect::effect(shaders *shadersys, IDirect3DDevice9 *dev, const char *name, const char *path)
{
- IDirect3DDevice9 *device = (IDirect3DDevice9 *)dev;
LPD3DXBUFFER buffer_errors = nullptr;
m_shaders = shadersys;
@@ -2966,7 +2950,7 @@ effect::effect(shaders *shadersys, device *dev, const char *name, const char *pa
sprintf(name_cstr, "%s\\%s", path, name);
TCHAR *effect_name = tstring_from_utf8(name_cstr);
- HRESULT hr = (*g_load_effect)(device, effect_name, nullptr, nullptr, 0, nullptr, &m_effect, &buffer_errors);
+ HRESULT hr = (*shadersys->d3dx_create_effect_from_file_ptr)(dev, effect_name, nullptr, nullptr, 0, nullptr, &m_effect, &buffer_errors);
if (FAILED(hr))
{
if (buffer_errors != nullptr)
@@ -3093,14 +3077,14 @@ void effect::set_bool(D3DXHANDLE param, bool value)
m_effect->SetBool(param, value);
}
-void effect::set_matrix(D3DXHANDLE param, matrix *matrix)
+void effect::set_matrix(D3DXHANDLE param, D3DMATRIX *matrix)
{
m_effect->SetMatrix(param, (D3DXMATRIX*)matrix);
}
-void effect::set_texture(D3DXHANDLE param, texture *tex)
+void effect::set_texture(D3DXHANDLE param, IDirect3DTexture9 *tex)
{
- m_effect->SetTexture(param, (IDirect3DTexture9*)tex);
+ m_effect->SetTexture(param, tex);
}
D3DXHANDLE effect::get_parameter(D3DXHANDLE param, const char *name)
diff --git a/src/osd/modules/render/d3d/d3dhlsl.h b/src/osd/modules/render/d3d/d3dhlsl.h
index 6f6e31f1933..858e486e3d3 100644
--- a/src/osd/modules/render/d3d/d3dhlsl.h
+++ b/src/osd/modules/render/d3d/d3dhlsl.h
@@ -13,16 +13,15 @@
#include "aviio.h"
#include "../frontend/mame/ui/menuitem.h"
#include "../frontend/mame/ui/slider.h"
-
-//============================================================
-// CONSTANTS
-//============================================================
-
+#include "modules/lib/osdlib.h"
//============================================================
// TYPE DEFINITIONS
//============================================================
+// Typedefs for dynamically loaded functions
+typedef HRESULT (*d3dx_create_effect_from_file_fn)(LPDIRECT3DDEVICE9, LPCTSTR, const D3DXMACRO *, LPD3DXINCLUDE, DWORD, LPD3DXEFFECTPOOL, LPD3DXEFFECT *, LPD3DXBUFFER *);
+
class effect;
class shaders;
@@ -115,8 +114,8 @@ public:
void set(float x);
void set(int x);
void set(bool x);
- void set(matrix *mat);
- void set(texture *tex);
+ void set(D3DMATRIX *mat);
+ void set(IDirect3DTexture9 *tex);
void upload();
void update();
@@ -127,10 +126,10 @@ protected:
float m_vec[4];
int m_ival;
bool m_bval;
- matrix *m_mval;
- texture *m_texture;
+ D3DMATRIX *m_mval;
+ IDirect3DTexture9 *m_texture;
int m_count;
- uniform_type m_type;
+ uniform_type m_type;
int m_id;
effect *m_shader;
@@ -142,7 +141,7 @@ class effect
friend class uniform;
public:
- effect(shaders *shadersys, device *dev, const char *name, const char *path);
+ effect(shaders *shadersys, IDirect3DDevice9 *dev, const char *name, const char *path);
~effect();
void begin(UINT *passes, DWORD flags);
@@ -157,8 +156,8 @@ public:
void set_float(D3DXHANDLE param, float value);
void set_int(D3DXHANDLE param, int value);
void set_bool(D3DXHANDLE param, bool value);
- void set_matrix(D3DXHANDLE param, matrix *matrix);
- void set_texture(D3DXHANDLE param, texture *tex);
+ void set_matrix(D3DXHANDLE param, D3DMATRIX *matrix);
+ void set_texture(D3DXHANDLE param, IDirect3DTexture9 *tex);
void add_uniform(const char *name, uniform::uniform_type type, int id);
void update_uniforms();
@@ -329,8 +328,8 @@ public:
void window_record();
bool recording() const { return avi_output_file != nullptr; }
- void avi_update_snap(surface *surface);
- void render_snapshot(surface *surface);
+ void avi_update_snap(IDirect3DSurface9 *surface);
+ void render_snapshot(IDirect3DSurface9 *surface);
void record_texture();
void init_fsfx_quad(void *vertbuf);
@@ -350,7 +349,7 @@ public:
void *get_slider_option(int id, int index = 0);
private:
- void blit(surface *dst, bool clear_dst, D3DPRIMITIVETYPE prim_type, UINT32 prim_index, UINT32 prim_count);
+ void blit(IDirect3DSurface9 *dst, bool clear_dst, D3DPRIMITIVETYPE prim_type, UINT32 prim_index, UINT32 prim_count);
void enumerate_screens();
void end_avi_recording();
@@ -399,28 +398,28 @@ private:
int avi_frame; // AVI frame
attotime avi_frame_period; // AVI frame period
attotime avi_next_frame_time; // AVI next frame time
- surface * avi_copy_surface; // AVI destination surface in system memory
- texture * avi_copy_texture; // AVI destination texture in system memory
- surface * avi_final_target; // AVI upscaled surface
- texture * avi_final_texture; // AVI upscaled texture
+ IDirect3DSurface9 * avi_copy_surface; // AVI destination surface in system memory
+ IDirect3DTexture9 * avi_copy_texture; // AVI destination texture in system memory
+ IDirect3DSurface9 * avi_final_target; // AVI upscaled surface
+ IDirect3DTexture9 * avi_final_texture; // AVI upscaled texture
- surface * black_surface; // black dummy surface
- texture * black_texture; // black dummy texture
+ IDirect3DSurface9 * black_surface; // black dummy surface
+ IDirect3DTexture9 * black_texture; // black dummy texture
bool render_snap; // whether or not to take HLSL post-render snapshot
bool snap_rendered; // whether we just rendered our HLSL post-render shot or not
- surface * snap_copy_target; // snapshot destination surface in system memory
- texture * snap_copy_texture; // snapshot destination surface in system memory
- surface * snap_target; // snapshot upscaled surface
- texture * snap_texture; // snapshot upscaled texture
+ IDirect3DSurface9 * snap_copy_target; // snapshot destination surface in system memory
+ IDirect3DTexture9 * snap_copy_texture; // snapshot destination surface in system memory
+ IDirect3DSurface9 * snap_target; // snapshot upscaled surface
+ IDirect3DTexture9 * snap_texture; // snapshot upscaled texture
int snap_width; // snapshot width
int snap_height; // snapshot height
bool lines_pending; // whether or not we have lines to flush on the next quad
- bool initialized; // whether or not we're initialize
+ bool initialized; // whether or not we're initialized
// HLSL effects
- surface * backbuffer; // pointer to our device's backbuffer
+ IDirect3DSurface9 * backbuffer; // pointer to our device's backbuffer
effect * curr_effect; // pointer to the currently active effect object
effect * default_effect; // pointer to the primary-effect object
effect * prescale_effect; // pointer to the prescale-effect object
@@ -447,6 +446,9 @@ private:
static slider_desc s_sliders[];
static hlsl_options last_options; // last used options
static char last_system_name[16]; // last used system
+
+ osd::dynamic_module::ptr d3dx9_dll;
+ d3dx_create_effect_from_file_fn d3dx_create_effect_from_file_ptr;
};
#endif
diff --git a/src/osd/modules/render/drawd3d.cpp b/src/osd/modules/render/drawd3d.cpp
index 44dd1b10600..0a6f4e50f1b 100644
--- a/src/osd/modules/render/drawd3d.cpp
+++ b/src/osd/modules/render/drawd3d.cpp
@@ -2,18 +2,10 @@
// copyright-holders:Aaron Giles
//============================================================
//
-// drawd3d.c - Win32 Direct3D implementation
+// drawd3d.cpp - Win32 Direct3D implementation
//
//============================================================
-// Useful info:
-// Windows XP/2003 shipped with DirectX 8.1
-// Windows 2000 shipped with DirectX 7a
-// Windows 98SE shipped with DirectX 6.1a
-// Windows 98 shipped with DirectX 5
-// Windows NT shipped with DirectX 3.0a
-// Windows 95 shipped with DirectX 2
-
// MAME headers
#include "emu.h"
#include "render.h"
@@ -30,6 +22,13 @@
//============================================================
+// TYPE DEFINITIONS
+//============================================================
+
+typedef IDirect3D9* (*d3d9_create_fn)(UINT);
+
+
+//============================================================
// CONSTANTS
//============================================================
@@ -122,10 +121,6 @@ static d3d_base * d3dintf; // FIX ME
//============================================================
-// PROTOTYPES
-//============================================================
-
-//============================================================
// drawd3d_window_init
//============================================================
@@ -133,7 +128,7 @@ int renderer_d3d9::create()
{
if (!initialize())
{
- osd_printf_error("Unable to initialize Direct3D.\n");
+ osd_printf_error("Unable to initialize Direct3D 9\n");
return 1;
}
@@ -183,21 +178,31 @@ render_primitive_list *renderer_d3d9::get_primitives()
//============================================================
-// drawnone_create
+// renderer_d3d9::init
//============================================================
bool renderer_d3d9::init(running_machine &machine)
{
- // Use Direct3D9
- d3dintf = drawd3d9_init();
+ d3dintf = global_alloc(d3d_base);
+
+ d3dintf->d3d9_dll = osd::dynamic_module::open({ "d3d9.dll" });
- // if we failed, note the error
- if (d3dintf == nullptr)
+ d3d9_create_fn d3d9_create_ptr = d3dintf->d3d9_dll->bind<d3d9_create_fn>("Direct3DCreate9");
+ if (d3d9_create_ptr == nullptr)
{
- osd_printf_error("Unable to initialize Direct3D.\n");
+ osd_printf_verbose("Direct3D: Unable to find Direct3D 9 runtime library\n");
+ return true;
+ }
+
+ d3dintf->d3dobj = (*d3d9_create_ptr)(D3D_SDK_VERSION);
+ if (d3dintf->d3dobj == nullptr)
+ {
+ osd_printf_verbose("Direct3D: Unable to initialize Direct3D 9\n");
return true;
}
+ osd_printf_verbose("Direct3D: Using Direct3D 9\n");
+
return false;
}
@@ -225,9 +230,10 @@ void renderer_d3d9::set_texture(texture_info *texture)
{
m_last_texture = texture;
m_last_texture_flags = (texture == nullptr ? 0 : texture->get_flags());
- HRESULT result = (*d3dintf->device.set_texture)(m_device, 0, (texture == nullptr) ? get_default_texture()->get_finaltex() : texture->get_finaltex());
+ HRESULT result = m_device->SetTexture(0, (texture == nullptr) ? get_default_texture()->get_finaltex() : texture->get_finaltex());
m_shaders->set_texture(texture);
- if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_texture call\n", (int)result);
+ if (FAILED(result))
+ osd_printf_verbose("Direct3D: Error %08lX during device set_texture call\n", result);
}
}
@@ -236,14 +242,18 @@ void renderer_d3d9::set_filter(int filter)
if (filter != m_last_filter)
{
m_last_filter = filter;
- HRESULT result = (*d3dintf->device.set_texture_stage_state)(m_device, 0, (D3DTEXTURESTAGESTATETYPE)D3DTSS_MINFILTER, filter ? D3DTEXF_LINEAR : D3DTEXF_POINT);
- if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_texture_stage_state call\n", (int)result);
- result = (*d3dintf->device.set_texture_stage_state)(m_device, 0, (D3DTEXTURESTAGESTATETYPE)D3DTSS_MAGFILTER, filter ? D3DTEXF_LINEAR : D3DTEXF_POINT);
- if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_texture_stage_state call\n", (int)result);
- result = (*d3dintf->device.set_texture_stage_state)(m_device, 1, (D3DTEXTURESTAGESTATETYPE)D3DTSS_MINFILTER, filter ? D3DTEXF_LINEAR : D3DTEXF_POINT);
- if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_texture_stage_state call\n", (int)result);
- result = (*d3dintf->device.set_texture_stage_state)(m_device, 1, (D3DTEXTURESTAGESTATETYPE)D3DTSS_MAGFILTER, filter ? D3DTEXF_LINEAR : D3DTEXF_POINT);
- if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_texture_stage_state call\n", (int)result);
+ HRESULT result = m_device->SetSamplerState(0, D3DSAMP_MINFILTER, filter ? D3DTEXF_LINEAR : D3DTEXF_POINT);
+ if (FAILED(result))
+ osd_printf_verbose("Direct3D: Error %08lX during device SetSamplerState call\n", result);
+ result = m_device->SetSamplerState(0, D3DSAMP_MAGFILTER, filter ? D3DTEXF_LINEAR : D3DTEXF_POINT);
+ if (FAILED(result))
+ osd_printf_verbose("Direct3D: Error %08lX during device SetSamplerState call\n", result);
+ result = m_device->SetSamplerState(1, D3DSAMP_MINFILTER, filter ? D3DTEXF_LINEAR : D3DTEXF_POINT);
+ if (FAILED(result))
+ osd_printf_verbose("Direct3D: Error %08lX during device SetSamplerState call\n", result);
+ result = m_device->SetSamplerState(1, D3DSAMP_MAGFILTER, filter ? D3DTEXF_LINEAR : D3DTEXF_POINT);
+ if (FAILED(result))
+ osd_printf_verbose("Direct3D: Error %08lX during device SetSamplerState call\n", result);
}
}
@@ -252,14 +262,18 @@ void renderer_d3d9::set_wrap(unsigned int wrap)
if (wrap != m_last_wrap)
{
m_last_wrap = wrap;
- HRESULT result = (*d3dintf->device.set_texture_stage_state)(m_device, 0, (D3DTEXTURESTAGESTATETYPE)D3DTSS_ADDRESSU, wrap);
- if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_texture_stage_state call\n", (int)result);
- result = (*d3dintf->device.set_texture_stage_state)(m_device, 0, (D3DTEXTURESTAGESTATETYPE)D3DTSS_ADDRESSV, wrap);
- if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_texture_stage_state call\n", (int)result);
- result = (*d3dintf->device.set_texture_stage_state)(m_device, 1, (D3DTEXTURESTAGESTATETYPE)D3DTSS_ADDRESSU, wrap);
- if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_texture_stage_state call\n", (int)result);
- result = (*d3dintf->device.set_texture_stage_state)(m_device, 1, (D3DTEXTURESTAGESTATETYPE)D3DTSS_ADDRESSV, wrap);
- if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_texture_stage_state call\n", (int)result);
+ HRESULT result = m_device->SetSamplerState(0, D3DSAMP_ADDRESSU, wrap);
+ if (FAILED(result))
+ osd_printf_verbose("Direct3D: Error %08lX during device SetSamplerState call\n", result);
+ result = m_device->SetSamplerState(0, D3DSAMP_ADDRESSV, wrap);
+ if (FAILED(result))
+ osd_printf_verbose("Direct3D: Error %08lX during device SetSamplerState call\n", result);
+ result = m_device->SetSamplerState(1, D3DSAMP_ADDRESSU, wrap);
+ if (FAILED(result))
+ osd_printf_verbose("Direct3D: Error %08lX during device SetSamplerState call\n", result);
+ result = m_device->SetSamplerState(1, D3DSAMP_ADDRESSV, wrap);
+ if (FAILED(result))
+ osd_printf_verbose("Direct3D: Error %08lX during device SetSamplerState call\n", result);
}
}
@@ -268,10 +282,12 @@ void renderer_d3d9::set_modmode(int modmode)
if (modmode != m_last_modmode)
{
m_last_modmode = modmode;
- HRESULT result = (*d3dintf->device.set_texture_stage_state)(m_device, 0, D3DTSS_COLOROP, modmode);
- if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_texture_stage_state call\n", (int)result);
- result = (*d3dintf->device.set_texture_stage_state)(m_device, 1, D3DTSS_COLOROP, modmode);
- if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_texture_stage_state call\n", (int)result);
+ HRESULT result = m_device->SetTextureStageState(0, D3DTSS_COLOROP, modmode);
+ if (FAILED(result))
+ osd_printf_verbose("Direct3D: Error %08lX during device SetTextureStageState call\n", result);
+ result = m_device->SetTextureStageState(1, D3DTSS_COLOROP, modmode);
+ if (FAILED(result))
+ osd_printf_verbose("Direct3D: Error %08lX during device SetTextureStageState call\n", result);
}
}
@@ -296,29 +312,33 @@ void renderer_d3d9::set_blendmode(int blendmode)
if (blendenable != m_last_blendenable)
{
m_last_blendenable = blendenable;
- HRESULT result = (*d3dintf->device.set_render_state)(m_device, D3DRS_ALPHABLENDENABLE, blendenable);
- if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_render_state call\n", (int)result);
+ HRESULT result = m_device->SetRenderState(D3DRS_ALPHABLENDENABLE, blendenable);
+ if (FAILED(result))
+ osd_printf_verbose("Direct3D: Error %08lX during device SetRenderState call\n", result);
}
if (blendop != m_last_blendop)
{
m_last_blendop = blendop;
- HRESULT result = (*d3dintf->device.set_render_state)(m_device, D3DRS_BLENDOP, blendop);
- if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_render_state call\n", (int)result);
+ HRESULT result = m_device->SetRenderState(D3DRS_BLENDOP, blendop);
+ if (FAILED(result))
+ osd_printf_verbose("Direct3D: Error %08lX during device SetRenderState call\n", result);
}
if (blendsrc != m_last_blendsrc)
{
m_last_blendsrc = blendsrc;
- HRESULT result = (*d3dintf->device.set_render_state)(m_device, D3DRS_SRCBLEND, blendsrc);
- if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_render_state call\n", (int)result);
+ HRESULT result = m_device->SetRenderState(D3DRS_SRCBLEND, blendsrc);
+ if (FAILED(result))
+ osd_printf_verbose("Direct3D: Error %08lX during device SetRenderState call\n", result);
}
if (blenddst != m_last_blenddst)
{
m_last_blenddst = blenddst;
- HRESULT result = (*d3dintf->device.set_render_state)(m_device, D3DRS_DESTBLEND, blenddst);
- if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_render_state call\n", (int)result);
+ HRESULT result = m_device->SetRenderState(D3DRS_DESTBLEND, blenddst);
+ if (FAILED(result))
+ osd_printf_verbose("Direct3D: Error %08lX during device SetRenderState call\n", result);
}
}
@@ -341,37 +361,35 @@ d3d_texture_manager::d3d_texture_manager(renderer_d3d9 *d3d)
m_texlist = nullptr;
m_default_texture = nullptr;
+ D3DCAPS9 caps;
+ HRESULT result = d3dintf->d3dobj->GetDeviceCaps(d3d->get_adapter(), D3DDEVTYPE_HAL, &caps);
+ if (FAILED(result))
+ osd_printf_verbose("Direct3D: Error %08lX during GetDeviceCaps call\n", result);
+
// check for dynamic texture support
- DWORD tempcaps;
- HRESULT result = (*d3dintf->d3d.get_caps_dword)(d3dintf, d3d->get_adapter(), D3DDEVTYPE_HAL, CAPS_CAPS2, &tempcaps);
- if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during get_caps_dword call\n", (int)result);
- m_dynamic_supported = ((tempcaps & D3DCAPS2_DYNAMICTEXTURES) != 0);
- if (m_dynamic_supported) osd_printf_verbose("Direct3D: Using dynamic textures\n");
+ m_dynamic_supported = ((caps.Caps2 & D3DCAPS2_DYNAMICTEXTURES) != 0);
+ if (m_dynamic_supported)
+ osd_printf_verbose("Direct3D: Using dynamic textures\n");
// check for stretchrect support
- result = (*d3dintf->d3d.get_caps_dword)(d3dintf, d3d->get_adapter(), D3DDEVTYPE_HAL, CAPS_STRETCH_RECT_FILTER, &tempcaps);
- if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during get_caps_dword call\n", (int)result);
- m_stretch_supported = ((tempcaps & D3DPTFILTERCAPS_MAGFPOINT) != 0);
- if (m_stretch_supported && video_config.prescale > 1) osd_printf_verbose("Direct3D: Using StretchRect for prescaling\n");
+ m_stretch_supported = ((caps.StretchRectFilterCaps & D3DPTFILTERCAPS_MAGFPOINT) != 0);
+ if (m_stretch_supported && video_config.prescale > 1)
+ osd_printf_verbose("Direct3D: Using StretchRect for prescaling\n");
// get texture caps
- result = (*d3dintf->d3d.get_caps_dword)(d3dintf, d3d->get_adapter(), D3DDEVTYPE_HAL, CAPS_TEXTURE_CAPS, &m_texture_caps);
- if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during get_caps_dword call\n", (int)result);
- result = (*d3dintf->d3d.get_caps_dword)(d3dintf, d3d->get_adapter(), D3DDEVTYPE_HAL, CAPS_MAX_TEXTURE_ASPECT, &m_texture_max_aspect);
- if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during get_caps_dword call\n", (int)result);
- result = (*d3dintf->d3d.get_caps_dword)(d3dintf, d3d->get_adapter(), D3DDEVTYPE_HAL, CAPS_MAX_TEXTURE_WIDTH, &m_texture_max_width);
- if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during get_caps_dword call\n", (int)result);
- result = (*d3dintf->d3d.get_caps_dword)(d3dintf, d3d->get_adapter(), D3DDEVTYPE_HAL, CAPS_MAX_TEXTURE_HEIGHT, &m_texture_max_height);
- if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during get_caps_dword call\n", (int)result);
+ m_texture_caps = caps.TextureCaps;
+ m_texture_max_aspect = caps.MaxTextureAspectRatio;
+ m_texture_max_width = caps.MaxTextureWidth;
+ m_texture_max_height = caps.MaxTextureHeight;
// pick a YUV texture format
m_yuv_format = D3DFMT_UYVY;
- result = (*d3dintf->d3d.check_device_format)(d3dintf, d3d->get_adapter(), D3DDEVTYPE_HAL, d3d->get_pixel_format(), 0, D3DRTYPE_TEXTURE, D3DFMT_UYVY);
- if (result != D3D_OK)
+ result = d3dintf->d3dobj->CheckDeviceFormat(d3d->get_adapter(), D3DDEVTYPE_HAL, d3d->get_pixel_format(), 0, D3DRTYPE_TEXTURE, D3DFMT_UYVY);
+ if (FAILED(result))
{
m_yuv_format = D3DFMT_YUY2;
- result = (*d3dintf->d3d.check_device_format)(d3dintf, d3d->get_adapter(), D3DDEVTYPE_HAL, d3d->get_pixel_format(), 0, D3DRTYPE_TEXTURE, D3DFMT_YUY2);
- if (result != D3D_OK)
+ result = d3dintf->d3dobj->CheckDeviceFormat(d3d->get_adapter(), D3DDEVTYPE_HAL, d3d->get_pixel_format(), 0, D3DRTYPE_TEXTURE, D3DFMT_YUY2);
+ if (FAILED(result))
m_yuv_format = D3DFMT_A8R8G8B8;
}
osd_printf_verbose("Direct3D: YUV format = %s\n", (m_yuv_format == D3DFMT_YUY2) ? "YUY2" : (m_yuv_format == D3DFMT_UYVY) ? "UYVY" : "RGB");
@@ -383,10 +401,6 @@ d3d_texture_manager::d3d_texture_manager(renderer_d3d9 *d3d)
osd_printf_verbose("Direct3D: Max texture size = %dx%d\n", (int)m_texture_max_width, (int)m_texture_max_height);
}
-d3d_texture_manager::~d3d_texture_manager()
-{
-}
-
void d3d_texture_manager::create_resources()
{
auto win = m_renderer->assert_window();
@@ -631,8 +645,9 @@ void renderer_d3d9::begin_frame()
{
auto win = assert_window();
- HRESULT result = (*d3dintf->device.clear)(m_device, 0, nullptr, D3DCLEAR_TARGET, D3DCOLOR_ARGB(0,0,0,0), 0, 0);
- if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device clear call\n", (int)result);
+ HRESULT result = m_device->Clear(0, nullptr, D3DCLEAR_TARGET, D3DCOLOR_ARGB(0,0,0,0), 0, 0);
+ if (FAILED(result))
+ osd_printf_verbose("Direct3D: Error %08lX during device clear call\n", result);
m_shaders->begin_frame();
@@ -642,8 +657,9 @@ void renderer_d3d9::begin_frame()
m_texture_manager->update_textures();
// begin the scene
- result = (*d3dintf->device.begin_scene)(m_device);
- if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device begin_scene call\n", (int)result);
+ result = m_device->BeginScene();
+ if (FAILED(result))
+ osd_printf_verbose("Direct3D: Error %08lX during device BeginScene call\n", result);
m_lockedbuf = nullptr;
@@ -710,12 +726,14 @@ void renderer_d3d9::end_frame()
m_shaders->end_frame();
// finish the scene
- HRESULT result = (*d3dintf->device.end_scene)(m_device);
- if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device end_scene call\n", (int)result);
+ HRESULT result = m_device->EndScene();
+ if (FAILED(result))
+ osd_printf_verbose("Direct3D: Error %08lX during device end_scene call\n", result);
// present the current buffers
- result = (*d3dintf->device.present)(m_device, nullptr, nullptr, nullptr, nullptr, 0);
- if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device present call\n", (int)result);
+ result = m_device->Present(nullptr, nullptr, nullptr, nullptr);
+ if (FAILED(result))
+ osd_printf_verbose("Direct3D: Error %08lX during device present call\n", result);
}
//============================================================
@@ -743,8 +761,8 @@ int renderer_d3d9::device_create(HWND device_hwnd)
}
// verify texture formats
- HRESULT result = (*d3dintf->d3d.check_device_format)(d3dintf, m_adapter, D3DDEVTYPE_HAL, m_pixformat, 0, D3DRTYPE_TEXTURE, D3DFMT_A8R8G8B8);
- if (result != D3D_OK)
+ HRESULT result = d3dintf->d3dobj->CheckDeviceFormat(m_adapter, D3DDEVTYPE_HAL, m_pixformat, 0, D3DRTYPE_TEXTURE, D3DFMT_A8R8G8B8);
+ if (FAILED(result))
{
osd_printf_error("Error: A8R8G8B8 format textures not supported\n");
return 1;
@@ -755,18 +773,18 @@ int renderer_d3d9::device_create(HWND device_hwnd)
try_again:
// try for XRGB first
m_screen_format = D3DFMT_X8R8G8B8;
- result = (*d3dintf->d3d.check_device_format)(d3dintf, m_adapter, D3DDEVTYPE_HAL, m_pixformat, m_texture_manager->is_dynamic_supported() ? D3DUSAGE_DYNAMIC : 0, D3DRTYPE_TEXTURE, m_screen_format);
- if (result != D3D_OK)
+ result = d3dintf->d3dobj->CheckDeviceFormat(m_adapter, D3DDEVTYPE_HAL, m_pixformat, m_texture_manager->is_dynamic_supported() ? D3DUSAGE_DYNAMIC : 0, D3DRTYPE_TEXTURE, m_screen_format);
+ if (FAILED(result))
{
// if not, try for ARGB
m_screen_format = D3DFMT_A8R8G8B8;
- result = (*d3dintf->d3d.check_device_format)(d3dintf, m_adapter, D3DDEVTYPE_HAL, m_pixformat, m_texture_manager->is_dynamic_supported() ? D3DUSAGE_DYNAMIC : 0, D3DRTYPE_TEXTURE, m_screen_format);
- if (result != D3D_OK && m_texture_manager->is_dynamic_supported())
+ result = d3dintf->d3dobj->CheckDeviceFormat(m_adapter, D3DDEVTYPE_HAL, m_pixformat, m_texture_manager->is_dynamic_supported() ? D3DUSAGE_DYNAMIC : 0, D3DRTYPE_TEXTURE, m_screen_format);
+ if (FAILED(result) && m_texture_manager->is_dynamic_supported())
{
m_texture_manager->set_dynamic_supported(FALSE);
goto try_again;
}
- if (result != D3D_OK)
+ if (FAILED(result))
{
osd_printf_error("Error: unable to configure a screen texture format\n");
return 1;
@@ -794,9 +812,9 @@ try_again:
D3DPRESENT_INTERVAL_ONE : D3DPRESENT_INTERVAL_IMMEDIATE;
// create the D3D device
- result = (*d3dintf->d3d.create_device)(d3dintf, m_adapter, D3DDEVTYPE_HAL, device_hwnd,
+ result = d3dintf->d3dobj->CreateDevice(m_adapter, D3DDEVTYPE_HAL, device_hwnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING | D3DCREATE_FPU_PRESERVE, &m_presentation, &m_device);
- if (result != D3D_OK)
+ if (FAILED(result))
{
// if we got a "DEVICELOST" error, it may be transitory; count it and only fail if
// we exceed a threshold
@@ -839,7 +857,7 @@ try_again:
{
ramp.red[i] = ramp.green[i] = ramp.blue[i] = apply_brightness_contrast_gamma(i, brightness, contrast, gamma) << 8;
}
- (*d3dintf->device.set_gamma_ramp)(m_device, 0, &ramp);
+ m_device->SetGammaRamp(0, 0, &ramp);
}
}
}
@@ -874,57 +892,56 @@ try_again:
int renderer_d3d9::device_create_resources()
{
// allocate a vertex buffer to use
- HRESULT result = (*d3dintf->device.create_vertex_buffer)(m_device,
- sizeof(vertex) * VERTEX_BUFFER_SIZE,
+ HRESULT result = m_device->CreateVertexBuffer(sizeof(vertex) * VERTEX_BUFFER_SIZE,
D3DUSAGE_DYNAMIC | D3DUSAGE_SOFTWAREPROCESSING | D3DUSAGE_WRITEONLY,
VERTEX_BASE_FORMAT | ((m_shaders->enabled() && d3dintf->post_fx_available) ? D3DFVF_XYZW : D3DFVF_XYZRHW),
- D3DPOOL_DEFAULT, &m_vertexbuf);
- if (result != D3D_OK)
+ D3DPOOL_DEFAULT, &m_vertexbuf, nullptr);
+ if (FAILED(result))
{
osd_printf_error("Error creating vertex buffer (%08X)\n", (UINT32)result);
return 1;
}
// set the vertex format
- result = (*d3dintf->device.set_vertex_format)(m_device, (D3DFORMAT)(VERTEX_BASE_FORMAT | ((m_shaders->enabled() &&
+ result = m_device->SetFVF((D3DFORMAT)(VERTEX_BASE_FORMAT | ((m_shaders->enabled() &&
d3dintf->post_fx_available) ? D3DFVF_XYZW : D3DFVF_XYZRHW)));
- if (result != D3D_OK)
+ if (FAILED(result))
{
osd_printf_error("Error setting vertex format (%08X)\n", (UINT32)result);
return 1;
}
// set the fixed render state
- result = (*d3dintf->device.set_render_state)(m_device, D3DRS_ZENABLE, D3DZB_FALSE);
- result = (*d3dintf->device.set_render_state)(m_device, D3DRS_FILLMODE, D3DFILL_SOLID);
- result = (*d3dintf->device.set_render_state)(m_device, D3DRS_SHADEMODE, D3DSHADE_FLAT);
- result = (*d3dintf->device.set_render_state)(m_device, D3DRS_ZWRITEENABLE, FALSE);
- result = (*d3dintf->device.set_render_state)(m_device, D3DRS_ALPHATESTENABLE, TRUE);
- result = (*d3dintf->device.set_render_state)(m_device, D3DRS_LASTPIXEL, TRUE);
- result = (*d3dintf->device.set_render_state)(m_device, D3DRS_CULLMODE, D3DCULL_NONE);
- result = (*d3dintf->device.set_render_state)(m_device, D3DRS_ZFUNC, D3DCMP_LESS);
- result = (*d3dintf->device.set_render_state)(m_device, D3DRS_ALPHAREF, 0);
- result = (*d3dintf->device.set_render_state)(m_device, D3DRS_ALPHAFUNC, D3DCMP_GREATER);
- result = (*d3dintf->device.set_render_state)(m_device, D3DRS_DITHERENABLE, FALSE);
- result = (*d3dintf->device.set_render_state)(m_device, D3DRS_FOGENABLE, FALSE);
- result = (*d3dintf->device.set_render_state)(m_device, D3DRS_SPECULARENABLE, FALSE);
- result = (*d3dintf->device.set_render_state)(m_device, D3DRS_STENCILENABLE, FALSE);
- result = (*d3dintf->device.set_render_state)(m_device, D3DRS_WRAP0, FALSE);
- result = (*d3dintf->device.set_render_state)(m_device, D3DRS_CLIPPING, TRUE);
- result = (*d3dintf->device.set_render_state)(m_device, D3DRS_LIGHTING, FALSE);
- result = (*d3dintf->device.set_render_state)(m_device, D3DRS_COLORVERTEX, TRUE);
-
- result = (*d3dintf->device.set_texture_stage_state)(m_device, 0, D3DTSS_COLOROP, D3DTOP_MODULATE);
- result = (*d3dintf->device.set_texture_stage_state)(m_device, 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
- result = (*d3dintf->device.set_texture_stage_state)(m_device, 1, D3DTSS_COLOROP, D3DTOP_MODULATE);
- result = (*d3dintf->device.set_texture_stage_state)(m_device, 1, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
+ result = m_device->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE);
+ result = m_device->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);
+ result = m_device->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_FLAT);
+ result = m_device->SetRenderState(D3DRS_ZWRITEENABLE, FALSE);
+ result = m_device->SetRenderState(D3DRS_ALPHATESTENABLE, TRUE);
+ result = m_device->SetRenderState(D3DRS_LASTPIXEL, TRUE);
+ result = m_device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
+ result = m_device->SetRenderState(D3DRS_ZFUNC, D3DCMP_LESS);
+ result = m_device->SetRenderState(D3DRS_ALPHAREF, 0);
+ result = m_device->SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATER);
+ result = m_device->SetRenderState(D3DRS_DITHERENABLE, FALSE);
+ result = m_device->SetRenderState(D3DRS_FOGENABLE, FALSE);
+ result = m_device->SetRenderState(D3DRS_SPECULARENABLE, FALSE);
+ result = m_device->SetRenderState(D3DRS_STENCILENABLE, FALSE);
+ result = m_device->SetRenderState(D3DRS_WRAP0, FALSE);
+ result = m_device->SetRenderState(D3DRS_CLIPPING, TRUE);
+ result = m_device->SetRenderState(D3DRS_LIGHTING, FALSE);
+ result = m_device->SetRenderState(D3DRS_COLORVERTEX, TRUE);
+
+ result = m_device->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
+ result = m_device->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
+ result = m_device->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_MODULATE);
+ result = m_device->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
// reset the local states to force updates
reset_render_states();
// clear the buffer
- result = (*d3dintf->device.clear)(m_device, 0, nullptr, D3DCLEAR_TARGET, D3DCOLOR_ARGB(0,0,0,0), 0, 0);
- result = (*d3dintf->device.present)(m_device, nullptr, nullptr, nullptr, nullptr, 0);
+ result = m_device->Clear(0, nullptr, D3DCLEAR_TARGET, D3DCOLOR_ARGB(0,0,0,0), 0, 0);
+ result = m_device->Present(nullptr, nullptr, nullptr, nullptr);
m_texture_manager->create_resources();
@@ -953,7 +970,10 @@ renderer_d3d9::~renderer_d3d9()
void renderer_d3d9::exit()
{
if (d3dintf != nullptr)
- (*d3dintf->d3d.release)(d3dintf);
+ {
+ d3dintf->d3dobj->Release();
+ global_free(d3dintf);
+ }
}
void renderer_d3d9::device_delete()
@@ -980,7 +1000,7 @@ void renderer_d3d9::device_delete()
// free the device itself
if (m_device != nullptr)
{
- (*d3dintf->device.release)(m_device);
+ m_device->Release();
m_device = nullptr;
}
}
@@ -1000,7 +1020,7 @@ void renderer_d3d9::device_delete_resources()
// free the vertex buffer
if (m_vertexbuf != nullptr)
{
- (*d3dintf->vertexbuf.release)(m_vertexbuf);
+ m_vertexbuf->Release();
m_vertexbuf = nullptr;
}
}
@@ -1014,59 +1034,53 @@ int renderer_d3d9::device_verify_caps()
{
int retval = 0;
- DWORD tempcaps;
- HRESULT result = (*d3dintf->d3d.get_caps_dword)(d3dintf, m_adapter, D3DDEVTYPE_HAL, CAPS_MAX_PS30_INSN_SLOTS, &tempcaps);
- if (result != D3D_OK) osd_printf_verbose("Direct3D Error %08X during get_caps_dword call\n", (int)result);
- if (tempcaps < 512)
+ D3DCAPS9 caps;
+ HRESULT result = d3dintf->d3dobj->GetDeviceCaps(m_adapter, D3DDEVTYPE_HAL, &caps);
+ if (FAILED(result))
+ osd_printf_verbose("Direct3D: Error %08lX during GetDeviceCaps call\n", result);
+
+ if (caps.MaxPixelShader30InstructionSlots < 512)
{
osd_printf_verbose("Direct3D: Warning - Device does not support Pixel Shader 3.0, falling back to non-PS rendering\n");
d3dintf->post_fx_available = false;
}
// verify presentation capabilities
- result = (*d3dintf->d3d.get_caps_dword)(d3dintf, m_adapter, D3DDEVTYPE_HAL, CAPS_PRESENTATION_INTERVALS, &tempcaps);
- if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during get_caps_dword call\n", (int)result);
- if (!(tempcaps & D3DPRESENT_INTERVAL_IMMEDIATE))
+ if (!(caps.PresentationIntervals & D3DPRESENT_INTERVAL_IMMEDIATE))
{
osd_printf_verbose("Direct3D: Error - Device does not support immediate presentations\n");
retval = 2;
}
- if (!(tempcaps & D3DPRESENT_INTERVAL_ONE))
+ if (!(caps.PresentationIntervals & D3DPRESENT_INTERVAL_ONE))
{
osd_printf_verbose("Direct3D: Error - Device does not support per-refresh presentations\n");
retval = 2;
}
// verify device capabilities
- result = (*d3dintf->d3d.get_caps_dword)(d3dintf, m_adapter, D3DDEVTYPE_HAL, CAPS_DEV_CAPS, &tempcaps);
- if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during get_caps_dword call\n", (int)result);
- if (!(tempcaps & D3DDEVCAPS_CANRENDERAFTERFLIP))
+ if (!(caps.DevCaps & D3DDEVCAPS_CANRENDERAFTERFLIP))
{
osd_printf_verbose("Direct3D: Warning - Device does not support queued rendering after a page flip\n");
retval = 1;
}
- if (!(tempcaps & D3DDEVCAPS_HWRASTERIZATION))
+ if (!(caps.DevCaps & D3DDEVCAPS_HWRASTERIZATION))
{
osd_printf_verbose("Direct3D: Warning - Device does not support hardware rasterization\n");
retval = 1;
}
// verify texture operation capabilities
- result = (*d3dintf->d3d.get_caps_dword)(d3dintf, m_adapter, D3DDEVTYPE_HAL, CAPS_TEXTURE_OP_CAPS, &tempcaps);
- if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during get_caps_dword call\n", (int)result);
- if (!(tempcaps & D3DTEXOPCAPS_MODULATE))
+ if (!(caps.TextureOpCaps & D3DTEXOPCAPS_MODULATE))
{
osd_printf_verbose("Direct3D: Warning - Device does not support texture modulation\n");
retval = 1;
}
// set a simpler flag to indicate mod2x and mod4x texture modes
- m_mod2x_supported = ((tempcaps & D3DTEXOPCAPS_MODULATE2X) != 0);
- m_mod4x_supported = ((tempcaps & D3DTEXOPCAPS_MODULATE4X) != 0);
+ m_mod2x_supported = ((caps.TextureOpCaps & D3DTEXOPCAPS_MODULATE2X) != 0);
+ m_mod4x_supported = ((caps.TextureOpCaps & D3DTEXOPCAPS_MODULATE4X) != 0);
- result = (*d3dintf->d3d.get_caps_dword)(d3dintf, m_adapter, D3DDEVTYPE_HAL, CAPS_CAPS2, &tempcaps);
- if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during get_caps_dword call\n", (int)result);
- m_gamma_supported = ((tempcaps & D3DCAPS2_FULLSCREENGAMMA) != 0);
+ m_gamma_supported = ((caps.Caps2 & D3DCAPS2_FULLSCREENGAMMA) != 0);
return retval;
}
@@ -1079,7 +1093,7 @@ int renderer_d3d9::device_verify_caps()
int renderer_d3d9::device_test_cooperative()
{
// check our current status; if we lost the device, punt to GDI
- HRESULT result = (*d3dintf->device.test_cooperative_level)(m_device);
+ HRESULT result = m_device->TestCooperativeLevel();
if (result == D3DERR_DEVICELOST)
return 1;
@@ -1092,12 +1106,12 @@ int renderer_d3d9::device_test_cooperative()
m_sliders.clear();
m_shaders->delete_resources(true);
device_delete_resources();
- result = (*d3dintf->device.reset)(m_device, &m_presentation);
+ result = m_device->Reset(&m_presentation);
// if it didn't work, punt to GDI
- if (result != D3D_OK)
+ if (FAILED(result))
{
- osd_printf_error("Unable to reset, result %08x\n", (UINT32)result);
+ osd_printf_error("Unable to reset, result %08lX\n", result);
return 1;
}
@@ -1127,23 +1141,23 @@ int renderer_d3d9::device_test_cooperative()
int renderer_d3d9::config_adapter_mode()
{
- adapter_identifier identifier;
-
// choose the monitor number
m_adapter = get_adapter_for_monitor();
// get the identifier
- HRESULT result = (*d3dintf->d3d.get_adapter_identifier)(d3dintf, m_adapter, 0, &identifier);
- if (result != D3D_OK)
+ D3DADAPTER_IDENTIFIER9 id;
+ HRESULT result = d3dintf->d3dobj->GetAdapterIdentifier(m_adapter, 0, &id);
+ if (FAILED(result))
{
osd_printf_error("Error getting identifier for adapter #%d\n", m_adapter);
return 1;
}
- osd_printf_verbose("Direct3D: Configuring adapter #%d = %s\n", m_adapter, identifier.Description);
+
+ osd_printf_verbose("Direct3D: Configuring adapter #%d = %s\n", m_adapter, id.Description);
// get the current display mode
- result = (*d3dintf->d3d.get_adapter_display_mode)(d3dintf, m_adapter, &m_origmode);
- if (result != D3D_OK)
+ result = d3dintf->d3dobj->GetAdapterDisplayMode(m_adapter, &m_origmode);
+ if (FAILED(result))
{
osd_printf_error("Error getting mode for adapter #%d\n", m_adapter);
return 1;
@@ -1188,8 +1202,8 @@ int renderer_d3d9::config_adapter_mode()
}
// see if we can handle the device type
- result = (*d3dintf->d3d.check_device_type)(d3dintf, m_adapter, D3DDEVTYPE_HAL, m_pixformat, m_pixformat, !win->fullscreen());
- if (result != D3D_OK)
+ result = d3dintf->d3dobj->CheckDeviceType(m_adapter, D3DDEVTYPE_HAL, m_pixformat, m_pixformat, !win->fullscreen());
+ if (FAILED(result))
{
osd_printf_error("Proposed video mode not supported on device %s\n", win->monitor()->devicename());
return 1;
@@ -1204,7 +1218,7 @@ int renderer_d3d9::config_adapter_mode()
int renderer_d3d9::get_adapter_for_monitor()
{
- int maxadapter = (*d3dintf->d3d.get_adapter_count)(d3dintf);
+ int maxadapter = d3dintf->d3dobj->GetAdapterCount();
auto win = assert_window();
@@ -1212,7 +1226,7 @@ int renderer_d3d9::get_adapter_for_monitor()
for (int adapternum = 0; adapternum < maxadapter; adapternum++)
{
// get the monitor for this adapter
- HMONITOR curmonitor = (*d3dintf->d3d.get_adapter_monitor)(d3dintf, adapternum);
+ HMONITOR curmonitor = d3dintf->d3dobj->GetAdapterMonitor(adapternum);
// if we match the proposed monitor, this is it
if (curmonitor == *((HMONITOR *)win->monitor()->oshandle()))
@@ -1256,7 +1270,7 @@ void renderer_d3d9::pick_best_mode()
INT32 target_height = minheight;
// determine the maximum number of modes
- int maxmodes = (*d3dintf->d3d.get_adapter_mode_count)(d3dintf, m_adapter, D3DFMT_X8R8G8B8);
+ int maxmodes = d3dintf->d3dobj->GetAdapterModeCount(m_adapter, D3DFMT_X8R8G8B8);
// enumerate all the video modes and find the best match
osd_printf_verbose("Direct3D: Selecting video mode...\n");
@@ -1264,8 +1278,8 @@ void renderer_d3d9::pick_best_mode()
{
// check this mode
D3DDISPLAYMODE mode;
- HRESULT result = (*d3dintf->d3d.enum_adapter_modes)(d3dintf, m_adapter, D3DFMT_X8R8G8B8, modenum, &mode);
- if (result != D3D_OK)
+ HRESULT result = d3dintf->d3dobj->EnumAdapterModes(m_adapter, D3DFMT_X8R8G8B8, modenum, &mode);
+ if (FAILED(result))
break;
// skip non-32 bit modes
@@ -1753,8 +1767,8 @@ vertex *renderer_d3d9::mesh_alloc(int numverts)
// if we don't have a lock, grab it now
if (m_lockedbuf == nullptr)
{
- result = (*d3dintf->vertexbuf.lock)(m_vertexbuf, 0, 0, (VOID **)&m_lockedbuf, D3DLOCK_DISCARD);
- if (result != D3D_OK)
+ result = m_vertexbuf->Lock(0, 0, (VOID **)&m_lockedbuf, D3DLOCK_DISCARD);
+ if (FAILED(result))
return nullptr;
}
@@ -1777,18 +1791,19 @@ void renderer_d3d9::primitive_flush_pending()
{
// ignore if we're not locked
if (m_lockedbuf == nullptr)
- {
return;
- }
// unlock the buffer
- HRESULT result = (*d3dintf->vertexbuf.unlock)(m_vertexbuf);
- if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during vertex buffer unlock call\n", (int)result);
+ HRESULT result = m_vertexbuf->Unlock();
+ if (FAILED(result))
+ osd_printf_verbose("Direct3D: Error %08lX during vertex buffer unlock call\n", result);
+
m_lockedbuf = nullptr;
// set the stream
- result = (*d3dintf->device.set_stream_source)(m_device, 0, m_vertexbuf, sizeof(vertex));
- if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_stream_source call\n", (int)result);
+ result = m_device->SetStreamSource(0, m_vertexbuf, 0, sizeof(vertex));
+ if (FAILED(result))
+ osd_printf_verbose("Direct3D: Error %08lX during device SetStreamSource call\n", result);
m_shaders->begin_draw();
@@ -1839,9 +1854,9 @@ void renderer_d3d9::primitive_flush_pending()
else
{
// add the primitives
- result = (*d3dintf->device.draw_primitive)(m_device, m_poly[polynum].get_type(), vertnum,
- m_poly[polynum].get_count());
- if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device draw_primitive call\n", (int)result);
+ result = m_device->DrawPrimitive(m_poly[polynum].get_type(), vertnum, m_poly[polynum].get_count());
+ if (FAILED(result))
+ osd_printf_verbose("Direct3D: Error %08lX during device draw_primitive call\n", result);
}
vertnum += m_poly[polynum].get_vertcount();
@@ -1864,22 +1879,16 @@ texture_info::~texture_info()
if (m_d3dfinaltex != nullptr)
{
if (m_d3dtex == m_d3dfinaltex)
- {
m_d3dtex = nullptr;
- }
- (*d3dintf->texture.release)(m_d3dfinaltex);
- m_d3dfinaltex = nullptr;
+
+ m_d3dfinaltex->Release();
}
+
if (m_d3dtex != nullptr)
- {
- (*d3dintf->texture.release)(m_d3dtex);
- m_d3dtex = nullptr;
- }
+ m_d3dtex->Release();
+
if (m_d3dsurface != nullptr)
- {
- (*d3dintf->surface.release)(m_d3dsurface);
- m_d3dsurface = nullptr;
- }
+ m_d3dsurface->Release();
}
@@ -1935,8 +1944,8 @@ texture_info::texture_info(d3d_texture_manager *manager, const render_texinfo* t
if (!PRIMFLAG_GET_SCREENTEX(flags))
{
assert(PRIMFLAG_TEXFORMAT(flags) != TEXFORMAT_YUY16);
- result = (*d3dintf->device.create_texture)(m_renderer->get_device(), m_rawdims.c.x, m_rawdims.c.y, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &m_d3dtex);
- if (result != D3D_OK)
+ result = m_renderer->get_device()->CreateTexture(m_rawdims.c.x, m_rawdims.c.y, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &m_d3dtex, nullptr);
+ if (FAILED(result))
goto error;
m_d3dfinaltex = m_d3dtex;
}
@@ -2001,7 +2010,7 @@ texture_info::texture_info(d3d_texture_manager *manager, const render_texinfo* t
// screen textures with no prescaling are pretty easy
if (m_xprescale == 1 && m_yprescale == 1)
{
- result = (*d3dintf->device.create_texture)(m_renderer->get_device(), m_rawdims.c.x, m_rawdims.c.y, 1, usage, format, pool, &m_d3dtex);
+ result = m_renderer->get_device()->CreateTexture(m_rawdims.c.x, m_rawdims.c.y, 1, usage, format, pool, &m_d3dtex, nullptr);
if (result == D3D_OK)
{
m_d3dfinaltex = m_d3dtex;
@@ -2015,8 +2024,8 @@ texture_info::texture_info(d3d_texture_manager *manager, const render_texinfo* t
// (won't work for YUY textures)
if (m_texture_manager->is_stretch_supported() && PRIMFLAG_GET_TEXFORMAT(flags) != TEXFORMAT_YUY16)
{
- result = (*d3dintf->device.create_offscreen_plain_surface)(m_renderer->get_device(), m_rawdims.c.x, m_rawdims.c.y, format, D3DPOOL_DEFAULT, &m_d3dsurface);
- if (result != D3D_OK)
+ result = m_renderer->get_device()->CreateOffscreenPlainSurface(m_rawdims.c.x, m_rawdims.c.y, format, D3DPOOL_DEFAULT, &m_d3dsurface, nullptr);
+ if (FAILED(result))
{
continue;
}
@@ -2024,8 +2033,8 @@ texture_info::texture_info(d3d_texture_manager *manager, const render_texinfo* t
// otherwise, we allocate a dynamic texture for the source
else
{
- result = (*d3dintf->device.create_texture)(m_renderer->get_device(), m_rawdims.c.x, m_rawdims.c.y, 1, usage, format, pool, &m_d3dtex);
- if (result != D3D_OK)
+ result = m_renderer->get_device()->CreateTexture(m_rawdims.c.x, m_rawdims.c.y, 1, usage, format, pool, &m_d3dtex, nullptr);
+ if (FAILED(result))
{
continue;
}
@@ -2038,13 +2047,13 @@ texture_info::texture_info(d3d_texture_manager *manager, const render_texinfo* t
// target surfaces typically cannot be YCbCr, so we always pick RGB in that case
D3DFORMAT finalfmt = (format != m_texture_manager->get_yuv_format()) ? format : D3DFMT_A8R8G8B8;
- result = (*d3dintf->device.create_texture)(m_renderer->get_device(), scwidth, scheight, 1, D3DUSAGE_RENDERTARGET, finalfmt, D3DPOOL_DEFAULT, &m_d3dfinaltex);
+ result = m_renderer->get_device()->CreateTexture(scwidth, scheight, 1, D3DUSAGE_RENDERTARGET, finalfmt, D3DPOOL_DEFAULT, &m_d3dfinaltex, nullptr);
if (result == D3D_OK)
{
break;
}
- (*d3dintf->texture.release)(m_d3dtex);
+ m_d3dtex->Release();
m_d3dtex = nullptr;
}
}
@@ -2065,9 +2074,9 @@ error:
d3dintf->post_fx_available = false;
osd_printf_error("Direct3D: Critical warning: A texture failed to allocate. Expect things to get bad quickly.\n");
if (m_d3dsurface != nullptr)
- (*d3dintf->surface.release)(m_d3dsurface);
+ m_d3dsurface->Release();
if (m_d3dtex != nullptr)
- (*d3dintf->texture.release)(m_d3dtex);
+ m_d3dtex->Release();
}
@@ -2536,11 +2545,11 @@ void texture_info::set_data(const render_texinfo *texsource, UINT32 flags)
switch (m_type)
{
default:
- case TEXTURE_TYPE_PLAIN: result = (*d3dintf->texture.lock_rect)(m_d3dtex, 0, &rect, nullptr, 0); break;
- case TEXTURE_TYPE_DYNAMIC: result = (*d3dintf->texture.lock_rect)(m_d3dtex, 0, &rect, nullptr, D3DLOCK_DISCARD); break;
- case TEXTURE_TYPE_SURFACE: result = (*d3dintf->surface.lock_rect)(m_d3dsurface, &rect, nullptr, D3DLOCK_DISCARD); break;
+ case TEXTURE_TYPE_PLAIN: result = m_d3dtex->LockRect(0, &rect, nullptr, 0); break;
+ case TEXTURE_TYPE_DYNAMIC: result = m_d3dtex->LockRect(0, &rect, nullptr, D3DLOCK_DISCARD); break;
+ case TEXTURE_TYPE_SURFACE: result = m_d3dsurface->LockRect(&rect, nullptr, D3DLOCK_DISCARD); break;
}
- if (result != D3D_OK)
+ if (FAILED(result))
{
return;
}
@@ -2591,14 +2600,12 @@ void texture_info::set_data(const render_texinfo *texsource, UINT32 flags)
switch (m_type)
{
default:
- case TEXTURE_TYPE_PLAIN: result = (*d3dintf->texture.unlock_rect)(m_d3dtex, 0); break;
- case TEXTURE_TYPE_DYNAMIC: result = (*d3dintf->texture.unlock_rect)(m_d3dtex, 0); break;
- case TEXTURE_TYPE_SURFACE: result = (*d3dintf->surface.unlock_rect)(m_d3dsurface); break;
- }
- if (result != D3D_OK)
- {
- osd_printf_verbose("Direct3D: Error %08X during texture unlock_rect call\n", (int)result);
+ case TEXTURE_TYPE_PLAIN: result = m_d3dtex->UnlockRect(0); break;
+ case TEXTURE_TYPE_DYNAMIC: result = m_d3dtex->UnlockRect(0); break;
+ case TEXTURE_TYPE_SURFACE: result = m_d3dsurface->UnlockRect(); break;
}
+ if (FAILED(result))
+ osd_printf_verbose("Direct3D: Error %08lX during texture UnlockRect call\n", result);
// prescale
prescale();
@@ -2611,7 +2618,7 @@ void texture_info::set_data(const render_texinfo *texsource, UINT32 flags)
void texture_info::prescale()
{
- surface *scale_surface;
+ IDirect3DSurface9 *scale_surface;
HRESULT result;
int i;
@@ -2620,8 +2627,9 @@ void texture_info::prescale()
return;
// for all cases, we need to get the surface of the render target
- result = (*d3dintf->texture.get_surface_level)(m_d3dfinaltex, 0, &scale_surface);
- if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during texture get_surface_level call\n", (int)result);
+ result = m_d3dfinaltex->GetSurfaceLevel(0, &scale_surface);
+ if (FAILED(result))
+ osd_printf_verbose("Direct3D: Error %08lX during texture GetSurfaceLevel call\n", result);
// if we have an offscreen plain surface, we can just StretchRect to it
if (m_type == TEXTURE_TYPE_SURFACE)
@@ -2641,37 +2649,43 @@ void texture_info::prescale()
dest.bottom *= m_yprescale;
// do the stretchrect
- result = (*d3dintf->device.stretch_rect)(m_renderer->get_device(), m_d3dsurface, &source, scale_surface, &dest, D3DTEXF_POINT);
- if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device stretct_rect call\n", (int)result);
+ result = m_renderer->get_device()->StretchRect(m_d3dsurface, &source, scale_surface, &dest, D3DTEXF_POINT);
+ if (FAILED(result))
+ osd_printf_verbose("Direct3D: Error %08lX during device stretct_rect call\n", result);
}
// if we are using a texture render target, we need to do more preparations
else
{
- surface *backbuffer;
+ IDirect3DSurface9 *backbuffer;
assert(m_d3dtex != nullptr);
// first remember the original render target and set the new one
- result = (*d3dintf->device.get_render_target)(m_renderer->get_device(), 0, &backbuffer);
- if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device get_render_target call\n", (int)result);
- result = (*d3dintf->device.set_render_target)(m_renderer->get_device(), 0, scale_surface);
- if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_render_target call 1\n", (int)result);
+ result = m_renderer->get_device()->GetRenderTarget(0, &backbuffer);
+ if (FAILED(result))
+ osd_printf_verbose("Direct3D: Error %08lX during device GetRenderTarget call\n", result);
+ result = m_renderer->get_device()->SetRenderTarget(0, scale_surface);
+ if (FAILED(result))
+ osd_printf_verbose("Direct3D: Error %08lX during device SetRenderTarget call 1\n", result);
m_renderer->reset_render_states();
// start the scene
- result = (*d3dintf->device.begin_scene)(m_renderer->get_device());
- if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device begin_scene call\n", (int)result);
+ result = m_renderer->get_device()->BeginScene();
+ if (FAILED(result))
+ osd_printf_verbose("Direct3D: Error %08lX during device BeginScene call\n", result);
// configure the rendering pipeline
m_renderer->set_filter(FALSE);
m_renderer->set_blendmode(BLENDMODE_NONE);
- result = (*d3dintf->device.set_texture)(m_renderer->get_device(), 0, m_d3dtex);
- if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_texture call\n", (int)result);
+ result = m_renderer->get_device()->SetTexture(0, m_d3dtex);
+ if (FAILED(result))
+ osd_printf_verbose("Direct3D: Error %08lX during device SetTexture call\n", result);
// lock the vertex buffer
- result = (*d3dintf->vertexbuf.lock)(m_renderer->get_vertex_buffer(), 0, 0, m_renderer->get_locked_buffer_ptr(), D3DLOCK_DISCARD);
- if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during vertex buffer lock call\n", (int)result);
+ result = m_renderer->get_vertex_buffer()->Lock(0, 0, m_renderer->get_locked_buffer_ptr(), D3DLOCK_DISCARD);
+ if (FAILED(result))
+ osd_printf_verbose("Direct3D: Error %08lX during vertex buffer lock call\n", result);
// configure the X/Y coordinates on the target surface
vertex *lockedbuf = m_renderer->get_locked_buffer();
@@ -2703,29 +2717,34 @@ void texture_info::prescale()
}
// unlock the vertex buffer
- result = (*d3dintf->vertexbuf.unlock)(m_renderer->get_vertex_buffer());
- if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during vertex buffer unlock call\n", (int)result);
+ result = m_renderer->get_vertex_buffer()->Unlock();
+ if (FAILED(result))
+ osd_printf_verbose("Direct3D: Error %08lX during vertex buffer unlock call\n", result);
m_renderer->set_locked_buffer(nullptr);
// set the stream and draw the triangle strip
- result = (*d3dintf->device.set_stream_source)(m_renderer->get_device(), 0, m_renderer->get_vertex_buffer(), sizeof(vertex));
- if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_stream_source call\n", (int)result);
- result = (*d3dintf->device.draw_primitive)(m_renderer->get_device(), D3DPT_TRIANGLESTRIP, 0, 2);
- if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device draw_primitive call\n", (int)result);
+ result = m_renderer->get_device()->SetStreamSource(0, m_renderer->get_vertex_buffer(), 0, sizeof(vertex));
+ if (FAILED(result))
+ osd_printf_verbose("Direct3D: Error %08lX during device SetStreamSource call\n", result);
+ result = m_renderer->get_device()->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);
+ if (FAILED(result))
+ osd_printf_verbose("Direct3D: Error %08lX during device DrawPrimitive call\n", result);
// end the scene
- result = (*d3dintf->device.end_scene)(m_renderer->get_device());
- if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device end_scene call\n", (int)result);
+ result = m_renderer->get_device()->EndScene();
+ if (FAILED(result))
+ osd_printf_verbose("Direct3D: Error %08lX during device end_scene call\n", result);
// reset the render target and release our reference to the backbuffer
- result = (*d3dintf->device.set_render_target)(m_renderer->get_device(), 0, backbuffer);
- if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_render_target call 2\n", (int)result);
- (*d3dintf->surface.release)(backbuffer);
+ result = m_renderer->get_device()->SetRenderTarget(0, backbuffer);
+ if (FAILED(result))
+ osd_printf_verbose("Direct3D: Error %08lX during device SetRenderTarget call 2\n", result);
+ backbuffer->Release();
m_renderer->reset_render_states();
}
// release our reference to the target surface
- (*d3dintf->surface.release)(scale_surface);
+ scale_surface->Release();
}
@@ -2736,15 +2755,10 @@ void texture_info::prescale()
cache_target::~cache_target()
{
if (last_texture != nullptr)
- {
- (*d3dintf->texture.release)(last_texture);
- last_texture = nullptr;
- }
+ last_texture->Release();
+
if (last_target != nullptr)
- {
- (*d3dintf->surface.release)(last_target);
- last_target = nullptr;
- }
+ last_target->Release();
}
@@ -2759,12 +2773,11 @@ bool cache_target::init(renderer_d3d9 *d3d, d3d_base *d3dintf, int source_width,
this->target_width = target_width;
this->target_height = target_height;
- HRESULT result = (*d3dintf->device.create_texture)(d3d->get_device(), target_width, target_height, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &last_texture);
- if (result != D3D_OK)
- {
+ HRESULT result = d3d->get_device()->CreateTexture(target_width, target_height, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &last_texture, nullptr);
+ if (FAILED(result))
return false;
- }
- (*d3dintf->texture.get_surface_level)(last_texture, 0, &last_target);
+
+ last_texture->GetSurfaceLevel(0, &last_target);
return true;
}
@@ -2779,39 +2792,25 @@ d3d_render_target::~d3d_render_target()
for (int index = 0; index < MAX_BLOOM_COUNT; index++)
{
if (bloom_texture[index] != nullptr)
- {
- (*d3dintf->texture.release)(bloom_texture[index]);
- bloom_texture[index] = nullptr;
- }
+ bloom_texture[index]->Release();
+
if (bloom_surface[index] != nullptr)
- {
- (*d3dintf->surface.release)(bloom_surface[index]);
- bloom_surface[index] = nullptr;
- }
+ bloom_surface[index]->Release();
}
for (int index = 0; index < 2; index++)
{
if (source_texture[index] != nullptr)
- {
- (*d3dintf->texture.release)(source_texture[index]);
- source_texture[index] = nullptr;
- }
+ source_texture[index]->Release();
+
if (source_surface[index] != nullptr)
- {
- (*d3dintf->surface.release)(source_surface[index]);
- source_surface[index] = nullptr;
- }
+ source_surface[index]->Release();
+
if (target_texture[index] != nullptr)
- {
- (*d3dintf->texture.release)(target_texture[index]);
- target_texture[index] = nullptr;
- }
+ target_texture[index]->Release();
+
if (target_surface[index] != nullptr)
- {
- (*d3dintf->surface.release)(target_surface[index]);
- target_surface[index] = nullptr;
- }
+ target_surface[index]->Release();
}
}
@@ -2832,19 +2831,17 @@ bool d3d_render_target::init(renderer_d3d9 *d3d, d3d_base *d3dintf, int source_w
for (int index = 0; index < 2; index++)
{
- result = (*d3dintf->device.create_texture)(d3d->get_device(), source_width, source_height, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &source_texture[index]);
- if (result != D3D_OK)
- {
+ result = d3d->get_device()->CreateTexture(source_width, source_height, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &source_texture[index], nullptr);
+ if (FAILED(result))
return false;
- }
- (*d3dintf->texture.get_surface_level)(source_texture[index], 0, &source_surface[index]);
- result = (*d3dintf->device.create_texture)(d3d->get_device(), target_width, target_height, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &target_texture[index]);
- if (result != D3D_OK)
- {
+ source_texture[index]->GetSurfaceLevel(0, &source_surface[index]);
+
+ result = d3d->get_device()->CreateTexture(target_width, target_height, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &target_texture[index], nullptr);
+ if (FAILED(result))
return false;
- }
- (*d3dintf->texture.get_surface_level)(target_texture[index], 0, &target_surface[index]);
+
+ target_texture[index]->GetSurfaceLevel(0, &target_surface[index]);
}
auto win = d3d->assert_window();
@@ -2865,12 +2862,11 @@ bool d3d_render_target::init(renderer_d3d9 *d3d, d3d_base *d3dintf, int source_w
this->bloom_dims[bloom_index][0] = (int)bloom_width;
this->bloom_dims[bloom_index][1] = (int)bloom_height;
- result = (*d3dintf->device.create_texture)(d3d->get_device(), (int)bloom_width, (int)bloom_height, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &bloom_texture[bloom_index]);
- if (result != D3D_OK)
- {
+ result = d3d->get_device()->CreateTexture((int)bloom_width, (int)bloom_height, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &bloom_texture[bloom_index], nullptr);
+ if (FAILED(result))
return false;
- }
- (*d3dintf->texture.get_surface_level)(bloom_texture[bloom_index], 0, &bloom_surface[bloom_index]);
+
+ bloom_texture[bloom_index]->GetSurfaceLevel(0, &bloom_surface[bloom_index]);
bloom_width *= scale_factor;
bloom_height *= scale_factor;
diff --git a/src/osd/modules/render/drawd3d.h b/src/osd/modules/render/drawd3d.h
index 59d32a46ce7..1c044299b36 100644
--- a/src/osd/modules/render/drawd3d.h
+++ b/src/osd/modules/render/drawd3d.h
@@ -13,8 +13,17 @@
#ifdef OSD_WINDOWS
-#include "d3d/d3dintf.h"
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <tchar.h>
+#include <mmsystem.h>
+#include <d3d9.h>
+#include <d3dx9.h>
+#include <math.h>
+#undef interface
+
#include "d3d/d3dcomm.h"
+#include "modules/lib/osdlib.h"
//============================================================
// CONSTANTS
@@ -27,14 +36,17 @@
// TYPE DEFINITIONS
//============================================================
-struct vertex;
-class texture_info;
-class texture_manager;
-struct device;
-struct vertex_buffer;
+struct d3d_base
+{
+ // internal objects
+ IDirect3D9 *d3dobj;
+ bool post_fx_available;
+
+ osd::dynamic_module::ptr d3d9_dll;
+};
+
class shaders;
struct hlsl_options;
-class poly_info;
/* renderer is the information about Direct3D for the current screen */
class renderer_d3d9 : public osd_renderer
@@ -97,10 +109,10 @@ public:
int get_height() const { return m_height; }
int get_refresh() const { return m_refresh; }
- device * get_device() const { return m_device; }
- present_parameters * get_presentation() { return &m_presentation; }
+ IDirect3DDevice9 * get_device() const { return m_device; }
+ D3DPRESENT_PARAMETERS * get_presentation() { return &m_presentation; }
- vertex_buffer * get_vertex_buffer() const { return m_vertexbuf; }
+ IDirect3DVertexBuffer9 *get_vertex_buffer() const { return m_vertexbuf; }
vertex * get_locked_buffer() const { return m_lockedbuf; }
VOID ** get_locked_buffer_ptr()const { return (VOID **)&m_lockedbuf; }
void set_locked_buffer(vertex *lockedbuf) { m_lockedbuf = lockedbuf; }
@@ -128,13 +140,13 @@ private:
int m_refresh; // current refresh rate
int m_create_error_count; // number of consecutive create errors
- device * m_device; // pointer to the Direct3DDevice object
+ IDirect3DDevice9 * m_device; // pointer to the Direct3DDevice object
int m_gamma_supported; // is full screen gamma supported?
- present_parameters m_presentation; // set of presentation parameters
+ D3DPRESENT_PARAMETERS m_presentation; // set of presentation parameters
D3DDISPLAYMODE m_origmode; // original display mode for the adapter
D3DFORMAT m_pixformat; // pixel format we are using
- vertex_buffer * m_vertexbuf; // pointer to the vertex buffer object
+ IDirect3DVertexBuffer9 *m_vertexbuf; // pointer to the vertex buffer object
vertex * m_lockedbuf; // pointer to the locked vertex buffer
int m_numverts; // number of accumulated vertices
diff --git a/src/osd/modules/render/drawogl.cpp b/src/osd/modules/render/drawogl.cpp
index 77acf017790..83a48e67b51 100644
--- a/src/osd/modules/render/drawogl.cpp
+++ b/src/osd/modules/render/drawogl.cpp
@@ -360,17 +360,11 @@ static void loadgl_functions(osd_gl_context *context)
osd_gl_dispatch *gl_dispatch;
#endif
-#ifdef OSD_WINDOWS
-HMODULE win_gl_context::m_module;
-#endif
-
void renderer_ogl::load_gl_lib(running_machine &machine)
{
if (!s_dll_loaded)
{
-#ifdef OSD_WINDOWS
- win_gl_context::load_library();
-#else
+#ifndef OSD_WINDOWS
#ifdef USE_DISPATCH_GL
/*
* directfb and and x11 use this env var
diff --git a/src/osd/modules/render/winglcontext.h b/src/osd/modules/render/winglcontext.h
index 843532fe33f..54e9a0ebae0 100644
--- a/src/osd/modules/render/winglcontext.h
+++ b/src/osd/modules/render/winglcontext.h
@@ -14,6 +14,17 @@
#define __WIN_GL_CONTEXT__
#include "modules/opengl/osd_opengl.h"
+#include "modules/lib/osdlib.h"
+
+// Typedefs for dynamically loaded functions
+typedef PROC WINAPI (*wglGetProcAddress_fn)(LPCSTR);
+typedef HGLRC WINAPI (*wglCreateContext_fn)(HDC);
+typedef BOOL WINAPI (*wglDeleteContext_fn)(HGLRC);
+typedef BOOL WINAPI (*wglMakeCurrent_fn)(HDC, HGLRC);
+
+typedef const char * WINAPI (*wglGetExtensionsStringEXT_fn)(void);
+typedef BOOL WINAPI (*wglSwapIntervalEXT_fn)(int);
+typedef int WINAPI (*wglGetSwapIntervalEXT_fn)(void);
class win_gl_context : public osd_gl_context
{
@@ -22,17 +33,25 @@ public:
{
m_error[0] = 0;
- this->pfn_wglGetProcAddress = (PROC (WINAPI *)(LPCSTR lpszProc)) GetProcAddress(m_module, "wglGetProcAddress");
- this->pfn_wglCreateContext = (HGLRC (WINAPI *)(HDC hdc)) GetProcAddress(m_module, "wglCreateContext");
- this->pfn_wglDeleteContext = (BOOL (WINAPI *)(HGLRC hglrc)) GetProcAddress(m_module, "wglDeleteContext");
- this->pfn_wglMakeCurrent = (BOOL (WINAPI *)(HDC hdc, HGLRC hglrc)) GetProcAddress(m_module, "wglMakeCurrent");
+ opengl32_dll = osd::dynamic_module::open({ "opengl32.dll" });
- this->pfn_wglGetExtensionsStringEXT = (const char *(WINAPI *) (void)) pfn_wglGetProcAddress("wglGetExtensionsStringEXT");
+ pfn_wglGetProcAddress = opengl32_dll->bind<wglGetProcAddress_fn>("wglGetProcAddress");
+ pfn_wglCreateContext = opengl32_dll->bind<wglCreateContext_fn>("wglCreateContext");
+ pfn_wglDeleteContext = opengl32_dll->bind<wglDeleteContext_fn>("wglDeleteContext");
+ pfn_wglMakeCurrent = opengl32_dll->bind<wglMakeCurrent_fn>("wglMakeCurrent");
+
+ if (pfn_wglGetProcAddress == nullptr || pfn_wglCreateContext == nullptr ||
+ pfn_wglDeleteContext == nullptr || pfn_wglMakeCurrent == nullptr)
+ {
+ return;
+ }
+
+ pfn_wglGetExtensionsStringEXT = (wglGetExtensionsStringEXT_fn)(*pfn_wglGetProcAddress)("wglGetExtensionsStringEXT");
if (WGLExtensionSupported("WGL_EXT_swap_control"))
{
- this->pfn_wglSwapIntervalEXT = (BOOL (WINAPI *) (int)) getProcAddress("wglSwapIntervalEXT");
- this->pfn_wglGetSwapIntervalEXT = (int (WINAPI *) (void)) getProcAddress("wglGetSwapIntervalEXT");
+ pfn_wglSwapIntervalEXT = (BOOL (WINAPI *) (int)) getProcAddress("wglSwapIntervalEXT");
+ pfn_wglGetSwapIntervalEXT = (int (WINAPI *) (void)) getProcAddress("wglGetSwapIntervalEXT");
}
else
{
@@ -43,25 +62,25 @@ public:
m_hdc = GetDC(window);
if (!setupPixelFormat(m_hdc))
{
- m_context = this->pfn_wglCreateContext(m_hdc);
- if (!m_context)
+ m_context = (*pfn_wglCreateContext)(m_hdc);
+ if (!m_context)
{
FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, nullptr, GetLastError(), 0, m_error, 255, nullptr);
return;
}
- this->pfn_wglMakeCurrent(m_hdc, m_context);
+ (*pfn_wglMakeCurrent)(m_hdc, m_context);
}
}
virtual ~win_gl_context()
{
- this->pfn_wglDeleteContext(m_context);
+ (*pfn_wglDeleteContext)(m_context);
ReleaseDC(m_window, m_hdc);
}
virtual void MakeCurrent() override
{
- this->pfn_wglMakeCurrent(m_hdc, m_context);
+ (*pfn_wglMakeCurrent)(m_hdc, m_context);
}
virtual const char *LastErrorMsg() override
@@ -74,17 +93,14 @@ public:
virtual void *getProcAddress(const char *proc) override
{
- void *ret = (void *) GetProcAddress(m_module, proc);
- if (ret == nullptr)
- ret = (void *) this->pfn_wglGetProcAddress(proc);
- return ret;
+ return (void *)(*pfn_wglGetProcAddress)(proc);
}
virtual int SetSwapInterval(const int swap) override
{
- if (this->pfn_wglSwapIntervalEXT != nullptr)
+ if (pfn_wglSwapIntervalEXT != nullptr)
{
- this->pfn_wglSwapIntervalEXT(swap ? 1 : 0);
+ pfn_wglSwapIntervalEXT(swap ? 1 : 0);
}
return 0;
}
@@ -95,11 +111,6 @@ public:
//wglSwapLayerBuffers(GetDC(window().m_hwnd), WGL_SWAP_MAIN_PLANE);
}
- static void load_library()
- {
- m_module = LoadLibraryA("opengl32.dll");
- }
-
private:
int setupPixelFormat(HDC hDC)
@@ -124,15 +135,17 @@ private:
0, /* reserved */
0, 0, 0, /* no layer, visible, damage masks */
};
- int pixelFormat;
- pixelFormat = ChoosePixelFormat(hDC, &pfd);
- if (pixelFormat == 0) {
- strcpy(m_error, "ChoosePixelFormat failed");
+ int pixelFormat = ChoosePixelFormat(hDC, &pfd);
+
+ if (pixelFormat == 0)
+ {
+ strcpy(m_error, "ChoosePixelFormat failed.");
return 1;
}
- if (SetPixelFormat(hDC, pixelFormat, &pfd) != TRUE) {
+ if (SetPixelFormat(hDC, pixelFormat, &pfd) != TRUE)
+ {
strcpy(m_error, "SetPixelFormat failed.");
return 1;
}
@@ -141,10 +154,12 @@ private:
bool WGLExtensionSupported(const char *extension_name)
{
- //if (pfn_wglGetExtensionsStringEXT != nullptr)
- // printf("%s\n", this->pfn_wglGetExtensionsStringEXT());
+ if (pfn_wglGetExtensionsStringEXT == nullptr)
+ return false;
+
+ // printf("%s\n", pfn_wglGetExtensionsStringEXT());
- if (pfn_wglGetExtensionsStringEXT != nullptr && strstr(pfn_wglGetExtensionsStringEXT(), extension_name) != nullptr)
+ if (strstr(pfn_wglGetExtensionsStringEXT(), extension_name) != nullptr)
return true;
else
return false;
@@ -155,16 +170,15 @@ private:
HDC m_hdc;
char m_error[256];
- PROC (WINAPI *pfn_wglGetProcAddress)(LPCSTR lpszProc);
- HGLRC (WINAPI *pfn_wglCreateContext)(HDC hdc);
- BOOL (WINAPI *pfn_wglDeleteContext)(HGLRC hglrc);
- BOOL (WINAPI *pfn_wglMakeCurrent)(HDC hdc, HGLRC hglrc);
-
- const char *(WINAPI *pfn_wglGetExtensionsStringEXT) (void);
- BOOL (WINAPI *pfn_wglSwapIntervalEXT) (int interval);
- int (WINAPI * pfn_wglGetSwapIntervalEXT) (void);
+ osd::dynamic_module::ptr opengl32_dll;
+ wglGetProcAddress_fn pfn_wglGetProcAddress;
+ wglCreateContext_fn pfn_wglCreateContext;
+ wglDeleteContext_fn pfn_wglDeleteContext;
+ wglMakeCurrent_fn pfn_wglMakeCurrent;
- static HMODULE m_module;
+ wglGetExtensionsStringEXT_fn pfn_wglGetExtensionsStringEXT;
+ wglSwapIntervalEXT_fn pfn_wglSwapIntervalEXT;
+ wglGetSwapIntervalEXT_fn pfn_wglGetSwapIntervalEXT;
};
#endif // __WIN_GL_CONTEXT__
diff --git a/src/osd/modules/sound/xaudio2_sound.cpp b/src/osd/modules/sound/xaudio2_sound.cpp
index f4da54db2ec..66fdb1ba009 100644..100755
--- a/src/osd/modules/sound/xaudio2_sound.cpp
+++ b/src/osd/modules/sound/xaudio2_sound.cpp
@@ -33,6 +33,8 @@
#include "winutil.h"
+#include "modules/lib/osdlib.h"
+
//============================================================
// Constants
//============================================================
@@ -118,7 +120,7 @@ typedef std::unique_ptr<IXAudio2MasteringVoice, xaudio2_custom_deleter> masterin
typedef std::unique_ptr<IXAudio2SourceVoice, xaudio2_custom_deleter> src_voice_ptr;
// Typedef for pointer to XAudio2Create
-typedef lazy_loaded_function_p3<HRESULT, IXAudio2**, UINT32, XAUDIO2_PROCESSOR> xaudio2_create_ptr;
+typedef HRESULT (*xaudio2_create_ptr)(IXAudio2 **, UINT32, XAUDIO2_PROCESSOR);
//============================================================
// Helper classes
@@ -181,28 +183,27 @@ public:
class sound_xaudio2 : public osd_module, public sound_module, public IXAudio2VoiceCallback
{
private:
- const wchar_t* XAUDIO_DLLS[2] = { L"XAudio2_9.dll", L"XAudio2_8.dll" };
-
- Microsoft::WRL::ComPtr<IXAudio2> m_xAudio2;
- mastering_voice_ptr m_masterVoice;
- src_voice_ptr m_sourceVoice;
- DWORD m_sample_bytes;
- std::unique_ptr<BYTE[]> m_buffer;
- DWORD m_buffer_size;
- DWORD m_buffer_count;
- DWORD m_writepos;
- std::mutex m_buffer_lock;
- HANDLE m_hEventBufferCompleted;
- HANDLE m_hEventDataAvailable;
- HANDLE m_hEventExiting;
- std::thread m_audioThread;
- std::queue<xaudio2_buffer> m_queue;
- std::unique_ptr<bufferpool> m_buffer_pool;
- UINT32 m_overflows;
- UINT32 m_underflows;
- BOOL m_in_underflow;
- xaudio2_create_ptr XAudio2Create;
- BOOL m_initialized;
+ Microsoft::WRL::ComPtr<IXAudio2> m_xAudio2;
+ mastering_voice_ptr m_masterVoice;
+ src_voice_ptr m_sourceVoice;
+ DWORD m_sample_bytes;
+ std::unique_ptr<BYTE[]> m_buffer;
+ DWORD m_buffer_size;
+ DWORD m_buffer_count;
+ DWORD m_writepos;
+ std::mutex m_buffer_lock;
+ HANDLE m_hEventBufferCompleted;
+ HANDLE m_hEventDataAvailable;
+ HANDLE m_hEventExiting;
+ std::thread m_audioThread;
+ std::queue<xaudio2_buffer> m_queue;
+ std::unique_ptr<bufferpool> m_buffer_pool;
+ UINT32 m_overflows;
+ UINT32 m_underflows;
+ BOOL m_in_underflow;
+ osd::dynamic_module::ptr m_xaudio_dll;
+ xaudio2_create_ptr XAudio2Create;
+ BOOL m_initialized;
public:
sound_xaudio2() :
@@ -223,7 +224,6 @@ public:
m_overflows(0),
m_underflows(0),
m_in_underflow(FALSE),
- XAudio2Create("XAudio2Create", XAUDIO_DLLS, ARRAY_LENGTH(XAUDIO_DLLS)),
m_initialized(FALSE)
{
}
@@ -261,8 +261,13 @@ private:
bool sound_xaudio2::probe()
{
- int status = XAudio2Create.initialize();
- return status == 0;
+ m_xaudio_dll = osd::dynamic_module::open({ "XAudio2_9.dll", "XAudio2_8.dll" });
+ if (m_xaudio_dll == nullptr)
+ return false;
+
+ XAudio2Create = m_xaudio_dll->bind<xaudio2_create_ptr>("XAudio2Create");
+
+ return (XAudio2Create ? true : false);
}
//============================================================
@@ -276,10 +281,9 @@ int sound_xaudio2::init(osd_options const &options)
CoInitializeEx(nullptr, COINIT_MULTITHREADED);
// Make sure our XAudio2Create entrypoint is bound
- int status = XAudio2Create.initialize();
- if (status != 0)
+ if (!XAudio2Create)
{
- osd_printf_error("Could not find XAudio2 library\n");
+ osd_printf_error("Could not find XAudio2. Please try to reinstall DirectX runtime package.\n");
return 1;
}