Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/wined3d/stateblock.c | 38 ++++++++++++++++++++++++++++++++++++++ dlls/wined3d/wined3d.spec | 1 + include/wine/wined3d.h | 2 ++ 3 files changed, 41 insertions(+)
diff --git a/dlls/wined3d/stateblock.c b/dlls/wined3d/stateblock.c index 933ad46a93d..bf1e577f85c 100644 --- a/dlls/wined3d/stateblock.c +++ b/dlls/wined3d/stateblock.c @@ -1640,6 +1640,44 @@ HRESULT CDECL wined3d_stateblock_set_stream_source_freq(struct wined3d_statebloc stateblock->changed.streamFreq |= 1u << stream_idx; return WINED3D_OK; } +HRESULT CDECL wined3d_stateblock_set_light(struct wined3d_stateblock *stateblock, + UINT light_idx, const struct wined3d_light *light) +{ + struct wined3d_light_info *object = NULL; + + TRACE("stateblock %p, light_idx %u, light %p.\n", stateblock, light_idx, light); + + /* Check the parameter range. Need for speed most wanted sets junk lights + * which confuse the GL driver. */ + if (!light) + return WINED3DERR_INVALIDCALL; + + switch (light->type) + { + case WINED3D_LIGHT_POINT: + case WINED3D_LIGHT_SPOT: + case WINED3D_LIGHT_GLSPOT: + /* Incorrect attenuation values can cause the gl driver to crash. + * Happens with Need for speed most wanted. */ + if (light->attenuation0 < 0.0f || light->attenuation1 < 0.0f || light->attenuation2 < 0.0f) + { + WARN("Attenuation is negative, returning WINED3DERR_INVALIDCALL.\n"); + return WINED3DERR_INVALIDCALL; + } + break; + + case WINED3D_LIGHT_DIRECTIONAL: + case WINED3D_LIGHT_PARALLELPOINT: + /* Ignores attenuation */ + break; + + default: + WARN("Light type out of range, returning WINED3DERR_INVALIDCALL.\n"); + return WINED3DERR_INVALIDCALL; + } + + return wined3d_light_state_set_light(&stateblock->stateblock_state.light_state, light_idx, light, &object); +}
static void init_default_render_states(DWORD rs[WINEHIGHEST_RENDER_STATE + 1], const struct wined3d_d3d_info *d3d_info) { diff --git a/dlls/wined3d/wined3d.spec b/dlls/wined3d/wined3d.spec index a4caebe7185..8591aa51648 100644 --- a/dlls/wined3d/wined3d.spec +++ b/dlls/wined3d/wined3d.spec @@ -267,6 +267,7 @@ @ cdecl wined3d_stateblock_set_blend_factor(ptr ptr) @ cdecl wined3d_stateblock_set_clip_plane(ptr long ptr) @ cdecl wined3d_stateblock_set_index_buffer(ptr ptr long) +@ cdecl wined3d_stateblock_set_light(ptr long ptr) @ cdecl wined3d_stateblock_set_material(ptr ptr) @ cdecl wined3d_stateblock_set_pixel_shader(ptr ptr) @ cdecl wined3d_stateblock_set_ps_consts_b(ptr long long ptr) diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h index a05305f4d6c..33f668f9347 100644 --- a/include/wine/wined3d.h +++ b/include/wine/wined3d.h @@ -2675,6 +2675,8 @@ HRESULT __cdecl wined3d_stateblock_set_clip_plane(struct wined3d_stateblock *sta UINT plane_idx, const struct wined3d_vec4 *plane); void __cdecl wined3d_stateblock_set_index_buffer(struct wined3d_stateblock *stateblock, struct wined3d_buffer *index_buffer, enum wined3d_format_id format_id); +HRESULT __cdecl wined3d_stateblock_set_light(struct wined3d_stateblock *stateblock, + UINT light_idx, const struct wined3d_light *light); void __cdecl wined3d_stateblock_set_material(struct wined3d_stateblock *stateblock, const struct wined3d_material *material); void __cdecl wined3d_stateblock_set_pixel_shader(struct wined3d_stateblock *stateblock, struct wined3d_shader *shader); HRESULT __cdecl wined3d_stateblock_set_ps_consts_b(struct wined3d_stateblock *stateblock,