[D3DX9_*]
authorAmine Khaldi <amine.khaldi@reactos.org>
Thu, 25 Sep 2014 19:46:26 +0000 (19:46 +0000)
committerAmine Khaldi <amine.khaldi@reactos.org>
Thu, 25 Sep 2014 19:46:26 +0000 (19:46 +0000)
* Sync with Wine 1.7.27.
CORE-8540

svn path=/trunk/; revision=64286

reactos/dll/directx/wine/d3dx9_36/d3dx9_36.spec
reactos/dll/directx/wine/d3dx9_36/font.c
reactos/dll/directx/wine/d3dx9_36/mesh.c
reactos/dll/directx/wine/d3dx9_36/shader.c
reactos/dll/directx/wine/d3dx9_36/surface.c
reactos/dll/directx/wine/d3dx9_36/texture.c
reactos/dll/directx/wine/d3dx9_36/util.c
reactos/dll/directx/wine/d3dx9_36/xfile.c
reactos/media/doc/README.WINE

index e88b7b0..3535120 100644 (file)
 @ stdcall D3DXCreateTextureFromResourceW(ptr ptr wstr ptr)
 @ stdcall -stub D3DXCreateTextureGutterHelper(long long ptr long ptr)
 @ stdcall -stub D3DXCreateTextureShader(ptr ptr)
-@ stdcall -stub D3DXCreateTorus(ptr long long long long ptr ptr)
+@ stdcall D3DXCreateTorus(ptr long long long long ptr ptr)
 @ stdcall D3DXCreateVolumeTexture(ptr long long long long long long long ptr)
 @ stdcall D3DXCreateVolumeTextureFromFileA(ptr ptr ptr)
 @ stdcall D3DXCreateVolumeTextureFromFileExA(ptr ptr long long long long long long long long long long ptr ptr ptr)
index c3f4c42..92254a2 100644 (file)
@@ -140,8 +140,8 @@ static HDC WINAPI ID3DXFontImpl_GetDC(ID3DXFont *iface)
 static HRESULT WINAPI ID3DXFontImpl_GetGlyphData(ID3DXFont *iface, UINT glyph,
         IDirect3DTexture9 **texture, RECT *blackbox, POINT *cellinc)
 {
-    FIXME("iface %p, glyph %#x, texture %p, blackbox %s, cellinc %s stub!\n",
-            iface, glyph, texture, wine_dbgstr_rect(blackbox), wine_dbgstr_point(cellinc));
+    FIXME("iface %p, glyph %#x, texture %p, blackbox %p, cellinc %p stub!\n",
+            iface, glyph, texture, blackbox, cellinc);
     return E_NOTIMPL;
 }
 
index aa74c7a..0528e2a 100644 (file)
@@ -2741,16 +2741,20 @@ static HRESULT parse_material(ID3DXFileData *filedata, D3DXMATERIAL *material)
             return hr;
         hr = child->lpVtbl->GetType(child, &type);
         if (FAILED(hr))
-            return hr;
+            goto err;
 
         if (IsEqualGUID(&type, &TID_D3DRMTextureFilename)) {
             hr = parse_texture_filename(child, &material->pTextureFilename);
             if (FAILED(hr))
-                return hr;
+                goto err;
         }
+        IUnknown_Release(child);
     }
-
     return D3D_OK;
+
+err:
+    IUnknown_Release(child);
+    return hr;
 }
 
 static void destroy_materials(struct mesh_data *mesh)
@@ -2771,7 +2775,7 @@ static HRESULT parse_material_list(ID3DXFileData *filedata, struct mesh_data *me
     SIZE_T data_size;
     const DWORD *data, *in_ptr;
     GUID type;
-    ID3DXFileData *child;
+    ID3DXFileData *child = NULL;
     DWORD num_materials;
     DWORD i;
     SIZE_T nb_children;
@@ -2854,6 +2858,9 @@ static HRESULT parse_material_list(ID3DXFileData *filedata, struct mesh_data *me
             if (FAILED(hr))
                 goto end;
         }
+
+        IUnknown_Release(child);
+        child = NULL;
     }
     if (num_materials != mesh->num_materials) {
         WARN("only %u of %u materials defined\n", num_materials, mesh->num_materials);
@@ -2861,6 +2868,8 @@ static HRESULT parse_material_list(ID3DXFileData *filedata, struct mesh_data *me
     }
 
 end:
+    if (child)
+        IUnknown_Release(child);
     filedata->lpVtbl->Unlock(filedata);
     return hr;
 }
