[PATCH 1/2] d3dx9_36: Port mesh code to use ID3DXFile instead of IDirectXFile and enable D3DXLoadSkinMeshFromXof.
Christian Costa
titan.costa at gmail.com
Tue May 21 17:03:01 CDT 2013
This serie fixes the main problem with character display in bug 32572.
---
dlls/d3dx9_36/d3dx9_36.spec | 2
dlls/d3dx9_36/mesh.c | 580 ++++++++++++++++++++++++++-----------------
2 files changed, 351 insertions(+), 231 deletions(-)
diff --git a/dlls/d3dx9_36/d3dx9_36.spec b/dlls/d3dx9_36/d3dx9_36.spec
index b2511e8..f2c229a 100644
--- a/dlls/d3dx9_36/d3dx9_36.spec
+++ b/dlls/d3dx9_36/d3dx9_36.spec
@@ -181,7 +181,7 @@
@ stub D3DXLoadPRTBufferFromFileW(ptr ptr)
@ stub D3DXLoadPRTCompBufferFromFileA(ptr ptr)
@ stub D3DXLoadPRTCompBufferFromFileW(ptr ptr)
-@ stub D3DXLoadSkinMeshFromXof(ptr long ptr ptr ptr ptr ptr ptr ptr)
+@ stdcall D3DXLoadSkinMeshFromXof(ptr long ptr ptr ptr ptr ptr ptr ptr)
@ stdcall D3DXLoadSurfaceFromFileA(ptr ptr ptr str ptr long long ptr)
@ stdcall D3DXLoadSurfaceFromFileInMemory(ptr ptr ptr ptr long ptr long long ptr)
@ stdcall D3DXLoadSurfaceFromFileW(ptr ptr ptr wstr ptr long long ptr)
diff --git a/dlls/d3dx9_36/mesh.c b/dlls/d3dx9_36/mesh.c
index 8a3d49a..2b7579e 100644
--- a/dlls/d3dx9_36/mesh.c
+++ b/dlls/d3dx9_36/mesh.c
@@ -2634,41 +2634,10 @@ struct mesh_data {
DWORD *material_indices;
};
-static HRESULT get_next_child(IDirectXFileData *filedata, IDirectXFileData **child, const GUID **type)
+static HRESULT parse_texture_filename(ID3DXFileData *filedata, LPSTR *filename_out)
{
HRESULT hr;
- IDirectXFileDataReference *child_ref = NULL;
- IDirectXFileObject *child_obj = NULL;
- IDirectXFileData *child_data = NULL;
-
- hr = IDirectXFileData_GetNextObject(filedata, &child_obj);
- if (FAILED(hr)) return hr;
-
- hr = IDirectXFileObject_QueryInterface(child_obj, &IID_IDirectXFileDataReference, (void**)&child_ref);
- if (SUCCEEDED(hr)) {
- hr = IDirectXFileDataReference_Resolve(child_ref, &child_data);
- IDirectXFileDataReference_Release(child_ref);
- } else {
- hr = IDirectXFileObject_QueryInterface(child_obj, &IID_IDirectXFileData, (void**)&child_data);
- }
- IDirectXFileObject_Release(child_obj);
- if (FAILED(hr))
- return hr;
-
- hr = IDirectXFileData_GetType(child_data, type);
- if (FAILED(hr)) {
- IDirectXFileData_Release(child_data);
- } else {
- *child = child_data;
- }
-
- return hr;
-}
-
-static HRESULT parse_texture_filename(IDirectXFileData *filedata, LPSTR *filename_out)
-{
- HRESULT hr;
- DWORD data_size;
+ SIZE_T data_size;
BYTE *data;
char *filename_in;
char *filename = NULL;
@@ -2681,35 +2650,44 @@ static HRESULT parse_texture_filename(IDirectXFileData *filedata, LPSTR *filenam
HeapFree(GetProcessHeap(), 0, *filename_out);
*filename_out = NULL;
- hr = IDirectXFileData_GetData(filedata, NULL, &data_size, (void**)&data);
+ hr = filedata->lpVtbl->Lock(filedata, &data_size, (const void**)&data);
if (FAILED(hr)) return hr;
+ /* FIXME: String must be retreive directly instead through a pointer once ID3DXFILE is fixed */
if (data_size < sizeof(LPSTR)) {
- WARN("truncated data (%u bytes)\n", data_size);
+ WARN("truncated data (%lu bytes)\n", data_size);
+ filedata->lpVtbl->Unlock(filedata);
return E_FAIL;
}
filename_in = *(LPSTR*)data;
filename = HeapAlloc(GetProcessHeap(), 0, strlen(filename_in) + 1);
- if (!filename) return E_OUTOFMEMORY;
+ if (!filename) {
+ filedata->lpVtbl->Unlock(filedata);
+ return E_OUTOFMEMORY;
+ }
strcpy(filename, filename_in);
*filename_out = filename;
+ filedata->lpVtbl->Unlock(filedata);
+
return D3D_OK;
}
-static HRESULT parse_material(IDirectXFileData *filedata, D3DXMATERIAL *material)
+static HRESULT parse_material(ID3DXFileData *filedata, D3DXMATERIAL *material)
{
HRESULT hr;
- DWORD data_size;
- BYTE *data;
- const GUID *type;
- IDirectXFileData *child;
+ SIZE_T data_size;
+ const BYTE *data;
+ GUID type;
+ ID3DXFileData *child;
+ SIZE_T nb_children;
+ int i;
material->pTextureFilename = NULL;
- hr = IDirectXFileData_GetData(filedata, NULL, &data_size, (void**)&data);
+ hr = filedata->lpVtbl->Lock(filedata, &data_size, (const void**)&data);
if (FAILED(hr)) return hr;
/*
@@ -2733,7 +2711,8 @@ static HRESULT parse_material(IDirectXFileData *filedata, D3DXMATERIAL *material
* }
*/
if (data_size != sizeof(FLOAT) * 11) {
- WARN("incorrect data size (%u bytes)\n", data_size);
+ WARN("incorrect data size (%ld bytes)\n", data_size);
+ filedata->lpVtbl->Unlock(filedata);
return E_FAIL;
}
@@ -2751,14 +2730,29 @@ static HRESULT parse_material(IDirectXFileData *filedata, D3DXMATERIAL *material
material->MatD3D.Ambient.b = 0.0f;
material->MatD3D.Ambient.a = 1.0f;
- while (SUCCEEDED(hr = get_next_child(filedata, &child, &type)))
+ filedata->lpVtbl->Unlock(filedata);
+
+ hr = filedata->lpVtbl->GetChildren(filedata, &nb_children);
+ if (FAILED(hr))
+ return hr;
+
+ for (i = 0; i < nb_children; i++)
{
- if (IsEqualGUID(type, &TID_D3DRMTextureFilename)) {
+ hr = filedata->lpVtbl->GetChild(filedata, i, &child);
+ if (FAILED(hr))
+ return hr;
+ hr = child->lpVtbl->GetType(child, &type);
+ if (FAILED(hr))
+ return hr;
+
+ if (IsEqualGUID(&type, &TID_D3DRMTextureFilename)) {
hr = parse_texture_filename(child, &material->pTextureFilename);
- if (FAILED(hr)) break;
+ if (FAILED(hr))
+ return hr;
}
}
- return hr == DXFILEERR_NOMOREOBJECTS ? D3D_OK : hr;
+
+ return D3D_OK;
}
static void destroy_materials(struct mesh_data *mesh)
@@ -2773,19 +2767,20 @@ static void destroy_materials(struct mesh_data *mesh)
mesh->material_indices = NULL;
}
-static HRESULT parse_material_list(IDirectXFileData *filedata, struct mesh_data *mesh)
+static HRESULT parse_material_list(ID3DXFileData *filedata, struct mesh_data *mesh)
{
HRESULT hr;
- DWORD data_size;
- DWORD *data, *in_ptr;
- const GUID *type;
- IDirectXFileData *child;
+ SIZE_T data_size;
+ const DWORD *data, *in_ptr;
+ GUID type;
+ ID3DXFileData *child;
DWORD num_materials;
DWORD i;
+ SIZE_T nb_children;
destroy_materials(mesh);
- hr = IDirectXFileData_GetData(filedata, NULL, &data_size, (void**)&data);
+ hr = filedata->lpVtbl->Lock(filedata, &data_size, (const void**)&data);
if (FAILED(hr)) return hr;
/* template MeshMaterialList {
@@ -2797,70 +2792,94 @@ static HRESULT parse_material_list(IDirectXFileData *filedata, struct mesh_data
*/
in_ptr = data;
+ hr = E_FAIL;
- if (data_size < sizeof(DWORD))
- goto truncated_data_error;
+ if (data_size < sizeof(DWORD)) {
+ WARN("truncated data (%ld bytes)\n", data_size);
+ goto end;
+ }
num_materials = *in_ptr++;
- if (!num_materials)
- return D3D_OK;
+ if (!num_materials) {
+ hr = D3D_OK;
+ goto end;
+ }
- if (data_size < 2 * sizeof(DWORD))
- goto truncated_data_error;
+ if (data_size < 2 * sizeof(DWORD)) {
+ WARN("truncated data (%ld bytes)\n", data_size);
+ goto end;
+ }
if (*in_ptr++ != mesh->num_poly_faces) {
WARN("number of material face indices (%u) doesn't match number of faces (%u)\n",
*(in_ptr - 1), mesh->num_poly_faces);
- return E_FAIL;
+ goto end;
+ }
+ if (data_size < 2 * sizeof(DWORD) + mesh->num_poly_faces * sizeof(DWORD)) {
+ WARN("truncated data (%ld bytes)\n", data_size);
+ goto end;
}
- if (data_size < 2 * sizeof(DWORD) + mesh->num_poly_faces * sizeof(DWORD))
- goto truncated_data_error;
for (i = 0; i < mesh->num_poly_faces; i++) {
if (*in_ptr++ >= num_materials) {
WARN("face %u: reference to undefined material %u (only %u materials)\n",
i, *(in_ptr - 1), num_materials);
- return E_FAIL;
+ goto end;
}
}
mesh->materials = HeapAlloc(GetProcessHeap(), 0, num_materials * sizeof(*mesh->materials));
mesh->material_indices = HeapAlloc(GetProcessHeap(), 0, mesh->num_poly_faces * sizeof(*mesh->material_indices));
- if (!mesh->materials || !mesh->material_indices)
- return E_OUTOFMEMORY;
+ if (!mesh->materials || !mesh->material_indices) {
+ hr = E_OUTOFMEMORY;
+ goto end;
+ }
memcpy(mesh->material_indices, data + 2, mesh->num_poly_faces * sizeof(DWORD));
- while (SUCCEEDED(hr = get_next_child(filedata, &child, &type)))
+ hr = filedata->lpVtbl->GetChildren(filedata, &nb_children);
+ if (FAILED(hr))
+ goto end;
+
+ for (i = 0; i < nb_children; i++)
{
- if (IsEqualGUID(type, &TID_D3DRMMaterial)) {
+ hr = filedata->lpVtbl->GetChild(filedata, i, &child);
+ if (FAILED(hr))
+ goto end;
+ hr = child->lpVtbl->GetType(child, &type);
+ if (FAILED(hr))
+ goto end;
+
+ if (IsEqualGUID(&type, &TID_D3DRMMaterial)) {
if (mesh->num_materials >= num_materials) {
WARN("more materials defined than declared\n");
- return E_FAIL;
+ hr = E_FAIL;
+ goto end;
}
hr = parse_material(child, &mesh->materials[mesh->num_materials++]);
- if (FAILED(hr)) break;
+ if (FAILED(hr))
+ goto end;
}
}
- if (hr != DXFILEERR_NOMOREOBJECTS)
- return hr;
if (num_materials != mesh->num_materials) {
WARN("only %u of %u materials defined\n", num_materials, mesh->num_materials);
- return E_FAIL;
+ hr = E_FAIL;
+ goto end;
}
- return D3D_OK;
-truncated_data_error:
- WARN("truncated data (%u bytes)\n", data_size);
- return E_FAIL;
+ hr = D3D_OK;
+
+end:
+ filedata->lpVtbl->Unlock(filedata);
+ return hr;
}
-static HRESULT parse_texture_coords(IDirectXFileData *filedata, struct mesh_data *mesh)
+static HRESULT parse_texture_coords(ID3DXFileData *filedata, struct mesh_data *mesh)
{
HRESULT hr;
- DWORD data_size;
- BYTE *data;
+ SIZE_T data_size;
+ const BYTE *data;
HeapFree(GetProcessHeap(), 0, mesh->tex_coords);
mesh->tex_coords = NULL;
- hr = IDirectXFileData_GetData(filedata, NULL, &data_size, (void**)&data);
+ hr = filedata->lpVtbl->Lock(filedata, &data_size, (const void**)&data);
if (FAILED(hr)) return hr;
/* template Coords2d {
@@ -2873,41 +2892,51 @@ static HRESULT parse_texture_coords(IDirectXFileData *filedata, struct mesh_data
* }
*/
- if (data_size < sizeof(DWORD))
- goto truncated_data_error;
+ hr = E_FAIL;
+
+ if (data_size < sizeof(DWORD)) {
+ WARN("truncated data (%ld bytes)\n", data_size);
+ goto end;
+ }
if (*(DWORD*)data != mesh->num_vertices) {
WARN("number of texture coordinates (%u) doesn't match number of vertices (%u)\n",
*(DWORD*)data, mesh->num_vertices);
- return E_FAIL;
+ goto end;
}
data += sizeof(DWORD);
- if (data_size < sizeof(DWORD) + mesh->num_vertices * sizeof(*mesh->tex_coords))
- goto truncated_data_error;
+ if (data_size < sizeof(DWORD) + mesh->num_vertices * sizeof(*mesh->tex_coords)) {
+ WARN("truncated data (%ld bytes)\n", data_size);
+ goto end;
+ }
mesh->tex_coords = HeapAlloc(GetProcessHeap(), 0, mesh->num_vertices * sizeof(*mesh->tex_coords));
- if (!mesh->tex_coords) return E_OUTOFMEMORY;
+ if (!mesh->tex_coords) {
+ hr = E_OUTOFMEMORY;
+ goto end;
+ }
memcpy(mesh->tex_coords, data, mesh->num_vertices * sizeof(*mesh->tex_coords));
mesh->fvf |= D3DFVF_TEX1;
- return D3D_OK;
-truncated_data_error:
- WARN("truncated data (%u bytes)\n", data_size);
- return E_FAIL;
+ hr = D3D_OK;
+
+end:
+ filedata->lpVtbl->Unlock(filedata);
+ return hr;
}
-static HRESULT parse_vertex_colors(IDirectXFileData *filedata, struct mesh_data *mesh)
+static HRESULT parse_vertex_colors(ID3DXFileData *filedata, struct mesh_data *mesh)
{
HRESULT hr;
- DWORD data_size;
- BYTE *data;
+ SIZE_T data_size;
+ const BYTE *data;
DWORD num_colors;
DWORD i;
HeapFree(GetProcessHeap(), 0, mesh->vertex_colors);
mesh->vertex_colors = NULL;
- hr = IDirectXFileData_GetData(filedata, NULL, &data_size, (void**)&data);
+ hr = filedata->lpVtbl->Lock(filedata, &data_size, (const void**)&data);
if (FAILED(hr)) return hr;
/* template IndexedColor {
@@ -2920,16 +2949,24 @@ static HRESULT parse_vertex_colors(IDirectXFileData *filedata, struct mesh_data
* }
*/
- if (data_size < sizeof(DWORD))
- goto truncated_data_error;
+ hr = E_FAIL;
+
+ if (data_size < sizeof(DWORD)) {
+ WARN("truncated data (%ld bytes)\n", data_size);
+ goto end;
+ }
num_colors = *(DWORD*)data;
data += sizeof(DWORD);
- if (data_size < sizeof(DWORD) + num_colors * (sizeof(DWORD) + sizeof(D3DCOLORVALUE)))
- goto truncated_data_error;
+ if (data_size < sizeof(DWORD) + num_colors * (sizeof(DWORD) + sizeof(D3DCOLORVALUE))) {
+ WARN("truncated data (%ld bytes)\n", data_size);
+ goto end;
+ }
mesh->vertex_colors = HeapAlloc(GetProcessHeap(), 0, mesh->num_vertices * sizeof(DWORD));
- if (!mesh->vertex_colors)
- return E_OUTOFMEMORY;
+ if (!mesh->vertex_colors) {
+ hr = E_OUTOFMEMORY;
+ goto end;
+ }
for (i = 0; i < mesh->num_vertices; i++)
mesh->vertex_colors[i] = D3DCOLOR_ARGB(0, 0xff, 0xff, 0xff);
@@ -2941,7 +2978,7 @@ static HRESULT parse_vertex_colors(IDirectXFileData *filedata, struct mesh_data
if (index >= mesh->num_vertices) {
WARN("vertex color %u references undefined vertex %u (only %u vertices)\n",
i, index, mesh->num_vertices);
- return E_FAIL;
+ goto end;
}
memcpy(&color, data, sizeof(color));
data += sizeof(color);
@@ -2957,17 +2994,18 @@ static HRESULT parse_vertex_colors(IDirectXFileData *filedata, struct mesh_data
mesh->fvf |= D3DFVF_DIFFUSE;
- return D3D_OK;
-truncated_data_error:
- WARN("truncated data (%u bytes)\n", data_size);
- return E_FAIL;
+ hr = D3D_OK;
+
+end:
+ filedata->lpVtbl->Unlock(filedata);
+ return hr;
}
-static HRESULT parse_normals(IDirectXFileData *filedata, struct mesh_data *mesh)
+static HRESULT parse_normals(ID3DXFileData *filedata, struct mesh_data *mesh)
{
HRESULT hr;
- DWORD data_size;
- BYTE *data;
+ SIZE_T data_size;
+ const BYTE *data;
DWORD *index_out_ptr;
DWORD i;
DWORD num_face_indices = mesh->num_poly_faces * 2 + mesh->num_tri_faces;
@@ -2978,7 +3016,7 @@ static HRESULT parse_normals(IDirectXFileData *filedata, struct mesh_data *mesh)
mesh->normal_indices = NULL;
mesh->fvf |= D3DFVF_NORMAL;
- hr = IDirectXFileData_GetData(filedata, NULL, &data_size, (void**)&data);
+ hr = filedata->lpVtbl->Lock(filedata, &data_size, (const void**)&data);
if (FAILED(hr)) return hr;
/* template Vector {
@@ -2998,18 +3036,26 @@ static HRESULT parse_normals(IDirectXFileData *filedata, struct mesh_data *mesh)
* }
*/
- if (data_size < sizeof(DWORD) * 2)
- goto truncated_data_error;
+ hr = E_FAIL;
+
+ if (data_size < sizeof(DWORD) * 2) {
+ WARN("truncated data (%ld bytes)\n", data_size);
+ goto end;
+ }
mesh->num_normals = *(DWORD*)data;
data += sizeof(DWORD);
if (data_size < sizeof(DWORD) * 2 + mesh->num_normals * sizeof(D3DXVECTOR3) +
- num_face_indices * sizeof(DWORD))
- goto truncated_data_error;
+ num_face_indices * sizeof(DWORD)) {
+ WARN("truncated data (%ld bytes)\n", data_size);
+ goto end;
+ }
mesh->normals = HeapAlloc(GetProcessHeap(), 0, mesh->num_normals * sizeof(D3DXVECTOR3));
mesh->normal_indices = HeapAlloc(GetProcessHeap(), 0, num_face_indices * sizeof(DWORD));
- if (!mesh->normals || !mesh->normal_indices)
- return E_OUTOFMEMORY;
+ if (!mesh->normals || !mesh->normal_indices) {
+ hr = E_OUTOFMEMORY;
+ goto end;
+ }
memcpy(mesh->normals, data, mesh->num_normals * sizeof(D3DXVECTOR3));
data += mesh->num_normals * sizeof(D3DXVECTOR3);
@@ -3019,7 +3065,7 @@ static HRESULT parse_normals(IDirectXFileData *filedata, struct mesh_data *mesh)
if (*(DWORD*)data != mesh->num_poly_faces) {
WARN("number of face normals (%u) doesn't match number of faces (%u)\n",
*(DWORD*)data, mesh->num_poly_faces);
- return E_FAIL;
+ goto end;
}
data += sizeof(DWORD);
index_out_ptr = mesh->normal_indices;
@@ -3030,7 +3076,7 @@ static HRESULT parse_normals(IDirectXFileData *filedata, struct mesh_data *mesh)
if (count != mesh->num_tri_per_face[i] + 2) {
WARN("face %u: number of normals (%u) doesn't match number of vertices (%u)\n",
i, count, mesh->num_tri_per_face[i] + 2);
- return E_FAIL;
+ goto end;
}
data += sizeof(DWORD);
@@ -3039,17 +3085,18 @@ static HRESULT parse_normals(IDirectXFileData *filedata, struct mesh_data *mesh)
if (normal_index >= mesh->num_normals) {
WARN("face %u, normal index %u: reference to undefined normal %u (only %u normals)\n",
i, j, normal_index, mesh->num_normals);
- return E_FAIL;
+ goto end;
}
*index_out_ptr++ = normal_index;
data += sizeof(DWORD);
}
}
- return D3D_OK;
-truncated_data_error:
- WARN("truncated data (%u bytes)\n", data_size);
- return E_FAIL;
+ hr = D3D_OK;
+
+end:
+ filedata->lpVtbl->Unlock(filedata);
+ return hr;
}
/* for provide_flags parameters */
@@ -3057,15 +3104,16 @@ truncated_data_error:
#define PROVIDE_SKININFO 0x2
#define PROVIDE_ADJACENCY 0x4
-static HRESULT parse_mesh(IDirectXFileData *filedata, struct mesh_data *mesh_data, DWORD provide_flags)
+static HRESULT parse_mesh(ID3DXFileData *filedata, struct mesh_data *mesh_data, DWORD provide_flags)
{
HRESULT hr;
- DWORD data_size;
- BYTE *data, *in_ptr;
+ SIZE_T data_size;
+ const BYTE *data, *in_ptr;
DWORD *index_out_ptr;
- const GUID *type;
- IDirectXFileData *child;
+ GUID type;
+ ID3DXFileData *child;
DWORD i;
+ SIZE_T nb_children;
/*
* template Mesh {
@@ -3077,15 +3125,21 @@ static HRESULT parse_mesh(IDirectXFileData *filedata, struct mesh_data *mesh_dat
* }
*/
- hr = IDirectXFileData_GetData(filedata, NULL, &data_size, (void**)&data);
+ hr = filedata->lpVtbl->Lock(filedata, &data_size, (const void**)&data);
if (FAILED(hr)) return hr;
in_ptr = data;
- if (data_size < sizeof(DWORD) * 2)
- goto truncated_data_error;
+ hr = E_FAIL;
+
+ if (data_size < sizeof(DWORD) * 2) {
+ WARN("truncated data (%ld bytes)\n", data_size);
+ goto end;
+ }
mesh_data->num_vertices = *(DWORD*)in_ptr;
- if (data_size < sizeof(DWORD) * 2 + mesh_data->num_vertices * sizeof(D3DXVECTOR3))
- goto truncated_data_error;
+ if (data_size < sizeof(DWORD) * 2 + mesh_data->num_vertices * sizeof(D3DXVECTOR3)) {
+ WARN("truncated data (%ld bytes)\n", data_size);
+ goto end;
+ }
in_ptr += sizeof(DWORD) + mesh_data->num_vertices * sizeof(D3DXVECTOR3);
mesh_data->num_poly_faces = *(DWORD*)in_ptr;
@@ -3097,21 +3151,25 @@ static HRESULT parse_mesh(IDirectXFileData *filedata, struct mesh_data *mesh_dat
DWORD num_poly_vertices;
DWORD j;
- if (data_size - (in_ptr - data) < sizeof(DWORD))
- goto truncated_data_error;
+ if (data_size - (in_ptr - data) < sizeof(DWORD)) {
+ WARN("truncated data (%ld bytes)\n", data_size);
+ goto end;
+ }
num_poly_vertices = *(DWORD*)in_ptr;
in_ptr += sizeof(DWORD);
- if (data_size - (in_ptr - data) < num_poly_vertices * sizeof(DWORD))
- goto truncated_data_error;
+ if (data_size - (in_ptr - data) < num_poly_vertices * sizeof(DWORD)) {
+ WARN("truncated data (%ld bytes)\n", data_size);
+ goto end;
+ }
if (num_poly_vertices < 3) {
WARN("face %u has only %u vertices\n", i, num_poly_vertices);
- return E_FAIL;
+ goto end;
}
for (j = 0; j < num_poly_vertices; j++) {
if (*(DWORD*)in_ptr >= mesh_data->num_vertices) {
WARN("face %u, index %u: undefined vertex %u (only %u vertices)\n",
i, j, *(DWORD*)in_ptr, mesh_data->num_vertices);
- return E_FAIL;
+ goto end;
}
in_ptr += sizeof(DWORD);
}
@@ -3126,8 +3184,10 @@ static HRESULT parse_mesh(IDirectXFileData *filedata, struct mesh_data *mesh_dat
mesh_data->num_poly_faces * sizeof(*mesh_data->num_tri_per_face));
mesh_data->indices = HeapAlloc(GetProcessHeap(), 0,
(mesh_data->num_tri_faces + mesh_data->num_poly_faces * 2) * sizeof(*mesh_data->indices));
- if (!mesh_data->vertices || !mesh_data->num_tri_per_face || !mesh_data->indices)
- return E_OUTOFMEMORY;
+ if (!mesh_data->vertices || !mesh_data->num_tri_per_face || !mesh_data->indices) {
+ hr = E_OUTOFMEMORY;
+ goto end;
+ }
in_ptr = data + sizeof(DWORD);
memcpy(mesh_data->vertices, in_ptr, mesh_data->num_vertices * sizeof(D3DXVECTOR3));
@@ -3148,33 +3208,50 @@ static HRESULT parse_mesh(IDirectXFileData *filedata, struct mesh_data *mesh_dat
}
}
- while (SUCCEEDED(hr = get_next_child(filedata, &child, &type)))
+ hr = filedata->lpVtbl->GetChildren(filedata, &nb_children);
+ if (FAILED(hr))
+ goto end;
+
+ for (i = 0; i < nb_children; i++)
{
- if (IsEqualGUID(type, &TID_D3DRMMeshNormals)) {
+ hr = filedata->lpVtbl->GetChild(filedata, i, &child);
+ if (FAILED(hr))
+ goto end;
+ hr = child->lpVtbl->GetType(child, &type);
+ if (FAILED(hr))
+ goto end;
+
+ if (IsEqualGUID(&type, &TID_D3DRMMeshNormals)) {
hr = parse_normals(child, mesh_data);
- } else if (IsEqualGUID(type, &TID_D3DRMMeshVertexColors)) {
+ } else if (IsEqualGUID(&type, &TID_D3DRMMeshVertexColors)) {
hr = parse_vertex_colors(child, mesh_data);
- } else if (IsEqualGUID(type, &TID_D3DRMMeshTextureCoords)) {
+ } else if (IsEqualGUID(&type, &TID_D3DRMMeshTextureCoords)) {
hr = parse_texture_coords(child, mesh_data);
- } else if (IsEqualGUID(type, &TID_D3DRMMeshMaterialList) &&
+ hr = filedata->lpVtbl->GetChild(filedata, i, &child);
+ if (FAILED(hr))
+ goto end;
+ } else if (IsEqualGUID(&type, &TID_D3DRMMeshMaterialList) &&
(provide_flags & PROVIDE_MATERIALS))
{
hr = parse_material_list(child, mesh_data);
} else if (provide_flags & PROVIDE_SKININFO) {
- if (IsEqualGUID(type, &DXFILEOBJ_XSkinMeshHeader)) {
+ if (IsEqualGUID(&type, &DXFILEOBJ_XSkinMeshHeader)) {
FIXME("Skin mesh loading not implemented.\n");
hr = E_NOTIMPL;
- } else if (IsEqualGUID(type, &DXFILEOBJ_SkinWeights)) {
+ goto end;
+ } else if (IsEqualGUID(&type, &DXFILEOBJ_SkinWeights)) {
/* ignored without XSkinMeshHeader */
}
}
if (FAILED(hr))
- break;
+ goto end;
}
- return hr == DXFILEERR_NOMOREOBJECTS ? D3D_OK : hr;
-truncated_data_error:
- WARN("truncated data (%u bytes)\n", data_size);
- return E_FAIL;
+
+ hr = D3D_OK;
+
+end:
+ filedata->lpVtbl->Unlock(filedata);
+ return hr;
}
static HRESULT generate_effects(ID3DXBuffer *materials, DWORD num_materials,
@@ -3274,8 +3351,7 @@ static HRESULT generate_effects(ID3DXBuffer *materials, DWORD num_materials,
return D3D_OK;
}
-/* change to D3DXLoadSkinMeshFromXof when ID3DXFileData is implemented */
-static HRESULT load_skin_mesh_from_xof(struct IDirectXFileData *filedata, DWORD options,
+HRESULT WINAPI D3DXLoadSkinMeshFromXof(struct ID3DXFileData *filedata, DWORD options,
struct IDirect3DDevice9 *device, struct ID3DXBuffer **adjacency_out, struct ID3DXBuffer **materials_out,
struct ID3DXBuffer **effects_out, DWORD *num_materials_out, struct ID3DXSkinInfo **skin_info_out,
struct ID3DXMesh **mesh_out)
@@ -3298,6 +3374,9 @@ static HRESULT load_skin_mesh_from_xof(struct IDirectXFileData *filedata, DWORD
BYTE *out_ptr;
DWORD provide_flags = 0;
+ TRACE("(%p, %x, %p, %p, %p, %p, %p, %p, %p)\n", filedata, options, device, adjacency_out, materials_out,
+ effects_out, num_materials_out, skin_info_out, mesh_out);
+
ZeroMemory(&mesh_data, sizeof(mesh_data));
if (num_materials_out || materials_out || effects_out)
@@ -3566,12 +3645,12 @@ HRESULT WINAPI D3DXLoadMeshHierarchyFromXW(const WCHAR *filename, DWORD options,
return hr;
}
-static HRESULT filedata_get_name(IDirectXFileData *filedata, char **name)
+static HRESULT filedata_get_name(ID3DXFileData *filedata, char **name)
{
HRESULT hr;
- DWORD name_len;
+ SIZE_T name_len;
- hr = IDirectXFileData_GetName(filedata, NULL, &name_len);
+ hr = filedata->lpVtbl->GetName(filedata, NULL, &name_len);
if (FAILED(hr)) return hr;
if (!name_len)
@@ -3579,7 +3658,7 @@ static HRESULT filedata_get_name(IDirectXFileData *filedata, char **name)
*name = HeapAlloc(GetProcessHeap(), 0, name_len);
if (!*name) return E_OUTOFMEMORY;
- hr = IDirectXFileObject_GetName(filedata, *name, &name_len);
+ hr = filedata->lpVtbl->GetName(filedata, *name, &name_len);
if (FAILED(hr))
HeapFree(GetProcessHeap(), 0, *name);
else if (!name_len)
@@ -3588,7 +3667,7 @@ static HRESULT filedata_get_name(IDirectXFileData *filedata, char **name)
return hr;
}
-static HRESULT load_mesh_container(struct IDirectXFileData *filedata, DWORD options, struct IDirect3DDevice9 *device,
+static HRESULT load_mesh_container(struct ID3DXFileData *filedata, DWORD options, struct IDirect3DDevice9 *device,
struct ID3DXAllocateHierarchy *alloc_hier, D3DXMESHCONTAINER **mesh_container)
{
HRESULT hr;
@@ -3603,7 +3682,7 @@ static HRESULT load_mesh_container(struct IDirectXFileData *filedata, DWORD opti
mesh_data.Type = D3DXMESHTYPE_MESH;
mesh_data.u.pMesh = NULL;
- hr = load_skin_mesh_from_xof(filedata, options, device,
+ hr = D3DXLoadSkinMeshFromXof(filedata, options, device,
&adjacency, &materials, &effects, &num_materials,
&skin_info, &mesh_data.u.pMesh);
if (FAILED(hr)) return hr;
@@ -3628,11 +3707,11 @@ cleanup:
return hr;
}
-static HRESULT parse_transform_matrix(IDirectXFileData *filedata, D3DXMATRIX *transform)
+static HRESULT parse_transform_matrix(ID3DXFileData *filedata, D3DXMATRIX *transform)
{
HRESULT hr;
- DWORD data_size;
- BYTE *data;
+ SIZE_T data_size;
+ const BYTE *data;
/* template Matrix4x4 {
* array FLOAT matrix[16];
@@ -3642,29 +3721,33 @@ static HRESULT parse_transform_matrix(IDirectXFileData *filedata, D3DXMATRIX *tr
* }
*/
- hr = IDirectXFileData_GetData(filedata, NULL, &data_size, (void**)&data);
+ hr = filedata->lpVtbl->Lock(filedata, &data_size, (const void**)&data);
if (FAILED(hr)) return hr;
if (data_size != sizeof(D3DXMATRIX)) {
- WARN("incorrect data size (%u bytes)\n", data_size);
+ WARN("incorrect data size (%ld bytes)\n", data_size);
+ filedata->lpVtbl->Unlock(filedata);
return E_FAIL;
}
memcpy(transform, data, sizeof(D3DXMATRIX));
+ filedata->lpVtbl->Unlock(filedata);
return D3D_OK;
}
-static HRESULT load_frame(struct IDirectXFileData *filedata, DWORD options, struct IDirect3DDevice9 *device,
+static HRESULT load_frame(struct ID3DXFileData *filedata, DWORD options, struct IDirect3DDevice9 *device,
struct ID3DXAllocateHierarchy *alloc_hier, D3DXFRAME **frame_out)
{
HRESULT hr;
- const GUID *type;
- IDirectXFileData *child;
+ GUID type;
+ ID3DXFileData *child;
char *name = NULL;
D3DXFRAME *frame = NULL;
D3DXMESHCONTAINER **next_container;
D3DXFRAME **next_child;
+ SIZE_T nb_children;
+ int i;
hr = filedata_get_name(filedata, &name);
if (FAILED(hr)) return hr;
@@ -3678,25 +3761,35 @@ static HRESULT load_frame(struct IDirectXFileData *filedata, DWORD options, stru
next_child = &frame->pFrameFirstChild;
next_container = &frame->pMeshContainer;
- while (SUCCEEDED(hr = get_next_child(filedata, &child, &type)))
+ hr = filedata->lpVtbl->GetChildren(filedata, &nb_children);
+ if (FAILED(hr))
+ return hr;
+
+ for (i = 0; i < nb_children; i++)
{
- if (IsEqualGUID(type, &TID_D3DRMMesh)) {
+ hr = filedata->lpVtbl->GetChild(filedata, i, &child);
+ if (FAILED(hr))
+ return hr;
+ hr = child->lpVtbl->GetType(child, &type);
+ if (FAILED(hr))
+ return hr;
+
+ if (IsEqualGUID(&type, &TID_D3DRMMesh)) {
hr = load_mesh_container(child, options, device, alloc_hier, next_container);
if (SUCCEEDED(hr))
next_container = &(*next_container)->pNextMeshContainer;
- } else if (IsEqualGUID(type, &TID_D3DRMFrameTransformMatrix)) {
+ } else if (IsEqualGUID(&type, &TID_D3DRMFrameTransformMatrix)) {
hr = parse_transform_matrix(child, &frame->TransformationMatrix);
- } else if (IsEqualGUID(type, &TID_D3DRMFrame)) {
+ } else if (IsEqualGUID(&type, &TID_D3DRMFrame)) {
hr = load_frame(child, options, device, alloc_hier, next_child);
if (SUCCEEDED(hr))
next_child = &(*next_child)->pFrameSibling;
}
- if (FAILED(hr)) break;
+ if (FAILED(hr))
+ return hr;
}
- if (hr == DXFILEERR_NOMOREOBJECTS)
- hr = D3D_OK;
- return hr;
+ return D3D_OK;
}
HRESULT WINAPI D3DXLoadMeshHierarchyFromXInMemory(const void *memory, DWORD memory_size, DWORD options,
@@ -3705,12 +3798,15 @@ HRESULT WINAPI D3DXLoadMeshHierarchyFromXInMemory(const void *memory, DWORD memo
struct ID3DXAnimationController **anim_controller)
{
HRESULT hr;
- IDirectXFile *dxfile = NULL;
- IDirectXFileEnumObject *enumobj = NULL;
- IDirectXFileData *filedata = NULL;
- DXFILELOADMEMORY source;
+ ID3DXFile *d3dxfile = NULL;
+ ID3DXFileEnumObject *enumobj = NULL;
+ ID3DXFileData *filedata = NULL;
+ D3DXF_FILELOADMEMORY source;
D3DXFRAME *first_frame = NULL;
D3DXFRAME **next_frame = &first_frame;
+ SIZE_T nb_children;
+ GUID guid;
+ int i;
TRACE("(%p, %u, %x, %p, %p, %p, %p, %p)\n", memory, memory_size, options,
device, alloc_hier, load_user_data, frame_hierarchy, anim_controller);
@@ -3725,24 +3821,30 @@ HRESULT WINAPI D3DXLoadMeshHierarchyFromXInMemory(const void *memory, DWORD memo
return E_NOTIMPL;
}
- hr = DirectXFileCreate(&dxfile);
+ hr = D3DXFileCreate(&d3dxfile);
if (FAILED(hr)) goto cleanup;
- hr = IDirectXFile_RegisterTemplates(dxfile, D3DRM_XTEMPLATES, D3DRM_XTEMPLATE_BYTES);
+ hr = d3dxfile->lpVtbl->RegisterTemplates(d3dxfile, D3DRM_XTEMPLATES, D3DRM_XTEMPLATE_BYTES);
if (FAILED(hr)) goto cleanup;
source.lpMemory = (void*)memory;
source.dSize = memory_size;
- hr = IDirectXFile_CreateEnumObject(dxfile, &source, DXFILELOAD_FROMMEMORY, &enumobj);
+ hr = d3dxfile->lpVtbl->CreateEnumObject(d3dxfile, &source, D3DXF_FILELOAD_FROMMEMORY, &enumobj);
if (FAILED(hr)) goto cleanup;
- while (SUCCEEDED(hr = IDirectXFileEnumObject_GetNextDataObject(enumobj, &filedata)))
+ hr = enumobj->lpVtbl->GetChildren(enumobj, &nb_children);
+ if (FAILED(hr))
+ goto cleanup;
+
+ for (i = 0; i < nb_children; i++)
{
- const GUID *guid = NULL;
+ hr = enumobj->lpVtbl->GetChild(enumobj, i, &filedata);
+ if (FAILED(hr))
+ goto cleanup;
- hr = IDirectXFileData_GetType(filedata, &guid);
+ hr = filedata->lpVtbl->GetType(filedata, &guid);
if (SUCCEEDED(hr)) {
- if (IsEqualGUID(guid, &TID_D3DRMMesh)) {
+ if (IsEqualGUID(&guid, &TID_D3DRMMesh)) {
hr = alloc_hier->lpVtbl->CreateFrame(alloc_hier, NULL, next_frame);
if (FAILED(hr)) {
hr = E_FAIL;
@@ -3753,7 +3855,7 @@ HRESULT WINAPI D3DXLoadMeshHierarchyFromXInMemory(const void *memory, DWORD memo
hr = load_mesh_container(filedata, options, device, alloc_hier, &(*next_frame)->pMeshContainer);
if (FAILED(hr)) goto cleanup;
- } else if (IsEqualGUID(guid, &TID_D3DRMFrame)) {
+ } else if (IsEqualGUID(&guid, &TID_D3DRMFrame)) {
hr = load_frame(filedata, options, device, alloc_hier, next_frame);
if (FAILED(hr)) goto cleanup;
}
@@ -3761,13 +3863,11 @@ HRESULT WINAPI D3DXLoadMeshHierarchyFromXInMemory(const void *memory, DWORD memo
next_frame = &(*next_frame)->pFrameSibling;
}
- IDirectXFileData_Release(filedata);
+ filedata->lpVtbl->Release(filedata);
filedata = NULL;
if (FAILED(hr))
goto cleanup;
}
- if (hr != DXFILEERR_NOMOREOBJECTS)
- goto cleanup;
if (!first_frame) {
hr = E_FAIL;
@@ -3789,9 +3889,9 @@ HRESULT WINAPI D3DXLoadMeshHierarchyFromXInMemory(const void *memory, DWORD memo
cleanup:
if (FAILED(hr) && first_frame) D3DXFrameDestroy(first_frame, alloc_hier);
- if (filedata) IDirectXFileData_Release(filedata);
- if (enumobj) IDirectXFileEnumObject_Release(enumobj);
- if (dxfile) IDirectXFile_Release(dxfile);
+ if (filedata) filedata->lpVtbl->Release(filedata);
+ if (enumobj) enumobj->lpVtbl->Release(enumobj);
+ if (d3dxfile) d3dxfile->lpVtbl->Release(d3dxfile);
return hr;
}
@@ -3931,39 +4031,52 @@ struct mesh_container
D3DXMATRIX transform;
};
-static HRESULT parse_frame(struct IDirectXFileData *filedata, DWORD options, struct IDirect3DDevice9 *device,
+static HRESULT parse_frame(struct ID3DXFileData *filedata, DWORD options, struct IDirect3DDevice9 *device,
const D3DXMATRIX *parent_transform, struct list *container_list, DWORD provide_flags)
{
HRESULT hr;
D3DXMATRIX transform = *parent_transform;
- IDirectXFileData *child;
- const GUID *type;
+ ID3DXFileData *child;
+ GUID type;
+ SIZE_T nb_children;
+ int i;
+
+ hr = filedata->lpVtbl->GetChildren(filedata, &nb_children);
+ if (FAILED(hr))
+ return hr;
- while (SUCCEEDED(hr = get_next_child(filedata, &child, &type)))
+ for (i = 0; i < nb_children; i++)
{
- if (IsEqualGUID(type, &TID_D3DRMMesh)) {
+ hr = filedata->lpVtbl->GetChild(filedata, i, &child);
+ if (FAILED(hr))
+ return hr;
+ hr = child->lpVtbl->GetType(child, &type);
+ if (FAILED(hr))
+ return hr;
+
+ if (IsEqualGUID(&type, &TID_D3DRMMesh)) {
struct mesh_container *container = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*container));
- if (!container) {
- hr = E_OUTOFMEMORY;
- break;
- }
+ if (!container)
+ return E_OUTOFMEMORY;
list_add_tail(container_list, &container->entry);
container->transform = transform;
- hr = load_skin_mesh_from_xof(child, options, device,
+ hr = D3DXLoadSkinMeshFromXof(child, options, device,
(provide_flags & PROVIDE_ADJACENCY) ? &container->adjacency : NULL,
(provide_flags & PROVIDE_MATERIALS) ? &container->materials : NULL,
NULL, &container->num_materials, NULL, &container->mesh);
- } else if (IsEqualGUID(type, &TID_D3DRMFrameTransformMatrix)) {
+ } else if (IsEqualGUID(&type, &TID_D3DRMFrameTransformMatrix)) {
D3DXMATRIX new_transform;
hr = parse_transform_matrix(child, &new_transform);
D3DXMatrixMultiply(&transform, &transform, &new_transform);
- } else if (IsEqualGUID(type, &TID_D3DRMFrame)) {
+ } else if (IsEqualGUID(&type, &TID_D3DRMFrame)) {
hr = parse_frame(child, options, device, &transform, container_list, provide_flags);
}
- if (FAILED(hr)) break;
+ if (FAILED(hr))
+ return hr;
}
- return hr == DXFILEERR_NOMOREOBJECTS ? D3D_OK : hr;
+
+ return D3D_OK;
}
HRESULT WINAPI D3DXLoadMeshFromXInMemory(const void *memory, DWORD memory_size, DWORD options,
@@ -3971,10 +4084,10 @@ HRESULT WINAPI D3DXLoadMeshFromXInMemory(const void *memory, DWORD memory_size,
struct ID3DXBuffer **effects_out, DWORD *num_materials_out, struct ID3DXMesh **mesh_out)
{
HRESULT hr;
- IDirectXFile *dxfile = NULL;
- IDirectXFileEnumObject *enumobj = NULL;
- IDirectXFileData *filedata = NULL;
- DXFILELOADMEMORY source;
+ ID3DXFile *d3dxfile = NULL;
+ ID3DXFileEnumObject *enumobj = NULL;
+ ID3DXFileData *filedata = NULL;
+ D3DXF_FILELOADMEMORY source;
ID3DXBuffer *materials = NULL;
ID3DXBuffer *effects = NULL;
ID3DXBuffer *adjacency = NULL;
@@ -3991,6 +4104,9 @@ HRESULT WINAPI D3DXLoadMeshFromXInMemory(const void *memory, DWORD memory_size,
void *concat_indices = NULL;
DWORD index_offset;
DWORD concat_vertex_size;
+ SIZE_T nb_children;
+ GUID guid;
+ int i;
TRACE("(%p, %u, %x, %p, %p, %p, %p, %p, %p)\n", memory, memory_size, options,
device, adjacency_out, materials_out, effects_out, num_materials_out, mesh_out);
@@ -3998,28 +4114,34 @@ HRESULT WINAPI D3DXLoadMeshFromXInMemory(const void *memory, DWORD memory_size,
if (!memory || !memory_size || !device || !mesh_out)
return D3DERR_INVALIDCALL;
- hr = DirectXFileCreate(&dxfile);
+ hr = D3DXFileCreate(&d3dxfile);
if (FAILED(hr)) goto cleanup;
- hr = IDirectXFile_RegisterTemplates(dxfile, D3DRM_XTEMPLATES, D3DRM_XTEMPLATE_BYTES);
+ hr = d3dxfile->lpVtbl->RegisterTemplates(d3dxfile, D3DRM_XTEMPLATES, D3DRM_XTEMPLATE_BYTES);
if (FAILED(hr)) goto cleanup;
source.lpMemory = (void*)memory;
source.dSize = memory_size;
- hr = IDirectXFile_CreateEnumObject(dxfile, &source, DXFILELOAD_FROMMEMORY, &enumobj);
+ hr = d3dxfile->lpVtbl->CreateEnumObject(d3dxfile, &source, D3DXF_FILELOAD_FROMMEMORY, &enumobj);
if (FAILED(hr)) goto cleanup;
D3DXMatrixIdentity(&identity);
if (adjacency_out) provide_flags |= PROVIDE_ADJACENCY;
if (materials_out || effects_out) provide_flags |= PROVIDE_MATERIALS;
- while (SUCCEEDED(hr = IDirectXFileEnumObject_GetNextDataObject(enumobj, &filedata)))
+ hr = enumobj->lpVtbl->GetChildren(enumobj, &nb_children);
+ if (FAILED(hr))
+ goto cleanup;
+
+ for (i = 0; i < nb_children; i++)
{
- const GUID *guid = NULL;
+ hr = enumobj->lpVtbl->GetChild(enumobj, i, &filedata);
+ if (FAILED(hr))
+ goto cleanup;
- hr = IDirectXFileData_GetType(filedata, &guid);
+ hr = filedata->lpVtbl->GetType(filedata, &guid);
if (SUCCEEDED(hr)) {
- if (IsEqualGUID(guid, &TID_D3DRMMesh)) {
+ if (IsEqualGUID(&guid, &TID_D3DRMMesh)) {
container_ptr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*container_ptr));
if (!container_ptr) {
hr = E_OUTOFMEMORY;
@@ -4028,27 +4150,25 @@ HRESULT WINAPI D3DXLoadMeshFromXInMemory(const void *memory, DWORD memory_size,
list_add_tail(&container_list, &container_ptr->entry);
D3DXMatrixIdentity(&container_ptr->transform);
- hr = load_skin_mesh_from_xof(filedata, options, device,
+ hr = D3DXLoadSkinMeshFromXof(filedata, options, device,
(provide_flags & PROVIDE_ADJACENCY) ? &container_ptr->adjacency : NULL,
(provide_flags & PROVIDE_MATERIALS) ? &container_ptr->materials : NULL,
NULL, &container_ptr->num_materials, NULL, &container_ptr->mesh);
- } else if (IsEqualGUID(guid, &TID_D3DRMFrame)) {
+ } else if (IsEqualGUID(&guid, &TID_D3DRMFrame)) {
hr = parse_frame(filedata, options, device, &identity, &container_list, provide_flags);
}
if (FAILED(hr)) goto cleanup;
}
- IDirectXFileData_Release(filedata);
+ filedata->lpVtbl->Release(filedata);
filedata = NULL;
if (FAILED(hr))
goto cleanup;
}
- if (hr != DXFILEERR_NOMOREOBJECTS)
- goto cleanup;
- IDirectXFileEnumObject_Release(enumobj);
+ enumobj->lpVtbl->Release(enumobj);
enumobj = NULL;
- IDirectXFile_Release(dxfile);
- dxfile = NULL;
+ d3dxfile->lpVtbl->Release(d3dxfile);
+ d3dxfile = NULL;
if (list_empty(&container_list)) {
hr = E_FAIL;
@@ -4299,9 +4419,9 @@ HRESULT WINAPI D3DXLoadMeshFromXInMemory(const void *memory, DWORD memory_size,
cleanup:
if (concat_indices) concat_mesh->lpVtbl->UnlockIndexBuffer(concat_mesh);
if (concat_vertices) concat_mesh->lpVtbl->UnlockVertexBuffer(concat_mesh);
- if (filedata) IDirectXFileData_Release(filedata);
- if (enumobj) IDirectXFileEnumObject_Release(enumobj);
- if (dxfile) IDirectXFile_Release(dxfile);
+ if (filedata) filedata->lpVtbl->Release(filedata);
+ if (enumobj) enumobj->lpVtbl->Release(enumobj);
+ if (d3dxfile) d3dxfile->lpVtbl->Release(d3dxfile);
if (FAILED(hr)) {
if (concat_mesh) IUnknown_Release(concat_mesh);
if (materials) ID3DXBuffer_Release(materials);
More information about the wine-patches
mailing list