Needed by https://store.steampowered.com/app/1138210/Esperia__Uprising_of_the_Scarlet_... demo (and presumably the full game too); without this, it throws a message box saying No Interface | 1 | 88990028 on first entry to any combat (the 1 varies depending on which specific effect is unimplemented), then segfaults if any character gets a critical hit (those are prefixed with a bar showing the character's eyes).
Even with these stubs, the game looks glitched when getting a crit, but better ugly than segfault.
The game also needs Color Matrix, Gaussian Blur and Flood effects relative to Proton 10, but those three were already stubbed in Wine 10.n.
-- v2: d2d1: Add Saturation effect stub d2d1: Add Hue Rotation effect stub d2d1: Add Directional Blur effect stub d2d1: Add Brightness effect stub d2d1: Add Blend effect stub
From: Alfred Agrell floating@muncher.se
--- dlls/d2d1/effect.c | 33 ++++++++++++++++++++++++++++++++ dlls/d2d1/tests/d2d1.c | 42 +++++++++++++++++++++++++++++++++++++++++ include/d2d1effects.idl | 6 ++++++ 3 files changed, 81 insertions(+)
diff --git a/dlls/d2d1/effect.c b/dlls/d2d1/effect.c index 003fdb02e5d..8bac19f8d7c 100644 --- a/dlls/d2d1/effect.c +++ b/dlls/d2d1/effect.c @@ -1570,6 +1570,38 @@ static HRESULT __stdcall arithmetic_composite_factory(IUnknown **effect) return d2d_effect_create_impl(effect, &properties, sizeof(properties)); }
+static const WCHAR blend_description[] = +L"<?xml version='1.0'?> \ + <Effect> \ + <Property name='DisplayName' type='string' value='Blend'/> \ + <Property name='Author' type='string' value='The Wine Project'/> \ + <Property name='Category' type='string' value='Stub'/> \ + <Property name='Description' type='string' value='Blend'/> \ + <Inputs minimum='2' maximum='2' > \ + <Input name='Source1'/> \ + <Input name='Source2'/> \ + </Inputs> \ + <Property name='Mode' type='enum' /> \ + </Effect>"; + +struct blend_properties +{ + D2D1_BLEND_MODE mode; +}; + +EFFECT_PROPERTY_RW(blend, mode, ENUM) + +static const D2D1_PROPERTY_BINDING blend_bindings[] = +{ + { L"Mode", BINDING_RW(blend, mode) }, +}; + +static HRESULT __stdcall blend_factory(IUnknown **effect) +{ + static const struct blend_properties properties = {}; + return d2d_effect_create_impl(effect, &properties, sizeof(properties)); +} + void d2d_effects_init_builtins(struct d2d_factory *factory) { static const struct builtin_description @@ -1595,6 +1627,7 @@ void d2d_effects_init_builtins(struct d2d_factory *factory) { &CLSID_D2D1GaussianBlur, X2(gaussian_blur) }, { &CLSID_D2D1PointSpecular, X2(point_specular) }, { &CLSID_D2D1ArithmeticComposite, X2(arithmetic_composite) }, + { &CLSID_D2D1Blend, X2(blend) }, #undef X2 #undef X }; diff --git a/dlls/d2d1/tests/d2d1.c b/dlls/d2d1/tests/d2d1.c index 556d93a970f..716fbb46279 100644 --- a/dlls/d2d1/tests/d2d1.c +++ b/dlls/d2d1/tests/d2d1.c @@ -13986,6 +13986,47 @@ static void test_effect_color_matrix(BOOL d3d11) release_test_context(&ctx); }
+static void test_effect_blend(BOOL d3d11) +{ + static const struct effect_property properties[] = + { + { L"Mode", D2D1_BLEND_PROP_MODE, D2D1_PROPERTY_TYPE_ENUM }, + }; + D2D1_BLEND_MODE mode; + struct d2d1_test_context ctx; + ID2D1DeviceContext *context; + unsigned int count, i; + ID2D1Effect *effect; + WCHAR name[64]; + HRESULT hr; + + if (!init_test_context(&ctx, d3d11)) + return; + + context = ctx.context; + + hr = ID2D1DeviceContext_CreateEffect(context, &CLSID_D2D1Blend, &effect); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + + check_system_properties(effect); + + count = ID2D1Effect_GetPropertyCount(effect); + ok(count == 1, "Got unexpected property count %u.\n", count); + + for (i = 0; i < ARRAY_SIZE(properties); ++i) + { + hr = ID2D1Effect_GetPropertyName(effect, properties[i].index, name, 64); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + ok(!wcscmp(name, properties[i].name), "Unexpected name %s.\n", wine_dbgstr_w(name)); + } + + mode = effect_get_enum_prop(effect, D2D1_BLEND_PROP_MODE); + ok(mode == D2D1_BLEND_MODE_MULTIPLY, "got %d.\n", mode); + + ID2D1Effect_Release(effect); + release_test_context(&ctx); +} + static void test_registered_effects(BOOL d3d11) { UINT32 ret, count, count2, count3; @@ -17368,6 +17409,7 @@ START_TEST(d2d1) queue_d3d10_test(test_effect_composite); queue_d3d10_test(test_effect_color_matrix); queue_test(test_effect_flood); + queue_d3d10_test(test_effect_blend); queue_test(test_transform_graph); queue_test(test_offset_transform); queue_test(test_blend_transform); diff --git a/include/d2d1effects.idl b/include/d2d1effects.idl index 5534314468e..e65520ba9f1 100644 --- a/include/d2d1effects.idl +++ b/include/d2d1effects.idl @@ -234,3 +234,9 @@ typedef enum D2D1_COLORMATRIX_ALPHA_MODE D2D1_COLORMATRIX_ALPHA_MODE_STRAIGHT = 2, D2D1_COLORMATRIX_ALPHA_MODE_FORCE_DWORD = 0xffffffff } D2D1_COLORMATRIX_ALPHA_MODE; + +typedef enum D2D1_BLEND_PROP +{ + D2D1_BLEND_PROP_MODE = 0, + D2D1_BLEND_PROP_FORCE_DWORD = 0xffffffff +} D2D1_BLEND_PROP;
From: Alfred Agrell floating@muncher.se
--- dlls/d2d1/effect.c | 39 +++++++++++++++++++++++++++++++++ dlls/d2d1/tests/d2d1.c | 48 ++++++++++++++++++++++++++++++++++++++++- include/d2d1effects.idl | 7 ++++++ 3 files changed, 93 insertions(+), 1 deletion(-)
diff --git a/dlls/d2d1/effect.c b/dlls/d2d1/effect.c index 8bac19f8d7c..e1b9fb5da4f 100644 --- a/dlls/d2d1/effect.c +++ b/dlls/d2d1/effect.c @@ -1602,6 +1602,44 @@ static HRESULT __stdcall blend_factory(IUnknown **effect) return d2d_effect_create_impl(effect, &properties, sizeof(properties)); }
+static const WCHAR brightness_description[] = +L"<?xml version='1.0'?> \ + <Effect> \ + <Property name='DisplayName' type='string' value='Brightness'/> \ + <Property name='Author' type='string' value='The Wine Project'/> \ + <Property name='Category' type='string' value='Stub'/> \ + <Property name='Description' type='string' value='Brightness'/> \ + <Inputs> \ + <Input name='Source'/> \ + </Inputs> \ + <Property name='WhitePoint' type='vector2' /> \ + <Property name='BlackPoint' type='vector2' /> \ + </Effect>"; + +struct brightness_properties +{ + D2D_VECTOR_2F white_point; + D2D_VECTOR_2F black_point; +}; + +EFFECT_PROPERTY_RW(brightness, white_point, VECTOR2) +EFFECT_PROPERTY_RW(brightness, black_point, VECTOR2) + +static const D2D1_PROPERTY_BINDING brightness_bindings[] = +{ + { L"WhitePoint", BINDING_RW(brightness, white_point) }, + { L"BlackPoint", BINDING_RW(brightness, black_point) }, +}; + +static HRESULT __stdcall brightness_factory(IUnknown **effect) +{ + static const struct brightness_properties properties = + { + .white_point = { 1.0f, 1.0f }, + }; + return d2d_effect_create_impl(effect, &properties, sizeof(properties)); +} + void d2d_effects_init_builtins(struct d2d_factory *factory) { static const struct builtin_description @@ -1628,6 +1666,7 @@ void d2d_effects_init_builtins(struct d2d_factory *factory) { &CLSID_D2D1PointSpecular, X2(point_specular) }, { &CLSID_D2D1ArithmeticComposite, X2(arithmetic_composite) }, { &CLSID_D2D1Blend, X2(blend) }, + { &CLSID_D2D1Brightness, X2(brightness) }, #undef X2 #undef X }; diff --git a/dlls/d2d1/tests/d2d1.c b/dlls/d2d1/tests/d2d1.c index 716fbb46279..ae571dc24b1 100644 --- a/dlls/d2d1/tests/d2d1.c +++ b/dlls/d2d1/tests/d2d1.c @@ -13793,7 +13793,7 @@ static void test_effect_3d_perspective_transform(BOOL d3d11) ok(f == 1000.0f, "Unexpected value %.8e.\n", f);
vec2 = effect_get_vec2_prop(effect, D2D1_3DPERSPECTIVETRANSFORM_PROP_PERSPECTIVE_ORIGIN); - ok(vec2.x == 0.0f && vec2.y == 0.0f, "Unexpected value {%.8e,%.8e}.\n", vec2.x, vec2.y); + ok(vec2.x == 1.0f && vec2.y == 1.0f, "Unexpected value {%.8e,%.8e}.\n", vec2.x, vec2.y);
vec3 = effect_get_vec3_prop(effect, D2D1_3DPERSPECTIVETRANSFORM_PROP_LOCAL_OFFSET); ok(vec3.x == 0.0f && vec3.y == 0.0f && vec3.z == 0.0f, @@ -14027,6 +14027,51 @@ static void test_effect_blend(BOOL d3d11) release_test_context(&ctx); }
+static void test_effect_brightness(BOOL d3d11) +{ + static const struct effect_property properties[] = + { + { L"WhitePoint", D2D1_BRIGHTNESS_PROP_WHITE_POINT, D2D1_PROPERTY_TYPE_VECTOR2 }, + { L"BlackPoint", D2D1_BRIGHTNESS_PROP_BLACK_POINT, D2D1_PROPERTY_TYPE_VECTOR2 }, + }; + struct d2d1_test_context ctx; + ID2D1DeviceContext *context; + unsigned int count, i; + ID2D1Effect *effect; + D2D_VECTOR_2F vec; + WCHAR name[64]; + HRESULT hr; + + if (!init_test_context(&ctx, d3d11)) + return; + + context = ctx.context; + + hr = ID2D1DeviceContext_CreateEffect(context, &CLSID_D2D1Brightness, &effect); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + + check_system_properties(effect); + + count = ID2D1Effect_GetPropertyCount(effect); + ok(count == 2, "Got unexpected property count %u.\n", count); + + for (i = 0; i < ARRAY_SIZE(properties); ++i) + { + hr = ID2D1Effect_GetPropertyName(effect, properties[i].index, name, 64); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + ok(!wcscmp(name, properties[i].name), "Unexpected name %s.\n", wine_dbgstr_w(name)); + } + + vec = effect_get_vec2_prop(effect, D2D1_BRIGHTNESS_PROP_WHITE_POINT); + ok(vec.x == 1.0f && vec.y == 1.0f, "Unexpected value {%.8e,%.8e}.\n", vec.x, vec.y); + + vec = effect_get_vec2_prop(effect, D2D1_BRIGHTNESS_PROP_BLACK_POINT); + ok(vec.x == 0.0f && vec.y == 0.0f, "Unexpected value {%.8e,%.8e}.\n", vec.x, vec.y); + + ID2D1Effect_Release(effect); + release_test_context(&ctx); +} + static void test_registered_effects(BOOL d3d11) { UINT32 ret, count, count2, count3; @@ -17410,6 +17455,7 @@ START_TEST(d2d1) queue_d3d10_test(test_effect_color_matrix); queue_test(test_effect_flood); queue_d3d10_test(test_effect_blend); + queue_d3d10_test(test_effect_brightness); queue_test(test_transform_graph); queue_test(test_offset_transform); queue_test(test_blend_transform); diff --git a/include/d2d1effects.idl b/include/d2d1effects.idl index e65520ba9f1..76ac79b0724 100644 --- a/include/d2d1effects.idl +++ b/include/d2d1effects.idl @@ -240,3 +240,10 @@ typedef enum D2D1_BLEND_PROP D2D1_BLEND_PROP_MODE = 0, D2D1_BLEND_PROP_FORCE_DWORD = 0xffffffff } D2D1_BLEND_PROP; + +typedef enum D2D1_BRIGHTNESS_PROP +{ + D2D1_BRIGHTNESS_PROP_WHITE_POINT = 0, + D2D1_BRIGHTNESS_PROP_BLACK_POINT = 1, + D2D1_BRIGHTNESS_PROP_FORCE_DWORD = 0xffffffff +} D2D1_BRIGHTNESS_PROP;
From: Alfred Agrell floating@muncher.se
--- dlls/d2d1/effect.c | 48 +++++++++++++++++++++++++++++++++++ dlls/d2d1/tests/d2d1.c | 55 +++++++++++++++++++++++++++++++++++++++++ include/d2d1effects.idl | 17 +++++++++++++ 3 files changed, 120 insertions(+)
diff --git a/dlls/d2d1/effect.c b/dlls/d2d1/effect.c index e1b9fb5da4f..429ab4a0716 100644 --- a/dlls/d2d1/effect.c +++ b/dlls/d2d1/effect.c @@ -1640,6 +1640,53 @@ static HRESULT __stdcall brightness_factory(IUnknown **effect) return d2d_effect_create_impl(effect, &properties, sizeof(properties)); }
+static const WCHAR directional_blur_description[] = +L"<?xml version='1.0'?> \ + <Effect> \ + <Property name='DisplayName' type='string' value='Directional Blur'/> \ + <Property name='Author' type='string' value='The Wine Project'/> \ + <Property name='Category' type='string' value='Stub'/> \ + <Property name='Description' type='string' value='Directional Blur'/> \ + <Inputs> \ + <Input name='Source'/> \ + </Inputs> \ + <Property name='StandardDeviation' type='float' /> \ + <Property name='Angle' type='float' /> \ + <Property name='Optimization' type='enum' /> \ + <Property name='BorderMode' type='enum' /> \ + </Effect>"; + +struct directional_blur_properties +{ + float standard_deviation; + float angle; + D2D1_DIRECTIONALBLUR_OPTIMIZATION optimization; + D2D1_BORDER_MODE border_mode; +}; + +EFFECT_PROPERTY_RW(directional_blur, standard_deviation, FLOAT) +EFFECT_PROPERTY_RW(directional_blur, angle, FLOAT) +EFFECT_PROPERTY_RW(directional_blur, optimization, ENUM) +EFFECT_PROPERTY_RW(directional_blur, border_mode, ENUM) + +static const D2D1_PROPERTY_BINDING directional_blur_bindings[] = +{ + { L"StandardDeviation", BINDING_RW(directional_blur, standard_deviation) }, + { L"Angle", BINDING_RW(directional_blur, angle) }, + { L"Optimization", BINDING_RW(directional_blur, optimization) }, + { L"BorderMode", BINDING_RW(directional_blur, border_mode) }, +}; + +static HRESULT __stdcall directional_blur_factory(IUnknown **effect) +{ + static const struct directional_blur_properties properties = + { + .standard_deviation = 3.0f, + .optimization = D2D1_DIRECTIONALBLUR_OPTIMIZATION_BALANCED, + }; + return d2d_effect_create_impl(effect, &properties, sizeof(properties)); +} + void d2d_effects_init_builtins(struct d2d_factory *factory) { static const struct builtin_description @@ -1667,6 +1714,7 @@ void d2d_effects_init_builtins(struct d2d_factory *factory) { &CLSID_D2D1ArithmeticComposite, X2(arithmetic_composite) }, { &CLSID_D2D1Blend, X2(blend) }, { &CLSID_D2D1Brightness, X2(brightness) }, + { &CLSID_D2D1DirectionalBlur, X2(directional_blur) }, #undef X2 #undef X }; diff --git a/dlls/d2d1/tests/d2d1.c b/dlls/d2d1/tests/d2d1.c index ae571dc24b1..ed186116f85 100644 --- a/dlls/d2d1/tests/d2d1.c +++ b/dlls/d2d1/tests/d2d1.c @@ -14072,6 +14072,60 @@ static void test_effect_brightness(BOOL d3d11) release_test_context(&ctx); }
+static void test_effect_directional_blur(BOOL d3d11) +{ + static const struct effect_property properties[] = + { + { L"StandardDeviation", D2D1_DIRECTIONALBLUR_PROP_STANDARD_DEVIATION, D2D1_PROPERTY_TYPE_FLOAT }, + { L"Angle", D2D1_DIRECTIONALBLUR_PROP_ANGLE, D2D1_PROPERTY_TYPE_FLOAT }, + { L"Optimization", D2D1_DIRECTIONALBLUR_PROP_OPTIMIZATION, D2D1_PROPERTY_TYPE_ENUM }, + { L"BorderMode", D2D1_DIRECTIONALBLUR_PROP_BORDER_MODE, D2D1_PROPERTY_TYPE_ENUM }, + }; + struct d2d1_test_context ctx; + ID2D1DeviceContext *context; + unsigned int count, i; + ID2D1Effect *effect; + WCHAR name[64]; + HRESULT hr; + UINT32 v; + float f; + + if (!init_test_context(&ctx, d3d11)) + return; + + context = ctx.context; + + hr = ID2D1DeviceContext_CreateEffect(context, &CLSID_D2D1DirectionalBlur, &effect); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + + check_system_properties(effect); + + count = ID2D1Effect_GetPropertyCount(effect); + ok(count == 4, "Got unexpected property count %u.\n", count); + + for (i = 0; i < ARRAY_SIZE(properties); ++i) + { + hr = ID2D1Effect_GetPropertyName(effect, properties[i].index, name, 64); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + ok(!wcscmp(name, properties[i].name), "Unexpected name %s.\n", wine_dbgstr_w(name)); + } + + f = effect_get_float_prop(effect, D2D1_DIRECTIONALBLUR_PROP_STANDARD_DEVIATION); + ok(f == 3.0f, "got %f.\n", f); + + f = effect_get_float_prop(effect, D2D1_DIRECTIONALBLUR_PROP_ANGLE); + ok(f == 0.0f, "got %f.\n", f); + + v = effect_get_enum_prop(effect, D2D1_DIRECTIONALBLUR_PROP_OPTIMIZATION); + ok(v == D2D1_DIRECTIONALBLUR_OPTIMIZATION_BALANCED, "Unexpected value %#x.\n", v); + + v = effect_get_enum_prop(effect, D2D1_DIRECTIONALBLUR_PROP_BORDER_MODE); + ok(v == D2D1_BORDER_MODE_SOFT, "Unexpected value %#x.\n", v); + + ID2D1Effect_Release(effect); + release_test_context(&ctx); +} + static void test_registered_effects(BOOL d3d11) { UINT32 ret, count, count2, count3; @@ -17456,6 +17510,7 @@ START_TEST(d2d1) queue_test(test_effect_flood); queue_d3d10_test(test_effect_blend); queue_d3d10_test(test_effect_brightness); + queue_d3d10_test(test_effect_directional_blur); queue_test(test_transform_graph); queue_test(test_offset_transform); queue_test(test_blend_transform); diff --git a/include/d2d1effects.idl b/include/d2d1effects.idl index 76ac79b0724..ad843a9344d 100644 --- a/include/d2d1effects.idl +++ b/include/d2d1effects.idl @@ -247,3 +247,20 @@ typedef enum D2D1_BRIGHTNESS_PROP D2D1_BRIGHTNESS_PROP_BLACK_POINT = 1, D2D1_BRIGHTNESS_PROP_FORCE_DWORD = 0xffffffff } D2D1_BRIGHTNESS_PROP; + +typedef enum D2D1_DIRECTIONALBLUR_PROP +{ + D2D1_DIRECTIONALBLUR_PROP_STANDARD_DEVIATION = 0, + D2D1_DIRECTIONALBLUR_PROP_ANGLE = 1, + D2D1_DIRECTIONALBLUR_PROP_OPTIMIZATION = 2, + D2D1_DIRECTIONALBLUR_PROP_BORDER_MODE = 3, + D2D1_DIRECTIONALBLUR_PROP_FORCE_DWORD = 0xffffffff +} D2D1_DIRECTIONALBLUR_PROP; + +typedef enum D2D1_DIRECTIONALBLUR_OPTIMIZATION +{ + D2D1_DIRECTIONALBLUR_OPTIMIZATION_SPEED = 0, + D2D1_DIRECTIONALBLUR_OPTIMIZATION_BALANCED = 1, + D2D1_DIRECTIONALBLUR_OPTIMIZATION_QUALITY = 2, + D2D1_DIRECTIONALBLUR_OPTIMIZATION_FORCE_DWORD = 0xffffffff +} D2D1_DIRECTIONALBLUR_OPTIMIZATION;
From: Alfred Agrell floating@muncher.se
--- dlls/d2d1/effect.c | 32 +++++++++++++++++++++++++++++++ dlls/d2d1/tests/d2d1.c | 42 +++++++++++++++++++++++++++++++++++++++++ include/d2d1effects.idl | 6 ++++++ 3 files changed, 80 insertions(+)
diff --git a/dlls/d2d1/effect.c b/dlls/d2d1/effect.c index 429ab4a0716..418dd013293 100644 --- a/dlls/d2d1/effect.c +++ b/dlls/d2d1/effect.c @@ -1687,6 +1687,37 @@ static HRESULT __stdcall directional_blur_factory(IUnknown **effect) return d2d_effect_create_impl(effect, &properties, sizeof(properties)); }
+static const WCHAR hue_rotation_description[] = +L"<?xml version='1.0'?> \ + <Effect> \ + <Property name='DisplayName' type='string' value='Hue Rotation'/> \ + <Property name='Author' type='string' value='The Wine Project'/> \ + <Property name='Category' type='string' value='Stub'/> \ + <Property name='Description' type='string' value='Hue Rotation'/> \ + <Inputs> \ + <Input name='Source'/> \ + </Inputs> \ + <Property name='Angle' type='float' /> \ + </Effect>"; + +struct hue_rotation_properties +{ + float angle; +}; + +EFFECT_PROPERTY_RW(hue_rotation, angle, FLOAT) + +static const D2D1_PROPERTY_BINDING hue_rotation_bindings[] = +{ + { L"Angle", BINDING_RW(hue_rotation, angle) }, +}; + +static HRESULT __stdcall hue_rotation_factory(IUnknown **effect) +{ + static const struct hue_rotation_properties properties = {}; + return d2d_effect_create_impl(effect, &properties, sizeof(properties)); +} + void d2d_effects_init_builtins(struct d2d_factory *factory) { static const struct builtin_description @@ -1715,6 +1746,7 @@ void d2d_effects_init_builtins(struct d2d_factory *factory) { &CLSID_D2D1Blend, X2(blend) }, { &CLSID_D2D1Brightness, X2(brightness) }, { &CLSID_D2D1DirectionalBlur, X2(directional_blur) }, + { &CLSID_D2D1HueRotation, X2(hue_rotation) }, #undef X2 #undef X }; diff --git a/dlls/d2d1/tests/d2d1.c b/dlls/d2d1/tests/d2d1.c index ed186116f85..1a8790eae2a 100644 --- a/dlls/d2d1/tests/d2d1.c +++ b/dlls/d2d1/tests/d2d1.c @@ -14126,6 +14126,47 @@ static void test_effect_directional_blur(BOOL d3d11) release_test_context(&ctx); }
+static void test_effect_hue_rotation(BOOL d3d11) +{ + static const struct effect_property properties[] = + { + { L"Angle", D2D1_HUEROTATION_PROP_ANGLE, D2D1_PROPERTY_TYPE_FLOAT }, + }; + struct d2d1_test_context ctx; + ID2D1DeviceContext *context; + unsigned int count, i; + ID2D1Effect *effect; + WCHAR name[64]; + HRESULT hr; + float f; + + if (!init_test_context(&ctx, d3d11)) + return; + + context = ctx.context; + + hr = ID2D1DeviceContext_CreateEffect(context, &CLSID_D2D1HueRotation, &effect); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + + check_system_properties(effect); + + count = ID2D1Effect_GetPropertyCount(effect); + ok(count == 1, "Got unexpected property count %u.\n", count); + + for (i = 0; i < ARRAY_SIZE(properties); ++i) + { + hr = ID2D1Effect_GetPropertyName(effect, properties[i].index, name, 64); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + ok(!wcscmp(name, properties[i].name), "Unexpected name %s.\n", wine_dbgstr_w(name)); + } + + f = effect_get_float_prop(effect, D2D1_HUEROTATION_PROP_ANGLE); + ok(f == 0.0f, "got %f.\n", f); + + ID2D1Effect_Release(effect); + release_test_context(&ctx); +} + static void test_registered_effects(BOOL d3d11) { UINT32 ret, count, count2, count3; @@ -17511,6 +17552,7 @@ START_TEST(d2d1) queue_d3d10_test(test_effect_blend); queue_d3d10_test(test_effect_brightness); queue_d3d10_test(test_effect_directional_blur); + queue_d3d10_test(test_effect_hue_rotation); queue_test(test_transform_graph); queue_test(test_offset_transform); queue_test(test_blend_transform); diff --git a/include/d2d1effects.idl b/include/d2d1effects.idl index ad843a9344d..93876229138 100644 --- a/include/d2d1effects.idl +++ b/include/d2d1effects.idl @@ -264,3 +264,9 @@ typedef enum D2D1_DIRECTIONALBLUR_OPTIMIZATION D2D1_DIRECTIONALBLUR_OPTIMIZATION_QUALITY = 2, D2D1_DIRECTIONALBLUR_OPTIMIZATION_FORCE_DWORD = 0xffffffff } D2D1_DIRECTIONALBLUR_OPTIMIZATION; + +typedef enum D2D1_HUEROTATION_PROP +{ + D2D1_HUEROTATION_PROP_ANGLE = 0, + D2D1_HUEROTATION_PROP_FORCE_DWORD = 0xffffffff +} D2D1_HUEROTATION_PROP;
From: Alfred Agrell floating@muncher.se
--- dlls/d2d1/effect.c | 35 ++++++++++++++++++++++++++++++++++ dlls/d2d1/tests/d2d1.c | 42 +++++++++++++++++++++++++++++++++++++++++ include/d2d1effects.idl | 6 ++++++ 3 files changed, 83 insertions(+)
diff --git a/dlls/d2d1/effect.c b/dlls/d2d1/effect.c index 418dd013293..891f6fc42e4 100644 --- a/dlls/d2d1/effect.c +++ b/dlls/d2d1/effect.c @@ -1718,6 +1718,40 @@ static HRESULT __stdcall hue_rotation_factory(IUnknown **effect) return d2d_effect_create_impl(effect, &properties, sizeof(properties)); }
+static const WCHAR saturation_description[] = +L"<?xml version='1.0'?> \ + <Effect> \ + <Property name='DisplayName' type='string' value='Saturation'/> \ + <Property name='Author' type='string' value='The Wine Project'/> \ + <Property name='Category' type='string' value='Stub'/> \ + <Property name='Description' type='string' value='Saturation'/> \ + <Inputs> \ + <Input name='Source'/> \ + </Inputs> \ + <Property name='Saturation' type='float' /> \ + </Effect>"; + +struct saturation_properties +{ + float saturation; +}; + +EFFECT_PROPERTY_RW(saturation, saturation, FLOAT) + +static const D2D1_PROPERTY_BINDING saturation_bindings[] = +{ + { L"Saturation", BINDING_RW(saturation, saturation) }, +}; + +static HRESULT __stdcall saturation_factory(IUnknown **effect) +{ + static const struct saturation_properties properties = + { + .saturation = 0.5f, + }; + return d2d_effect_create_impl(effect, &properties, sizeof(properties)); +} + void d2d_effects_init_builtins(struct d2d_factory *factory) { static const struct builtin_description @@ -1747,6 +1781,7 @@ void d2d_effects_init_builtins(struct d2d_factory *factory) { &CLSID_D2D1Brightness, X2(brightness) }, { &CLSID_D2D1DirectionalBlur, X2(directional_blur) }, { &CLSID_D2D1HueRotation, X2(hue_rotation) }, + { &CLSID_D2D1Saturation, X2(saturation) }, #undef X2 #undef X }; diff --git a/dlls/d2d1/tests/d2d1.c b/dlls/d2d1/tests/d2d1.c index 1a8790eae2a..67ac840ff25 100644 --- a/dlls/d2d1/tests/d2d1.c +++ b/dlls/d2d1/tests/d2d1.c @@ -14167,6 +14167,47 @@ static void test_effect_hue_rotation(BOOL d3d11) release_test_context(&ctx); }
+static void test_effect_saturation(BOOL d3d11) +{ + static const struct effect_property properties[] = + { + { L"Saturation", D2D1_SATURATION_PROP_SATURATION, D2D1_PROPERTY_TYPE_FLOAT }, + }; + struct d2d1_test_context ctx; + ID2D1DeviceContext *context; + unsigned int count, i; + ID2D1Effect *effect; + WCHAR name[64]; + HRESULT hr; + float f; + + if (!init_test_context(&ctx, d3d11)) + return; + + context = ctx.context; + + hr = ID2D1DeviceContext_CreateEffect(context, &CLSID_D2D1Saturation, &effect); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + + check_system_properties(effect); + + count = ID2D1Effect_GetPropertyCount(effect); + ok(count == 1, "Got unexpected property count %u.\n", count); + + for (i = 0; i < ARRAY_SIZE(properties); ++i) + { + hr = ID2D1Effect_GetPropertyName(effect, properties[i].index, name, 64); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + ok(!wcscmp(name, properties[i].name), "Unexpected name %s.\n", wine_dbgstr_w(name)); + } + + f = effect_get_float_prop(effect, D2D1_SATURATION_PROP_SATURATION); + ok(f == 0.5f, "got %f.\n", f); + + ID2D1Effect_Release(effect); + release_test_context(&ctx); +} + static void test_registered_effects(BOOL d3d11) { UINT32 ret, count, count2, count3; @@ -17553,6 +17594,7 @@ START_TEST(d2d1) queue_d3d10_test(test_effect_brightness); queue_d3d10_test(test_effect_directional_blur); queue_d3d10_test(test_effect_hue_rotation); + queue_d3d10_test(test_effect_saturation); queue_test(test_transform_graph); queue_test(test_offset_transform); queue_test(test_blend_transform); diff --git a/include/d2d1effects.idl b/include/d2d1effects.idl index 93876229138..cf374bdeb19 100644 --- a/include/d2d1effects.idl +++ b/include/d2d1effects.idl @@ -270,3 +270,9 @@ typedef enum D2D1_HUEROTATION_PROP D2D1_HUEROTATION_PROP_ANGLE = 0, D2D1_HUEROTATION_PROP_FORCE_DWORD = 0xffffffff } D2D1_HUEROTATION_PROP; + +typedef enum D2D1_SATURATION_PROP +{ + D2D1_SATURATION_PROP_SATURATION = 0, + D2D1_SATURATION_PROP_FORCE_DWORD = 0xffffffff +} D2D1_SATURATION_PROP;
On Sat Nov 22 15:38:25 2025 +0000, Alfred Agrell wrote:
changed this line in [version 2 of the diff](/wine/wine/-/merge_requests/9558/diffs?diff_id=226784&start_sha=48bfb68c743b1fc4c185a6bf9856f4163eddb12d#c9ddb70961e28daab0cad64fc4a2b1bf1fd34ca3_1642_1639)
I felt it's clearer to include everything, but if you say otherwise, then so it is.
And yeah, I've got a nasty habit of forgetting code formatting. I keep thinking that once things work, it's done.