From 941aeade01caa4fcd177c4f303ad98b90c8f3526 Mon Sep 17 00:00:00 2001 From: Henri Verbeet Date: Thu, 29 Jul 2010 12:56:58 +0200 Subject: [PATCH] ddraw: Use a less offensive handle table implementation for matrices. --- dlls/ddraw/ddraw_private.h | 2 +- dlls/ddraw/device.c | 101 +++++++++++++++++-------------------- dlls/ddraw/executebuffer.c | 68 +++++++++++++------------ 3 files changed, 81 insertions(+), 90 deletions(-) diff --git a/dlls/ddraw/ddraw_private.h b/dlls/ddraw/ddraw_private.h index e5e6ff408cb..49ec31777a3 100644 --- a/dlls/ddraw/ddraw_private.h +++ b/dlls/ddraw/ddraw_private.h @@ -326,7 +326,6 @@ typedef enum { DDrawHandle_Unknown = 0, DDrawHandle_Texture = 1, - DDrawHandle_Matrix = 3, DDrawHandle_StateBlock = 4 } DDrawHandleTypes; @@ -342,6 +341,7 @@ enum ddraw_handle_type { DDRAW_HANDLE_FREE, DDRAW_HANDLE_MATERIAL, + DDRAW_HANDLE_MATRIX, }; struct ddraw_handle_entry diff --git a/dlls/ddraw/device.c b/dlls/ddraw/device.c index fee434e1b34..449ca4d9d3b 100644 --- a/dlls/ddraw/device.c +++ b/dlls/ddraw/device.c @@ -382,14 +382,6 @@ IDirect3DDeviceImpl_7_Release(IDirect3DDevice7 *iface) } 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: { /* No fixme here because this might happen because of sloppy apps */ @@ -423,6 +415,14 @@ IDirect3DDeviceImpl_7_Release(IDirect3DDevice7 *iface) 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: FIXME("Handle %#x (%p) has unknown type %#x.\n", i + 1, entry->object, entry->type); break; @@ -1426,6 +1426,8 @@ IDirect3DDeviceImpl_1_CreateMatrix(IDirect3DDevice *iface, D3DMATRIXHANDLE *D3DM { IDirect3DDeviceImpl *This = device_from_device1(iface); D3DMATRIX *Matrix; + DWORD h; + TRACE("(%p)->(%p)\n", This, D3DMatHandle); if(!D3DMatHandle) @@ -1439,16 +1441,18 @@ IDirect3DDeviceImpl_1_CreateMatrix(IDirect3DDevice *iface, D3DMATRIXHANDLE *D3DM } 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); LeaveCriticalSection(&ddraw_cs); 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); LeaveCriticalSection(&ddraw_cs); @@ -1479,21 +1483,18 @@ IDirect3DDeviceImpl_1_SetMatrix(IDirect3DDevice *iface, D3DMATRIX *D3DMatrix) { IDirect3DDeviceImpl *This = device_from_device1(iface); + D3DMATRIX *m; + TRACE("(%p)->(%08x,%p)\n", This, D3DMatHandle, D3DMatrix); - if( (!D3DMatHandle) || (!D3DMatrix) ) - return DDERR_INVALIDPARAMS; + if (!D3DMatrix) return DDERR_INVALIDPARAMS; 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); - 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); + WARN("Invalid matrix handle.\n"); LeaveCriticalSection(&ddraw_cs); return DDERR_INVALIDPARAMS; } @@ -1501,7 +1502,7 @@ IDirect3DDeviceImpl_1_SetMatrix(IDirect3DDevice *iface, if (TRACE_ON(d3d7)) dump_D3DMATRIX(D3DMatrix); - *((D3DMATRIX *) This->Handles[D3DMatHandle - 1].ptr) = *D3DMatrix; + *m = *D3DMatrix; if(This->world == D3DMatHandle) { @@ -1548,29 +1549,23 @@ IDirect3DDeviceImpl_1_GetMatrix(IDirect3DDevice *iface, D3DMATRIX *D3DMatrix) { IDirect3DDeviceImpl *This = device_from_device1(iface); + D3DMATRIX *m; + TRACE("(%p)->(%08x,%p)\n", This, D3DMatHandle, D3DMatrix); - if(!D3DMatrix) - return DDERR_INVALIDPARAMS; - if(!D3DMatHandle) - return DDERR_INVALIDPARAMS; + if (!D3DMatrix) return DDERR_INVALIDPARAMS; 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); - 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); + WARN("Invalid matrix handle.\n"); LeaveCriticalSection(&ddraw_cs); return DDERR_INVALIDPARAMS; } - /* The handle is simply a pointer to a D3DMATRIX structure */ - *D3DMatrix = *((D3DMATRIX *) This->Handles[D3DMatHandle - 1].ptr); + *D3DMatrix = *m; LeaveCriticalSection(&ddraw_cs); return D3D_OK; @@ -1596,30 +1591,24 @@ IDirect3DDeviceImpl_1_DeleteMatrix(IDirect3DDevice *iface, D3DMATRIXHANDLE D3DMatHandle) { IDirect3DDeviceImpl *This = device_from_device1(iface); + D3DMATRIX *m; + TRACE("(%p)->(%08x)\n", This, D3DMatHandle); - if(!D3DMatHandle) - return DDERR_INVALIDPARAMS; - 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); - This->Handles[D3DMatHandle - 1].ptr = NULL; - This->Handles[D3DMatHandle - 1].type = DDrawHandle_Unknown; + m = ddraw_free_handle(&This->handle_table, D3DMatHandle - 1, DDRAW_HANDLE_MATRIX); + if (!m) + { + WARN("Invalid matrix handle.\n"); + LeaveCriticalSection(&ddraw_cs); + return DDERR_INVALIDPARAMS; + } LeaveCriticalSection(&ddraw_cs); + + HeapFree(GetProcessHeap(), 0, m); + return D3D_OK; } diff --git a/dlls/ddraw/executebuffer.c b/dlls/ddraw/executebuffer.c index 40b586fe326..59481b1a079 100644 --- a/dlls/ddraw/executebuffer.c +++ b/dlls/ddraw/executebuffer.c @@ -188,25 +188,24 @@ IDirect3DExecuteBufferImpl_Execute(IDirect3DExecuteBufferImpl *This, int i; TRACE("MATRIXMULTIPLY (%d)\n", count); - for (i = 0; i < count; i++) { - LPD3DMATRIXMULTIPLY ci = (LPD3DMATRIXMULTIPLY) instr; - LPD3DMATRIX a, b, c; + for (i = 0; i < count; ++i) + { + D3DMATRIXMULTIPLY *ci = (D3DMATRIXMULTIPLY *)instr; + D3DMATRIX *a, *b, *c; - if(!ci->hDestMatrix || ci->hDestMatrix > lpDevice->numHandles || - !ci->hSrcMatrix1 || ci->hSrcMatrix1 > lpDevice->numHandles || - !ci->hSrcMatrix2 || ci->hSrcMatrix2 > lpDevice->numHandles) { - ERR("Handles out of bounds\n"); - } else if (lpDevice->Handles[ci->hDestMatrix - 1].type != DDrawHandle_Matrix || - lpDevice->Handles[ci->hSrcMatrix1 - 1].type != DDrawHandle_Matrix || - lpDevice->Handles[ci->hSrcMatrix2 - 1].type != DDrawHandle_Matrix) { - ERR("Handle types invalid\n"); - } else { - a = (LPD3DMATRIX) lpDevice->Handles[ci->hDestMatrix - 1].ptr; - b = (LPD3DMATRIX) lpDevice->Handles[ci->hSrcMatrix1 - 1].ptr; - c = (LPD3DMATRIX) lpDevice->Handles[ci->hSrcMatrix2 - 1].ptr; - TRACE(" Dest : %p Src1 : %p Src2 : %p\n", - a, b, c); - multiply_matrix(a,c,b); + a = ddraw_get_object(&lpDevice->handle_table, ci->hDestMatrix - 1, DDRAW_HANDLE_MATRIX); + b = ddraw_get_object(&lpDevice->handle_table, ci->hSrcMatrix1 - 1, DDRAW_HANDLE_MATRIX); + c = ddraw_get_object(&lpDevice->handle_table, ci->hSrcMatrix2 - 1, DDRAW_HANDLE_MATRIX); + + if (!a || !b || !c) + { + ERR("Invalid matrix handle (a %#x -> %p, b %#x -> %p, c %#x -> %p).\n", + ci->hDestMatrix, a, ci->hSrcMatrix1, b, ci->hSrcMatrix2, c); + } + else + { + TRACE("dst %p, src1 %p, src2 %p.\n", a, b, c); + multiply_matrix(a, c, b); } instr += size; @@ -217,27 +216,30 @@ IDirect3DExecuteBufferImpl_Execute(IDirect3DExecuteBufferImpl *This, int i; TRACE("STATETRANSFORM (%d)\n", count); - for (i = 0; i < count; i++) { - LPD3DSTATE ci = (LPD3DSTATE) instr; + for (i = 0; i < count; ++i) + { + D3DSTATE *ci = (D3DSTATE *)instr; + D3DMATRIX *m; - if(!ci->u2.dwArg[0]) { - ERR("Setting a NULL matrix handle, what should I do?\n"); - } else if(ci->u2.dwArg[0] > lpDevice->numHandles) { - ERR("Handle %d is out of bounds\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 { - if(ci->u1.dtstTransformStateType == D3DTRANSFORMSTATE_WORLD) + m = ddraw_get_object(&lpDevice->handle_table, ci->u2.dwArg[0] - 1, DDRAW_HANDLE_MATRIX); + if (!m) + { + ERR("Invalid matrix handle %#x.\n", ci->u2.dwArg[0]); + } + else + { + if (ci->u1.dtstTransformStateType == D3DTRANSFORMSTATE_WORLD) lpDevice->world = ci->u2.dwArg[0]; - if(ci->u1.dtstTransformStateType == D3DTRANSFORMSTATE_VIEW) + if (ci->u1.dtstTransformStateType == D3DTRANSFORMSTATE_VIEW) lpDevice->view = ci->u2.dwArg[0]; - if(ci->u1.dtstTransformStateType == D3DTRANSFORMSTATE_PROJECTION) + if (ci->u1.dtstTransformStateType == D3DTRANSFORMSTATE_PROJECTION) lpDevice->proj = ci->u2.dwArg[0]; 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; case D3DOP_STATELIGHT: {