ddraw: Use a less offensive handle table implementation for matrices.

This commit is contained in:
Henri Verbeet 2010-07-29 12:56:58 +02:00 committed by Alexandre Julliard
parent 0cb4de4542
commit 941aeade01
3 changed files with 81 additions and 90 deletions

View File

@ -326,7 +326,6 @@ typedef enum
{ {
DDrawHandle_Unknown = 0, DDrawHandle_Unknown = 0,
DDrawHandle_Texture = 1, DDrawHandle_Texture = 1,
DDrawHandle_Matrix = 3,
DDrawHandle_StateBlock = 4 DDrawHandle_StateBlock = 4
} DDrawHandleTypes; } DDrawHandleTypes;
@ -342,6 +341,7 @@ enum ddraw_handle_type
{ {
DDRAW_HANDLE_FREE, DDRAW_HANDLE_FREE,
DDRAW_HANDLE_MATERIAL, DDRAW_HANDLE_MATERIAL,
DDRAW_HANDLE_MATRIX,
}; };
struct ddraw_handle_entry struct ddraw_handle_entry

View File

@ -382,14 +382,6 @@ IDirect3DDeviceImpl_7_Release(IDirect3DDevice7 *iface)
} }
break; break;
case DDrawHandle_Matrix:
{
/* No fixme here because this might happen because of sloppy apps */
WARN("Leftover matrix handle %d, deleting\n", i + 1);
IDirect3DDevice_DeleteMatrix((IDirect3DDevice *)&This->IDirect3DDevice_vtbl, i + 1);
}
break;
case DDrawHandle_StateBlock: case DDrawHandle_StateBlock:
{ {
/* No fixme here because this might happen because of sloppy apps */ /* No fixme here because this might happen because of sloppy apps */
@ -423,6 +415,14 @@ IDirect3DDeviceImpl_7_Release(IDirect3DDevice7 *iface)
break; break;
} }
case DDRAW_HANDLE_MATRIX:
{
/* No FIXME here because this might happen because of sloppy applications. */
WARN("Leftover matrix handle %#x (%p), deleting.\n", i + 1, entry->object);
IDirect3DDevice_DeleteMatrix((IDirect3DDevice *)&This->IDirect3DDevice_vtbl, i + 1);
break;
}
default: default:
FIXME("Handle %#x (%p) has unknown type %#x.\n", i + 1, entry->object, entry->type); FIXME("Handle %#x (%p) has unknown type %#x.\n", i + 1, entry->object, entry->type);
break; break;
@ -1426,6 +1426,8 @@ IDirect3DDeviceImpl_1_CreateMatrix(IDirect3DDevice *iface, D3DMATRIXHANDLE *D3DM
{ {
IDirect3DDeviceImpl *This = device_from_device1(iface); IDirect3DDeviceImpl *This = device_from_device1(iface);
D3DMATRIX *Matrix; D3DMATRIX *Matrix;
DWORD h;
TRACE("(%p)->(%p)\n", This, D3DMatHandle); TRACE("(%p)->(%p)\n", This, D3DMatHandle);
if(!D3DMatHandle) if(!D3DMatHandle)
@ -1439,16 +1441,18 @@ IDirect3DDeviceImpl_1_CreateMatrix(IDirect3DDevice *iface, D3DMATRIXHANDLE *D3DM
} }
EnterCriticalSection(&ddraw_cs); EnterCriticalSection(&ddraw_cs);
*D3DMatHandle = IDirect3DDeviceImpl_CreateHandle(This);
if(!(*D3DMatHandle)) h = ddraw_allocate_handle(&This->handle_table, Matrix, DDRAW_HANDLE_MATRIX);
if (h == DDRAW_INVALID_HANDLE)
{ {
ERR("Failed to create a matrix handle\n"); ERR("Failed to allocate a matrix handle.\n");
HeapFree(GetProcessHeap(), 0, Matrix); HeapFree(GetProcessHeap(), 0, Matrix);
LeaveCriticalSection(&ddraw_cs); LeaveCriticalSection(&ddraw_cs);
return DDERR_OUTOFMEMORY; return DDERR_OUTOFMEMORY;
} }
This->Handles[*D3DMatHandle - 1].ptr = Matrix;
This->Handles[*D3DMatHandle - 1].type = DDrawHandle_Matrix; *D3DMatHandle = h + 1;
TRACE(" returning matrix handle %d\n", *D3DMatHandle); TRACE(" returning matrix handle %d\n", *D3DMatHandle);
LeaveCriticalSection(&ddraw_cs); LeaveCriticalSection(&ddraw_cs);
@ -1479,21 +1483,18 @@ IDirect3DDeviceImpl_1_SetMatrix(IDirect3DDevice *iface,
D3DMATRIX *D3DMatrix) D3DMATRIX *D3DMatrix)
{ {
IDirect3DDeviceImpl *This = device_from_device1(iface); IDirect3DDeviceImpl *This = device_from_device1(iface);
D3DMATRIX *m;
TRACE("(%p)->(%08x,%p)\n", This, D3DMatHandle, D3DMatrix); TRACE("(%p)->(%08x,%p)\n", This, D3DMatHandle, D3DMatrix);
if( (!D3DMatHandle) || (!D3DMatrix) ) if (!D3DMatrix) return DDERR_INVALIDPARAMS;
return DDERR_INVALIDPARAMS;
EnterCriticalSection(&ddraw_cs); EnterCriticalSection(&ddraw_cs);
if(D3DMatHandle > This->numHandles)
m = ddraw_get_object(&This->handle_table, D3DMatHandle - 1, DDRAW_HANDLE_MATRIX);
if (!m)
{ {
ERR("Handle %d out of range\n", D3DMatHandle); WARN("Invalid matrix handle.\n");
LeaveCriticalSection(&ddraw_cs);
return DDERR_INVALIDPARAMS;
}
else if(This->Handles[D3DMatHandle - 1].type != DDrawHandle_Matrix)
{
ERR("Handle %d is not a matrix handle\n", D3DMatHandle);
LeaveCriticalSection(&ddraw_cs); LeaveCriticalSection(&ddraw_cs);
return DDERR_INVALIDPARAMS; return DDERR_INVALIDPARAMS;
} }
@ -1501,7 +1502,7 @@ IDirect3DDeviceImpl_1_SetMatrix(IDirect3DDevice *iface,
if (TRACE_ON(d3d7)) if (TRACE_ON(d3d7))
dump_D3DMATRIX(D3DMatrix); dump_D3DMATRIX(D3DMatrix);
*((D3DMATRIX *) This->Handles[D3DMatHandle - 1].ptr) = *D3DMatrix; *m = *D3DMatrix;
if(This->world == D3DMatHandle) if(This->world == D3DMatHandle)
{ {
@ -1548,29 +1549,23 @@ IDirect3DDeviceImpl_1_GetMatrix(IDirect3DDevice *iface,
D3DMATRIX *D3DMatrix) D3DMATRIX *D3DMatrix)
{ {
IDirect3DDeviceImpl *This = device_from_device1(iface); IDirect3DDeviceImpl *This = device_from_device1(iface);
D3DMATRIX *m;
TRACE("(%p)->(%08x,%p)\n", This, D3DMatHandle, D3DMatrix); TRACE("(%p)->(%08x,%p)\n", This, D3DMatHandle, D3DMatrix);
if(!D3DMatrix) if (!D3DMatrix) return DDERR_INVALIDPARAMS;
return DDERR_INVALIDPARAMS;
if(!D3DMatHandle)
return DDERR_INVALIDPARAMS;
EnterCriticalSection(&ddraw_cs); EnterCriticalSection(&ddraw_cs);
if(D3DMatHandle > This->numHandles)
m = ddraw_get_object(&This->handle_table, D3DMatHandle - 1, DDRAW_HANDLE_MATRIX);
if (!m)
{ {
ERR("Handle %d out of range\n", D3DMatHandle); WARN("Invalid matrix handle.\n");
LeaveCriticalSection(&ddraw_cs);
return DDERR_INVALIDPARAMS;
}
else if(This->Handles[D3DMatHandle - 1].type != DDrawHandle_Matrix)
{
ERR("Handle %d is not a matrix handle\n", D3DMatHandle);
LeaveCriticalSection(&ddraw_cs); LeaveCriticalSection(&ddraw_cs);
return DDERR_INVALIDPARAMS; return DDERR_INVALIDPARAMS;
} }
/* The handle is simply a pointer to a D3DMATRIX structure */ *D3DMatrix = *m;
*D3DMatrix = *((D3DMATRIX *) This->Handles[D3DMatHandle - 1].ptr);
LeaveCriticalSection(&ddraw_cs); LeaveCriticalSection(&ddraw_cs);
return D3D_OK; return D3D_OK;
@ -1596,30 +1591,24 @@ IDirect3DDeviceImpl_1_DeleteMatrix(IDirect3DDevice *iface,
D3DMATRIXHANDLE D3DMatHandle) D3DMATRIXHANDLE D3DMatHandle)
{ {
IDirect3DDeviceImpl *This = device_from_device1(iface); IDirect3DDeviceImpl *This = device_from_device1(iface);
D3DMATRIX *m;
TRACE("(%p)->(%08x)\n", This, D3DMatHandle); TRACE("(%p)->(%08x)\n", This, D3DMatHandle);
if(!D3DMatHandle)
return DDERR_INVALIDPARAMS;
EnterCriticalSection(&ddraw_cs); EnterCriticalSection(&ddraw_cs);
if(D3DMatHandle > This->numHandles)
{
ERR("Handle %d out of range\n", D3DMatHandle);
LeaveCriticalSection(&ddraw_cs);
return DDERR_INVALIDPARAMS;
}
else if(This->Handles[D3DMatHandle - 1].type != DDrawHandle_Matrix)
{
ERR("Handle %d is not a matrix handle\n", D3DMatHandle);
LeaveCriticalSection(&ddraw_cs);
return DDERR_INVALIDPARAMS;
}
HeapFree(GetProcessHeap(), 0, This->Handles[D3DMatHandle - 1].ptr); m = ddraw_free_handle(&This->handle_table, D3DMatHandle - 1, DDRAW_HANDLE_MATRIX);
This->Handles[D3DMatHandle - 1].ptr = NULL; if (!m)
This->Handles[D3DMatHandle - 1].type = DDrawHandle_Unknown; {
WARN("Invalid matrix handle.\n");
LeaveCriticalSection(&ddraw_cs);
return DDERR_INVALIDPARAMS;
}
LeaveCriticalSection(&ddraw_cs); LeaveCriticalSection(&ddraw_cs);
HeapFree(GetProcessHeap(), 0, m);
return D3D_OK; return D3D_OK;
} }

View File

@ -188,25 +188,24 @@ IDirect3DExecuteBufferImpl_Execute(IDirect3DExecuteBufferImpl *This,
int i; int i;
TRACE("MATRIXMULTIPLY (%d)\n", count); TRACE("MATRIXMULTIPLY (%d)\n", count);
for (i = 0; i < count; i++) { for (i = 0; i < count; ++i)
LPD3DMATRIXMULTIPLY ci = (LPD3DMATRIXMULTIPLY) instr; {
LPD3DMATRIX a, b, c; D3DMATRIXMULTIPLY *ci = (D3DMATRIXMULTIPLY *)instr;
D3DMATRIX *a, *b, *c;
if(!ci->hDestMatrix || ci->hDestMatrix > lpDevice->numHandles || a = ddraw_get_object(&lpDevice->handle_table, ci->hDestMatrix - 1, DDRAW_HANDLE_MATRIX);
!ci->hSrcMatrix1 || ci->hSrcMatrix1 > lpDevice->numHandles || b = ddraw_get_object(&lpDevice->handle_table, ci->hSrcMatrix1 - 1, DDRAW_HANDLE_MATRIX);
!ci->hSrcMatrix2 || ci->hSrcMatrix2 > lpDevice->numHandles) { c = ddraw_get_object(&lpDevice->handle_table, ci->hSrcMatrix2 - 1, DDRAW_HANDLE_MATRIX);
ERR("Handles out of bounds\n");
} else if (lpDevice->Handles[ci->hDestMatrix - 1].type != DDrawHandle_Matrix || if (!a || !b || !c)
lpDevice->Handles[ci->hSrcMatrix1 - 1].type != DDrawHandle_Matrix || {
lpDevice->Handles[ci->hSrcMatrix2 - 1].type != DDrawHandle_Matrix) { ERR("Invalid matrix handle (a %#x -> %p, b %#x -> %p, c %#x -> %p).\n",
ERR("Handle types invalid\n"); ci->hDestMatrix, a, ci->hSrcMatrix1, b, ci->hSrcMatrix2, c);
} else { }
a = (LPD3DMATRIX) lpDevice->Handles[ci->hDestMatrix - 1].ptr; else
b = (LPD3DMATRIX) lpDevice->Handles[ci->hSrcMatrix1 - 1].ptr; {
c = (LPD3DMATRIX) lpDevice->Handles[ci->hSrcMatrix2 - 1].ptr; TRACE("dst %p, src1 %p, src2 %p.\n", a, b, c);
TRACE(" Dest : %p Src1 : %p Src2 : %p\n", multiply_matrix(a, c, b);
a, b, c);
multiply_matrix(a,c,b);
} }
instr += size; instr += size;
@ -217,27 +216,30 @@ IDirect3DExecuteBufferImpl_Execute(IDirect3DExecuteBufferImpl *This,
int i; int i;
TRACE("STATETRANSFORM (%d)\n", count); TRACE("STATETRANSFORM (%d)\n", count);
for (i = 0; i < count; i++) { for (i = 0; i < count; ++i)
LPD3DSTATE ci = (LPD3DSTATE) instr; {
D3DSTATE *ci = (D3DSTATE *)instr;
D3DMATRIX *m;
if(!ci->u2.dwArg[0]) { m = ddraw_get_object(&lpDevice->handle_table, ci->u2.dwArg[0] - 1, DDRAW_HANDLE_MATRIX);
ERR("Setting a NULL matrix handle, what should I do?\n"); if (!m)
} else if(ci->u2.dwArg[0] > lpDevice->numHandles) { {
ERR("Handle %d is out of bounds\n", ci->u2.dwArg[0]); ERR("Invalid matrix handle %#x.\n", ci->u2.dwArg[0]);
} else if(lpDevice->Handles[ci->u2.dwArg[0] - 1].type != DDrawHandle_Matrix) { }
ERR("Handle %d is not a matrix handle\n", ci->u2.dwArg[0]); else
} else { {
if(ci->u1.dtstTransformStateType == D3DTRANSFORMSTATE_WORLD) if (ci->u1.dtstTransformStateType == D3DTRANSFORMSTATE_WORLD)
lpDevice->world = ci->u2.dwArg[0]; lpDevice->world = ci->u2.dwArg[0];
if(ci->u1.dtstTransformStateType == D3DTRANSFORMSTATE_VIEW) if (ci->u1.dtstTransformStateType == D3DTRANSFORMSTATE_VIEW)
lpDevice->view = ci->u2.dwArg[0]; lpDevice->view = ci->u2.dwArg[0];
if(ci->u1.dtstTransformStateType == D3DTRANSFORMSTATE_PROJECTION) if (ci->u1.dtstTransformStateType == D3DTRANSFORMSTATE_PROJECTION)
lpDevice->proj = ci->u2.dwArg[0]; lpDevice->proj = ci->u2.dwArg[0];
IDirect3DDevice7_SetTransform((IDirect3DDevice7 *)lpDevice, IDirect3DDevice7_SetTransform((IDirect3DDevice7 *)lpDevice,
ci->u1.dtstTransformStateType, (LPD3DMATRIX)lpDevice->Handles[ci->u2.dwArg[0] - 1].ptr); ci->u1.dtstTransformStateType, m);
} }
instr += size;
} instr += size;
}
} break; } break;
case D3DOP_STATELIGHT: { case D3DOP_STATELIGHT: {