[D3DX9_*]

* Sync with Wine 1.7.27.
CORE-8540

svn path=/trunk/; revision=64286
This commit is contained in:
Amine Khaldi 2014-09-25 19:46:26 +00:00
parent b5a2ac0266
commit 48e0c746fd
9 changed files with 338 additions and 78 deletions

View File

@ -105,7 +105,7 @@
@ stdcall D3DXCreateTextureFromResourceW(ptr ptr wstr ptr) @ stdcall D3DXCreateTextureFromResourceW(ptr ptr wstr ptr)
@ stdcall -stub D3DXCreateTextureGutterHelper(long long ptr long ptr) @ stdcall -stub D3DXCreateTextureGutterHelper(long long ptr long ptr)
@ stdcall -stub D3DXCreateTextureShader(ptr 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 D3DXCreateVolumeTexture(ptr long long long long long long long ptr)
@ stdcall D3DXCreateVolumeTextureFromFileA(ptr ptr ptr) @ stdcall D3DXCreateVolumeTextureFromFileA(ptr ptr ptr)
@ stdcall D3DXCreateVolumeTextureFromFileExA(ptr ptr long long long long long long long long long long ptr ptr ptr) @ stdcall D3DXCreateVolumeTextureFromFileExA(ptr ptr long long long long long long long long long long ptr ptr ptr)

View File

@ -140,8 +140,8 @@ static HDC WINAPI ID3DXFontImpl_GetDC(ID3DXFont *iface)
static HRESULT WINAPI ID3DXFontImpl_GetGlyphData(ID3DXFont *iface, UINT glyph, static HRESULT WINAPI ID3DXFontImpl_GetGlyphData(ID3DXFont *iface, UINT glyph,
IDirect3DTexture9 **texture, RECT *blackbox, POINT *cellinc) IDirect3DTexture9 **texture, RECT *blackbox, POINT *cellinc)
{ {
FIXME("iface %p, glyph %#x, texture %p, blackbox %s, cellinc %s stub!\n", FIXME("iface %p, glyph %#x, texture %p, blackbox %p, cellinc %p stub!\n",
iface, glyph, texture, wine_dbgstr_rect(blackbox), wine_dbgstr_point(cellinc)); iface, glyph, texture, blackbox, cellinc);
return E_NOTIMPL; return E_NOTIMPL;
} }

View File

@ -2741,16 +2741,20 @@ static HRESULT parse_material(ID3DXFileData *filedata, D3DXMATERIAL *material)
return hr; return hr;
hr = child->lpVtbl->GetType(child, &type); hr = child->lpVtbl->GetType(child, &type);
if (FAILED(hr)) if (FAILED(hr))
return hr; goto err;
if (IsEqualGUID(&type, &TID_D3DRMTextureFilename)) { if (IsEqualGUID(&type, &TID_D3DRMTextureFilename)) {
hr = parse_texture_filename(child, &material->pTextureFilename); hr = parse_texture_filename(child, &material->pTextureFilename);
if (FAILED(hr)) if (FAILED(hr))
return hr; goto err;
} }
IUnknown_Release(child);
} }
return D3D_OK; return D3D_OK;
err:
IUnknown_Release(child);
return hr;
} }
static void destroy_materials(struct mesh_data *mesh) 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; SIZE_T data_size;
const DWORD *data, *in_ptr; const DWORD *data, *in_ptr;
GUID type; GUID type;
ID3DXFileData *child; ID3DXFileData *child = NULL;
DWORD num_materials; DWORD num_materials;
DWORD i; DWORD i;
SIZE_T nb_children; SIZE_T nb_children;
@ -2854,6 +2858,9 @@ static HRESULT parse_material_list(ID3DXFileData *filedata, struct mesh_data *me
if (FAILED(hr)) if (FAILED(hr))
goto end; goto end;
} }
IUnknown_Release(child);
child = NULL;
} }
if (num_materials != mesh->num_materials) { if (num_materials != mesh->num_materials) {
WARN("only %u of %u materials defined\n", 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: end:
if (child)
IUnknown_Release(child);
filedata->lpVtbl->Unlock(filedata); filedata->lpVtbl->Unlock(filedata);
return hr; return hr;
} }
@ -3158,7 +3167,7 @@ static HRESULT parse_mesh(ID3DXFileData *filedata, struct mesh_data *mesh_data,
const BYTE *data, *in_ptr; const BYTE *data, *in_ptr;
DWORD *index_out_ptr; DWORD *index_out_ptr;
GUID type; GUID type;
ID3DXFileData *child; ID3DXFileData *child = NULL;
DWORD i; DWORD i;
SIZE_T nb_children; SIZE_T nb_children;
DWORD nb_skin_weigths_info = 0; 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); 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); 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) && } else if (IsEqualGUID(&type, &TID_D3DRMMeshMaterialList) &&
(provide_flags & PROVIDE_MATERIALS)) (provide_flags & PROVIDE_MATERIALS))
{ {
@ -3306,6 +3312,9 @@ static HRESULT parse_mesh(ID3DXFileData *filedata, struct mesh_data *mesh_data,
} }
if (FAILED(hr)) if (FAILED(hr))
goto end; goto end;
IUnknown_Release(child);
child = NULL;
} }
if (mesh_data->skin_info && (nb_skin_weigths_info != mesh_data->nb_bones)) { 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; hr = D3D_OK;
end: end:
if (child)
IUnknown_Release(child);
filedata->lpVtbl->Unlock(filedata); filedata->lpVtbl->Unlock(filedata);
return hr; return hr;
} }
@ -3846,7 +3857,7 @@ static HRESULT load_frame(struct ID3DXFileData *filedata, DWORD options, struct
return hr; return hr;
hr = child->lpVtbl->GetType(child, &type); hr = child->lpVtbl->GetType(child, &type);
if (FAILED(hr)) if (FAILED(hr))
return hr; goto err;
if (IsEqualGUID(&type, &TID_D3DRMMesh)) { if (IsEqualGUID(&type, &TID_D3DRMMesh)) {
hr = load_mesh_container(child, options, device, alloc_hier, next_container); 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; next_child = &(*next_child)->pFrameSibling;
} }
if (FAILED(hr)) if (FAILED(hr))
return hr; goto err;
}
IUnknown_Release(child);
}
return D3D_OK; return D3D_OK;
err:
IUnknown_Release(child);
return hr;
} }
HRESULT WINAPI D3DXLoadMeshHierarchyFromXInMemory(const void *memory, DWORD memory_size, DWORD options, 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; return hr;
hr = child->lpVtbl->GetType(child, &type); hr = child->lpVtbl->GetType(child, &type);
if (FAILED(hr)) if (FAILED(hr))
return hr; goto err;
if (IsEqualGUID(&type, &TID_D3DRMMesh)) { if (IsEqualGUID(&type, &TID_D3DRMMesh)) {
struct mesh_container *container = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*container)); struct mesh_container *container = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*container));
if (!container) if (!container)
return E_OUTOFMEMORY; {
hr = E_OUTOFMEMORY;
goto err;
}
list_add_tail(container_list, &container->entry); list_add_tail(container_list, &container->entry);
container->transform = transform; 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); hr = parse_frame(child, options, device, &transform, container_list, provide_flags);
} }
if (FAILED(hr)) if (FAILED(hr))
return hr; goto err;
}
IUnknown_Release(child);
}
return D3D_OK; return D3D_OK;
err:
IUnknown_Release(child);
return hr;
} }
HRESULT WINAPI D3DXLoadMeshFromXInMemory(const void *memory, DWORD memory_size, DWORD options, 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; 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_vertices = 2 + slices * (stacks-1);
number_of_faces = 2 * slices + (stacks - 2) * (2 * slices); 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); free_sincos_table(&phi);
sphere->lpVtbl->UnlockIndexBuffer(sphere); sphere->lpVtbl->UnlockIndexBuffer(sphere);
sphere->lpVtbl->UnlockVertexBuffer(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; *mesh = sphere;
return D3D_OK; return D3D_OK;
@ -5046,6 +5082,113 @@ HRESULT WINAPI D3DXCreateTextA(struct IDirect3DDevice9 *device, HDC hdc, const c
return hr; 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 { enum pointtype {
POINTTYPE_CURVE = 0, POINTTYPE_CURVE = 0,
POINTTYPE_CORNER, POINTTYPE_CORNER,

View File

@ -207,6 +207,20 @@ HRESULT WINAPI D3DXAssembleShader(const char *data, UINT data_len, const D3DXMAC
return hr; 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 /* D3DXInclude private implementation, used to implement
* D3DXAssembleShaderFromFile() from D3DXAssembleShader(). */ * D3DXAssembleShaderFromFile() from D3DXAssembleShader(). */
/* To be able to correctly resolve include search paths we have to store the /* 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 *filename, const void *parent_data, const void **data, UINT *bytes)
{ {
const char *p, *parent_name = ""; const char *p, *parent_name = "";
char *pathname = NULL; char *pathname = NULL, *ptr;
char **buffer = NULL; char **buffer = NULL;
HANDLE file; HANDLE file;
UINT size; UINT size;
if(parent_data != NULL) if (parent_data)
{
parent_name = *((const char **)parent_data - 1); 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)); 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++; if ((p = strrchr(parent_name, '\\')))
else p = parent_name; ++p;
else
p = parent_name;
pathname = HeapAlloc(GetProcessHeap(), 0, (p - parent_name) + strlen(filename) + 1); pathname = HeapAlloc(GetProcessHeap(), 0, (p - parent_name) + strlen(filename) + 1);
if(!pathname) if(!pathname)
return HRESULT_FROM_WIN32(GetLastError()); return HRESULT_FROM_WIN32(GetLastError());
memcpy(pathname, parent_name, p - parent_name); memcpy(pathname, parent_name, p - parent_name);
strcpy(pathname + (p - parent_name), filename); 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); file = CreateFileA(pathname, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
if(file == INVALID_HANDLE_VALUE) if(file == INVALID_HANDLE_VALUE)
@ -253,6 +283,8 @@ static HRESULT WINAPI d3dincludefromfile_open(ID3DXInclude *iface, D3DXINCLUDE_T
goto error; goto error;
*data = buffer + 1; *data = buffer + 1;
if (!main_file_data)
main_file_data = *data;
CloseHandle(file); CloseHandle(file);
return S_OK; 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));
HeapFree(GetProcessHeap(), 0, (char **)data - 1); HeapFree(GetProcessHeap(), 0, (char **)data - 1);
if (main_file_data == data)
main_file_data = NULL;
return S_OK; return S_OK;
} }
@ -327,9 +361,11 @@ HRESULT WINAPI D3DXAssembleShaderFromFileW(const WCHAR *filename, const D3DXMACR
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
WideCharToMultiByte(CP_ACP, 0, filename, -1, filename_a, len, NULL, NULL); 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); hr = ID3DXInclude_Open(include, D3D_INCLUDE_LOCAL, filename_a, NULL, &buffer, &len);
if (FAILED(hr)) if (FAILED(hr))
{ {
LeaveCriticalSection(&from_file_mutex);
HeapFree(GetProcessHeap(), 0, filename_a); HeapFree(GetProcessHeap(), 0, filename_a);
return D3DXERR_INVALIDDATA; 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); hr = D3DXAssembleShader(buffer, len, defines, include, flags, shader, error_messages);
ID3DXInclude_Close(include, buffer); ID3DXInclude_Close(include, buffer);
LeaveCriticalSection(&from_file_mutex);
HeapFree(GetProcessHeap(), 0, filename_a); HeapFree(GetProcessHeap(), 0, filename_a);
return hr; return hr;
} }
@ -459,9 +496,11 @@ HRESULT WINAPI D3DXCompileShaderFromFileW(const WCHAR *filename, const D3DXMACRO
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
WideCharToMultiByte(CP_ACP, 0, filename, -1, filename_a, filename_len, NULL, NULL); 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); hr = ID3DXInclude_Open(include, D3D_INCLUDE_LOCAL, filename_a, NULL, &buffer, &len);
if (FAILED(hr)) if (FAILED(hr))
{ {
LeaveCriticalSection(&from_file_mutex);
HeapFree(GetProcessHeap(), 0, filename_a); HeapFree(GetProcessHeap(), 0, filename_a);
return D3DXERR_INVALIDDATA; return D3DXERR_INVALIDDATA;
} }
@ -475,6 +514,7 @@ HRESULT WINAPI D3DXCompileShaderFromFileW(const WCHAR *filename, const D3DXMACRO
constant_table); constant_table);
ID3DXInclude_Close(include, buffer); ID3DXInclude_Close(include, buffer);
LeaveCriticalSection(&from_file_mutex);
HeapFree(GetProcessHeap(), 0, filename_a); HeapFree(GetProcessHeap(), 0, filename_a);
return hr; return hr;
} }
@ -579,9 +619,11 @@ HRESULT WINAPI D3DXPreprocessShaderFromFileW(const WCHAR *filename, const D3DXMA
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
WideCharToMultiByte(CP_ACP, 0, filename, -1, filename_a, len, NULL, NULL); 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); hr = ID3DXInclude_Open(include, D3D_INCLUDE_LOCAL, filename_a, NULL, &buffer, &len);
if (FAILED(hr)) if (FAILED(hr))
{ {
LeaveCriticalSection(&from_file_mutex);
HeapFree(GetProcessHeap(), 0, filename_a); HeapFree(GetProcessHeap(), 0, filename_a);
return D3DXERR_INVALIDDATA; return D3DXERR_INVALIDDATA;
} }
@ -592,6 +634,7 @@ HRESULT WINAPI D3DXPreprocessShaderFromFileW(const WCHAR *filename, const D3DXMA
(ID3DBlob **)shader, (ID3DBlob **)error_messages); (ID3DBlob **)shader, (ID3DBlob **)error_messages);
ID3DXInclude_Close(include, buffer); ID3DXInclude_Close(include, buffer);
LeaveCriticalSection(&from_file_mutex);
HeapFree(GetProcessHeap(), 0, filename_a); HeapFree(GetProcessHeap(), 0, filename_a);
return hr; return hr;
} }

View File

@ -1026,7 +1026,7 @@ HRESULT WINAPI D3DXGetImageInfoFromResourceW(HMODULE module, const WCHAR *resour
* *
* RETURNS * RETURNS
* Success: D3D_OK * 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 * 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 * Extracts the relevant components from the source color and
* drops the less significant bits if they aren't used by the destination format. * 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; unsigned int i, j;
for(;i < 4;i++) unsigned int component, mask;
if(info->process_channel[i])
out[i] = (col & info->srcmask[i]) >> info->srcshift[i]; 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; 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); val = make_argb_color(&conv_info, channels);
if (color_key) if (color_key)
{ {
DWORD ck_pixel; 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); ck_pixel = make_argb_color(&ck_conv_info, channels);
if (ck_pixel == color_key) if (ck_pixel == color_key)
val &= ~conv_info.destmask[0]; 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; 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); val = make_argb_color(&conv_info, channels);
if (color_key) if (color_key)
{ {
DWORD ck_pixel; 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); ck_pixel = make_argb_color(&ck_conv_info, channels);
if (ck_pixel == color_key) if (ck_pixel == color_key)
val &= ~conv_info.destmask[0]; 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 * RETURNS
* Success: D3D_OK, if we successfully load the pixel data into our surface or * Success: D3D_OK, if we successfully load the pixel data into our surface or
* if pSrcMemory is NULL but the other parameters are valid * 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 SrcFormat is an invalid format (other than D3DFMT_UNKNOWN) or
* if DestRect is invalid * if DestRect is invalid
* D3DXERR_INVALIDDATA, if we fail to lock pDestSurface * D3DXERR_INVALIDDATA, if we fail to lock pDestSurface
@ -1867,7 +1883,7 @@ HRESULT WINAPI D3DXLoadSurfaceFromMemory(IDirect3DSurface9 *dst_surface,
* *
* RETURNS * RETURNS
* Success: D3D_OK * 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 * D3DXERR_INVALIDDATA, if one of the surfaces is not lockable
* *
*/ */

View 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, HRESULT WINAPI D3DXCheckTextureRequirements(struct IDirect3DDevice9 *device, UINT *width, UINT *height,
UINT *miplevels, DWORD usage, D3DFORMAT *format, D3DPOOL pool) 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); FIXME("Pixel format %x not handled\n", usedformat);
goto cleanup; goto cleanup;
} }
fmt = get_format_info(get_luminance_replacement_format(usedformat));
allow_24bits = fmt->bytes_per_pixel == 3; allow_24bits = fmt->bytes_per_pixel == 3;
channels = (fmt->bits[0] ? 1 : 0) + (fmt->bits[1] ? 1 : 0) channels = !!fmt->bits[0] + !!fmt->bits[1] + !!fmt->bits[2] + !!fmt->bits[3];
+ (fmt->bits[2] ? 1 : 0) + (fmt->bits[3] ? 1 : 0);
usedformat = D3DFMT_UNKNOWN; usedformat = D3DFMT_UNKNOWN;
while ((curfmt = get_format_info_idx(i))) while ((curfmt = get_format_info_idx(i)))
{ {
unsigned int curchannels = (curfmt->bits[0] ? 1 : 0) + (curfmt->bits[1] ? 1 : 0) unsigned int curchannels = !!curfmt->bits[0] + !!curfmt->bits[1]
+ (curfmt->bits[2] ? 1 : 0) + (curfmt->bits[3] ? 1 : 0); + !!curfmt->bits[2] + !!curfmt->bits[3];
int score; int score;
i++; i++;
@ -521,8 +542,6 @@ HRESULT WINAPI D3DXCreateTextureFromFileInMemoryEx(struct IDirect3DDevice9 *devi
IDirect3DTexture9 **texptr; IDirect3DTexture9 **texptr;
IDirect3DTexture9 *buftex; IDirect3DTexture9 *buftex;
IDirect3DSurface9 *surface; IDirect3DSurface9 *surface;
BOOL file_width = FALSE, file_height = FALSE;
BOOL file_format = FALSE, file_miplevels = FALSE;
BOOL dynamic_texture; BOOL dynamic_texture;
D3DXIMAGE_INFO imginfo; D3DXIMAGE_INFO imginfo;
UINT loaded_miplevels, skip_levels; UINT loaded_miplevels, skip_levels;
@ -565,25 +584,21 @@ HRESULT WINAPI D3DXCreateTextureFromFileInMemoryEx(struct IDirect3DDevice9 *devi
if (width == D3DX_FROM_FILE) if (width == D3DX_FROM_FILE)
{ {
file_width = TRUE;
width = imginfo.Width; width = imginfo.Width;
} }
if (height == D3DX_FROM_FILE) if (height == D3DX_FROM_FILE)
{ {
file_height = TRUE;
height = imginfo.Height; height = imginfo.Height;
} }
if (format == D3DFMT_FROM_FILE) if (format == D3DFMT_FROM_FILE)
{ {
file_format = TRUE;
format = imginfo.Format; format = imginfo.Format;
} }
if (miplevels == D3DX_FROM_FILE) if (miplevels == D3DX_FROM_FILE)
{ {
file_miplevels = TRUE;
miplevels = imginfo.MipLevels; miplevels = imginfo.MipLevels;
} }
@ -623,14 +638,6 @@ HRESULT WINAPI D3DXCreateTextureFromFileInMemoryEx(struct IDirect3DDevice9 *devi
miplevels = 1; 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))) if (FAILED(IDirect3DDevice9_GetDeviceCaps(device, &caps)))
return D3DERR_INVALIDCALL; return D3DERR_INVALIDCALL;

View File

@ -178,6 +178,7 @@ HRESULT write_buffer_to_file(const WCHAR *dst_filename, ID3DXBuffer *buffer)
HRESULT hr = S_OK; HRESULT hr = S_OK;
void *buffer_pointer; void *buffer_pointer;
DWORD buffer_size; DWORD buffer_size;
DWORD bytes_written;
HANDLE file = CreateFileW(dst_filename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); HANDLE file = CreateFileW(dst_filename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (file == INVALID_HANDLE_VALUE) if (file == INVALID_HANDLE_VALUE)
return HRESULT_FROM_WIN32(GetLastError()); 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_pointer = ID3DXBuffer_GetBufferPointer(buffer);
buffer_size = ID3DXBuffer_GetBufferSize(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()); hr = HRESULT_FROM_WIN32(GetLastError());
CloseHandle(file); CloseHandle(file);

View File

@ -294,6 +294,7 @@ static HRESULT d3dx9_file_data_create(IDirectXFileObject *dxfile_object, ID3DXFi
{ {
struct d3dx9_file_data *object; struct d3dx9_file_data *object;
IDirectXFileObject *data_object; IDirectXFileObject *data_object;
unsigned int children_array_size = 0;
HRESULT ret; HRESULT ret;
TRACE("dxfile_object %p, ret_iface %p.\n", dxfile_object, ret_iface); 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)) if (SUCCEEDED(ret))
{ {
ret = IDirectXFileDataReference_Resolve(reference, &object->dxfile_data); ret = IDirectXFileDataReference_Resolve(reference, &object->dxfile_data);
IUnknown_Release(reference);
if (FAILED(ret)) if (FAILED(ret))
{ {
HeapFree(GetProcessHeap(), 0, object); 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))) while (SUCCEEDED(ret = IDirectXFileData_GetNextObject(object->dxfile_data, &data_object)))
{ {
if (object->nb_children >= children_array_size)
{
ID3DXFileData **new_children;
if (object->children) if (object->children)
object->children = HeapReAlloc(GetProcessHeap(), 0, object->children, sizeof(ID3DXFileData*) * (object->nb_children + 1)); {
children_array_size *= 2;
new_children = HeapReAlloc(GetProcessHeap(), 0, object->children,
sizeof(*object->children) * children_array_size);
}
else else
object->children = HeapAlloc(GetProcessHeap(), 0, sizeof(ID3DXFileData*)); {
if (!object->children) children_array_size = 4;
new_children = HeapAlloc(GetProcessHeap(), 0, sizeof(*object->children) * children_array_size);
}
if (!new_children)
{ {
ret = E_OUTOFMEMORY; ret = E_OUTOFMEMORY;
break; break;
} }
if (FAILED(ret = d3dx9_file_data_create(data_object, &object->children[object->nb_children]))) object->children = new_children;
}
ret = d3dx9_file_data_create(data_object, &object->children[object->nb_children]);
IUnknown_Release(data_object);
if (FAILED(ret))
break; break;
object->nb_children++; object->nb_children++;
} }
if (ret != DXFILEERR_NOMOREOBJECTS) if (ret != DXFILEERR_NOMOREOBJECTS)
{ {
(&object->ID3DXFileData_iface)->lpVtbl->Release(&object->ID3DXFileData_iface); (&object->ID3DXFileData_iface)->lpVtbl->Release(&object->ID3DXFileData_iface);
return ret; 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); 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; DXFILELOADRESOURCE dxfile_resource;
DXFILELOADMEMORY dxfile_memory; DXFILELOADMEMORY dxfile_memory;
IDirectXFileData *data_object; IDirectXFileData *data_object;
unsigned children_array_size = 0;
HRESULT ret; HRESULT ret;
TRACE("iface %p, source %p, options %#x, enum_object %p.\n", iface, source, options, enum_object); 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 */ /* Fill enum object with top level data objects */
while (SUCCEEDED(ret = IDirectXFileEnumObject_GetNextDataObject(dxfile_enum_object, &data_object))) while (SUCCEEDED(ret = IDirectXFileEnumObject_GetNextDataObject(dxfile_enum_object, &data_object)))
{ {
if (object->nb_children >= children_array_size)
{
ID3DXFileData **new_children;
if (object->children) if (object->children)
object->children = HeapReAlloc(GetProcessHeap(), 0, object->children, sizeof(*object->children) * (object->nb_children + 1)); {
children_array_size *= 2;
new_children = HeapReAlloc(GetProcessHeap(), 0, object->children,
sizeof(*object->children) * children_array_size);
}
else else
object->children = HeapAlloc(GetProcessHeap(), 0, sizeof(*object->children)); {
if (!object->children) children_array_size = 4;
new_children = HeapAlloc(GetProcessHeap(), 0, sizeof(*object->children) * children_array_size);
}
if (!new_children)
{ {
ret = E_OUTOFMEMORY; ret = E_OUTOFMEMORY;
break; break;
} }
if (FAILED(ret = d3dx9_file_data_create((IDirectXFileObject*)data_object, object->children = new_children;
&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; break;
object->nb_children++; 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); IDirectXFileEnumObject_Release(dxfile_enum_object);

View 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/d3d8 # Synced to Wine-1.7.27
reactos/dll/directx/wine/d3d9 # 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/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/d3dxof # Synced to Wine-1.7.17
reactos/dll/directx/wine/ddraw # Synced to Wine-1.7.27 reactos/dll/directx/wine/ddraw # Synced to Wine-1.7.27
reactos/dll/directx/wine/devenum # Synced to Wine-1.7.17 reactos/dll/directx/wine/devenum # Synced to Wine-1.7.17