Commit 87a0edaf authored by Paul Gofman's avatar Paul Gofman Committed by Alexandre Julliard

ddraw: Factor out viewport_alloc_active_light_index() function.

parent 672ce5c7
......@@ -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,
......@@ -445,7 +447,7 @@ struct d3d_light
D3DLIGHT2 light;
D3DLIGHT7 light7;
DWORD dwLightIndex;
DWORD active_light_index;
struct list entry;
};
......@@ -499,7 +501,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;
......
......@@ -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)
......
......@@ -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();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment