Merge pull request #911 from GiuseppeGorgoglione/master

Three patches with code cleanups to the OSD layer [
Giuseppe Gorgoglione]
* Fix debugging code in font_dwrite.cpp
* Introduce dynamic_module
* Remove Direct3D abstraction layer
This commit is contained in:
Vas Crabb 2016-06-15 14:52:19 +10:00 committed by GitHub
commit d479f0b4be
26 changed files with 1070 additions and 1922 deletions

View File

@ -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",

View File

@ -22,30 +22,21 @@
#include <memory>
#include <vector>
#include "modules/lib/osdlib.h"
#include <windows/winutil.h>
template<typename _FunctionPtr>
class dynamic_bind
{
public:
// constructor which looks up the function
dynamic_bind(const TCHAR *dll, const char *symbol)
: m_function(nullptr)
{
HMODULE module = LoadLibrary(dll);
if (module != nullptr)
m_function = reinterpret_cast<_FunctionPtr>(GetProcAddress(module, symbol));
}
// 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<BOOL(WINAPI *)(DWORD, HANDLE, HANDLE, LPSTACKFRAME64, PVOID, PREAD_PROCESS_MEMORY_ROUTINE64, PFUNCTION_TABLE_ACCESS_ROUTINE64, PGET_MODULE_BASE_ROUTINE64, PTRANSLATE_ADDRESS_ROUTINE64)>
m_stack_walk_64;
dynamic_bind<BOOL(WINAPI *)(HANDLE, LPCTSTR, BOOL)> m_sym_initialize;
dynamic_bind<PVOID(WINAPI *)(HANDLE, DWORD64)> m_sym_function_table_access_64;
dynamic_bind<DWORD64(WINAPI *)(HANDLE, DWORD64)> m_sym_get_module_base_64;
dynamic_bind<VOID(WINAPI *)(PCONTEXT)> m_rtl_capture_context;
osd::dynamic_module::ptr m_dbghelp_dll;
osd::dynamic_module::ptr m_kernel32_dll;
StackWalk64_fn m_stack_walk_64;
SymInitialize_fn m_sym_initialize;
SymFunctionTableAccess64_fn m_sym_function_table_access_64;
SymGetModuleBase64_fn m_sym_get_module_base_64;
RtlCaptureContext_fn m_rtl_capture_context;
static bool s_initialized;
};
@ -126,8 +119,10 @@ private:
FPTR m_last_base;
FPTR m_text_base;
dynamic_bind<BOOL(WINAPI *)(HANDLE, DWORD64, PDWORD64, PSYMBOL_INFO)> m_sym_from_addr;
dynamic_bind<BOOL(WINAPI *)(HANDLE, DWORD64, PDWORD, PIMAGEHLP_LINE64)> m_sym_get_line_from_addr_64;
osd::dynamic_module::ptr m_dbghelp_dll;
SymFromAddr_fn m_sym_from_addr;
SymGetLineFromAddr64_fn m_sym_get_line_from_addr_64;
};
class sampling_profiler
@ -176,17 +171,21 @@ bool stack_walker::s_initialized = false;
stack_walker::stack_walker()
: m_process(GetCurrentProcess()),
m_thread(GetCurrentThread()),
m_first(true),
m_stack_walk_64(TEXT("dbghelp.dll"), "StackWalk64"),
m_sym_initialize(TEXT("dbghelp.dll"), "SymInitialize"),
m_sym_function_table_access_64(TEXT("dbghelp.dll"), "SymFunctionTableAccess64"),
m_sym_get_module_base_64(TEXT("dbghelp.dll"), "SymGetModuleBase64"),
m_rtl_capture_context(TEXT("kernel32.dll"), "RtlCaptureContext")
m_first(true)
{
// zap the structs
memset(&m_stackframe, 0, sizeof(m_stackframe));
memset(&m_context, 0, sizeof(m_context));
m_dbghelp_dll = osd::dynamic_module::open({ "dbghelp.dll" });
m_kernel32_dll = osd::dynamic_module::open({ "kernel32.dll" });
m_stack_walk_64 = m_dbghelp_dll->bind<StackWalk64_fn>("StackWalk64");
m_sym_initialize = m_dbghelp_dll->bind<SymInitialize_fn>("SymInitialize");
m_sym_function_table_access_64 = m_dbghelp_dll->bind<SymFunctionTableAccess64_fn>("SymFunctionTableAccess64");
m_sym_get_module_base_64 = m_dbghelp_dll->bind<SymGetModuleBase64_fn>("SymGetModuleBase64");
m_rtl_capture_context = m_kernel32_dll->bind<RtlCaptureContext_fn>("RtlCaptureContext");
// initialize the symbols
if (!s_initialized && m_sym_initialize && m_stack_walk_64 && m_sym_function_table_access_64 && m_sym_get_module_base_64)
{
@ -294,9 +293,7 @@ symbol_manager::symbol_manager(const char *argv0)
m_symfile(argv0),
m_process(GetCurrentProcess()),
m_last_base(0),
m_text_base(0),
m_sym_from_addr(TEXT("dbghelp.dll"), "SymFromAddr"),
m_sym_get_line_from_addr_64(TEXT("dbghelp.dll"), "SymGetLineFromAddr64")
m_text_base(0)
{
#ifdef __GNUC__
// compute the name of the mapfile
@ -317,6 +314,11 @@ symbol_manager::symbol_manager(const char *argv0)
// expand the buffer to be decently large up front
m_buffer = string_format("%500s", "");
m_dbghelp_dll = osd::dynamic_module::open({ "dbghelp.dll" });
m_sym_from_addr = m_dbghelp_dll->bind<SymFromAddr_fn>("SymFromAddr");
m_sym_get_line_from_addr_64 = m_dbghelp_dll->bind<SymGetLineFromAddr64_fn>("SymGetLineFromAddr64");
}
@ -603,8 +605,10 @@ void symbol_manager::format_symbol(const char *name, UINT32 displacement, const
FPTR symbol_manager::get_text_section_base()
{
dynamic_bind<PIMAGE_SECTION_HEADER(WINAPI *)(PIMAGE_NT_HEADERS, PVOID, ULONG)> image_rva_to_section(TEXT("dbghelp.dll"), "ImageRvaToSection");
dynamic_bind<PIMAGE_NT_HEADERS(WINAPI *)(PVOID)> image_nt_header(TEXT("dbghelp.dll"), "ImageNtHeader");
osd::dynamic_module::ptr m_dbghelp_dll = osd::dynamic_module::open({ "dbghelp.dll" });
ImageRvaToSection_fn image_rva_to_section = m_dbghelp_dll->bind<ImageRvaToSection_fn>("ImageRvaToSection");
ImageNtHeader_fn image_nt_header = m_dbghelp_dll->bind<ImageNtHeader_fn>("ImageNtHeader");
// start with the image base
PVOID base = reinterpret_cast<PVOID>(GetModuleHandleUni());

View File

@ -7,6 +7,7 @@
#include "font_module.h"
#include "modules/osdmodule.h"
#include "modules/lib/osdlib.h"
// We take dependencies on WRL client headers and
// we can only build with a high enough version
@ -78,8 +79,8 @@ struct osd_deleter
typedef std::unique_ptr<char, osd_deleter> osd_utf8_ptr;
// Typedefs for dynamically loaded functions
typedef lazy_loaded_function_p4<HRESULT, D2D1_FACTORY_TYPE, REFIID, const D2D1_FACTORY_OPTIONS*, void**> d2d_create_factory_fn;
typedef lazy_loaded_function_p3<HRESULT, DWRITE_FACTORY_TYPE, REFIID, IUnknown**> dwrite_create_factory_fn;
typedef HRESULT WINAPI (*d2d_create_factory_fn)(D2D1_FACTORY_TYPE, REFIID, const D2D1_FACTORY_OPTIONS *, void **);
typedef HRESULT (*dwrite_create_factory_fn)(DWRITE_FACTORY_TYPE, REFIID, IUnknown **);
// Debugging functions
#ifdef DWRITE_DEBUGGING
@ -88,7 +89,7 @@ typedef lazy_loaded_function_p3<HRESULT, DWRITE_FACTORY_TYPE, REFIID, IUnknown**
// Save image to file
//-------------------------------------------------
void SaveBitmap(IWICBitmap* bitmap, GUID pixelFormat, const WCHAR *filename)
HRESULT SaveBitmap(IWICBitmap* bitmap, GUID pixelFormat, const WCHAR *filename)
{
HRESULT result = S_OK;
ComPtr<IWICStream> stream;
@ -96,13 +97,17 @@ void SaveBitmap(IWICBitmap* bitmap, GUID pixelFormat, const WCHAR *filename)
ComPtr<IDWriteFactory> dwriteFactory;
ComPtr<IWICImagingFactory> wicFactory;
d2d_create_factory_fn pfn_D2D1CreateFactory("D2D1CreateFactory", L"D2d1.dll");
dwrite_create_factory_fn pfn_DWriteCreateFactory("DWriteCreateFactory", L"Dwrite.dll");
HR_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<d2d_create_factory_fn>("D2D1CreateFactory");
dwrite_create_factory_fn pfn_DWriteCreateFactory = dwrite_dll->bind<dwrite_create_factory_fn>("DWriteCreateFactory");
if (!pfn_D2D1CreateFactory || !pfn_DWriteCreateFactory)
return ERROR_DLL_NOT_FOUND;
// Create a Direct2D factory
HR_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<IUnknown **>(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<IWICBitmapEncoder> 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<IWICBitmapFrameEncode> 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<IWICImagingFactory> 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<ID2D1Factory> m_d2dfactory;
ComPtr<IDWriteFactory> m_dwriteFactory;
ComPtr<IWICImagingFactory> m_wicFactory;
osd::dynamic_module::ptr m_d2d1_dll;
osd::dynamic_module::ptr m_dwrite_dll;
d2d_create_factory_fn m_pfnD2D1CreateFactory;
dwrite_create_factory_fn m_pfnDWriteCreateFactory;
ComPtr<ID2D1Factory> m_d2dfactory;
ComPtr<IDWriteFactory> m_dwriteFactory;
ComPtr<IWICImagingFactory> m_wicFactory;
public:
font_dwrite() :
osd_module(OSD_FONT_PROVIDER, "dwrite"),
font_module(),
m_pfnD2D1CreateFactory("D2D1CreateFactory", L"D2d1.dll"),
m_pfnDWriteCreateFactory("DWriteCreateFactory", L"Dwrite.dll"),
m_d2dfactory(nullptr),
m_dwriteFactory(nullptr),
m_wicFactory(nullptr)
@ -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<d2d_create_factory_fn>("D2D1CreateFactory");
m_pfnDWriteCreateFactory = m_dwrite_dll->bind<dwrite_create_factory_fn>("DWriteCreateFactory");
// This module is available if it can load the expected API Functions
if (m_pfnD2D1CreateFactory.initialize() != 0
|| m_pfnDWriteCreateFactory.initialize() != 0)
{
if (!m_pfnD2D1CreateFactory || !m_pfnDWriteCreateFactory)
return false;
}
return true;
}
@ -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<IUnknown **>(m_dwriteFactory.GetAddressOf())));

View File

@ -136,8 +136,7 @@ void dinput_keyboard_device::reset()
dinput_api_helper::dinput_api_helper(int version)
: m_dinput(nullptr),
m_dinput_version(version),
m_pfn_DirectInputCreate("DirectInputCreateW", L"dinput.dll")
m_dinput_version(version)
{
}
@ -163,18 +162,23 @@ int dinput_api_helper::initialize()
else
#endif
{
result = m_pfn_DirectInputCreate.initialize();
if (result != DI_OK)
return result;
m_dinput_dll = osd::dynamic_module::open({ "dinput.dll" });
m_dinput_create_prt = m_dinput_dll->bind<dinput_create_fn>("DirectInputCreateW");
if (m_dinput_create_prt == nullptr)
{
osd_printf_verbose("Legacy DirectInput library dinput.dll is not available\n");
return ERROR_DLL_NOT_FOUND;
}
// first attempt to initialize DirectInput at v7
m_dinput_version = 0x0700;
result = m_pfn_DirectInputCreate(GetModuleHandleUni(), m_dinput_version, m_dinput.GetAddressOf(), nullptr);
result = (*m_dinput_create_prt)(GetModuleHandleUni(), m_dinput_version, m_dinput.GetAddressOf(), nullptr);
if (result != DI_OK)
{
// if that fails, try version 5
m_dinput_version = 0x0500;
result = m_pfn_DirectInputCreate(GetModuleHandleUni(), m_dinput_version, m_dinput.GetAddressOf(), nullptr);
result = (*m_dinput_create_prt)(GetModuleHandleUni(), m_dinput_version, m_dinput.GetAddressOf(), nullptr);
if (result != DI_OK)
{
m_dinput_version = 0;

View File

@ -2,7 +2,7 @@
#define INPUT_DINPUT_H_
#include "input_common.h"
#include "winutil.h"
#include "modules/lib/osdlib.h"
//============================================================
// dinput_device - base directinput device
@ -43,10 +43,11 @@ public:
virtual BOOL device_enum_callback(LPCDIDEVICEINSTANCE instance, LPVOID ref) = 0;
};
// Typedef for dynamically loaded function
#if DIRECTINPUT_VERSION >= 0x0800
typedef lazy_loaded_function_p4<HRESULT, HMODULE, int, IDirectInput8 **, LPUNKNOWN> pfn_dinput_create;
typedef HRESULT WINAPI (*dinput_create_fn)(HINSTANCE, DWORD, LPDIRECTINPUT8 *, LPUNKNOWN);
#else
typedef lazy_loaded_function_p4<HRESULT, HMODULE, int, IDirectInput **, LPUNKNOWN> pfn_dinput_create;
typedef HRESULT WINAPI (*dinput_create_fn)(HINSTANCE, DWORD, LPDIRECTINPUT *, LPUNKNOWN);
#endif
class dinput_api_helper
@ -58,7 +59,8 @@ private:
Microsoft::WRL::ComPtr<IDirectInput> m_dinput;
#endif
int m_dinput_version;
pfn_dinput_create m_pfn_DirectInputCreate;
osd::dynamic_module::ptr m_dinput_dll;
dinput_create_fn m_dinput_create_prt;
public:
dinput_api_helper(int version);

View File

@ -26,7 +26,7 @@
#include "strconv.h"
// MAMEOS headers
#include "winutil.h"
#include "modules/lib/osdlib.h"
#include "winmain.h"
#include "window.h"
@ -37,17 +37,11 @@
// MACROS
//============================================================
#ifdef UNICODE
#define UNICODE_SUFFIX "W"
#else
#define UNICODE_SUFFIX "A"
#endif
// RawInput APIs
typedef lazy_loaded_function_p3<INT, PRAWINPUTDEVICELIST, PINT, UINT> get_rawinput_device_list_ptr;
typedef lazy_loaded_function_p5<INT, HRAWINPUT, UINT, LPVOID, PINT, UINT> get_rawinput_data_ptr;
typedef lazy_loaded_function_p4<INT, HANDLE, UINT, LPVOID, PINT> get_rawinput_device_info_ptr;
typedef lazy_loaded_function_p3<BOOL, PCRAWINPUTDEVICE, UINT, UINT> register_rawinput_devices_ptr;
// Typedefs for dynamically loaded functions
typedef UINT WINAPI (*get_rawinput_device_list_ptr)(PRAWINPUTDEVICELIST, PUINT, UINT);
typedef UINT WINAPI (*get_rawinput_data_ptr)( HRAWINPUT, UINT, LPVOID, PUINT, UINT);
typedef UINT WINAPI (*get_rawinput_device_info_ptr)(HANDLE, UINT, LPVOID, PUINT);
typedef BOOL WINAPI (*register_rawinput_devices_ptr)(PCRAWINPUTDEVICE, UINT, UINT);
class safe_regkey
{
@ -395,13 +389,6 @@ public:
}
};
/*
register_rawinput_devices = (register_rawinput_devices_ptr)GetProcAddress(user32, "RegisterRawInputDevices");
get_rawinput_device_list = (get_rawinput_device_list_ptr)GetProcAddress(user32, "GetRawInputDeviceList");
get_rawinput_device_info = (get_rawinput_device_info_ptr)GetProcAddress(user32, "GetRawInputDeviceInfo" UNICODE_SUFFIX);
get_rawinput_data = (get_rawinput_data_ptr)GetProcAddress(user32, "GetRawInputData");
*/
//============================================================
// rawinput_module - base class for rawinput modules
//============================================================
@ -409,32 +396,33 @@ get_rawinput_data = (get_rawinput_data_ptr)GetProcAddress(user32, "GetRawInputDa
class rawinput_module : public wininput_module
{
private:
// RawInput variables
get_rawinput_device_list_ptr get_rawinput_device_list;
get_rawinput_data_ptr get_rawinput_data;
get_rawinput_device_info_ptr get_rawinput_device_info;
register_rawinput_devices_ptr register_rawinput_devices;
std::mutex m_module_lock;
osd::dynamic_module::ptr m_user32_dll;
get_rawinput_device_list_ptr get_rawinput_device_list;
get_rawinput_data_ptr get_rawinput_data;
get_rawinput_device_info_ptr get_rawinput_device_info;
register_rawinput_devices_ptr register_rawinput_devices;
std::mutex m_module_lock;
public:
rawinput_module(const char *type, const char* name)
: wininput_module(type, name),
get_rawinput_device_list("GetRawInputDeviceList", L"user32.dll"),
get_rawinput_data("GetRawInputData", L"user32.dll"),
get_rawinput_device_info("GetRawInputDeviceInfoW", L"user32.dll"),
register_rawinput_devices("RegisterRawInputDevices", L"user32.dll")
: wininput_module(type, name)
{
}
bool probe() override
{
int status = get_rawinput_device_list.initialize();
status |= get_rawinput_data.initialize();
status |= get_rawinput_device_info.initialize();
status |= register_rawinput_devices.initialize();
m_user32_dll = osd::dynamic_module::open({ "user32.dll" });
if (status != 0)
get_rawinput_device_list = m_user32_dll->bind<get_rawinput_device_list_ptr>("GetRawInputDeviceList");
get_rawinput_data = m_user32_dll->bind<get_rawinput_data_ptr>("GetRawInputData");
get_rawinput_device_info = m_user32_dll->bind<get_rawinput_device_info_ptr>("GetRawInputDeviceInfoW");
register_rawinput_devices = m_user32_dll->bind<register_rawinput_devices_ptr>("RegisterRawInputDevices");
if (!get_rawinput_device_list || !get_rawinput_data ||
!get_rawinput_device_info || !register_rawinput_devices )
{
return false;
}
return true;
}
@ -442,15 +430,15 @@ public:
void input_init(running_machine &machine) override
{
// get the number of devices, allocate a device list, and fetch it
int device_count = 0;
if (get_rawinput_device_list(nullptr, &device_count, sizeof(RAWINPUTDEVICELIST)) != 0)
UINT device_count = 0;
if ((*get_rawinput_device_list)(nullptr, &device_count, sizeof(RAWINPUTDEVICELIST)) != 0)
return;
if (device_count == 0)
return;
auto rawinput_devices = std::make_unique<RAWINPUTDEVICELIST[]>(device_count);
if (get_rawinput_device_list(rawinput_devices.get(), &device_count, sizeof(RAWINPUTDEVICELIST)) == -1)
if ((*get_rawinput_device_list)(rawinput_devices.get(), &device_count, sizeof(RAWINPUTDEVICELIST)) == -1)
return;
// iterate backwards through devices; new devices are added at the head
@ -478,7 +466,7 @@ public:
registration.hwndTarget = osd_common_t::s_window_list.front()->platform_window<HWND>();
// register the device
register_rawinput_devices(&registration, 1, sizeof(registration));
(*register_rawinput_devices)(&registration, 1, sizeof(registration));
}
protected:
@ -488,13 +476,11 @@ protected:
int init_internal() override
{
// look up the entry points
int status = get_rawinput_device_list.initialize();
status |= get_rawinput_data.initialize();
status |= get_rawinput_device_info.initialize();
status |= register_rawinput_devices.initialize();
if (status != 0)
if (!get_rawinput_device_list || !get_rawinput_data ||
!get_rawinput_device_info || !register_rawinput_devices )
{
return 1;
}
osd_printf_verbose("RawInput: APIs detected\n");
return 0;
@ -504,13 +490,13 @@ protected:
TDevice* create_rawinput_device(running_machine &machine, PRAWINPUTDEVICELIST rawinputdevice)
{
TDevice* devinfo;
INT name_length = 0;
UINT name_length = 0;
// determine the length of the device name, allocate it, and fetch it if not nameless
if (get_rawinput_device_info(rawinputdevice->hDevice, RIDI_DEVICENAME, nullptr, &name_length) != 0)
if ((*get_rawinput_device_info)(rawinputdevice->hDevice, RIDI_DEVICENAME, nullptr, &name_length) != 0)
return nullptr;
std::unique_ptr<TCHAR[]> tname = std::make_unique<TCHAR[]>(name_length + 1);
if (name_length > 1 && get_rawinput_device_info(rawinputdevice->hDevice, RIDI_DEVICENAME, tname.get(), &name_length) == -1)
if (name_length > 1 && (*get_rawinput_device_info)(rawinputdevice->hDevice, RIDI_DEVICENAME, tname.get(), &name_length) == -1)
return nullptr;
// if this is an RDP name, skip it
@ -544,14 +530,14 @@ protected:
std::unique_ptr<BYTE[]> larger_buffer;
LPBYTE data = small_buffer;
BOOL result;
int size;
UINT size;
// ignore if not enabled
if (!input_enabled())
return FALSE;
// determine the size of databuffer we need
if (get_rawinput_data(rawinputdevice, RID_INPUT, nullptr, &size, sizeof(RAWINPUTHEADER)) != 0)
if ((*get_rawinput_data)(rawinputdevice, RID_INPUT, nullptr, &size, sizeof(RAWINPUTHEADER)) != 0)
return FALSE;
// if necessary, allocate a temporary buffer and fetch the data
@ -564,7 +550,7 @@ protected:
}
// fetch the data and process the appropriate message types
result = get_rawinput_data(static_cast<HRAWINPUT>(rawinputdevice), RID_INPUT, data, &size, sizeof(RAWINPUTHEADER));
result = (*get_rawinput_data)(static_cast<HRAWINPUT>(rawinputdevice), RID_INPUT, data, &size, sizeof(RAWINPUTHEADER));
if (result)
{
std::lock_guard<std::mutex> scope_lock(m_module_lock);

View File

@ -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);

View File

@ -32,50 +32,28 @@
#include "input_windows.h"
#include "input_xinput.h"
xinput_api_helper::xinput_api_helper()
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
: XInputGetState("XInputGetState", xinput_dll_names, ARRAY_LENGTH(xinput_dll_names))
, XInputGetCapabilities("XInputGetCapabilities", xinput_dll_names, ARRAY_LENGTH(xinput_dll_names))
#define XINPUT_LIBRARIES { "xinput1_4.dll", "xinput9_1_0.dll" }
#else
#define XINPUT_LIBRARIES { "xinput1_4.dll" }
#endif
{
}
int xinput_api_helper::initialize()
{
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
int status;
status = XInputGetState.initialize();
if (status != 0)
{
osd_printf_verbose("Failed to initialize function pointer for %s. Error: %d\n", XInputGetState.name(), status);
return -1;
}
m_xinput_dll = osd::dynamic_module::open(XINPUT_LIBRARIES);
status = XInputGetCapabilities.initialize();
if (status != 0)
XInputGetState = m_xinput_dll->bind<xinput_get_state_fn>("XInputGetState");
XInputGetCapabilities = m_xinput_dll->bind<xinput_get_caps_fn>("XInputGetCapabilities");
if (!XInputGetState || !XInputGetCapabilities)
{
osd_printf_verbose("Failed to initialize function pointer for %s. Error: %d\n", XInputGetCapabilities.name(), status);
osd_printf_verbose("Could not find XInput. Please try to reinstall DirectX runtime package.\n");
return -1;
}
#endif
return 0;
}
#if !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
// Pass-through functions for Universal Windows
inline DWORD xinput_api_helper::XInputGetState(DWORD dwUserindex, XINPUT_STATE *pState)
{
return ::XInputGetState(dwUserindex, pState);
}
inline DWORD xinput_api_helper::XInputGetCapabilities(DWORD dwUserindex, DWORD dwFlags, XINPUT_CAPABILITIES* pCapabilities)
{
return ::XInputGetCapabilities(dwUserindex, dwFlags, pCapabilities);
}
#endif
//============================================================
// create_xinput_device
//============================================================
@ -85,7 +63,7 @@ xinput_joystick_device * xinput_api_helper::create_xinput_device(running_machine
xinput_joystick_device *devinfo;
XINPUT_CAPABILITIES caps = { 0 };
if (FAILED(XInputGetCapabilities(index, 0, &caps)))
if (FAILED(xinput_get_capabilities(index, 0, &caps)))
{
// If we can't get the capabilities skip this device
return nullptr;
@ -125,7 +103,7 @@ void xinput_joystick_device::poll()
return;
// poll the device first
HRESULT result = m_xinput_helper->XInputGetState(xinput_state.player_index, &xinput_state.xstate);
HRESULT result = m_xinput_helper->xinput_get_state(xinput_state.player_index, &xinput_state.xstate);
// If we can't poll the device, skip
if (FAILED(result))
@ -262,7 +240,7 @@ protected:
{
XINPUT_STATE state = {0};
if (m_xinput_helper->XInputGetState(i, &state) == ERROR_SUCCESS)
if (m_xinput_helper->xinput_get_state(i, &state) == ERROR_SUCCESS)
{
// allocate and link in a new device
devinfo = m_xinput_helper->create_xinput_device(machine, i, *this);

View File

@ -3,6 +3,8 @@
#include <mutex>
#include "modules/lib/osdlib.h"
#define XINPUT_MAX_POV 4
#define XINPUT_MAX_BUTTONS 10
#define XINPUT_MAX_AXIS 4
@ -88,34 +90,30 @@ struct xinput_api_state
XINPUT_CAPABILITIES caps;
};
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
// Typedef for pointers to XInput Functions
typedef lazy_loaded_function_p2<DWORD, DWORD, XINPUT_STATE*> xinput_get_state_fn;
typedef lazy_loaded_function_p3<DWORD, DWORD, DWORD, XINPUT_CAPABILITIES*> xinput_get_caps_fn;
#endif
// Typedefs for dynamically loaded functions
typedef DWORD (*xinput_get_state_fn)(DWORD, XINPUT_STATE *);
typedef DWORD (*xinput_get_caps_fn)(DWORD, DWORD, XINPUT_CAPABILITIES *);
class xinput_api_helper : public std::enable_shared_from_this<xinput_api_helper>
{
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
private:
const wchar_t* xinput_dll_names[2] = { L"xinput1_4.dll", L"xinput9_1_0.dll" };
public:
xinput_get_state_fn XInputGetState;
xinput_get_caps_fn XInputGetCapabilities;
#endif
public:
xinput_api_helper();
int initialize();
xinput_joystick_device * create_xinput_device(running_machine &machine, UINT index, wininput_module &module);
#if !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
// Pass-through functions for Universal Windows
inline DWORD XInputGetState(DWORD dwUserindex, XINPUT_STATE *pState);
inline DWORD XInputGetCapabilities(DWORD dwUserindex, DWORD dwFlags, XINPUT_CAPABILITIES* pCapabilities);
#endif
inline DWORD xinput_get_state(DWORD dwUserindex, XINPUT_STATE *pState)
{
return (*XInputGetState)(dwUserindex, pState);
}
inline DWORD xinput_get_capabilities(DWORD dwUserindex, DWORD dwFlags, XINPUT_CAPABILITIES* pCapabilities)
{
return (*XInputGetCapabilities)(dwUserindex, dwFlags, pCapabilities);
}
private:
osd::dynamic_module::ptr m_xinput_dll;
xinput_get_state_fn XInputGetState;
xinput_get_caps_fn XInputGetCapabilities;
};
class xinput_joystick_device : public device_info

View File

@ -19,6 +19,10 @@
#ifndef __OSDLIB__
#define __OSDLIB__
#include <string>
#include <type_traits>
#include <vector>
/*-----------------------------------------------------------------------------
osd_process_kill: kill the current process
@ -30,8 +34,10 @@
None.
-----------------------------------------------------------------------------*/
void osd_process_kill(void);
/*-----------------------------------------------------------------------------
osd_setenv: set environment variable
@ -48,14 +54,52 @@ void osd_process_kill(void);
int osd_setenv(const char *name, const char *value, int overwrite);
/*-----------------------------------------------------------------------------
osd_get_clipboard_text: retrieves text from the clipboard
Return value:
the returned string needs to be osd_free()-ed!
-----------------------------------------------------------------------------*/
char *osd_get_clipboard_text(void);
/*-----------------------------------------------------------------------------
dynamic_module: load functions from optional shared libraries
Notes:
- Supports Mac OS X, Unix and Windows (both desktop and Windows
Store universal applications)
- A symbol can be searched in a list of libraries (e.g. more
revisions of a same library)
-----------------------------------------------------------------------------*/
namespace osd {
class dynamic_module
{
public:
typedef std::unique_ptr<dynamic_module> ptr;
static ptr open(std::vector<std::string> &&libraries);
virtual ~dynamic_module() { };
template <typename T>
typename std::enable_if<std::is_pointer<T>::value, T>::type bind(char const *symbol)
{
return reinterpret_cast<T>(get_symbol_address(symbol));
}
protected:
typedef void (*generic_fptr_t)();
virtual generic_fptr_t get_symbol_address(char const *symbol) = 0;
};
} // namespace osd
#endif /* __OSDLIB__ */

View File

@ -13,6 +13,12 @@
#include <sys/mman.h>
#include <sys/types.h>
#include <signal.h>
#include <dlfcn.h>
#include <codecvt>
#include <iomanip>
#include <memory>
#include <mach/mach.h>
#include <mach/mach_time.h>
@ -215,3 +221,71 @@ char *osd_get_clipboard_text(void)
return result;
}
//============================================================
// dynamic_module_posix_impl
//============================================================
namespace osd {
class dynamic_module_posix_impl : public dynamic_module
{
public:
dynamic_module_posix_impl(std::vector<std::string> &libraries)
: m_module(nullptr)
{
m_libraries = libraries;
}
virtual ~dynamic_module_posix_impl() override
{
if (m_module != nullptr)
dlclose(m_module);
};
protected:
virtual generic_fptr_t get_symbol_address(char const *symbol) override
{
/*
* given a list of libraries, if a first symbol is successfully loaded from
* one of them, all additional symbols will be loaded from the same library
*/
if (m_module)
{
return reinterpret_cast<generic_fptr_t>(dlsym(m_module, symbol));
}
for (auto const &library : m_libraries)
{
void *module = dlopen(library.c_str(), RTLD_LAZY);
if (module != nullptr)
{
generic_fptr_t function = reinterpret_cast<generic_fptr_t>(dlsym(module, symbol));
if (function != nullptr)
{
m_module = module;
return function;
}
else
{
dlclose(module);
}
}
}
return nullptr;
}
private:
std::vector<std::string> m_libraries;
void * m_module;
};
dynamic_module::ptr dynamic_module::open(std::vector<std::string> &&names)
{
return std::make_unique<dynamic_module_posix_impl>(names);
}
} // namespace osd

View File

@ -13,12 +13,19 @@
#include <sys/mman.h>
#include <sys/types.h>
#include <signal.h>
#include <dlfcn.h>
#include <codecvt>
#include <iomanip>
#include <memory>
// MAME headers
#include "osdcore.h"
#include "osdlib.h"
#include <SDL2/SDL.h>
//============================================================
// osd_getenv
//============================================================
@ -159,3 +166,71 @@ char *osd_get_clipboard_text(void)
}
#endif
//============================================================
// dynamic_module_posix_impl
//============================================================
namespace osd {
class dynamic_module_posix_impl : public dynamic_module
{
public:
dynamic_module_posix_impl(std::vector<std::string> &libraries)
: m_module(nullptr)
{
m_libraries = libraries;
}
virtual ~dynamic_module_posix_impl() override
{
if (m_module != nullptr)
dlclose(m_module);
};
protected:
virtual generic_fptr_t get_symbol_address(char const *symbol) override
{
/*
* given a list of libraries, if a first symbol is successfully loaded from
* one of them, all additional symbols will be loaded from the same library
*/
if (m_module)
{
return reinterpret_cast<generic_fptr_t>(dlsym(m_module, symbol));
}
for (auto const &library : m_libraries)
{
void *module = dlopen(library.c_str(), RTLD_LAZY);
if (module != nullptr)
{
generic_fptr_t function = reinterpret_cast<generic_fptr_t>(dlsym(module, symbol));
if (function != nullptr)
{
m_module = module;
return function;
}
else
{
dlclose(module);
}
}
}
return nullptr;
}
private:
std::vector<std::string> m_libraries;
void * m_module;
};
dynamic_module::ptr dynamic_module::open(std::vector<std::string> &&names)
{
return std::make_unique<dynamic_module_posix_impl>(names);
}
} // namespace osd

View File

@ -17,6 +17,8 @@
#include <unistd.h>
#endif
#include <memory>
// MAME headers
#include "osdlib.h"
#include "osdcomm.h"
@ -314,3 +316,85 @@ char *osd_get_clipboard_text(void)
return result;
}
//============================================================
// osd_dynamic_bind
//============================================================
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
// for classic desktop applications
#define load_library(filename) LoadLibrary(filename)
#else
// for Windows Store universal applications
#define load_library(filename) LoadPackagedLibrary(filename, 0)
#endif
namespace osd {
class dynamic_module_win32_impl : public dynamic_module
{
public:
dynamic_module_win32_impl(std::vector<std::string> &libraries)
: m_module(nullptr)
{
m_libraries = libraries;
}
virtual ~dynamic_module_win32_impl() override
{
if (m_module != nullptr)
FreeLibrary(m_module);
};
protected:
virtual generic_fptr_t get_symbol_address(char const *symbol) override
{
/*
* given a list of libraries, if a first symbol is successfully loaded from
* one of them, all additional symbols will be loaded from the same library
*/
if (m_module)
{
return reinterpret_cast<generic_fptr_t>(GetProcAddress(m_module, symbol));
}
for (auto const &library : m_libraries)
{
TCHAR *tempstr = tstring_from_utf8(library.c_str());
if (!tempstr)
return nullptr;
HMODULE module = load_library(tempstr);
osd_free(tempstr);
if (module != nullptr)
{
generic_fptr_t function = reinterpret_cast<generic_fptr_t>(GetProcAddress(module, symbol));
if (function != nullptr)
{
m_module = module;
return function;
}
else
{
FreeLibrary(module);
}
}
}
return nullptr;
}
private:
std::vector<std::string> m_libraries;
HMODULE m_module;
};
dynamic_module::ptr dynamic_module::open(std::vector<std::string> &&names)
{
return std::make_unique<dynamic_module_win32_impl>(names);
}
} // namespace osd

View File

@ -1,61 +1,47 @@
// license:BSD-3-Clause
// copyright-holders:Carl
#if defined(OSD_NET_USE_PCAP)
#if defined(SDLMAME_WIN32) || defined(OSD_WINDOWS)
#ifdef UNICODE
#define LIB_NAME L"wpcap.dll"
#define LoadDynamicLibrary LoadLibraryW
#else
#define LIB_NAME "wpcap.dll"
#define LoadDynamicLibrary LoadLibraryA
#endif
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#endif
#include <pcap.h>
#include "emu.h"
#include "osdnet.h"
#include "netdev_module.h"
#include "modules/osdmodule.h"
#include "modules/lib/osdlib.h"
#if defined(SDLMAME_WIN32) || defined(OSD_WINDOWS)
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#undef interface
#define LIB_NAME "wpcap.dll"
#define LIB_ERROR_STR "Unable to load winpcap: %lx\n"
typedef DWORD except_type;
#else
#include <dlfcn.h>
#ifdef SDLMAME_MACOSX
#elif defined(SDLMAME_MACOSX)
#include <pthread.h>
#include <libkern/OSAtomic.h>
#endif
#ifdef SDLMAME_MACOSX
#define LIB_NAME "libpcap.dylib"
#else
#define LIB_NAME "libpcap.so"
#endif
#define LIB_ERROR_STR "Unable to load pcap: %s\n"
typedef void *HMODULE;
typedef const char *except_type;
#define FreeLibrary(x) dlclose(x)
#define GetLastError() dlerror()
#define GetProcAddress(x, y) dlsym(x, y)
#define LoadDynamicLibrary(x) dlopen(x, RTLD_LAZY)
#include <pcap.h>
#endif
// Typedefs for dynamically loaded functions
typedef int (*pcap_findalldevs_fn)(pcap_if_t **, char *);
typedef pcap_t *(*pcap_open_live_fn)(const char *, int, int, int, char *);
typedef int (*pcap_next_ex_fn)(pcap_t *, struct pcap_pkthdr **, const u_char **);
typedef int (*pcap_compile_fn)(pcap_t *, struct bpf_program *, const char *, int, bpf_u_int32);
typedef void (*pcap_close_fn)(pcap_t *);
typedef int (*pcap_setfilter_fn)(pcap_t *, struct bpf_program *);
typedef int (*pcap_sendpacket_fn)(pcap_t *, const u_char *, int);
typedef int (*pcap_set_datalink_fn)(pcap_t *, int);
typedef int (*pcap_dispatch_fn)(pcap_t *, int, pcap_handler, u_char *);
class pcap_module : public osd_module, public netdev_module
{
public:
pcap_module()
: osd_module(OSD_NETDEV_PROVIDER, "pcap"), netdev_module(), handle(nullptr)
: osd_module(OSD_NETDEV_PROVIDER, "pcap"), netdev_module()
{
}
virtual ~pcap_module() { }
@ -63,32 +49,46 @@ public:
virtual int init(const osd_options &options) override;
virtual void exit() override;
virtual bool probe() override;
virtual bool probe() override
{
pcap_dll = osd::dynamic_module::open({ LIB_NAME });
HMODULE handle;
pcap_findalldevs_dl = pcap_dll->bind<pcap_findalldevs_fn>("pcap_findalldevs");
pcap_open_live_dl = pcap_dll->bind<pcap_open_live_fn>("pcap_open_live");
pcap_next_ex_dl = pcap_dll->bind<pcap_next_ex_fn>("pcap_next_ex");
pcap_compile_dl = pcap_dll->bind<pcap_compile_fn>("pcap_compile");
pcap_close_dl = pcap_dll->bind<pcap_close_fn>("pcap_close");
pcap_setfilter_dl = pcap_dll->bind<pcap_setfilter_fn>("pcap_setfilter");
pcap_sendpacket_dl = pcap_dll->bind<pcap_sendpacket_fn>("pcap_sendpacket");
pcap_set_datalink_dl = pcap_dll->bind<pcap_set_datalink_fn>("pcap_set_datalink");
pcap_dispatch_dl = pcap_dll->bind<pcap_dispatch_fn>("pcap_dispatch");
if (!pcap_findalldevs_dl || !pcap_open_live_dl || !pcap_next_ex_dl ||
!pcap_compile_dl || !pcap_close_dl || !pcap_setfilter_dl ||
!pcap_sendpacket_dl || !pcap_set_datalink_dl || !pcap_dispatch_dl)
{
osd_printf_error("Unable to load the PCAP library\n");
return false;
}
return true;
}
osd::dynamic_module::ptr pcap_dll;
pcap_findalldevs_fn pcap_findalldevs_dl;
pcap_open_live_fn pcap_open_live_dl;
pcap_next_ex_fn pcap_next_ex_dl;
pcap_compile_fn pcap_compile_dl;
pcap_close_fn pcap_close_dl;
pcap_setfilter_fn pcap_setfilter_dl;
pcap_sendpacket_fn pcap_sendpacket_dl;
pcap_set_datalink_fn pcap_set_datalink_dl;
pcap_dispatch_fn pcap_dispatch_dl;
};
static int (*pcap_compile_dl)(pcap_t *, struct bpf_program *, char *, int, bpf_u_int32) = nullptr;
static int (*pcap_findalldevs_dl)(pcap_if_t **, char *) = nullptr;
static pcap_t *(*pcap_open_live_dl)(const char *name, int, int, int, char *) = nullptr;
static int (*pcap_next_ex_dl)(pcap_t *, struct pcap_pkthdr **, const u_char **) = nullptr;
static void (*pcap_close_dl)(pcap_t *) = nullptr;
static int (*pcap_setfilter_dl)(pcap_t *, struct bpf_program *) = nullptr;
static int (*pcap_sendpacket_dl)(pcap_t *, u_char *, int) = nullptr;
static int (*pcap_set_datalink_dl)(pcap_t *, int) = nullptr;
static int (*pcap_dispatch_dl)(pcap_t *, int, pcap_handler callback, u_char *) = nullptr;
#if 0
#define pcap_compile_dl pcap_compile
#define pcap_findalldevs_dl pcap_findalldevs
#define pcap_open_live_dl pcap_open_live
#define pcap_next_ex_dl pcap_next_ex
#define pcap_close_dl pcap_close
#define pcap_setfilter_dl pcap_setfilter
#define pcap_sendpacket_dl pcap_sendpacket
#define pcap_set_datalink_dl pcap_set_datalink
#endif
// FIXME: bridge between pcap_module and netdev_pcap
static pcap_module *module = nullptr;
#ifdef SDLMAME_MACOSX
struct netdev_pcap_context {
@ -140,7 +140,7 @@ static void *netdev_pcap_blocker(void *arg) {
struct netdev_pcap_context *ctx = (struct netdev_pcap_context*)arg;
while(ctx && ctx->p) {
pcap_dispatch_dl(ctx->p, 1, netdev_pcap_handler, (u_char*)ctx);
(*module->pcap_dispatch_dl)(ctx->p, 1, netdev_pcap_handler, (u_char*)ctx);
}
return 0;
@ -152,19 +152,19 @@ netdev_pcap::netdev_pcap(const char *name, class device_network_interface *ifdev
{
char errbuf[PCAP_ERRBUF_SIZE];
#if defined(SDLMAME_WIN32) || defined(OSD_WINDOWS)
m_p = pcap_open_live_dl(name, 65535, 1, -1, errbuf);
m_p = (*module->pcap_open_live_dl)(name, 65535, 1, -1, errbuf);
#else
m_p = pcap_open_live_dl(name, 65535, 1, 1, errbuf);
m_p = (*module->pcap_open_live_dl)(name, 65535, 1, 1, errbuf);
#endif
if(!m_p)
{
osd_printf_error("Unable to open %s: %s\n", name, errbuf);
return;
}
if(pcap_set_datalink_dl(m_p, DLT_EN10MB) == -1)
if ((*module->pcap_set_datalink_dl)(m_p, DLT_EN10MB) == -1)
{
osd_printf_error("Unable to set %s to ethernet", name);
pcap_close_dl(m_p);
(*module->pcap_close_dl)(m_p);
m_p = nullptr;
return;
}
@ -188,10 +188,10 @@ void netdev_pcap::set_mac(const char *mac)
#else
sprintf(filter, "ether dst %.2X:%.2X:%.2X:%.2X:%.2X:%.2X or ether multicast or ether broadcast", (unsigned char)mac[0], (unsigned char)mac[1], (unsigned char)mac[2],(unsigned char)mac[3], (unsigned char)mac[4], (unsigned char)mac[5]);
#endif
if(pcap_compile_dl(m_p, &fp, filter, 1, 0) == -1) {
if ((*module->pcap_compile_dl)(m_p, &fp, filter, 1, 0) == -1) {
osd_printf_error("Error with pcap_compile\n");
}
if(pcap_setfilter_dl(m_p, &fp) == -1) {
if ((*module->pcap_setfilter_dl)(m_p, &fp) == -1) {
osd_printf_error("Error with pcap_setfilter\n");
}
}
@ -203,7 +203,7 @@ int netdev_pcap::send(UINT8 *buf, int len)
printf("send invoked, but no pcap context\n");
return 0;
}
ret = pcap_sendpacket_dl(m_p, buf, len);
ret = (*module->pcap_sendpacket_dl)(m_p, buf, len);
printf("sent packet length %d, returned %d\n", len, ret);
return ret ? len : 0;
//return (!pcap_sendpacket_dl(m_p, buf, len))?len:0;
@ -228,7 +228,7 @@ int netdev_pcap::recv_dev(UINT8 **buf)
#else
struct pcap_pkthdr *header;
if(!m_p) return 0;
return (pcap_next_ex_dl(m_p, &header, (const u_char **)buf) == 1)?header->len:0;
return ((*module->pcap_next_ex_dl)(m_p, &header, (const u_char **)buf) == 1)?header->len:0;
#endif
}
@ -239,7 +239,7 @@ netdev_pcap::~netdev_pcap()
pthread_cancel(m_thread);
pthread_join(m_thread, nullptr);
#endif
if(m_p) pcap_close_dl(m_p);
if(m_p) (*module->pcap_close_dl)(m_p);
m_p = nullptr;
}
@ -249,52 +249,16 @@ static CREATE_NETDEV(create_pcap)
return dynamic_cast<osd_netdev *>(dev);
}
bool pcap_module::probe()
{
if (handle == nullptr)
{
handle = LoadDynamicLibrary(LIB_NAME);
return (handle != nullptr);
}
return true;
}
int pcap_module::init(const osd_options &options)
{
pcap_if_t *devs;
char errbuf[PCAP_ERRBUF_SIZE];
try
// 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"

View File

@ -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 <windows.h>
#include <d3d9.h>
#include <d3dx9.h>
#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;
}

View File

@ -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];

View File

@ -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<d3dx_create_effect_from_file_fn>("D3DXCreateEffectFromFileW");
if (!d3dx_create_effect_from_file_ptr)
{
printf("Direct3D: Unable to find D3DXCreateEffectFromFileW\n");
d3dintf->post_fx_available = false;
return;
}
d3dintf->post_fx_available = true;
this->d3dintf = d3dintf;
this->machine = machine;
this->d3d = renderer;
@ -837,41 +817,44 @@ int shaders::create_resources(bool reset, std::vector<ui::menu_item>& sliders)
options = &last_options;
}
HRESULT result = (*d3dintf->device.get_render_target)(d3d->get_device(), 0, &backbuffer);
if (result != D3D_OK)
HRESULT result = d3d->get_device()->GetRenderTarget(0, &backbuffer);
if (FAILED(result))
{
osd_printf_verbose("Direct3D: Error %08X during device get_render_target call\n", (int)result);
osd_printf_verbose("Direct3D: Error %08lX during device GetRenderTarget call\n", result);
}
result = (*d3dintf->device.create_texture)(d3d->get_device(), 4, 4, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &black_texture);
if (result != D3D_OK)
result = d3d->get_device()->CreateTexture(4, 4, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &black_texture, nullptr);
if (FAILED(result))
{
osd_printf_verbose("Direct3D: Unable to init video-memory target for black texture (%08x)\n", (UINT32)result);
return 1;
}
(*d3dintf->texture.get_surface_level)(black_texture, 0, &black_surface);
result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, black_surface);
if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_render_target call\n", (int)result);
result = (*d3dintf->device.clear)(d3d->get_device(), 0, nullptr, D3DCLEAR_TARGET, D3DCOLOR_ARGB(0,0,0,0), 0, 0);
if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device clear call\n", (int)result);
result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, backbuffer);
if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_render_target call\n", (int)result);
black_texture->GetSurfaceLevel(0, &black_surface);
result = d3d->get_device()->SetRenderTarget(0, black_surface);
if (FAILED(result))
osd_printf_verbose("Direct3D: Error %08lX during device SetRenderTarget call\n", result);
result = d3d->get_device()->Clear(0, nullptr, D3DCLEAR_TARGET, D3DCOLOR_ARGB(0,0,0,0), 0, 0);
if (FAILED(result))
osd_printf_verbose("Direct3D: Error %08lX during device clear call\n", result);
result = d3d->get_device()->SetRenderTarget(0, backbuffer);
if (FAILED(result))
osd_printf_verbose("Direct3D: Error %08lX during device SetRenderTarget call\n", result);
result = (*d3dintf->device.create_texture)(d3d->get_device(), (int)snap_width, (int)snap_height, 1, D3DUSAGE_DYNAMIC, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &avi_copy_texture);
if (result != D3D_OK)
result = d3d->get_device()->CreateTexture((int)snap_width, (int)snap_height, 1, D3DUSAGE_DYNAMIC, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &avi_copy_texture, nullptr);
if (FAILED(result))
{
osd_printf_verbose("Direct3D: Unable to init system-memory target for HLSL AVI dumping (%08x)\n", (UINT32)result);
return 1;
}
(*d3dintf->texture.get_surface_level)(avi_copy_texture, 0, &avi_copy_surface);
avi_copy_texture->GetSurfaceLevel(0, &avi_copy_surface);
result = (*d3dintf->device.create_texture)(d3d->get_device(), (int)snap_width, (int)snap_height, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &avi_final_texture);
if (result != D3D_OK)
result = d3d->get_device()->CreateTexture((int)snap_width, (int)snap_height, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &avi_final_texture, nullptr);
if (FAILED(result))
{
osd_printf_verbose("Direct3D: Unable to init video-memory target for HLSL AVI dumping (%08x)\n", (UINT32)result);
return 1;
}
(*d3dintf->texture.get_surface_level)(avi_final_texture, 0, &avi_final_target);
avi_final_texture->GetSurfaceLevel(0, &avi_final_target);
emu_file file(machine->options().art_path(), OPEN_FLAG_READ);
render_load_png(shadow_bitmap, file, nullptr, options->shadow_mask_texture);
@ -890,7 +873,7 @@ int shaders::create_resources(bool reset, std::vector<ui::menu_item>& sliders)
texture.seqid = 0;
// now create it (no prescale, no wrap)
shadow_texture = new texture_info(d3d->get_texture_manager(), &texture, 1, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXFORMAT(TEXFORMAT_ARGB32));
shadow_texture = global_alloc(texture_info(d3d->get_texture_manager(), &texture, 1, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXFORMAT(TEXFORMAT_ARGB32)));
}
const char *fx_dir = downcast<windows_options &>(machine->options()).screen_post_fx_dir();
@ -1035,10 +1018,10 @@ void shaders::begin_draw()
downsample_effect->set_technique("DefaultTechnique");
vector_effect->set_technique("DefaultTechnique");
HRESULT result = (*d3dintf->device.get_render_target)(d3d->get_device(), 0, &backbuffer);
if (result != D3D_OK)
HRESULT result = d3d->get_device()->GetRenderTarget(0, &backbuffer);
if (FAILED(result))
{
osd_printf_verbose("Direct3D: Error %08X during device get_render_target call\n", (int)result);
osd_printf_verbose("Direct3D: Error %08lX during device GetRenderTarget call\n", result);
}
}
@ -1058,7 +1041,7 @@ void shaders::begin_frame()
//============================================================
void shaders::blit(
surface *dst,
IDirect3DSurface9 *dst,
bool clear_dst,
D3DPRIMITIVETYPE prim_type,
UINT32 prim_index,
@ -1068,18 +1051,18 @@ void shaders::blit(
if (dst != nullptr)
{
result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, dst);
if (result != D3D_OK)
result = d3d->get_device()->SetRenderTarget(0, dst);
if (FAILED(result))
{
osd_printf_verbose("Direct3D: Error %08X during device set_render_target call\n", (int)result);
osd_printf_verbose("Direct3D: Error %08lX during device SetRenderTarget call\n", result);
}
if (clear_dst)
{
result = (*d3dintf->device.clear)(d3d->get_device(), 0, nullptr, D3DCLEAR_TARGET, D3DCOLOR_ARGB(1,0,0,0), 0, 0);
if (result != D3D_OK)
result = d3d->get_device()->Clear(0, nullptr, D3DCLEAR_TARGET, D3DCOLOR_ARGB(1,0,0,0), 0, 0);
if (FAILED(result))
{
osd_printf_verbose("Direct3D: Error %08X during device clear call\n", (int)result);
osd_printf_verbose("Direct3D: Error %08lX during device clear call\n", result);
}
}
}
@ -1092,10 +1075,10 @@ void shaders::blit(
curr_effect->begin_pass(pass);
// add the primitives
result = (*d3dintf->device.draw_primitive)(d3d->get_device(), prim_type, prim_index, prim_count);
if (result != D3D_OK)
result = d3d->get_device()->DrawPrimitive(prim_type, prim_index, prim_count);
if (FAILED(result))
{
osd_printf_verbose("Direct3D: Error %08X during device draw_primitive call\n", (int)result);
osd_printf_verbose("Direct3D: Error %08lX during device DrawPrimitive call\n", result);
}
curr_effect->end_pass();
@ -1565,10 +1548,10 @@ int shaders::screen_pass(d3d_render_target *rt, int source_index, poly_info *pol
{
blit(avi_final_target, false, poly->get_type(), vertnum, poly->get_count());
HRESULT result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, backbuffer);
if (result != D3D_OK)
HRESULT result = d3d->get_device()->SetRenderTarget(0, backbuffer);
if (FAILED(result))
{
osd_printf_verbose("Direct3D: Error %08X during device set_render_target call\n", (int)result);
osd_printf_verbose("Direct3D: Error %08lX during device SetRenderTarget call\n", result);
}
}
@ -1576,10 +1559,10 @@ int shaders::screen_pass(d3d_render_target *rt, int source_index, poly_info *pol
{
blit(snap_target, false, poly->get_type(), vertnum, poly->get_count());
HRESULT result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, backbuffer);
if (result != D3D_OK)
HRESULT result = d3d->get_device()->SetRenderTarget(0, backbuffer);
if (FAILED(result))
{
osd_printf_verbose("Direct3D: Error %08X during device set_render_target call\n", (int)result);
osd_printf_verbose("Direct3D: Error %08lX during device SetRenderTarget call\n", result);
}
snap_rendered = true;
@ -1684,10 +1667,10 @@ void shaders::render_quad(poly_info *poly, int vertnum)
next_index = vector_pass(rt, next_index, poly, vertnum);
HRESULT result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, backbuffer);
if (result != D3D_OK)
HRESULT result = d3d->get_device()->SetRenderTarget(0, backbuffer);
if (FAILED(result))
{
osd_printf_verbose("Direct3D: Error %08X during device set_render_target call\n", (int)result);
osd_printf_verbose("Direct3D: Error %08lX during device SetRenderTarget call\n", result);
}
}
else if (PRIMFLAG_GET_VECTORBUF(poly->get_flags()) && vector_enable)
@ -1736,10 +1719,10 @@ void shaders::render_quad(poly_info *poly, int vertnum)
next_index = screen_pass(rt, next_index, poly, vertnum);
d3d->set_wrap(PRIMFLAG_GET_TEXWRAP(curr_texture->get_flags()) ? D3DTADDRESS_WRAP : D3DTADDRESS_CLAMP);
HRESULT result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, backbuffer);
if (result != D3D_OK)
HRESULT result = d3d->get_device()->SetRenderTarget(0, backbuffer);
if (FAILED(result))
{
osd_printf_verbose("Direct3D: Error %08X during device set_render_target call\n", (int)result);
osd_printf_verbose("Direct3D: Error %08lX during device SetRenderTarget call\n", result);
}
lines_pending = false;
@ -1770,13 +1753,14 @@ void shaders::end_draw()
return;
}
(*d3dintf->surface.release)(backbuffer);
backbuffer->Release();
}
//============================================================
// shaders::add_cache_target - register a cache target
//============================================================
bool shaders::add_cache_target(renderer_d3d9* d3d, texture_info* texture, int source_width, int source_height, int target_width, int target_height, int screen_index)
{
cache_target* target = (cache_target*)global_alloc_clear<cache_target>();
@ -1803,6 +1787,7 @@ bool shaders::add_cache_target(renderer_d3d9* d3d, texture_info* texture, int so
//============================================================
// shaders::get_texture_target(render_primitive::prim, texture_info::texture)
//============================================================
d3d_render_target* shaders::get_texture_target(render_primitive *prim, texture_info *texture)
{
auto win = d3d->assert_window();
@ -2108,42 +2093,42 @@ void shaders::delete_resources(bool reset)
if (backbuffer != nullptr)
{
(*d3dintf->surface.release)(backbuffer);
backbuffer->Release();
backbuffer = nullptr;
}
if (black_surface != nullptr)
{
(*d3dintf->surface.release)(black_surface);
black_surface->Release();
black_surface = nullptr;
}
if (black_texture != nullptr)
{
(*d3dintf->texture.release)(black_texture);
black_texture->Release();
black_texture = nullptr;
}
if (avi_copy_texture != nullptr)
{
(*d3dintf->texture.release)(avi_copy_texture);
avi_copy_texture->Release();
avi_copy_texture = nullptr;
}
if (avi_copy_surface != nullptr)
{
(*d3dintf->surface.release)(avi_copy_surface);
avi_copy_surface->Release();
avi_copy_surface = nullptr;
}
if (avi_final_texture != nullptr)
{
(*d3dintf->texture.release)(avi_final_texture);
avi_final_texture->Release();
avi_final_texture = nullptr;
}
if (avi_final_target != nullptr)
{
(*d3dintf->surface.release)(avi_final_target);
avi_final_target->Release();
avi_final_target = nullptr;
}
@ -2909,12 +2894,12 @@ void uniform::set(bool x)
m_bval = x;
}
void uniform::set(matrix *mat)
void uniform::set(D3DMATRIX *mat)
{
m_mval = mat;
}
void uniform::set(texture *tex)
void uniform::set(IDirect3DTexture9 *tex)
{
m_texture = tex;
}
@ -2951,9 +2936,8 @@ void uniform::upload()
// effect functions
//============================================================
effect::effect(shaders *shadersys, device *dev, const char *name, const char *path)
effect::effect(shaders *shadersys, IDirect3DDevice9 *dev, const char *name, const char *path)
{
IDirect3DDevice9 *device = (IDirect3DDevice9 *)dev;
LPD3DXBUFFER buffer_errors = nullptr;
m_shaders = shadersys;
@ -2966,7 +2950,7 @@ effect::effect(shaders *shadersys, device *dev, const char *name, const char *pa
sprintf(name_cstr, "%s\\%s", path, name);
TCHAR *effect_name = tstring_from_utf8(name_cstr);
HRESULT hr = (*g_load_effect)(device, effect_name, nullptr, nullptr, 0, nullptr, &m_effect, &buffer_errors);
HRESULT hr = (*shadersys->d3dx_create_effect_from_file_ptr)(dev, effect_name, nullptr, nullptr, 0, nullptr, &m_effect, &buffer_errors);
if (FAILED(hr))
{
if (buffer_errors != nullptr)
@ -3093,14 +3077,14 @@ void effect::set_bool(D3DXHANDLE param, bool value)
m_effect->SetBool(param, value);
}
void effect::set_matrix(D3DXHANDLE param, matrix *matrix)
void effect::set_matrix(D3DXHANDLE param, D3DMATRIX *matrix)
{
m_effect->SetMatrix(param, (D3DXMATRIX*)matrix);
}
void effect::set_texture(D3DXHANDLE param, texture *tex)
void effect::set_texture(D3DXHANDLE param, IDirect3DTexture9 *tex)
{
m_effect->SetTexture(param, (IDirect3DTexture9*)tex);
m_effect->SetTexture(param, tex);
}
D3DXHANDLE effect::get_parameter(D3DXHANDLE param, const char *name)

View File

@ -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

View File

@ -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 <windows.h>
#include <tchar.h>
#include <mmsystem.h>
#include <d3d9.h>
#include <d3dx9.h>
#include <math.h>
#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

File diff suppressed because it is too large Load Diff

View File

@ -13,8 +13,17 @@
#ifdef OSD_WINDOWS
#include "d3d/d3dintf.h"
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <tchar.h>
#include <mmsystem.h>
#include <d3d9.h>
#include <d3dx9.h>
#include <math.h>
#undef interface
#include "d3d/d3dcomm.h"
#include "modules/lib/osdlib.h"
//============================================================
// CONSTANTS
@ -27,14 +36,17 @@
// TYPE DEFINITIONS
//============================================================
struct vertex;
class texture_info;
class texture_manager;
struct device;
struct vertex_buffer;
struct d3d_base
{
// internal objects
IDirect3D9 *d3dobj;
bool post_fx_available;
osd::dynamic_module::ptr d3d9_dll;
};
class shaders;
struct hlsl_options;
class poly_info;
/* renderer is the information about Direct3D for the current screen */
class renderer_d3d9 : public osd_renderer
@ -97,10 +109,10 @@ public:
int get_height() const { return m_height; }
int get_refresh() const { return m_refresh; }
device * get_device() const { return m_device; }
present_parameters * get_presentation() { return &m_presentation; }
IDirect3DDevice9 * get_device() const { return m_device; }
D3DPRESENT_PARAMETERS * get_presentation() { return &m_presentation; }
vertex_buffer * get_vertex_buffer() const { return m_vertexbuf; }
IDirect3DVertexBuffer9 *get_vertex_buffer() const { return m_vertexbuf; }
vertex * get_locked_buffer() const { return m_lockedbuf; }
VOID ** get_locked_buffer_ptr()const { return (VOID **)&m_lockedbuf; }
void set_locked_buffer(vertex *lockedbuf) { m_lockedbuf = lockedbuf; }
@ -128,13 +140,13 @@ private:
int m_refresh; // current refresh rate
int m_create_error_count; // number of consecutive create errors
device * m_device; // pointer to the Direct3DDevice object
IDirect3DDevice9 * m_device; // pointer to the Direct3DDevice object
int m_gamma_supported; // is full screen gamma supported?
present_parameters m_presentation; // set of presentation parameters
D3DPRESENT_PARAMETERS m_presentation; // set of presentation parameters
D3DDISPLAYMODE m_origmode; // original display mode for the adapter
D3DFORMAT m_pixformat; // pixel format we are using
vertex_buffer * m_vertexbuf; // pointer to the vertex buffer object
IDirect3DVertexBuffer9 *m_vertexbuf; // pointer to the vertex buffer object
vertex * m_lockedbuf; // pointer to the locked vertex buffer
int m_numverts; // number of accumulated vertices

View File

@ -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

View File

@ -14,6 +14,17 @@
#define __WIN_GL_CONTEXT__
#include "modules/opengl/osd_opengl.h"
#include "modules/lib/osdlib.h"
// Typedefs for dynamically loaded functions
typedef PROC WINAPI (*wglGetProcAddress_fn)(LPCSTR);
typedef HGLRC WINAPI (*wglCreateContext_fn)(HDC);
typedef BOOL WINAPI (*wglDeleteContext_fn)(HGLRC);
typedef BOOL WINAPI (*wglMakeCurrent_fn)(HDC, HGLRC);
typedef const char * WINAPI (*wglGetExtensionsStringEXT_fn)(void);
typedef BOOL WINAPI (*wglSwapIntervalEXT_fn)(int);
typedef int WINAPI (*wglGetSwapIntervalEXT_fn)(void);
class win_gl_context : public osd_gl_context
{
@ -22,17 +33,25 @@ public:
{
m_error[0] = 0;
this->pfn_wglGetProcAddress = (PROC (WINAPI *)(LPCSTR lpszProc)) GetProcAddress(m_module, "wglGetProcAddress");
this->pfn_wglCreateContext = (HGLRC (WINAPI *)(HDC hdc)) GetProcAddress(m_module, "wglCreateContext");
this->pfn_wglDeleteContext = (BOOL (WINAPI *)(HGLRC hglrc)) GetProcAddress(m_module, "wglDeleteContext");
this->pfn_wglMakeCurrent = (BOOL (WINAPI *)(HDC hdc, HGLRC hglrc)) GetProcAddress(m_module, "wglMakeCurrent");
opengl32_dll = osd::dynamic_module::open({ "opengl32.dll" });
this->pfn_wglGetExtensionsStringEXT = (const char *(WINAPI *) (void)) pfn_wglGetProcAddress("wglGetExtensionsStringEXT");
pfn_wglGetProcAddress = opengl32_dll->bind<wglGetProcAddress_fn>("wglGetProcAddress");
pfn_wglCreateContext = opengl32_dll->bind<wglCreateContext_fn>("wglCreateContext");
pfn_wglDeleteContext = opengl32_dll->bind<wglDeleteContext_fn>("wglDeleteContext");
pfn_wglMakeCurrent = opengl32_dll->bind<wglMakeCurrent_fn>("wglMakeCurrent");
if (pfn_wglGetProcAddress == nullptr || pfn_wglCreateContext == nullptr ||
pfn_wglDeleteContext == nullptr || pfn_wglMakeCurrent == nullptr)
{
return;
}
pfn_wglGetExtensionsStringEXT = (wglGetExtensionsStringEXT_fn)(*pfn_wglGetProcAddress)("wglGetExtensionsStringEXT");
if (WGLExtensionSupported("WGL_EXT_swap_control"))
{
this->pfn_wglSwapIntervalEXT = (BOOL (WINAPI *) (int)) getProcAddress("wglSwapIntervalEXT");
this->pfn_wglGetSwapIntervalEXT = (int (WINAPI *) (void)) getProcAddress("wglGetSwapIntervalEXT");
pfn_wglSwapIntervalEXT = (BOOL (WINAPI *) (int)) getProcAddress("wglSwapIntervalEXT");
pfn_wglGetSwapIntervalEXT = (int (WINAPI *) (void)) getProcAddress("wglGetSwapIntervalEXT");
}
else
{
@ -43,25 +62,25 @@ public:
m_hdc = GetDC(window);
if (!setupPixelFormat(m_hdc))
{
m_context = this->pfn_wglCreateContext(m_hdc);
if (!m_context)
m_context = (*pfn_wglCreateContext)(m_hdc);
if (!m_context)
{
FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, nullptr, GetLastError(), 0, m_error, 255, nullptr);
return;
}
this->pfn_wglMakeCurrent(m_hdc, m_context);
(*pfn_wglMakeCurrent)(m_hdc, m_context);
}
}
virtual ~win_gl_context()
{
this->pfn_wglDeleteContext(m_context);
(*pfn_wglDeleteContext)(m_context);
ReleaseDC(m_window, m_hdc);
}
virtual void MakeCurrent() override
{
this->pfn_wglMakeCurrent(m_hdc, m_context);
(*pfn_wglMakeCurrent)(m_hdc, m_context);
}
virtual const char *LastErrorMsg() override
@ -74,17 +93,14 @@ public:
virtual void *getProcAddress(const char *proc) override
{
void *ret = (void *) GetProcAddress(m_module, proc);
if (ret == nullptr)
ret = (void *) this->pfn_wglGetProcAddress(proc);
return ret;
return (void *)(*pfn_wglGetProcAddress)(proc);
}
virtual int SetSwapInterval(const int swap) override
{
if (this->pfn_wglSwapIntervalEXT != nullptr)
if (pfn_wglSwapIntervalEXT != nullptr)
{
this->pfn_wglSwapIntervalEXT(swap ? 1 : 0);
pfn_wglSwapIntervalEXT(swap ? 1 : 0);
}
return 0;
}
@ -95,11 +111,6 @@ public:
//wglSwapLayerBuffers(GetDC(window().m_hwnd), WGL_SWAP_MAIN_PLANE);
}
static void load_library()
{
m_module = LoadLibraryA("opengl32.dll");
}
private:
int setupPixelFormat(HDC hDC)
@ -124,15 +135,17 @@ private:
0, /* reserved */
0, 0, 0, /* no layer, visible, damage masks */
};
int pixelFormat;
pixelFormat = ChoosePixelFormat(hDC, &pfd);
if (pixelFormat == 0) {
strcpy(m_error, "ChoosePixelFormat failed");
int pixelFormat = ChoosePixelFormat(hDC, &pfd);
if (pixelFormat == 0)
{
strcpy(m_error, "ChoosePixelFormat failed.");
return 1;
}
if (SetPixelFormat(hDC, pixelFormat, &pfd) != TRUE) {
if (SetPixelFormat(hDC, pixelFormat, &pfd) != TRUE)
{
strcpy(m_error, "SetPixelFormat failed.");
return 1;
}
@ -141,10 +154,12 @@ private:
bool WGLExtensionSupported(const char *extension_name)
{
//if (pfn_wglGetExtensionsStringEXT != nullptr)
// printf("%s\n", this->pfn_wglGetExtensionsStringEXT());
if (pfn_wglGetExtensionsStringEXT == nullptr)
return false;
// printf("%s\n", pfn_wglGetExtensionsStringEXT());
if (pfn_wglGetExtensionsStringEXT != nullptr && strstr(pfn_wglGetExtensionsStringEXT(), extension_name) != nullptr)
if (strstr(pfn_wglGetExtensionsStringEXT(), extension_name) != nullptr)
return true;
else
return false;
@ -155,16 +170,15 @@ private:
HDC m_hdc;
char m_error[256];
PROC (WINAPI *pfn_wglGetProcAddress)(LPCSTR lpszProc);
HGLRC (WINAPI *pfn_wglCreateContext)(HDC hdc);
BOOL (WINAPI *pfn_wglDeleteContext)(HGLRC hglrc);
BOOL (WINAPI *pfn_wglMakeCurrent)(HDC hdc, HGLRC hglrc);
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__

62
src/osd/modules/sound/xaudio2_sound.cpp Normal file → Executable file
View File

@ -33,6 +33,8 @@
#include "winutil.h"
#include "modules/lib/osdlib.h"
//============================================================
// Constants
//============================================================
@ -118,7 +120,7 @@ typedef std::unique_ptr<IXAudio2MasteringVoice, xaudio2_custom_deleter> masterin
typedef std::unique_ptr<IXAudio2SourceVoice, xaudio2_custom_deleter> src_voice_ptr;
// Typedef for pointer to XAudio2Create
typedef lazy_loaded_function_p3<HRESULT, IXAudio2**, UINT32, XAUDIO2_PROCESSOR> xaudio2_create_ptr;
typedef HRESULT (*xaudio2_create_ptr)(IXAudio2 **, UINT32, XAUDIO2_PROCESSOR);
//============================================================
// Helper classes
@ -181,28 +183,27 @@ public:
class sound_xaudio2 : public osd_module, public sound_module, public IXAudio2VoiceCallback
{
private:
const wchar_t* XAUDIO_DLLS[2] = { L"XAudio2_9.dll", L"XAudio2_8.dll" };
Microsoft::WRL::ComPtr<IXAudio2> m_xAudio2;
mastering_voice_ptr m_masterVoice;
src_voice_ptr m_sourceVoice;
DWORD m_sample_bytes;
std::unique_ptr<BYTE[]> m_buffer;
DWORD m_buffer_size;
DWORD m_buffer_count;
DWORD m_writepos;
std::mutex m_buffer_lock;
HANDLE m_hEventBufferCompleted;
HANDLE m_hEventDataAvailable;
HANDLE m_hEventExiting;
std::thread m_audioThread;
std::queue<xaudio2_buffer> m_queue;
std::unique_ptr<bufferpool> m_buffer_pool;
UINT32 m_overflows;
UINT32 m_underflows;
BOOL m_in_underflow;
xaudio2_create_ptr XAudio2Create;
BOOL m_initialized;
Microsoft::WRL::ComPtr<IXAudio2> m_xAudio2;
mastering_voice_ptr m_masterVoice;
src_voice_ptr m_sourceVoice;
DWORD m_sample_bytes;
std::unique_ptr<BYTE[]> m_buffer;
DWORD m_buffer_size;
DWORD m_buffer_count;
DWORD m_writepos;
std::mutex m_buffer_lock;
HANDLE m_hEventBufferCompleted;
HANDLE m_hEventDataAvailable;
HANDLE m_hEventExiting;
std::thread m_audioThread;
std::queue<xaudio2_buffer> m_queue;
std::unique_ptr<bufferpool> m_buffer_pool;
UINT32 m_overflows;
UINT32 m_underflows;
BOOL m_in_underflow;
osd::dynamic_module::ptr m_xaudio_dll;
xaudio2_create_ptr XAudio2Create;
BOOL m_initialized;
public:
sound_xaudio2() :
@ -223,7 +224,6 @@ public:
m_overflows(0),
m_underflows(0),
m_in_underflow(FALSE),
XAudio2Create("XAudio2Create", XAUDIO_DLLS, ARRAY_LENGTH(XAUDIO_DLLS)),
m_initialized(FALSE)
{
}
@ -261,8 +261,13 @@ private:
bool sound_xaudio2::probe()
{
int status = XAudio2Create.initialize();
return status == 0;
m_xaudio_dll = osd::dynamic_module::open({ "XAudio2_9.dll", "XAudio2_8.dll" });
if (m_xaudio_dll == nullptr)
return false;
XAudio2Create = m_xaudio_dll->bind<xaudio2_create_ptr>("XAudio2Create");
return (XAudio2Create ? true : false);
}
//============================================================
@ -276,10 +281,9 @@ int sound_xaudio2::init(osd_options const &options)
CoInitializeEx(nullptr, COINIT_MULTITHREADED);
// Make sure our XAudio2Create entrypoint is bound
int status = XAudio2Create.initialize();
if (status != 0)
if (!XAudio2Create)
{
osd_printf_error("Could not find XAudio2 library\n");
osd_printf_error("Could not find XAudio2. Please try to reinstall DirectX runtime package.\n");
return 1;
}

View File

@ -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());
}

View File

@ -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<std::wstring> 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 TRet>
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 TRet, class P1>
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 TRet, class P1, class P2>
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 TRet, class P1, class P2, class P3>
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 TRet, class P1, class P2, class P3, class P4>
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 TRet, class P1, class P2, class P3, class P4, class P5>
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__