@@ -3158,7 +3167,7 @@ static HRESULT parse_mesh(ID3DXFileData *filedata, struct mesh_data *mesh_data,
     const BYTE *data, *in_ptr;
     DWORD *index_out_ptr;
     GUID type;
-    ID3DXFileData *child;
+    ID3DXFileData *child = NULL;
     DWORD i;
     SIZE_T nb_children;
     DWORD nb_skin_weigths_info = 0;
@@ -3275,9 +3284,6 @@ static HRESULT parse_mesh(ID3DXFileData *filedata, struct mesh_data *mesh_data,
             hr = parse_vertex_colors(child, mesh_data);
         } else if (IsEqualGUID(&type, &TID_D3DRMMeshTextureCoords)) {
             hr = parse_texture_coords(child, mesh_data);
-        hr = filedata->lpVtbl->GetChild(filedata, i, &child);
-        if (FAILED(hr))
-            goto end;
         } else if (IsEqualGUID(&type, &TID_D3DRMMeshMaterialList) &&
                    (provide_flags & PROVIDE_MATERIALS))
         {
@@ -3306,6 +3312,9 @@ static HRESULT parse_mesh(ID3DXFileData *filedata, struct mesh_data *mesh_data,
         }
         if (FAILED(hr))
             goto end;
+
+        IUnknown_Release(child);
+        child = NULL;
     }
 
     if (mesh_data->skin_info && (nb_skin_weigths_info != mesh_data->nb_bones)) {
@@ -3318,6 +3327,8 @@ static HRESULT parse_mesh(ID3DXFileData *filedata, struct mesh_data *mesh_data,
     hr = D3D_OK;
 
 end:
+    if (child)
+        IUnknown_Release(child);
     filedata->lpVtbl->Unlock(filedata);
     return hr;
 }
@@ -3846,7 +3857,7 @@ static HRESULT load_frame(struct ID3DXFileData *filedata, DWORD options, struct
             return hr;
         hr = child->lpVtbl->GetType(child, &type);
         if (FAILED(hr))
-            return hr;
+            goto err;
 
         if (IsEqualGUID(&type, &TID_D3DRMMesh)) {
             hr = load_mesh_container(child, options, device, alloc_hier, next_container);
@@ -3860,10 +3871,15 @@ static HRESULT load_frame(struct ID3DXFileData *filedata, DWORD options, struct
                 next_child = &(*next_child)->pFrameSibling;
         }
         if (FAILED(hr))
-            return hr;
-    }
+            goto err;
 
+        IUnknown_Release(child);
+    }
     return D3D_OK;
+
+err:
+    IUnknown_Release(child);
+    return hr;
 }
 
 HRESULT WINAPI D3DXLoadMeshHierarchyFromXInMemory(const void *memory, DWORD memory_size, DWORD options,
@@ -4129,12 +4145,15 @@ static HRESULT parse_frame(struct ID3DXFileData *filedata, DWORD options, struct
             return hr;
         hr = child->lpVtbl->GetType(child, &type);
         if (FAILED(hr))
-            return hr;
+            goto err;
 
         if (IsEqualGUID(&type, &TID_D3DRMMesh)) {
             struct mesh_container *container = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*container));
             if (!container)
-                return E_OUTOFMEMORY;
+            {
+                hr = E_OUTOFMEMORY;
+                goto err;
+            }
             list_add_tail(container_list, &container->entry);
             container->transform = transform;
 
@@ -4150,10 +4169,15 @@ static HRESULT parse_frame(struct ID3DXFileData *filedata, DWORD options, struct
             hr = parse_frame(child, options, device, &transform, container_list, provide_flags);
         }
         if (FAILED(hr))
-            return hr;
-    }
+            goto err;
 
+        IUnknown_Release(child);
+    }
     return D3D_OK;
