Signed-off-by: Paul Gofman gofmanp@gmail.com --- dlls/ddraw/ddraw_private.h | 6 ++-- dlls/ddraw/light.c | 6 ++-- dlls/ddraw/viewport.c | 66 ++++++++++++++++++++++++-------------- 3 files changed, 49 insertions(+), 29 deletions(-)
diff --git a/dlls/ddraw/ddraw_private.h b/dlls/ddraw/ddraw_private.h index a5fce2a15e..22910d7cc4 100644 --- a/dlls/ddraw/ddraw_private.h +++ b/dlls/ddraw/ddraw_private.h @@ -66,6 +66,8 @@ struct FvfToDecl | WINED3D_LEGACY_UNBOUND_RESOURCE_COLOR | WINED3D_NO_PRIMITIVE_RESTART \ | WINED3D_LEGACY_CUBEMAP_FILTERING)
+#define DDRAW_MAX_ACTIVE_LIGHTS 8 + enum ddraw_device_state { DDRAW_DEVICE_STATE_OK, @@ -446,7 +448,7 @@ struct d3d_light D3DLIGHT2 light; D3DLIGHT7 light7;
- DWORD dwLightIndex; + DWORD active_light_index;
struct list entry; }; @@ -500,7 +502,7 @@ struct d3d_viewport /* If this viewport is active for one device, put the device here */ struct d3d_device *active_device;
- DWORD num_lights; + DWORD active_lights_count; DWORD map_lights;
enum ddraw_viewport_version version; diff --git a/dlls/ddraw/light.c b/dlls/ddraw/light.c index c6513ffe8a..a86f046b74 100644 --- a/dlls/ddraw/light.c +++ b/dlls/ddraw/light.c @@ -39,7 +39,7 @@ static void light_update(struct d3d_light *light) if (!light->active_viewport || !light->active_viewport->active_device) return; device = light->active_viewport->active_device;
- IDirect3DDevice7_SetLight(&device->IDirect3DDevice7_iface, light->dwLightIndex, &light->light7); + IDirect3DDevice7_SetLight(&device->IDirect3DDevice7_iface, light->active_light_index, &light->light7); }
/***************************************************************************** @@ -61,7 +61,7 @@ void light_activate(struct d3d_light *light)
light_update(light); if (light->light.dwFlags & D3DLIGHT_ACTIVE) - IDirect3DDevice7_LightEnable(&device->IDirect3DDevice7_iface, light->dwLightIndex, TRUE); + IDirect3DDevice7_LightEnable(&device->IDirect3DDevice7_iface, light->active_light_index, TRUE); }
/***************************************************************************** @@ -83,7 +83,7 @@ void light_deactivate(struct d3d_light *light)
device = light->active_viewport->active_device; if (light->light.dwFlags & D3DLIGHT_ACTIVE) - IDirect3DDevice7_LightEnable(&device->IDirect3DDevice7_iface, light->dwLightIndex, FALSE); + IDirect3DDevice7_LightEnable(&device->IDirect3DDevice7_iface, light->active_light_index, FALSE); }
static inline struct d3d_light *impl_from_IDirect3DLight(IDirect3DLight *iface) diff --git a/dlls/ddraw/viewport.c b/dlls/ddraw/viewport.c index daa5ac8d5a..31724402b3 100644 --- a/dlls/ddraw/viewport.c +++ b/dlls/ddraw/viewport.c @@ -122,6 +122,34 @@ void viewport_deactivate(struct d3d_viewport *viewport) } }
+static void viewport_alloc_active_light_index(struct d3d_light *light) +{ + struct d3d_viewport *vp = light->active_viewport; + unsigned int i; + DWORD map; + + TRACE("vp %p, light %p, index %u, active_lights_count %u.\n", + vp, light, light->active_light_index, vp->active_lights_count); + + if (light->active_light_index) + return; + + if (vp->active_lights_count >= DDRAW_MAX_ACTIVE_LIGHTS) + return; + + map = vp->map_lights; + + i = 0; + while (map & 1) + { + map >>= 1; + ++i; + } + light->active_light_index = i + 1; + ++vp->active_lights_count; + vp->map_lights |= 1u << i; +} + /***************************************************************************** * _dump_D3DVIEWPORT, _dump_D3DVIEWPORT2 * @@ -753,23 +781,15 @@ static HRESULT WINAPI d3d_viewport_Clear(IDirect3DViewport3 *iface, * DDERR_INVALIDPARAMS if there are 8 lights or more * *****************************************************************************/ -static HRESULT WINAPI d3d_viewport_AddLight(IDirect3DViewport3 *iface, IDirect3DLight *lpDirect3DLight) +static HRESULT WINAPI d3d_viewport_AddLight(IDirect3DViewport3 *viewport, IDirect3DLight *light) { - struct d3d_viewport *This = impl_from_IDirect3DViewport3(iface); - struct d3d_light *light_impl = unsafe_impl_from_IDirect3DLight(lpDirect3DLight); - DWORD i = 0; - DWORD map = This->map_lights; + struct d3d_light *light_impl = unsafe_impl_from_IDirect3DLight(light); + struct d3d_viewport *vp = impl_from_IDirect3DViewport3(viewport);
- TRACE("iface %p, light %p.\n", iface, lpDirect3DLight); + TRACE("viewport %p, light %p.\n", viewport, light);
wined3d_mutex_lock();
- if (This->num_lights >= 8) - { - wined3d_mutex_unlock(); - return DDERR_INVALIDPARAMS; - } - if (light_impl->active_viewport) { wined3d_mutex_unlock(); @@ -777,22 +797,20 @@ static HRESULT WINAPI d3d_viewport_AddLight(IDirect3DViewport3 *iface, IDirect3D return D3DERR_LIGHTHASVIEWPORT; }
- /* Find a light number and update both light and viewports objects accordingly */ - while (map & 1) + light_impl->active_viewport = vp; + viewport_alloc_active_light_index(light_impl); + if (!light_impl->active_light_index) { - map >>= 1; - ++i; + light_impl->active_viewport = NULL; + wined3d_mutex_unlock(); + return DDERR_INVALIDPARAMS; } - light_impl->dwLightIndex = i; - This->num_lights++; - This->map_lights |= 1<<i;
/* Add the light in the 'linked' chain */ - list_add_head(&This->light_list, &light_impl->entry); - IDirect3DLight_AddRef(lpDirect3DLight); + list_add_head(&vp->light_list, &light_impl->entry); + IDirect3DLight_AddRef(light);
/* Attach the light to the viewport */ - light_impl->active_viewport = This; light_activate(light_impl);
wined3d_mutex_unlock(); @@ -833,8 +851,8 @@ static HRESULT WINAPI d3d_viewport_DeleteLight(IDirect3DViewport3 *iface, IDirec list_remove(&l->entry); l->active_viewport = NULL; IDirect3DLight_Release(lpDirect3DLight); - --viewport->num_lights; - viewport->map_lights &= ~(1 << l->dwLightIndex); + --viewport->active_lights_count; + viewport->map_lights &= ~(1 << l->active_light_index);
wined3d_mutex_unlock();