diff --git a/src/win/win_d2d.cpp b/src/win/win_d2d.c similarity index 67% rename from src/win/win_d2d.cpp rename to src/win/win_d2d.c index d05dc5764..038ef739c 100644 --- a/src/win/win_d2d.cpp +++ b/src/win/win_d2d.c @@ -8,7 +8,7 @@ * * Rendering module for Microsoft Direct2D. * - * Version: @(#)win_d2d.cpp 1.0.6 2019/12/10 + * Version: @(#)win_d2d.c 1.0.7 2019/12/13 * * Authors: David Hrdlička, * @@ -18,6 +18,7 @@ #include #include #include +#include #define UNICODE #define BITMAP WINDOWS_BITMAP #include @@ -40,22 +41,25 @@ static HWND d2d_hwnd, old_hwndMain; static ID2D1Factory *d2d_factory; static ID2D1HwndRenderTarget *d2d_target; static ID2D1Bitmap *d2d_buffer; -static int d2d_width, d2d_height, d2d_screen_width, d2d_screen_height, d2d_fs; +static int d2d_width, d2d_height, d2d_screen_width, + d2d_screen_height, d2d_fs; static volatile int d2d_enabled = 0; /* Pointers to the real functions. */ -static HRESULT (*D2D1_CreateFactory)(D2D1_FACTORY_TYPE facType, - REFIID riid, - CONST D2D1_FACTORY_OPTIONS *pFacOptions, - void **ppIFactory); +static HRESULT WINAPI (*D2D1_CreateFactory)( + D2D1_FACTORY_TYPE facType, + REFIID riid, + const D2D1_FACTORY_OPTIONS *pFacOptions, + void **ppIFactory); + static dllimp_t d2d_imports[] = { { "D2D1CreateFactory", &D2D1_CreateFactory }, { NULL, NULL } }; -static volatile void *d2d_handle; /* handle to WinPcap DLL */ +static volatile void *d2d_handle; /* handle to Direct2D DLL */ #ifdef ENABLE_D2D_LOG @@ -68,9 +72,9 @@ d2d_log(const char *fmt, ...) va_list ap; if (d2d_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); } } #else @@ -152,13 +156,8 @@ d2d_blit(int x, int y, int y1, int y2, int w, int h) { HRESULT hr = S_OK; - D2D1_RECT_U rectU; - - float fs_x, fs_y; - float fs_w = w; - float fs_h = h; - - d2d_log("Direct2D: d2d_blit(x=%d, y=%d, y1=%d, y2=%d, w=%d, h=%d)\n", x, y, y1, y2, w, h); + d2d_log("Direct2D: d2d_blit(x=%d, y=%d, y1=%d, y2=%d, w=%d, h=%d)\n", + x, y, y1, y2, w, h); if (!d2d_enabled) { video_blit_complete(); @@ -167,7 +166,8 @@ d2d_blit(int x, int y, int y1, int y2, int w, int h) if ((w != d2d_width || h != d2d_height) && !d2d_fs) { - hr = d2d_target->Resize(D2D1::SizeU(w, h)); + D2D1_SIZE_U size = { .width = w, .height = h }; + hr = ID2D1HwndRenderTarget_Resize(d2d_target, &size); if (SUCCEEDED(hr)) { @@ -189,17 +189,40 @@ d2d_blit(int x, int y, int y1, int y2, int w, int h) /* Create a bitmap to store intermediate data */ if (d2d_buffer == NULL) { if (SUCCEEDED(hr)) { - hr = d2d_target->CreateBitmap( - D2D1::SizeU(render_buffer->w, render_buffer->h), - D2D1::BitmapProperties(D2D1::PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_IGNORE)), + D2D1_SIZE_U size = { + .width = render_buffer->w, + .height = render_buffer->h }; + + D2D1_BITMAP_PROPERTIES bitmap_props = { + .pixelFormat = { + .format = DXGI_FORMAT_B8G8R8A8_UNORM, + .alphaMode = D2D1_ALPHA_MODE_IGNORE + }, + .dpiX = 96.0f, + .dpiY = 96.0f + }; + + hr = ID2D1HwndRenderTarget_CreateBitmap( + d2d_target, + size, + NULL, + 0, + &bitmap_props, &d2d_buffer); } } /* Copy data from render_buffer */ if (SUCCEEDED(hr)) { - rectU = D2D1::RectU(x, y + y1, x + w, y + y2); - hr = d2d_buffer->CopyFromMemory( + D2D1_RECT_U rectU = { + .left = x, + .top = y + y1, + .right = x + w, + .bottom = y + y2 + }; + + hr = ID2D1Bitmap_CopyFromMemory( + d2d_buffer, &rectU, &(render_buffer->line[y + y1][x]), render_buffer->w << 2); @@ -209,23 +232,53 @@ d2d_blit(int x, int y, int y1, int y2, int w, int h) /* Draw! */ if (SUCCEEDED(hr)) { - d2d_target->BeginDraw(); + D2D1_RECT_F destRect; + ID2D1HwndRenderTarget_BeginDraw(d2d_target); if (d2d_fs) { - d2d_target->Clear( - D2D1::ColorF(D2D1::ColorF::Black)); + float fs_x = 0, fs_y = 0, fs_w = 0, fs_h = 0; + + D2D1_COLOR_F black = { + .r = 0.0, .g = 0.0, .b = 0.0, .a = 1.0 }; + + ID2D1HwndRenderTarget_Clear( + d2d_target, + &black + ); d2d_stretch(&fs_w, &fs_h, &fs_x, &fs_y); + + destRect = (D2D1_RECT_F) { + .left = fs_x, + .top = fs_y, + .right = fs_x + fs_w, + .bottom = fs_y + fs_h + }; + } else { + destRect = (D2D1_RECT_F) { + .left = 0, + .top = 0, + .right = w, + .bottom = h + }; } - d2d_target->DrawBitmap( + D2D1_RECT_F srcRect = { + .left = x, + .top = y, + .right = x + w, + .bottom = y + h + }; + + ID2D1HwndRenderTarget_DrawBitmap( + d2d_target, d2d_buffer, - d2d_fs ? D2D1::RectF(fs_x, fs_y, fs_x + fs_w, fs_y + fs_h) : D2D1::RectF(0, 0, w, h), + &destRect, 1.0f, D2D1_BITMAP_INTERPOLATION_MODE_LINEAR, - D2D1::RectF(x, y, x + w, y + h)); + &srcRect); - hr = d2d_target->EndDraw(); + hr = ID2D1HwndRenderTarget_EndDraw(d2d_target, NULL, NULL); } if (FAILED(hr)) @@ -248,19 +301,19 @@ d2d_close(void) if (d2d_buffer) { - d2d_buffer->Release(); + ID2D1Bitmap_Release(d2d_buffer); d2d_buffer = NULL; } if (d2d_target) { - d2d_target->Release(); + ID2D1HwndRenderTarget_Release(d2d_target); d2d_target = NULL; } if (d2d_factory) { - d2d_factory->Release(); + ID2D1Factory_Release(d2d_factory); d2d_factory = NULL; } @@ -286,7 +339,6 @@ d2d_init_common(int fs) { HRESULT hr = S_OK; WCHAR title[200]; - D2D1_HWND_RENDER_TARGET_PROPERTIES props; d2d_log("Direct2D: d2d_init_common(fs=%d)\n", fs); @@ -319,30 +371,43 @@ d2d_init_common(int fs) plat_set_input(d2d_hwnd); SetFocus(d2d_hwnd); - SetWindowPos(d2d_hwnd, HWND_TOPMOST, 0, 0, d2d_screen_width, d2d_screen_height, SWP_SHOWWINDOW); + SetWindowPos( + d2d_hwnd, HWND_TOPMOST, + 0, 0, d2d_screen_width, d2d_screen_height, + SWP_SHOWWINDOW); } - hr = D2D1_CreateFactory(D2D1_FACTORY_TYPE_MULTI_THREADED, __uuidof(ID2D1Factory), - NULL, reinterpret_cast (&d2d_factory)); - - if (fs) - { - props = D2D1::HwndRenderTargetProperties(d2d_hwnd, - D2D1::SizeU(d2d_screen_width, d2d_screen_height)); - } - else - { - // HwndRenderTarget will get resized appropriately by d2d_blit, - // so it's fine to let D2D imply size of 0x0 for now - props = D2D1::HwndRenderTargetProperties(hwndRender); - } + hr = D2D1_CreateFactory( + D2D1_FACTORY_TYPE_MULTI_THREADED, + &IID_ID2D1Factory, NULL, (void **) &d2d_factory); if (SUCCEEDED(hr)) { - hr = d2d_factory->CreateHwndRenderTarget( - D2D1::RenderTargetProperties(), - props, - &d2d_target); + D2D1_HWND_RENDER_TARGET_PROPERTIES hwnd_props; + + if (fs) + { + hwnd_props = (D2D1_HWND_RENDER_TARGET_PROPERTIES) { + .hwnd = d2d_hwnd, + .pixelSize = { + .width = d2d_screen_width, + .height = d2d_screen_height + } + }; + } + else + { + // HwndRenderTarget will get resized appropriately by d2d_blit, + // so it's fine to let D2D imply size of 0x0 for now + hwnd_props = (D2D1_HWND_RENDER_TARGET_PROPERTIES) { + .hwnd = hwndRender + }; + } + + D2D1_RENDER_TARGET_PROPERTIES target_props = { 0 }; + + hr = ID2D1Factory_CreateHwndRenderTarget( + d2d_factory, &target_props, &hwnd_props, &d2d_target); } if (SUCCEEDED(hr)) diff --git a/src/win/win_d2d.h b/src/win/win_d2d.h index 0933d9e34..cc3fe4881 100644 --- a/src/win/win_d2d.h +++ b/src/win/win_d2d.h @@ -8,7 +8,7 @@ * * Definitions for the Direct2D rendering module. * - * Version: @(#)win_d2d.h 1.0.1 2019/10/12 + * Version: @(#)win_d2d.h 1.0.2 2019/12/13 * * Authors: David Hrdlička, * @@ -17,19 +17,10 @@ #ifndef WIN_D2D_H # define WIN_D2D_H -#ifdef __cplusplus -extern "C" { -#endif - extern void d2d_close(void); extern int d2d_init(HWND h); extern int d2d_init_fs(HWND h); extern int d2d_pause(void); extern void d2d_enable(int enable); -#ifdef __cplusplus -} -#endif - - #endif /*WIN_D2D_H*/ \ No newline at end of file