+
+err:
+    IUnknown_Release(child);
+    return hr;
 }
 
 HRESULT WINAPI D3DXLoadMeshFromXInMemory(const void *memory, DWORD memory_size, DWORD options,
@@ -4683,12 +4707,6 @@ HRESULT WINAPI D3DXCreateSphere(struct IDirect3DDevice9 *device, float radius, U
         return D3DERR_INVALIDCALL;
     }
 
-    if (adjacency)
-    {
-        FIXME("Case of adjacency != NULL not implemented.\n");
-        return E_NOTIMPL;
-    }
-
     number_of_vertices = 2 + slices * (stacks-1);
     number_of_faces = 2 * slices + (stacks - 2) * (2 * slices);
 
@@ -4826,6 +4844,24 @@ HRESULT WINAPI D3DXCreateSphere(struct IDirect3DDevice9 *device, float radius, U
     free_sincos_table(&phi);
     sphere->lpVtbl->UnlockIndexBuffer(sphere);
     sphere->lpVtbl->UnlockVertexBuffer(sphere);
+
+
+    if (adjacency)
+    {
+        if (FAILED(hr = D3DXCreateBuffer(number_of_faces * sizeof(DWORD) * 3, adjacency)))
+        {
+            sphere->lpVtbl->Release(sphere);
+            return hr;
+        }
+
+        if (FAILED(hr = sphere->lpVtbl->GenerateAdjacency(sphere, 0.0f, (*adjacency)->lpVtbl->GetBufferPointer(*adjacency))))
+        {
+            (*adjacency)->lpVtbl->Release(*adjacency);
+            sphere->lpVtbl->Release(sphere);
+            return hr;
+        }
+    }
+
     *mesh = sphere;
 
     return D3D_OK;
@@ -5046,6 +5082,113 @@ HRESULT WINAPI D3DXCreateTextA(struct IDirect3DDevice9 *device, HDC hdc, const c
     return hr;
 }
 
+HRESULT WINAPI D3DXCreateTorus(struct IDirect3DDevice9 *device,
+        float innerradius, float outerradius, UINT sides, UINT rings, struct ID3DXMesh **mesh, ID3DXBuffer **adjacency)
+{
+    HRESULT hr;
+    ID3DXMesh *torus;
+    WORD (*faces)[3];
+    struct vertex *vertices;
+    float phi, phi_step, sin_phi, cos_phi;
+    float theta, theta_step, sin_theta, cos_theta;
+    unsigned int i, j, numvert, numfaces;
+
+    TRACE("device %p, innerradius %.8e, outerradius %.8e, sides %u, rings %u, mesh %p, adjacency %p.\n",
+            device, innerradius, outerradius, sides, rings, mesh, adjacency);
+
+    numvert = sides * rings;
+    numfaces = numvert * 2;
+
+    if (!device || innerradius < 0.0f || outerradius < 0.0f || sides < 3 || rings < 3 || !mesh)
+    {
+        WARN("Invalid arguments.\n");
+        return D3DERR_INVALIDCALL;
+    }
+
+    if (FAILED(hr = D3DXCreateMeshFVF(numfaces, numvert, D3DXMESH_MANAGED, D3DFVF_XYZ | D3DFVF_NORMAL, device, &torus)))
+        return hr;
+
+    if (FAILED(hr = torus->lpVtbl->LockVertexBuffer(torus, 0, (void **)&vertices)))
+    {
+        torus->lpVtbl->Release(torus);
+        return hr;
+    }
+
+    if (FAILED(hr = torus->lpVtbl->LockIndexBuffer(torus, 0, (void **)&faces)))
+    {
+        torus->lpVtbl->UnlockVertexBuffer(torus);
+        torus->lpVtbl->Release(torus);
+        return hr;
+    }
+
+    phi_step = D3DX_PI / sides * 2.0f;
+    theta_step = D3DX_PI / rings * -2.0f;
+
+    theta = 0.0f;
+
+    for (i = 0; i < rings; ++i)
+    {
+        phi = 0.0f;
+
+        sin_theta = sinf(theta);
+        cos_theta = cosf(theta);
+
+        for (j = 0; j < sides; ++j)
+        {
+            sin_phi = sinf(phi);
+            cos_phi = cosf(phi);
+
+            vertices[i * sides + j].position.x = (innerradius * cos_phi + outerradius) * cos_theta;
+            vertices[i * sides + j].position.y = (innerradius * cos_phi + outerradius) * sin_theta;
+            vertices[i * sides + j].position.z = innerradius * sin_phi;
+            vertices[i * sides + j].normal.x = cos_phi * cos_theta;
+            vertices[i * sides + j].normal.y = cos_phi * sin_theta;
+            vertices[i * sides + j].normal.z = sin_phi;
+
+            phi += phi_step;
+        }
+
+        theta += theta_step;
+    }
+
+    for (i = 0; i < numfaces - sides * 2; ++i)
+    {
+        faces[i][0] = i % 2 ? i / 2 + sides : i / 2;
+        faces[i][1] = (i / 2 + 1) % sides ? i / 2 + 1 : i / 2 + 1 - sides;
+        faces[i][2] = (i + 1) % (sides * 2) ? (i + 1) / 2 + sides : (i + 1) / 2;
+    }
+
+    for (j = 0; i < numfaces; ++i, ++j)
+    {
+        faces[i][0] = i % 2 ? j / 2 : i / 2;
+        faces[i][1] = (i / 2 + 1) % sides ? i / 2 + 1 : i / 2 + 1 - sides;
+        faces[i][2] = i == numfaces - 1 ? 0 : (j + 1) / 2;
+    }
+
+    torus->lpVtbl->UnlockIndexBuffer(torus);
+    torus->lpVtbl->UnlockVertexBuffer(torus);
+
+    if (adjacency)
+    {
+        if (FAILED(hr = D3DXCreateBuffer(numfaces * sizeof(DWORD) * 3, adjacency)))
+        {
+            torus->lpVtbl->Release(torus);
+            return hr;
+        }
+
+        if (FAILED(hr = torus->lpVtbl->GenerateAdjacency(torus, 0.0f, (*adjacency)->lpVtbl->GetBufferPointer(*adjacency))))
+        {
+            (*adjacency)->lpVtbl->Release(*adjacency);
+            torus->lpVtbl->Release(torus);
+            return hr;
+        }
+    }
+
+    *mesh = torus;
+
+    return D3D_OK;
+}
+
 enum pointtype {
     POINTTYPE_CURVE = 0,
     POINTTYPE_CORNER,
index 36b1007..3e94709 100644 (file)
@@ -207,6 +207,20 @@ HRESULT WINAPI D3DXAssembleShader(const char *data, UINT data_len, const D3DXMAC
     return hr;
 }
 
+static const void *main_file_data;
+
+static CRITICAL_SECTION from_file_mutex;
+static CRITICAL_SECTION_DEBUG from_file_mutex_debug =
+{
+    0, 0, &from_file_mutex,
+    {
+        &from_file_mutex_debug.ProcessLocksList,
+        &from_file_mutex_debug.ProcessLocksList
+    },
+    0, 0, {(DWORD_PTR)(__FILE__ ": from_file_mutex")}
+};
+static CRITICAL_SECTION from_file_mutex = {&from_file_mutex_debug, -1, 0, 0, 0, 0};
+
 /* D3DXInclude private implementation, used to implement
  * D3DXAssembleShaderFromFile() from D3DXAssembleShader(). */
 /* To be able to correctly resolve include search paths we have to store the
@@ -216,24 +230,40 @@ static HRESULT WINAPI d3dincludefromfile_open(ID3DXInclude *iface, D3DXINCLUDE_T
         const char *filename, const void *parent_data, const void **data, UINT *bytes)
 {
     const char *p, *parent_name = "";
-    char *pathname = NULL;
+    char *pathname = NULL, *ptr;
     char **buffer = NULL;
     HANDLE file;
     UINT size;
 
-    if(parent_data != NULL)
+    if (parent_data)
+    {
         parent_name = *((const char **)parent_data - 1);
+    }
+    else
+    {
+        if (main_file_data)
+            parent_name = *((const char **)main_file_data - 1);
+    }
 
     TRACE("Looking up for include file %s, parent %s\n", debugstr_a(filename), debugstr_a(parent_name));
 
-    if ((p = strrchr(parent_name, '\\')) || (p = strrchr(parent_name, '/'))) p++;
-    else p = parent_name;
+    if ((p = strrchr(parent_name, '\\')))
+        ++p;
+    else
+        p = parent_name;
     pathname = HeapAlloc(GetProcessHeap(), 0, (p - parent_name) + strlen(filename) + 1);
     if(!pathname)
         return HRESULT_FROM_WIN32(GetLastError());
 
     memcpy(pathname, parent_name, p - parent_name);
     strcpy(pathname + (p - parent_name), filename);
+    ptr = pathname + (p - parent_name);
+    while (*ptr)
+    {
+        if (*ptr == '/')
+            *ptr = '\\';
+        ++ptr;
+    }
 
     file = CreateFileA(pathname, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
     if(file == INVALID_HANDLE_VALUE)
@@ -253,6 +283,8 @@ static HRESULT WINAPI d3dincludefromfile_open(ID3DXInclude *iface, D3DXINCLUDE_T
         goto error;
 
     *data = buffer + 1;
+    if (!main_file_data)
+        main_file_data = *data;
 
     CloseHandle(file);
     return S_OK;
@@ -268,6 +300,8 @@ static HRESULT WINAPI d3dincludefromfile_close(ID3DXInclude *iface, const void *
 {
     HeapFree(GetProcessHeap(), 0, *((char **)data - 1));
     HeapFree(GetProcessHeap(), 0, (char **)data - 1);
+    if (main_file_data == data)
+        main_file_data = NULL;
     return S_OK;
 }
 
@@ -327,9 +361,11 @@ HRESULT WINAPI D3DXAssembleShaderFromFileW(const WCHAR *filename, const D3DXMACR
         return E_OUTOFMEMORY;
     WideCharToMultiByte(CP_ACP, 0, filename, -1, filename_a, len, NULL, NULL);
 
+    EnterCriticalSection(&from_file_mutex);
     hr = ID3DXInclude_Open(include, D3D_INCLUDE_LOCAL, filename_a, NULL, &buffer, &len);
     if (FAILED(hr))
     {
+        LeaveCriticalSection(&from_file_mutex);
         HeapFree(GetProcessHeap(), 0, filename_a);
         return D3DXERR_INVALIDDATA;
     }
@@ -337,6 +373,7 @@ HRESULT WINAPI D3DXAssembleShaderFromFileW(const WCHAR *filename, const D3DXMACR
     hr = D3DXAssembleShader(buffer, len, defines, include, flags, shader, error_messages);
 
     ID3DXInclude_Close(include, buffer);
+    LeaveCriticalSection(&from_file_mutex);
     HeapFree(GetProcessHeap(), 0, filename_a);
     return hr;
 }
@@ -459,9 +496,11 @@ HRESULT WINAPI D3DXCompileShaderFromFileW(const WCHAR *filename, const D3DXMACRO
         return E_OUTOFMEMORY;
     WideCharToMultiByte(CP_ACP, 0, filename, -1, filename_a, filename_len, NULL, NULL);
 
+    EnterCriticalSection(&from_file_mutex);
     hr = ID3DXInclude_Open(include, D3D_INCLUDE_LOCAL, filename_a, NULL, &buffer, &len);
     if (FAILED(hr))
     {
+        LeaveCriticalSection(&from_file_mutex);
         HeapFree(GetProcessHeap(), 0, filename_a);
         return D3DXERR_INVALIDDATA;
     }
@@ -475,6 +514,7 @@ HRESULT WINAPI D3DXCompileShaderFromFileW(const WCHAR *filename, const D3DXMACRO
                                         constant_table);
 
     ID3DXInclude_Close(include, buffer);
+    LeaveCriticalSection(&from_file_mutex);
     HeapFree(GetProcessHeap(), 0, filename_a);
     return hr;
 }
@@ -579,9 +619,11 @@ HRESULT WINAPI D3DXPreprocessShaderFromFileW(const WCHAR *filename, const D3DXMA
         return E_OUTOFMEMORY;
     WideCharToMultiByte(CP_ACP, 0, filename, -1, filename_a, len, NULL, NULL);
 
+    EnterCriticalSection(&from_file_mutex);
     hr = ID3DXInclude_Open(include, D3D_INCLUDE_LOCAL, filename_a, NULL, &buffer, &len);
     if (FAILED(hr))
     {
+        LeaveCriticalSection(&from_file_mutex);
         HeapFree(GetProcessHeap(), 0, filename_a);
         return D3DXERR_INVALIDDATA;
     }
@@ -592,6 +634,7 @@ HRESULT WINAPI D3DXPreprocessShaderFromFileW(const WCHAR *filename, const D3DXMA
                        (ID3DBlob **)shader, (ID3DBlob **)error_messages);
 
     ID3DXInclude_Close(include, buffer);
+    LeaveCriticalSection(&from_file_mutex);
     HeapFree(GetProcessHeap(), 0, filename_a);
     return hr;
 }
index 29914c5..6a8223d 100644 (file)
@@ -1026,7 +1026,7 @@ HRESULT WINAPI D3DXGetImageInfoFromResourceW(HMODULE module, const WCHAR *resour
  *
  * RETURNS
  *   Success: D3D_OK
- *   Failure: D3DERR_INVALIDCALL, if pDestSurface or pSrcData or SrcDataSize are NULL
+ *   Failure: D3DERR_INVALIDCALL, if pDestSurface, pSrcData or SrcDataSize is NULL
  *            D3DXERR_INVALIDDATA, if pSrcData is no valid image file
  *
  */
@@ -1362,12 +1362,28 @@ static void init_argb_conversion_info(const struct pixel_format_desc *srcformat,
  * Extracts the relevant components from the source color and
  * drops the less significant bits if they aren't used by the destination format.
  */
-static void get_relevant_argb_components(const struct argb_conversion_info *info, DWORD col, DWORD *out)
+static void get_relevant_argb_components(const struct argb_conversion_info *info, const BYTE *col, DWORD *out)
 {
-    UINT i = 0;
-    for(;i < 4;i++)
-        if(info->process_channel[i])
-            out[i] = (col & info->srcmask[i]) >> info->srcshift[i];
+    unsigned int i, j;
+    unsigned int component, mask;
+
+    for (i = 0; i < 4; ++i)
+    {
+        if (!info->process_channel[i])
+            continue;
+
+        component = 0;
+        mask = info->srcmask[i];
+        for (j = 0; j < 4 && mask; ++j)
+        {
+            if (info->srcshift[i] < j * 8)
+                component |= (col[j] & mask) << (j * 8 - info->srcshift[i]);
+            else
+                component |= (col[j] & mask) >> (info->srcshift[i] - j * 8);
+            mask >>= 8;
+        }
+        out[i] = component;
+    }
 }
 
 /************************************************************
@@ -1545,14 +1561,14 @@ void convert_argb_pixels(const BYTE *src, UINT src_row_pitch, UINT src_slice_pit
                 {
                     DWORD val;
 
-                    get_relevant_argb_components(&conv_info, *(DWORD *)src_ptr, channels);
+                    get_relevant_argb_components(&conv_info, src_ptr, channels);
                     val = make_argb_color(&conv_info, channels);
 
                     if (color_key)
                     {
                         DWORD ck_pixel;
 
-                        get_relevant_argb_components(&ck_conv_info, *(DWORD *)src_ptr, channels);
+                        get_relevant_argb_components(&ck_conv_info, src_ptr, channels);
                         ck_pixel = make_argb_color(&ck_conv_info, channels);
                         if (ck_pixel == color_key)
                             val &= ~conv_info.destmask[0];
@@ -1648,14 +1664,14 @@ void point_filter_argb_pixels(const BYTE *src, UINT src_row_pitch, UINT src_slic
                 {
                     DWORD val;
 
-                    get_relevant_argb_components(&conv_info, *(DWORD *)src_ptr, channels);
+                    get_relevant_argb_components(&conv_info, src_ptr, channels);
                     val = make_argb_color(&conv_info, channels);
 
                     if (color_key)
                     {
                         DWORD ck_pixel;
 
-                        get_relevant_argb_components(&ck_conv_info, *(DWORD *)src_ptr, channels);
+                        get_relevant_argb_components(&ck_conv_info, src_ptr, channels);
                         ck_pixel = make_argb_color(&ck_conv_info, channels);
                         if (ck_pixel == color_key)
                             val &= ~conv_info.destmask[0];
@@ -1716,7 +1732,7 @@ void point_filter_argb_pixels(const BYTE *src, UINT src_row_pitch, UINT src_slic
  * RETURNS
  *   Success: D3D_OK, if we successfully load the pixel data into our surface or
  *                    if pSrcMemory is NULL but the other parameters are valid
- *   Failure: D3DERR_INVALIDCALL, if pDestSurface, SrcPitch or pSrcRect are NULL or
+ *   Failure: D3DERR_INVALIDCALL, if pDestSurface, SrcPitch or pSrcRect is NULL or
  *                                if SrcFormat is an invalid format (other than D3DFMT_UNKNOWN) or
  *                                if DestRect is invalid
  *            D3DXERR_INVALIDDATA, if we fail to lock pDestSurface
@@ -1867,7 +1883,7 @@ HRESULT WINAPI D3DXLoadSurfaceFromMemory(IDirect3DSurface9 *dst_surface,
  *
  * RETURNS
  *   Success: D3D_OK
- *   Failure: D3DERR_INVALIDCALL, if pDestSurface or pSrcSurface are NULL
+ *   Failure: D3DERR_INVALIDCALL, if pDestSurface or pSrcSurface is NULL
  *            D3DXERR_INVALIDDATA, if one of the surfaces is not lockable
  *
  */
index 5ed137e..95c1e5e 100644 (file)
@@ -180,6 +180,27 @@ HRESULT WINAPI D3DXFilterTexture(IDirect3DBaseTexture9 *texture,
     }
 }
 
+static D3DFORMAT get_luminance_replacement_format(D3DFORMAT format)
+{
+    static const struct
+    {
+        D3DFORMAT luminance_format;
+        D3DFORMAT replacement_format;
+    } luminance_replacements[] =
+    {
+        {D3DFMT_L8, D3DFMT_X8R8G8B8},
+        {D3DFMT_A8L8, D3DFMT_A8R8G8B8},
+        {D3DFMT_A4L4, D3DFMT_A4R4G4B4},
+        {D3DFMT_L16, D3DFMT_A16B16G16R16}
+    };
+    unsigned int i;
+
+    for (i = 0; i < sizeof(luminance_replacements) / sizeof(luminance_replacements[0]); ++i)
+        if (format == luminance_replacements[i].luminance_format)
+            return luminance_replacements[i].replacement_format;
+    return format;
+}
+
 HRESULT WINAPI D3DXCheckTextureRequirements(struct IDirect3DDevice9 *device, UINT *width, UINT *height,
         UINT *miplevels, DWORD usage, D3DFORMAT *format, D3DPOOL pool)
 {
@@ -251,16 +272,16 @@ HRESULT WINAPI D3DXCheckTextureRequirements(struct IDirect3DDevice9 *device, UIN
             FIXME("Pixel format %x not handled\n", usedformat);
             goto cleanup;
         }
+        fmt = get_format_info(get_luminance_replacement_format(usedformat));
 
         allow_24bits = fmt->bytes_per_pixel == 3;
-        channels = (fmt->bits[0] ? 1 : 0) + (fmt->bits[1] ? 1 : 0)
-            + (fmt->bits[2] ? 1 : 0) + (fmt->bits[3] ? 1 : 0);
+        channels = !!fmt->bits[0] + !!fmt->bits[1] + !!fmt->bits[2] + !!fmt->bits[3];
         usedformat = D3DFMT_UNKNOWN;
 
         while ((curfmt = get_format_info_idx(i)))
         {
-            unsigned int curchannels = (curfmt->bits[0] ? 1 : 0) + (curfmt->bits[1] ? 1 : 0)
-                + (curfmt->bits[2] ? 1 : 0) + (curfmt->bits[3] ? 1 : 0);
+            unsigned int curchannels = !!curfmt->bits[0] + !!curfmt->bits[1]
+                    + !!curfmt->bits[2] + !!curfmt->bits[3];
             int score;
 
             i++;
@@ -521,8 +542,6 @@ HRESULT WINAPI D3DXCreateTextureFromFileInMemoryEx(struct IDirect3DDevice9 *devi
     IDirect3DTexture9 **texptr;
     IDirect3DTexture9 *buftex;
     IDirect3DSurface9 *surface;
-    BOOL file_width = FALSE, file_height = FALSE;
-    BOOL file_format = FALSE, file_miplevels = FALSE;
     BOOL dynamic_texture;
     D3DXIMAGE_INFO imginfo;
     UINT loaded_miplevels, skip_levels;
@@ -565,25 +584,21 @@ HRESULT WINAPI D3DXCreateTextureFromFileInMemoryEx(struct IDirect3DDevice9 *devi
 
     if (width == D3DX_FROM_FILE)
     {
-        file_width = TRUE;
         width = imginfo.Width;
     }
 
     if (height == D3DX_FROM_FILE)
     {
-        file_height = TRUE;
         height = imginfo.Height;
     }
 
     if (format == D3DFMT_FROM_FILE)
     {
-        file_format = TRUE;
         format = imginfo.Format;
     }
 
     if (miplevels == D3DX_FROM_FILE)
     {
-        file_miplevels = TRUE;
         miplevels = imginfo.MipLevels;
     }
 
@@ -623,14 +638,6 @@ HRESULT WINAPI D3DXCreateTextureFromFileInMemoryEx(struct IDirect3DDevice9 *devi
         miplevels = 1;
     }
 
-    if (((file_width) && (width != imginfo.Width))    ||
-        ((file_height) && (height != imginfo.Height)) ||
-        ((file_format) && (format != imginfo.Format)) ||
-        ((file_miplevels) && (miplevels != imginfo.MipLevels)))
-    {
-        return D3DERR_NOTAVAILABLE;
-    }
-
     if (FAILED(IDirect3DDevice9_GetDeviceCaps(device, &caps)))
         return D3DERR_INVALIDCALL;
 
index a137418..d4e7df0 100644 (file)
@@ -178,6 +178,7 @@ HRESULT write_buffer_to_file(const WCHAR *dst_filename, ID3DXBuffer *buffer)
     HRESULT hr = S_OK;
     void *buffer_pointer;
     DWORD buffer_size;
+    DWORD bytes_written;
     HANDLE file = CreateFileW(dst_filename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
     if (file == INVALID_HANDLE_VALUE)
         return HRESULT_FROM_WIN32(GetLastError());
@@ -185,7 +186,7 @@ HRESULT write_buffer_to_file(const WCHAR *dst_filename, ID3DXBuffer *buffer)
     buffer_pointer = ID3DXBuffer_GetBufferPointer(buffer);
     buffer_size = ID3DXBuffer_GetBufferSize(buffer);
 
-    if (!WriteFile(file, buffer_pointer, buffer_size, NULL, NULL))
+    if (!WriteFile(file, buffer_pointer, buffer_size, &bytes_written, NULL))
         hr = HRESULT_FROM_WIN32(GetLastError());
 
     CloseHandle(file);
index 7cc0ba8..1442f52 100644 (file)
@@ -294,6 +294,7 @@ static HRESULT d3dx9_file_data_create(IDirectXFileObject *dxfile_object, ID3DXFi
 {
     struct d3dx9_file_data *object;
     IDirectXFileObject *data_object;
+    unsigned int children_array_size = 0;
     HRESULT ret;
 
     TRACE("dxfile_object %p, ret_iface %p.\n", dxfile_object, ret_iface);
@@ -316,6 +317,7 @@ static HRESULT d3dx9_file_data_create(IDirectXFileObject *dxfile_object, ID3DXFi
         if (SUCCEEDED(ret))
         {
             ret = IDirectXFileDataReference_Resolve(reference, &object->dxfile_data);
+            IUnknown_Release(reference);
             if (FAILED(ret))
             {
                 HeapFree(GetProcessHeap(), 0, object);
@@ -333,25 +335,48 @@ static HRESULT d3dx9_file_data_create(IDirectXFileObject *dxfile_object, ID3DXFi
 
     while (SUCCEEDED(ret = IDirectXFileData_GetNextObject(object->dxfile_data, &data_object)))
     {
-        if (object->children)
-            object->children = HeapReAlloc(GetProcessHeap(), 0, object->children, sizeof(ID3DXFileData*) * (object->nb_children + 1));
-        else
-            object->children = HeapAlloc(GetProcessHeap(), 0, sizeof(ID3DXFileData*));
-        if (!object->children)
+        if (object->nb_children >= children_array_size)
         {
-            ret = E_OUTOFMEMORY;
-            break;
+            ID3DXFileData **new_children;
+
+            if (object->children)
+            {
+                children_array_size *= 2;
+                new_children = HeapReAlloc(GetProcessHeap(), 0, object->children,
+                        sizeof(*object->children) * children_array_size);
+            }
+            else
+            {
+                children_array_size = 4;
+                new_children = HeapAlloc(GetProcessHeap(), 0, sizeof(*object->children) * children_array_size);
+            }
+            if (!new_children)
+            {
+                ret = E_OUTOFMEMORY;
+                break;
+            }
+            object->children = new_children;
         }
-        if (FAILED(ret = d3dx9_file_data_create(data_object, &object->children[object->nb_children])))
+        ret = d3dx9_file_data_create(data_object, &object->children[object->nb_children]);
+        IUnknown_Release(data_object);
+        if (FAILED(ret))
             break;
         object->nb_children++;
     }
-
     if (ret != DXFILEERR_NOMOREOBJECTS)
     {
         (&object->ID3DXFileData_iface)->lpVtbl->Release(&object->ID3DXFileData_iface);
         return ret;
     }
+    if (object->children)
+    {
+        ID3DXFileData **new_children;
+
+        new_children = HeapReAlloc(GetProcessHeap(), 0, object->children,
+                sizeof(*object->children) * object->nb_children);
+        if (new_children)
+            object->children = new_children;
+    }
 
     TRACE("Found %u children\n", object->nb_children);
 
@@ -530,6 +555,7 @@ static HRESULT WINAPI d3dx9_file_CreateEnumObject(ID3DXFile *iface, const void *
     DXFILELOADRESOURCE dxfile_resource;
     DXFILELOADMEMORY dxfile_memory;
     IDirectXFileData *data_object;
+    unsigned children_array_size = 0;
     HRESULT ret;
 
     TRACE("iface %p, source %p, options %#x, enum_object %p.\n", iface, source, options, enum_object);
@@ -587,20 +613,44 @@ static HRESULT WINAPI d3dx9_file_CreateEnumObject(ID3DXFile *iface, const void *
     /* Fill enum object with top level data objects */
     while (SUCCEEDED(ret = IDirectXFileEnumObject_GetNextDataObject(dxfile_enum_object, &data_object)))
     {
-        if (object->children)
-            object->children = HeapReAlloc(GetProcessHeap(), 0, object->children, sizeof(*object->children) * (object->nb_children + 1));
-        else
-            object->children = HeapAlloc(GetProcessHeap(), 0, sizeof(*object->children));
-        if (!object->children)
+        if (object->nb_children >= children_array_size)
         {
-            ret = E_OUTOFMEMORY;
-            break;
+            ID3DXFileData **new_children;
+
+            if (object->children)
+            {
+                children_array_size *= 2;
+                new_children = HeapReAlloc(GetProcessHeap(), 0, object->children,
+                        sizeof(*object->children) * children_array_size);
+            }
+            else
+            {
+                children_array_size = 4;
+                new_children = HeapAlloc(GetProcessHeap(), 0, sizeof(*object->children) * children_array_size);
+            }
+            if (!new_children)
+            {
+                ret = E_OUTOFMEMORY;
+                break;
+            }
+            object->children = new_children;
         }
-        if (FAILED(ret = d3dx9_file_data_create((IDirectXFileObject*)data_object,
-                &object->children[object->nb_children])))
+        ret = d3dx9_file_data_create((IDirectXFileObject*)data_object,
+                &object->children[object->nb_children]);
+        IUnknown_Release(data_object);
+        if (FAILED(ret))
             break;
         object->nb_children++;
     }
+    if (object->children)
+    {
+        ID3DXFileData **new_children;
+
+        new_children = HeapReAlloc(GetProcessHeap(), 0, object->children,
+                sizeof(*object->children) * object->nb_children);
+        if (new_children)
+            object->children = new_children;
+    }
 
     IDirectXFileEnumObject_Release(dxfile_enum_object);
 
index bde36bf..bbc5ba0 100644 (file)
@@ -31,7 +31,7 @@ reactos/dll/directx/wine/amstream       # Synced to Wine-1.7.27
 reactos/dll/directx/wine/d3d8           # Synced to Wine-1.7.27
 reactos/dll/directx/wine/d3d9           # Synced to Wine-1.7.27
 reactos/dll/directx/wine/d3dcompiler_43 # Synced to Wine-1.7.27
-reactos/dll/directx/wine/d3dx9_24 => 43 # Synced to Wine-1.7.17
+reactos/dll/directx/wine/d3dx9_24 => 43 # Synced to Wine-1.7.27
 reactos/dll/directx/wine/d3dxof         # Synced to Wine-1.7.17
 reactos/dll/directx/wine/ddraw          # Synced to Wine-1.7.27
 reactos/dll/directx/wine/devenum        # Synced to Wine-1.7.17