diff --git a/scripts/src/osd/windows.lua b/scripts/src/osd/windows.lua index 8b48b8f0771..9307c6dec71 100644 --- a/scripts/src/osd/windows.lua +++ b/scripts/src/osd/windows.lua @@ -154,8 +154,6 @@ project ("osd_" .. _OPTIONS["osd"]) } files { - MAME_DIR .. "src/osd/modules/render/d3d/d3d9intf.cpp", - MAME_DIR .. "src/osd/modules/render/d3d/d3dintf.h", MAME_DIR .. "src/osd/modules/render/d3d/d3dhlsl.cpp", MAME_DIR .. "src/osd/modules/render/d3d/d3dcomm.h", MAME_DIR .. "src/osd/modules/render/d3d/d3dhlsl.h", 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 #include + +#include "modules/lib/osdlib.h" + #include -template -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)); - } - - // bool to test if the function is nullptr or not - operator bool() const { return (m_function != nullptr); } - - // 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 - m_stack_walk_64; - dynamic_bind m_sym_initialize; - dynamic_bind m_sym_function_table_access_64; - dynamic_bind m_sym_get_module_base_64; - dynamic_bind 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 m_sym_from_addr; - dynamic_bind 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"); + m_sym_initialize = m_dbghelp_dll->bind("SymInitialize"); + m_sym_function_table_access_64 = m_dbghelp_dll->bind("SymFunctionTableAccess64"); + m_sym_get_module_base_64 = m_dbghelp_dll->bind("SymGetModuleBase64"); + m_rtl_capture_context = m_kernel32_dll->bind("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"); + m_sym_get_line_from_addr_64 = m_dbghelp_dll->bind("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 image_rva_to_section(TEXT("dbghelp.dll"), "ImageRvaToSection"); - dynamic_bind 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"); + ImageNtHeader_fn image_nt_header = m_dbghelp_dll->bind("ImageNtHeader"); // start with the image base PVOID base = reinterpret_cast(GetModuleHandleUni()); diff --git a/src/osd/modules/font/font_dwrite.cpp b/src/osd/modules/font/font_dwrite.cpp index 670986f0cfc..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 osd_utf8_ptr; // Typedefs for dynamically loaded functions -typedef lazy_loaded_function_p4 d2d_create_factory_fn; -typedef lazy_loaded_function_p3 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 @@ -88,7 +89,7 @@ typedef lazy_loaded_function_p3 stream; @@ -96,13 +97,17 @@ void SaveBitmap(IWICBitmap* bitmap, GUID pixelFormat, const WCHAR *filename) ComPtr dwriteFactory; ComPtr wicFactory; - d2d_create_factory_fn pfn_D2D1CreateFactory("D2D1CreateFactory", L"D2d1.dll"); - dwrite_create_factory_fn pfn_DWriteCreateFactory("DWriteCreateFactory", L"Dwrite.dll"); - HR_RET(pfn_D2D1CreateFactory.initialize()); - HR_RET(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("D2D1CreateFactory"); + dwrite_create_factory_fn pfn_DWriteCreateFactory = dwrite_dll->bind("DWriteCreateFactory"); + + if (!pfn_D2D1CreateFactory || !pfn_DWriteCreateFactory) + return ERROR_DLL_NOT_FOUND; // Create a Direct2D factory - HR_RET(pfn_D2D1CreateFactory( + HR_RETHR((*pfn_D2D1CreateFactory)( D2D1_FACTORY_TYPE_SINGLE_THREADED, __uuidof(ID2D1Factory1), nullptr, @@ -112,41 +117,43 @@ void SaveBitmap(IWICBitmap* bitmap, GUID pixelFormat, const WCHAR *filename) CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED); // Create a DirectWrite factory. - HR_RET(pfn_DWriteCreateFactory( + HR_RETHR((*pfn_DWriteCreateFactory)( DWRITE_FACTORY_TYPE_SHARED, __uuidof(IDWriteFactory), reinterpret_cast(dwriteFactory.GetAddressOf()))); - HR_RET(CoCreateInstance( + HR_RETHR(CoCreateInstance( CLSID_WICImagingFactory, nullptr, CLSCTX_INPROC_SERVER, __uuidof(IWICImagingFactory), (void**)&wicFactory)); - HR_RET(wicFactory->CreateStream(&stream)); - HR_RET(stream->InitializeFromFilename(filename, GENERIC_WRITE)); + HR_RETHR(wicFactory->CreateStream(&stream)); + HR_RETHR(stream->InitializeFromFilename(filename, GENERIC_WRITE)); ComPtr encoder; - HR_RET(wicFactory->CreateEncoder(GUID_ContainerFormatBmp, nullptr, &encoder)); - HR_RET(encoder->Initialize(stream.Get(), WICBitmapEncoderNoCache)); + HR_RETHR(wicFactory->CreateEncoder(GUID_ContainerFormatBmp, nullptr, &encoder)); + HR_RETHR(encoder->Initialize(stream.Get(), WICBitmapEncoderNoCache)); ComPtr frameEncode; - HR_RET(encoder->CreateNewFrame(&frameEncode, nullptr)); - HR_RET(frameEncode->Initialize(nullptr)); + HR_RETHR(encoder->CreateNewFrame(&frameEncode, nullptr)); + HR_RETHR(frameEncode->Initialize(nullptr)); UINT width, height; - HR_RET(bitmap->GetSize(&width, &height)); - HR_RET(frameEncode->SetSize(width, height)); - HR_RET(frameEncode->SetPixelFormat(&pixelFormat)); + HR_RETHR(bitmap->GetSize(&width, &height)); + HR_RETHR(frameEncode->SetSize(width, height)); + HR_RETHR(frameEncode->SetPixelFormat(&pixelFormat)); - HR_RET(frameEncode->WriteSource(bitmap, nullptr)); + HR_RETHR(frameEncode->WriteSource(bitmap, nullptr)); - HR_RET(frameEncode->Commit()); - HR_RET(encoder->Commit()); + HR_RETHR(frameEncode->Commit()); + HR_RETHR(encoder->Commit()); + + return S_OK; } -void SaveBitmap2(bitmap_argb32 &bitmap, const WCHAR *filename) +HRESULT SaveBitmap2(bitmap_argb32 &bitmap, const WCHAR *filename) { HRESULT result; @@ -158,12 +165,12 @@ void SaveBitmap2(bitmap_argb32 &bitmap, const WCHAR *filename) for (int x = 0; x < bitmap.width(); x++) { UINT32 pixel = bitmap.pix32(y, x); - pRow[x] = (pixel == 0xFFFFFFFF) ? rgb_t(0xFF, 0x00, 0x00, 0x00) : pRow[x] = rgb_t(0xFF, 0xFF, 0xFF, 0xFF); + pRow[x] = (pixel == 0xFFFFFFFF) ? rgb_t(0xFF, 0x00, 0x00, 0x00) : rgb_t(0xFF, 0xFF, 0xFF, 0xFF); } } ComPtr wicFactory; - HR_RET(CoCreateInstance( + HR_RETHR(CoCreateInstance( CLSID_WICImagingFactory, nullptr, CLSCTX_INPROC_SERVER, @@ -182,6 +189,8 @@ void SaveBitmap2(bitmap_argb32 &bitmap, const WCHAR *filename) &bmp2); SaveBitmap(bmp2.Get(), GUID_WICPixelFormat32bppRGBA, filename); + + return S_OK; } #endif @@ -648,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 m_d2dfactory; - ComPtr m_dwriteFactory; - ComPtr 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 m_d2dfactory; + ComPtr m_dwriteFactory; + ComPtr 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) @@ -668,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("D2D1CreateFactory"); + m_pfnDWriteCreateFactory = m_dwrite_dll->bind("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; } @@ -685,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, @@ -703,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(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("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 pfn_dinput_create; +typedef HRESULT WINAPI (*dinput_create_fn)(HINSTANCE, DWORD, LPDIRECTINPUT8 *, LPUNKNOWN); #else -typedef lazy_loaded_function_p4 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 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 get_rawinput_device_list_ptr; -typedef lazy_loaded_function_p5 get_rawinput_data_ptr; -typedef lazy_loaded_function_p4 get_rawinput_device_info_ptr; -typedef lazy_loaded_function_p3 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" }); - if (status != 0) + get_rawinput_device_list = m_user32_dll->bind("GetRawInputDeviceList"); + get_rawinput_data = m_user32_dll->bind("GetRawInputData"); + get_rawinput_device_info = m_user32_dll->bind("GetRawInputDeviceInfoW"); + register_rawinput_devices = m_user32_dll->bind("RegisterRawInputDevices"); + + 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(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(); // register the device - register_rawinput_devices(®istration, 1, sizeof(registration)); + (*register_rawinput_devices)(®istration, 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 tname = std::make_unique(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 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(rawinputdevice), RID_INPUT, data, &size, sizeof(RAWINPUTHEADER)); + result = (*get_rawinput_data)(static_cast(rawinputdevice), RID_INPUT, data, &size, sizeof(RAWINPUTHEADER)); if (result) { std::lock_guard 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("XInputGetState"); + XInputGetCapabilities = m_xinput_dll->bind("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 +#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 xinput_get_state_fn; -typedef lazy_loaded_function_p3 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 { -#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 +#include +#include + /*----------------------------------------------------------------------------- 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 ptr; + + static ptr open(std::vector &&libraries); + + virtual ~dynamic_module() { }; + + template + typename std::enable_if::value, T>::type bind(char const *symbol) + { + return reinterpret_cast(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 #include #include +#include + +#include +#include +#include + #include #include @@ -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 &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(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(dlsym(module, symbol)); + + if (function != nullptr) + { + m_module = module; + return function; + } + else + { + dlclose(module); + } + } + } + + return nullptr; + } + +private: + std::vector m_libraries; + void * m_module; +}; + +dynamic_module::ptr dynamic_module::open(std::vector &&names) +{ + return std::make_unique(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 #include #include +#include + +#include +#include +#include + // MAME headers #include "osdcore.h" #include "osdlib.h" #include + //============================================================ // 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 &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(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(dlsym(module, symbol)); + + if (function != nullptr) + { + m_module = module; + return function; + } + else + { + dlclose(module); + } + } + } + + return nullptr; + } + +private: + std::vector m_libraries; + void * m_module; +}; + +dynamic_module::ptr dynamic_module::open(std::vector &&names) +{ + return std::make_unique(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 #endif +#include + // 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 &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(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(GetProcAddress(module, symbol)); + + if (function != nullptr) + { + m_module = module; + return function; + } + else + { + FreeLibrary(module); + } + } + } + + return nullptr; + } + +private: + std::vector m_libraries; + HMODULE m_module; +}; + +dynamic_module::ptr dynamic_module::open(std::vector &&names) +{ + return std::make_unique(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 -#endif - -#include - #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 +#undef interface +#define LIB_NAME "wpcap.dll" -#define LIB_ERROR_STR "Unable to load winpcap: %lx\n" -typedef DWORD except_type; - -#else - -#include -#ifdef SDLMAME_MACOSX +#elif defined(SDLMAME_MACOSX) #include #include -#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 -#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 }); - HMODULE handle; + pcap_findalldevs_dl = pcap_dll->bind("pcap_findalldevs"); + pcap_open_live_dl = pcap_dll->bind("pcap_open_live"); + pcap_next_ex_dl = pcap_dll->bind("pcap_next_ex"); + pcap_compile_dl = pcap_dll->bind("pcap_compile"); + pcap_close_dl = pcap_dll->bind("pcap_close"); + pcap_setfilter_dl = pcap_dll->bind("pcap_setfilter"); + pcap_sendpacket_dl = pcap_dll->bind("pcap_sendpacket"); + pcap_set_datalink_dl = pcap_dll->bind("pcap_set_datalink"); + pcap_dispatch_dl = pcap_dll->bind("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; + } + + 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(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 + // FIXME: bridge between pcap_module and netdev_pcap + module = this; + + if ((*pcap_findalldevs_dl)(&devs, errbuf) == -1) { - 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) - { - 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 deleted file mode 100644 index 435ec7ef64c..00000000000 --- a/src/osd/modules/render/d3d/d3d9intf.cpp +++ /dev/null @@ -1,619 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Aaron Giles -//============================================================ -// -// d3d9intf.c - Direct3D 9 abstraction layer -// -//============================================================ - -// standard windows headers -#define WIN32_LEAN_AND_MEAN -#include -#include -#include -#undef interface - -// MAME headers -#include "emu.h" - -// MAMEOS headers -#include "d3dintf.h" - - - -//============================================================ -// TYPE DEFINITIONS -//============================================================ - -typedef IDirect3D9 *(WINAPI *direct3dcreate9_ptr)(UINT SDKVersion); - -//============================================================ -// PROTOTYPES -//============================================================ - -static void set_interfaces(d3d_base *d3dptr); - -//============================================================ -// INLINES -//============================================================ - -static inline void convert_present_params(const present_parameters *params, D3DPRESENT_PARAMETERS *d3d9params) -{ - memset(d3d9params, 0, sizeof(*d3d9params)); - d3d9params->BackBufferWidth = params->BackBufferWidth; - d3d9params->BackBufferHeight = params->BackBufferHeight; - d3d9params->BackBufferFormat = params->BackBufferFormat; - d3d9params->BackBufferCount = params->BackBufferCount; - d3d9params->MultiSampleType = params->MultiSampleType; - d3d9params->MultiSampleQuality = params->MultiSampleQuality; - d3d9params->SwapEffect = params->SwapEffect; - d3d9params->hDeviceWindow = params->hDeviceWindow; - d3d9params->Windowed = params->Windowed; - d3d9params->EnableAutoDepthStencil = params->EnableAutoDepthStencil; - d3d9params->AutoDepthStencilFormat = params->AutoDepthStencilFormat; - d3d9params->Flags = params->Flags; - d3d9params->FullScreen_RefreshRateInHz = params->FullScreen_RefreshRateInHz; - d3d9params->PresentationInterval = params->PresentationInterval; -} - - - -//============================================================ -// drawd3d9_init -//============================================================ - -d3d_base *drawd3d9_init(void) -{ - bool post_available = true; - - // 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; - } - - // import the create function - direct3dcreate9_ptr direct3dcreate9 = (direct3dcreate9_ptr)GetProcAddress(dllhandle, "Direct3DCreate9"); - if (direct3dcreate9 == nullptr) - { - osd_printf_verbose("Direct3D: Unable to find Direct3DCreate9\n"); - FreeLibrary(dllhandle); - return nullptr; - } - - // create our core direct 3d object - IDirect3D9 *d3d9 = (*direct3dcreate9)(D3D_SDK_VERSION); - if (d3d9 == nullptr) - { - osd_printf_verbose("Direct3D: Error attempting to initialize Direct3D9\n"); - FreeLibrary(dllhandle); - return nullptr; - } - - // 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; - set_interfaces(d3dptr); - - osd_printf_verbose("Direct3D: Using Direct3D 9\n"); - return d3dptr; -} - - - -//============================================================ -// Direct3D interfaces -//============================================================ - -static HRESULT check_device_format(d3d_base *d3dptr, UINT adapter, D3DDEVTYPE devtype, D3DFORMAT adapterformat, DWORD usage, D3DRESOURCETYPE restype, D3DFORMAT format) -{ - IDirect3D9 *d3d9 = (IDirect3D9 *)d3dptr->d3dobj; - return IDirect3D9_CheckDeviceFormat(d3d9, adapter, devtype, adapterformat, usage, restype, format); -} - - -static HRESULT check_device_type(d3d_base *d3dptr, UINT adapter, D3DDEVTYPE devtype, D3DFORMAT format, D3DFORMAT backformat, BOOL windowed) -{ - IDirect3D9 *d3d9 = (IDirect3D9 *)d3dptr->d3dobj; - return IDirect3D9_CheckDeviceType(d3d9, adapter, devtype, format, backformat, windowed); -} - -static HRESULT create_device(d3d_base *d3dptr, UINT adapter, D3DDEVTYPE devtype, HWND focus, DWORD behavior, present_parameters *params, device **dev) -{ - IDirect3D9 *d3d9 = (IDirect3D9 *)d3dptr->d3dobj; - D3DPRESENT_PARAMETERS d3d9params; - convert_present_params(params, &d3d9params); - return IDirect3D9_CreateDevice(d3d9, adapter, devtype, focus, behavior, &d3d9params, (IDirect3DDevice9 **)dev); -} - -static HRESULT enum_adapter_modes(d3d_base *d3dptr, UINT adapter, D3DFORMAT format, UINT index, D3DDISPLAYMODE *mode) -{ - IDirect3D9 *d3d9 = (IDirect3D9 *)d3dptr->d3dobj; - return IDirect3D9_EnumAdapterModes(d3d9, adapter, format, index, mode); -} - - -static UINT get_adapter_count(d3d_base *d3dptr) -{ - IDirect3D9 *d3d9 = (IDirect3D9 *)d3dptr->d3dobj; - return IDirect3D9_GetAdapterCount(d3d9); -} - - -static HRESULT get_adapter_display_mode(d3d_base *d3dptr, UINT adapter, D3DDISPLAYMODE *mode) -{ - IDirect3D9 *d3d9 = (IDirect3D9 *)d3dptr->d3dobj; - return IDirect3D9_GetAdapterDisplayMode(d3d9, adapter, mode); -} - - -static HRESULT get_adapter_identifier(d3d_base *d3dptr, UINT adapter, DWORD flags, adapter_identifier *identifier) -{ - IDirect3D9 *d3d9 = (IDirect3D9 *)d3dptr->d3dobj; - D3DADAPTER_IDENTIFIER9 id; - HRESULT result = IDirect3D9_GetAdapterIdentifier(d3d9, adapter, flags, &id); - memcpy(identifier->Driver, id.Driver, sizeof(identifier->Driver)); - memcpy(identifier->Description, id.Description, sizeof(identifier->Description)); - identifier->DriverVersion = id.DriverVersion; - identifier->VendorId = id.VendorId; - identifier->DeviceId = id.DeviceId; - identifier->SubSysId = id.SubSysId; - identifier->Revision = id.Revision; - identifier->DeviceIdentifier = id.DeviceIdentifier; - identifier->WHQLLevel = id.WHQLLevel; - return result; -} - - -static UINT get_adapter_mode_count(d3d_base *d3dptr, UINT adapter, D3DFORMAT format) -{ - IDirect3D9 *d3d9 = (IDirect3D9 *)d3dptr->d3dobj; - return IDirect3D9_GetAdapterModeCount(d3d9, adapter, format); -} - - -static HMONITOR get_adapter_monitor(d3d_base *d3dptr, UINT adapter) -{ - IDirect3D9 *d3d9 = (IDirect3D9 *)d3dptr->d3dobj; - return IDirect3D9_GetAdapterMonitor(d3d9, adapter); -} - - -static HRESULT get_caps_dword(d3d_base *d3dptr, UINT adapter, D3DDEVTYPE devtype, caps_index which, DWORD *value) -{ - IDirect3D9 *d3d9 = (IDirect3D9 *)d3dptr->d3dobj; - D3DCAPS9 caps; - HRESULT result = IDirect3D9_GetDeviceCaps(d3d9, adapter, devtype, &caps); - switch (which) - { - case CAPS_PRESENTATION_INTERVALS: *value = caps.PresentationIntervals; break; - case CAPS_CAPS2: *value = caps.Caps2; break; - case CAPS_DEV_CAPS: *value = caps.DevCaps; break; - case CAPS_SRCBLEND_CAPS: *value = caps.SrcBlendCaps; break; - case CAPS_DSTBLEND_CAPS: *value = caps.DestBlendCaps; break; - case CAPS_TEXTURE_CAPS: *value = caps.TextureCaps; break; - case CAPS_TEXTURE_FILTER_CAPS: *value = caps.TextureFilterCaps; break; - case CAPS_TEXTURE_ADDRESS_CAPS: *value = caps.TextureAddressCaps; break; - case CAPS_TEXTURE_OP_CAPS: *value = caps.TextureOpCaps; break; - case CAPS_MAX_TEXTURE_ASPECT: *value = caps.MaxTextureAspectRatio; break; - case CAPS_MAX_TEXTURE_WIDTH: *value = caps.MaxTextureWidth; break; - case CAPS_MAX_TEXTURE_HEIGHT: *value = caps.MaxTextureHeight; break; - case CAPS_STRETCH_RECT_FILTER: *value = caps.StretchRectFilterCaps; break; - case CAPS_MAX_PS30_INSN_SLOTS: *value = caps.MaxPixelShader30InstructionSlots; break; - } - return result; -} - - -static ULONG release(d3d_base *d3dptr) -{ - IDirect3D9 *d3d9 = (IDirect3D9 *)d3dptr->d3dobj; - ULONG result = IDirect3D9_Release(d3d9); - FreeLibrary(d3dptr->dllhandle); - global_free(d3dptr); - return result; -} - - -static const interface d3d9_interface = -{ - check_device_format, - check_device_type, - create_device, - enum_adapter_modes, - get_adapter_count, - get_adapter_display_mode, - get_adapter_identifier, - get_adapter_mode_count, - get_adapter_monitor, - get_caps_dword, - release -}; - - - -//============================================================ -// Direct3DDevice interfaces -//============================================================ - -static HRESULT device_begin_scene(device *dev) -{ - IDirect3DDevice9 *device = (IDirect3DDevice9 *)dev; - return IDirect3DDevice9_BeginScene(device); -} - -static HRESULT device_clear(device *dev, DWORD count, const D3DRECT *rects, DWORD flags, D3DCOLOR color, float z, DWORD stencil) -{ - IDirect3DDevice9 *device = (IDirect3DDevice9 *)dev; - return IDirect3DDevice9_Clear(device, count, rects, flags, color, z, stencil); -} - - -static HRESULT device_create_offscreen_plain_surface(device *dev, UINT width, UINT height, D3DFORMAT format, D3DPOOL pool, surface **surface) -{ - IDirect3DDevice9 *device = (IDirect3DDevice9 *)dev; - return IDirect3DDevice9_CreateOffscreenPlainSurface(device, width, height, format, pool, (IDirect3DSurface9 **)surface, nullptr); -} - -static HRESULT device_create_texture(device *dev, UINT width, UINT height, UINT levels, DWORD usage, D3DFORMAT format, D3DPOOL pool, texture **texture) -{ - IDirect3DDevice9 *device = (IDirect3DDevice9 *)dev; - return IDirect3DDevice9_CreateTexture(device, width, height, levels, usage, format, pool, (IDirect3DTexture9 **)texture, nullptr); -} - - -static HRESULT device_create_vertex_buffer(device *dev, UINT length, DWORD usage, DWORD fvf, D3DPOOL pool, vertex_buffer **buf) -{ - IDirect3DDevice9 *device = (IDirect3DDevice9 *)dev; - return IDirect3DDevice9_CreateVertexBuffer(device, length, usage, fvf, pool, (IDirect3DVertexBuffer9 **)buf, nullptr); -} - - -static HRESULT device_draw_primitive(device *dev, D3DPRIMITIVETYPE type, UINT start, UINT count) -{ - IDirect3DDevice9 *device = (IDirect3DDevice9 *)dev; - return IDirect3DDevice9_DrawPrimitive(device, type, start, count); -} - - -static HRESULT device_end_scene(device *dev) -{ - IDirect3DDevice9 *device = (IDirect3DDevice9 *)dev; - return IDirect3DDevice9_EndScene(device); -} - - -static HRESULT device_get_raster_status(device *dev, D3DRASTER_STATUS *status) -{ - IDirect3DDevice9 *device = (IDirect3DDevice9 *)dev; - return IDirect3DDevice9_GetRasterStatus(device, 0, status); -} - - -static HRESULT device_get_render_target(device *dev, DWORD index, surface **surface) -{ - IDirect3DDevice9 *device = (IDirect3DDevice9 *)dev; - return IDirect3DDevice9_GetRenderTarget(device, index, (IDirect3DSurface9 **)surface); -} - - -static HRESULT device_get_render_target_data(device *dev, surface *rendertarget, surface *destsurface) -{ - IDirect3DDevice9 *device = (IDirect3DDevice9 *)dev; - return IDirect3DDevice9_GetRenderTargetData(device, (IDirect3DSurface9 *)rendertarget, (IDirect3DSurface9 *)destsurface); -} - - -static HRESULT device_present(device *dev, const RECT *source, const RECT *dest, HWND override, RGNDATA *dirty, DWORD flags) -{ - IDirect3DDevice9 *device = (IDirect3DDevice9 *)dev; - if (flags != 0) - { - IDirect3DSwapChain9 *chain; - HRESULT result = IDirect3DDevice9_GetSwapChain(device, 0, &chain); - if (result == D3D_OK) - { - result = IDirect3DSwapChain9_Present(chain, source, dest, override, dirty, flags); - IDirect3DSwapChain9_Release(chain); - return result; - } - } - return IDirect3DDevice9_Present(device, source, dest, override, dirty); -} - - -static ULONG device_release(device *dev) -{ - IDirect3DDevice9 *device = (IDirect3DDevice9 *)dev; - return IDirect3DDevice9_Release(device); -} - - -static HRESULT device_reset(device *dev, present_parameters *params) -{ - IDirect3DDevice9 *device = (IDirect3DDevice9 *)dev; - D3DPRESENT_PARAMETERS d3d9params; - convert_present_params(params, &d3d9params); - return IDirect3DDevice9_Reset(device, &d3d9params); -} - - -static void device_set_gamma_ramp(device *dev, DWORD flags, const D3DGAMMARAMP *ramp) -{ - IDirect3DDevice9 *device = (IDirect3DDevice9 *)dev; - IDirect3DDevice9_SetGammaRamp(device, 0, flags, ramp); -} - - -static HRESULT device_set_render_state(device *dev, D3DRENDERSTATETYPE state, DWORD value) -{ - IDirect3DDevice9 *device = (IDirect3DDevice9 *)dev; - return IDirect3DDevice9_SetRenderState(device, state, value); -} - - -static HRESULT device_set_render_target(device *dev, DWORD index, surface *surf) -{ - IDirect3DDevice9 *device = (IDirect3DDevice9 *)dev; - IDirect3DSurface9 *surface = (IDirect3DSurface9 *)surf; - return IDirect3DDevice9_SetRenderTarget(device, index, surface); -} - - -static HRESULT device_create_render_target(device *dev, UINT width, UINT height, D3DFORMAT format, surface **surface) -{ - IDirect3DDevice9 *device = (IDirect3DDevice9 *)dev; - return IDirect3DDevice9_CreateRenderTarget(device, width, height, format, D3DMULTISAMPLE_NONE, 0, false, (IDirect3DSurface9 **)surface, nullptr); -} - - -static HRESULT device_set_stream_source(device *dev, UINT number, vertex_buffer *vbuf, UINT stride) -{ - IDirect3DDevice9 *device = (IDirect3DDevice9 *)dev; - IDirect3DVertexBuffer9 *vertexbuf = (IDirect3DVertexBuffer9 *)vbuf; - return IDirect3DDevice9_SetStreamSource(device, number, vertexbuf, 0, stride); -} - - -static HRESULT device_set_texture(device *dev, DWORD stage, texture *tex) -{ - IDirect3DDevice9 *device = (IDirect3DDevice9 *)dev; - IDirect3DBaseTexture9 *texture = (IDirect3DBaseTexture9 *)tex; - return IDirect3DDevice9_SetTexture(device, stage, texture); -} - - -static HRESULT device_set_texture_stage_state(device *dev, DWORD stage, D3DTEXTURESTAGESTATETYPE state, DWORD value) -{ - IDirect3DDevice9 *device = (IDirect3DDevice9 *)dev; - - // some state which was here got pushed into sampler state in D3D9 - switch ((DWORD)state) - { - case D3DTSS_ADDRESSU: - return IDirect3DDevice9_SetSamplerState(device, stage, D3DSAMP_ADDRESSU, value); - case D3DTSS_ADDRESSV: - return IDirect3DDevice9_SetSamplerState(device, stage, D3DSAMP_ADDRESSV, value); - case D3DTSS_BORDERCOLOR: - return IDirect3DDevice9_SetSamplerState(device, stage, D3DSAMP_BORDERCOLOR, value); - case D3DTSS_MAGFILTER: - return IDirect3DDevice9_SetSamplerState(device, stage, D3DSAMP_MAGFILTER, value); - case D3DTSS_MINFILTER: - return IDirect3DDevice9_SetSamplerState(device, stage, D3DSAMP_MINFILTER, value); - case D3DTSS_MIPFILTER: - return IDirect3DDevice9_SetSamplerState(device, stage, D3DSAMP_MIPFILTER, value); - case D3DTSS_MIPMAPLODBIAS: - return IDirect3DDevice9_SetSamplerState(device, stage, D3DSAMP_MIPMAPLODBIAS, value); - case D3DTSS_MAXMIPLEVEL: - return IDirect3DDevice9_SetSamplerState(device, stage, D3DSAMP_MAXMIPLEVEL, value); - case D3DTSS_MAXANISOTROPY: - return IDirect3DDevice9_SetSamplerState(device, stage, D3DSAMP_MAXANISOTROPY, value); - default: - return IDirect3DDevice9_SetTextureStageState(device, stage, state, value); - } -} - - -static HRESULT device_set_vertex_format(device *dev, D3DFORMAT format) -{ - IDirect3DDevice9 *device = (IDirect3DDevice9 *)dev; - return IDirect3DDevice9_SetFVF(device, format); -} - - -static HRESULT device_stretch_rect(device *dev, surface *source, const RECT *srcrect, surface *dest, const RECT *dstrect, D3DTEXTUREFILTERTYPE filter) -{ - IDirect3DDevice9 *device = (IDirect3DDevice9 *)dev; - IDirect3DSurface9 *ssurface = (IDirect3DSurface9 *)source; - IDirect3DSurface9 *dsurface = (IDirect3DSurface9 *)dest; - return IDirect3DDevice9_StretchRect(device, ssurface, srcrect, dsurface, dstrect, filter); -} - - -static HRESULT device_test_cooperative_level(device *dev) -{ - IDirect3DDevice9 *device = (IDirect3DDevice9 *)dev; - return IDirect3DDevice9_TestCooperativeLevel(device); -} - - -static const d3d_device_interface d3d9_device_interface = -{ - device_begin_scene, - device_clear, - device_create_offscreen_plain_surface, - device_create_texture, - device_create_vertex_buffer, - device_create_render_target, - device_draw_primitive, - device_end_scene, - device_get_raster_status, - device_get_render_target, - device_get_render_target_data, - device_present, - device_release, - device_reset, - device_set_gamma_ramp, - device_set_render_state, - device_set_render_target, - device_set_stream_source, - device_set_texture, - device_set_texture_stage_state, - device_set_vertex_format, - device_stretch_rect, - device_test_cooperative_level -}; - - - -//============================================================ -// Direct3DSurface interfaces -//============================================================ - -static HRESULT surface_lock_rect(surface *surf, D3DLOCKED_RECT *locked, const RECT *rect, DWORD flags) -{ - IDirect3DSurface9 *surface = (IDirect3DSurface9 *)surf; - return IDirect3DSurface9_LockRect(surface, locked, rect, flags); -} - - -static ULONG surface_release(surface *surf) -{ - IDirect3DSurface9 *surface = (IDirect3DSurface9 *)surf; - return IDirect3DSurface9_Release(surface); -} - - -static HRESULT surface_unlock_rect(surface *surf) -{ - IDirect3DSurface9 *surface = (IDirect3DSurface9 *)surf; - return IDirect3DSurface9_UnlockRect(surface); -} - - -static const surface_interface d3d9_surface_interface = -{ - surface_lock_rect, - surface_release, - surface_unlock_rect -}; - - - -//============================================================ -// Direct3DTexture interfaces -//============================================================ - -static HRESULT texture_get_surface_level(texture *tex, UINT level, surface **surface) -{ - IDirect3DTexture9 *texture = (IDirect3DTexture9 *)tex; - return IDirect3DTexture9_GetSurfaceLevel(texture, level, (IDirect3DSurface9 **)surface); -} - - -static HRESULT texture_lock_rect(texture *tex, UINT level, D3DLOCKED_RECT *locked, const RECT *rect, DWORD flags) -{ - IDirect3DTexture9 *texture = (IDirect3DTexture9 *)tex; - return IDirect3DTexture9_LockRect(texture, level, locked, rect, flags); -} - - -static ULONG texture_release(texture *tex) -{ - IDirect3DTexture9 *texture = (IDirect3DTexture9 *)tex; - return IDirect3DTexture9_Release(texture); -} - - -static HRESULT texture_unlock_rect(texture *tex, UINT level) -{ - IDirect3DTexture9 *texture = (IDirect3DTexture9 *)tex; - return IDirect3DTexture9_UnlockRect(texture, level); -} - - -static const texture_interface d3d9_texture_interface = -{ - texture_get_surface_level, - texture_lock_rect, - texture_release, - texture_unlock_rect -}; - - - -//============================================================ -// Direct3DVertexBuffer interfaces -//============================================================ - -static HRESULT vertex_buffer_lock(vertex_buffer *vbuf, UINT offset, UINT size, VOID **data, DWORD flags) -{ - IDirect3DVertexBuffer9 *vertexbuf = (IDirect3DVertexBuffer9 *)vbuf; - return IDirect3DVertexBuffer9_Lock(vertexbuf, offset, size, data, flags); -} - - -static ULONG vertex_buffer_release(vertex_buffer *vbuf) -{ - IDirect3DVertexBuffer9 *vertexbuf = (IDirect3DVertexBuffer9 *)vbuf; - return IDirect3DVertexBuffer9_Release(vertexbuf); -} - - -static HRESULT vertex_buffer_unlock(vertex_buffer *vbuf) -{ - IDirect3DVertexBuffer9 *vertexbuf = (IDirect3DVertexBuffer9 *)vbuf; - return IDirect3DVertexBuffer9_Unlock(vertexbuf); -} - - -static const vertex_buffer_interface d3d9_vertex_buffer_interface = -{ - vertex_buffer_lock, - vertex_buffer_release, - vertex_buffer_unlock -}; - - -//============================================================ -// set_interfaces -//============================================================ - -static void set_interfaces(d3d_base *d3dptr) -{ - d3dptr->d3d = d3d9_interface; - d3dptr->device = d3d9_device_interface; - d3dptr->surface = d3d9_surface_interface; - d3dptr->texture = d3d9_texture_interface; - d3dptr->vertexbuf = d3d9_vertex_buffer_interface; -} 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" @@ -46,14 +38,6 @@ static void get_vector(const char *data, int count, float *out, bool report_error); -//============================================================ -// 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("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& 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& 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(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(); @@ -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/d3d/d3dintf.h b/src/osd/modules/render/d3d/d3dintf.h deleted file mode 100644 index 3e0a90a46f5..00000000000 --- a/src/osd/modules/render/d3d/d3dintf.h +++ /dev/null @@ -1,239 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Aaron Giles -//============================================================ -// -// d3dintf.h - Direct3D 8/9 interface abstractions -// -//============================================================ - -#ifndef __WIN_D3DINTF__ -#define __WIN_D3DINTF__ - -// standard windows headers -#define WIN32_LEAN_AND_MEAN -#include -#include -#include -#include -#include -#include -#undef interface - -//============================================================ -// CONSTANTS -//============================================================ - -#ifndef D3DCAPS2_DYNAMICTEXTURES -#define D3DCAPS2_DYNAMICTEXTURES 0x20000000L -#endif - -#ifndef D3DPRESENT_DONOTWAIT -#define D3DPRESENT_DONOTWAIT 0x00000001L -#endif - - -#define D3DTSS_ADDRESSU 13 -#define D3DTSS_ADDRESSV 14 -#define D3DTSS_BORDERCOLOR 15 -#define D3DTSS_MAGFILTER 16 -#define D3DTSS_MINFILTER 17 -#define D3DTSS_MIPFILTER 18 -#define D3DTSS_MIPMAPLODBIAS 19 -#define D3DTSS_MAXMIPLEVEL 20 -#define D3DTSS_MAXANISOTROPY 21 - -//============================================================ -// TYPE DEFINITIONS -//============================================================ - -struct d3d_base; -struct device; -struct surface; -struct texture; -struct vertex_buffer; -class effect; -typedef D3DXVECTOR4 vector; -typedef D3DMATRIX matrix; - -//============================================================ -// Abstracted presentation parameters -//============================================================ - -struct present_parameters -{ - UINT BackBufferWidth; - UINT BackBufferHeight; - D3DFORMAT BackBufferFormat; - UINT BackBufferCount; - D3DMULTISAMPLE_TYPE MultiSampleType; - DWORD MultiSampleQuality; - D3DSWAPEFFECT SwapEffect; - HWND hDeviceWindow; - BOOL Windowed; - BOOL EnableAutoDepthStencil; - D3DFORMAT AutoDepthStencilFormat; - DWORD Flags; - UINT FullScreen_RefreshRateInHz; - UINT PresentationInterval; -}; - - -//============================================================ -// Abstracted device identifier -//============================================================ - -struct adapter_identifier -{ - char Driver[512]; - char Description[512]; - LARGE_INTEGER DriverVersion; - DWORD VendorId; - DWORD DeviceId; - DWORD SubSysId; - DWORD Revision; - GUID DeviceIdentifier; - DWORD WHQLLevel; -}; - - -//============================================================ -// Caps enumeration -//============================================================ - -enum caps_index -{ - CAPS_PRESENTATION_INTERVALS, - CAPS_CAPS2, - CAPS_DEV_CAPS, - CAPS_SRCBLEND_CAPS, - CAPS_DSTBLEND_CAPS, - CAPS_TEXTURE_CAPS, - CAPS_TEXTURE_FILTER_CAPS, - CAPS_TEXTURE_ADDRESS_CAPS, - CAPS_TEXTURE_OP_CAPS, - CAPS_MAX_TEXTURE_ASPECT, - CAPS_MAX_TEXTURE_WIDTH, - CAPS_MAX_TEXTURE_HEIGHT, - CAPS_STRETCH_RECT_FILTER, - CAPS_MAX_PS30_INSN_SLOTS -}; - - -//============================================================ -// Direct3D interfaces -//============================================================ - -struct interface -{ - HRESULT (*check_device_format)(d3d_base *d3dptr, UINT adapter, D3DDEVTYPE devtype, D3DFORMAT adapterformat, DWORD usage, D3DRESOURCETYPE restype, D3DFORMAT format); - HRESULT (*check_device_type)(d3d_base *d3dptr, UINT adapter, D3DDEVTYPE devtype, D3DFORMAT format, D3DFORMAT backformat, BOOL windowed); - HRESULT (*create_device)(d3d_base *d3dptr, UINT adapter, D3DDEVTYPE devtype, HWND focus, DWORD behavior, present_parameters *params, device **dev); - HRESULT (*enum_adapter_modes)(d3d_base *d3dptr, UINT adapter, D3DFORMAT format, UINT index, D3DDISPLAYMODE *mode); - UINT (*get_adapter_count)(d3d_base *d3dptr); - HRESULT (*get_adapter_display_mode)(d3d_base *d3dptr, UINT adapter, D3DDISPLAYMODE *mode); - HRESULT (*get_adapter_identifier)(d3d_base *d3dptr, UINT adapter, DWORD flags, adapter_identifier *identifier); - UINT (*get_adapter_mode_count)(d3d_base *d3dptr, UINT adapter, D3DFORMAT format); - HMONITOR (*get_adapter_monitor)(d3d_base *d3dptr, UINT adapter); - HRESULT (*get_caps_dword)(d3d_base *d3dptr, UINT adapter, D3DDEVTYPE devtype, caps_index which, DWORD *value); - ULONG (*release)(d3d_base *d3dptr); -}; - - -//============================================================ -// Direct3DDevice interfaces -//============================================================ - -struct d3d_device_interface -{ - HRESULT (*begin_scene)(device *dev); - HRESULT (*clear)(device *dev, DWORD count, const D3DRECT *rects, DWORD flags, D3DCOLOR color, float z, DWORD stencil); - HRESULT (*create_offscreen_plain_surface)(device *dev, UINT width, UINT height, D3DFORMAT format, D3DPOOL pool, surface **surface); - HRESULT (*create_texture)(device *dev, UINT width, UINT height, UINT levels, DWORD usage, D3DFORMAT format, D3DPOOL pool, texture **texture); - HRESULT (*create_vertex_buffer)(device *dev, UINT length, DWORD usage, DWORD fvf, D3DPOOL pool, vertex_buffer **buf); - HRESULT (*create_render_target)(device *dev, UINT width, UINT height, D3DFORMAT format, surface **surface); - HRESULT (*draw_primitive)(device *dev, D3DPRIMITIVETYPE type, UINT start, UINT count); - HRESULT (*end_scene)(device *dev); - HRESULT (*get_raster_status)(device *dev, D3DRASTER_STATUS *status); - HRESULT (*get_render_target)(device *dev, DWORD index, surface **surface); - HRESULT (*get_render_target_data)(device *dev, surface *rendertarget, surface *destsurface); - HRESULT (*present)(device *dev, const RECT *source, const RECT *dest, HWND override, RGNDATA *dirty, DWORD flags); - ULONG (*release)(device *dev); - HRESULT (*reset)(device *dev, present_parameters *params); - void (*set_gamma_ramp)(device *dev, DWORD flags, const D3DGAMMARAMP *ramp); - HRESULT (*set_render_state)(device *dev, D3DRENDERSTATETYPE state, DWORD value); - HRESULT (*set_render_target)(device *dev, DWORD index, surface *surf); - HRESULT (*set_stream_source)(device *dev, UINT number, vertex_buffer *vbuf, UINT stride); - HRESULT (*set_texture)(device *dev, DWORD stage, texture *tex); - HRESULT (*set_texture_stage_state)(device *dev, DWORD stage, D3DTEXTURESTAGESTATETYPE state, DWORD value); - HRESULT (*set_vertex_format)(device *dev, D3DFORMAT format); - HRESULT (*stretch_rect)(device *dev, surface *source, const RECT *srcrect, surface *dest, const RECT *dstrect, D3DTEXTUREFILTERTYPE filter); - HRESULT (*test_cooperative_level)(device *dev); -}; - - -//============================================================ -// Direct3DSurface interfaces -//============================================================ - -struct surface_interface -{ - HRESULT (*lock_rect)(surface *surf, D3DLOCKED_RECT *locked, const RECT *rect, DWORD flags); - ULONG (*release)(surface *tex); - HRESULT (*unlock_rect)(surface *surf); -}; - - -//============================================================ -// Direct3DTexture interfaces -//============================================================ - -struct texture_interface -{ - HRESULT (*get_surface_level)(texture *tex, UINT level, surface **surface); - HRESULT (*lock_rect)(texture *tex, UINT level, D3DLOCKED_RECT *locked, const RECT *rect, DWORD flags); - ULONG (*release)(texture *tex); - HRESULT (*unlock_rect)(texture *tex, UINT level); -}; - - -//============================================================ -// Direct3DVertexBuffer interfaces -//============================================================ - -struct vertex_buffer_interface -{ - HRESULT (*lock)(vertex_buffer *vbuf, UINT offset, UINT size, VOID **data, DWORD flags); - ULONG (*release)(vertex_buffer *vbuf); - HRESULT (*unlock)(vertex_buffer *vbuf); -}; - - -//============================================================ -// Core D3D object -//============================================================ - -struct d3d_base -{ - // internal objects - int version; - void * d3dobj; - HINSTANCE dllhandle; - bool post_fx_available; - HINSTANCE libhandle; - - // interface pointers - interface d3d; - d3d_device_interface device; - surface_interface surface; - texture_interface texture; - vertex_buffer_interface vertexbuf; -}; - - -//============================================================ -// PROTOTYPES -//============================================================ - -d3d_base *drawd3d9_init(void); - -#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" @@ -29,6 +21,13 @@ #include "modules/render/d3d/d3dhlsl.h" +//============================================================ +// TYPE DEFINITIONS +//============================================================ + +typedef IDirect3D9* (*d3d9_create_fn)(UINT); + + //============================================================ // CONSTANTS //============================================================ @@ -121,10 +120,6 @@ static inline UINT32 ycc_to_rgb(UINT8 y, UINT8 cb, UINT8 cr) 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("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 = 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 = (*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->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 +#include +#include +#include +#include +#include +#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"); + pfn_wglCreateContext = opengl32_dll->bind("wglCreateContext"); + pfn_wglDeleteContext = opengl32_dll->bind("wglDeleteContext"); + pfn_wglMakeCurrent = opengl32_dll->bind("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); + osd::dynamic_module::ptr opengl32_dll; + wglGetProcAddress_fn pfn_wglGetProcAddress; + wglCreateContext_fn pfn_wglCreateContext; + wglDeleteContext_fn pfn_wglDeleteContext; + wglMakeCurrent_fn pfn_wglMakeCurrent; - const char *(WINAPI *pfn_wglGetExtensionsStringEXT) (void); - BOOL (WINAPI *pfn_wglSwapIntervalEXT) (int interval); - int (WINAPI * pfn_wglGetSwapIntervalEXT) (void); - - 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 old mode 100644 new mode 100755 index f4da54db2ec..66fdb1ba009 --- 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 masterin typedef std::unique_ptr src_voice_ptr; // Typedef for pointer to XAudio2Create -typedef lazy_loaded_function_p3 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 m_xAudio2; - mastering_voice_ptr m_masterVoice; - src_voice_ptr m_sourceVoice; - DWORD m_sample_bytes; - std::unique_ptr 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 m_queue; - std::unique_ptr m_buffer_pool; - UINT32 m_overflows; - UINT32 m_underflows; - BOOL m_in_underflow; - xaudio2_create_ptr XAudio2Create; - BOOL m_initialized; + Microsoft::WRL::ComPtr m_xAudio2; + mastering_voice_ptr m_masterVoice; + src_voice_ptr m_sourceVoice; + DWORD m_sample_bytes; + std::unique_ptr 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 m_queue; + std::unique_ptr 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("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; } diff --git a/src/osd/windows/winutil.cpp b/src/osd/windows/winutil.cpp index 3574f00f398..880e9aa7a06 100644 --- a/src/osd/windows/winutil.cpp +++ b/src/osd/windows/winutil.cpp @@ -111,67 +111,3 @@ HMODULE WINAPI GetModuleHandleUni() VirtualQuery((LPCVOID)GetModuleHandleUni, &mbi, sizeof(mbi)); return (HMODULE)mbi.AllocationBase; } - -//----------------------------------------------------------- -// Lazy loaded function using LoadLibrary / GetProcAddress -//----------------------------------------------------------- - -lazy_loaded_function::lazy_loaded_function(const char * name, const wchar_t* dll_name) - : lazy_loaded_function(name, &dll_name, 1) -{ -} - -lazy_loaded_function::lazy_loaded_function(const char * name, const wchar_t** dll_names, int dll_count) - : m_name(name), m_module(nullptr), m_initialized(false), m_pfn(nullptr) -{ - for (int i = 0; i < dll_count; i++) - m_dll_names.push_back(std::wstring(dll_names[i])); -} - -lazy_loaded_function::~lazy_loaded_function() -{ - if (m_module != nullptr) - { - FreeLibrary(m_module); - m_module = nullptr; - } -} - -int lazy_loaded_function::initialize() -{ - if (m_module == nullptr) - { - for (int i = 0; i < m_dll_names.size(); i++) - { - m_module = LoadLibraryW(m_dll_names[i].c_str()); - if (m_module != nullptr) - break; - } - - if (m_module == nullptr) - { - osd_printf_verbose("Could not find DLL to dynamically link function %s.\n", m_name.c_str()); - return ERROR_DLL_NOT_FOUND; - } - } - - if (m_pfn == nullptr) - { - m_pfn = GetProcAddress(m_module, m_name.c_str()); - if (m_pfn == nullptr) - { - osd_printf_verbose("Could not find function address to dynamically link function %s.\n", m_name.c_str()); - return ERROR_NOT_FOUND; - } - } - - m_initialized = true; - - return 0; -} - -void lazy_loaded_function::check_init() const -{ - if (!m_initialized) - fatalerror("Attempt to use function pointer for function %s prior to init!", name()); -} diff --git a/src/osd/windows/winutil.h b/src/osd/windows/winutil.h index d122679438e..2598a920864 100644 --- a/src/osd/windows/winutil.h +++ b/src/osd/windows/winutil.h @@ -18,160 +18,4 @@ osd_dir_entry_type win_attributes_to_entry_type(DWORD attributes); BOOL win_is_gui_application(void); HMODULE WINAPI GetModuleHandleUni(); -//----------------------------------------------------------- -// Lazy loaded function using LoadLibrary / GetProcAddress -//----------------------------------------------------------- - -class lazy_loaded_function -{ -private: - std::string m_name; - std::vector m_dll_names; - HMODULE m_module; - bool m_initialized; - -protected: - void check_init() const; - FARPROC m_pfn; - -public: - lazy_loaded_function(const char * name, const wchar_t* dll_name); - lazy_loaded_function(const char * name, const wchar_t** dll_names, int dll_count); - ~lazy_loaded_function(); - int initialize(); - const char * name() const { return m_name.c_str(); } -}; - -// No parameters -template -class lazy_loaded_function_ret : public lazy_loaded_function -{ -public: - lazy_loaded_function_ret(const char * name, const wchar_t* dll_name) - : lazy_loaded_function(name, &dll_name, 1) - { - } - - lazy_loaded_function_ret(const char * name, const wchar_t** dll_names, int dll_count) - : lazy_loaded_function(name, dll_names, dll_count) - { - } - - TRet operator ()() - { - check_init(); - return ((TRet(__stdcall *) ())m_pfn)(); - } -}; - -// One parameter -template -class lazy_loaded_function_p1 : public lazy_loaded_function -{ -public: - lazy_loaded_function_p1(const char * name, const wchar_t* dll_name) - : lazy_loaded_function(name, &dll_name, 1) - { - } - - lazy_loaded_function_p1(const char * name, const wchar_t** dll_names, int dll_count) - : lazy_loaded_function(name, dll_names, dll_count) - { - } - - TRet operator ()(P1 p1) - { - check_init(); - return ((TRet(__stdcall *) (P1))m_pfn)(p1); - } -}; - -// Two parameters -template -class lazy_loaded_function_p2 : public lazy_loaded_function -{ -public: - lazy_loaded_function_p2(const char * name, const wchar_t* dll_name) - : lazy_loaded_function(name, &dll_name, 1) - { - } - - lazy_loaded_function_p2(const char * name, const wchar_t** dll_names, int dll_count) - : lazy_loaded_function(name, dll_names, dll_count) - { - } - - TRet operator ()(P1 p1, P2 p2) - { - check_init(); - return ((TRet(__stdcall *) (P1, P2))m_pfn)(p1, p2); - } -}; - -// Three parameters -template -class lazy_loaded_function_p3 : public lazy_loaded_function -{ -public: - lazy_loaded_function_p3(const char * name, const wchar_t* dll_name) - : lazy_loaded_function(name, &dll_name, 1) - { - } - - lazy_loaded_function_p3(const char * name, const wchar_t** dll_names, int dll_count) - : lazy_loaded_function(name, dll_names, dll_count) - { - } - - TRet operator ()(P1 p1, P2 p2, P3 p3) - { - check_init(); - return ((TRet(__stdcall *) (P1, P2, P3))m_pfn)(p1, p2, p3); - } -}; - -// Four parameters -template -class lazy_loaded_function_p4 : public lazy_loaded_function -{ -public: - lazy_loaded_function_p4(const char * name, const wchar_t* dll_name) - : lazy_loaded_function(name, &dll_name, 1) - { - } - - lazy_loaded_function_p4(const char * name, const wchar_t** dll_names, int dll_count) - : lazy_loaded_function(name, dll_names, dll_count) - { - } - - TRet operator ()(P1 p1, P2 p2, P3 p3, P4 p4) - { - check_init(); - return ((TRet(__stdcall *) (P1, P2, P3, P4))m_pfn)(p1, p2, p3, p4); - } -}; - -// Five parameters -template -class lazy_loaded_function_p5 : public lazy_loaded_function -{ -public: - lazy_loaded_function_p5(const char * name, const wchar_t* dll_name) - : lazy_loaded_function(name, &dll_name, 1) - { - } - - lazy_loaded_function_p5(const char * name, const wchar_t** dll_names, int dll_count) - : lazy_loaded_function(name, dll_names, dll_count) - { - } - - TRet operator ()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) - { - check_init(); - return ((TRet(__stdcall *) (P1, P2, P3, P4, P5))m_pfn)(p1, p2, p3, p4, p5); - } -}; - #endif // __WINUTIL__