1 #ifdef __REACTOS__ 2 #include "precomp.h" 3 #else 4 /* 5 * Copyright 2010 Christian Costa 6 * 7 * This library is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU Lesser General Public 9 * License as published by the Free Software Foundation; either 10 * version 2.1 of the License, or (at your option) any later version. 11 * 12 * This library is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * Lesser General Public License for more details. 16 * 17 * You should have received a copy of the GNU Lesser General Public 18 * License along with this library; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 20 */ 21 22 23 #include "d3dx9_private.h" 24 #endif /* __REACTOS__ */ 25 26 WINE_DEFAULT_DEBUG_CHANNEL(d3dx); 27 28 HRESULT WINAPI D3DXLoadVolumeFromFileA(IDirect3DVolume9 *dst_volume, 29 const PALETTEENTRY *dst_palette, 30 const D3DBOX *dst_box, 31 const char *filename, 32 const D3DBOX *src_box, 33 DWORD filter, 34 D3DCOLOR color_key, 35 D3DXIMAGE_INFO *info) 36 { 37 HRESULT hr; 38 int length; 39 WCHAR *filenameW; 40 41 TRACE("(%p, %p, %p, %s, %p, %#x, %#x, %p)\n", 42 dst_volume, dst_palette, dst_box, debugstr_a(filename), src_box, 43 filter, color_key, info); 44 45 if (!dst_volume || !filename) return D3DERR_INVALIDCALL; 46 47 length = MultiByteToWideChar(CP_ACP, 0, filename, -1, NULL, 0); 48 filenameW = HeapAlloc(GetProcessHeap(), 0, length * sizeof(*filenameW)); 49 if (!filenameW) return E_OUTOFMEMORY; 50 51 hr = D3DXLoadVolumeFromFileW(dst_volume, dst_palette, dst_box, filenameW, 52 src_box, filter, color_key, info); 53 HeapFree(GetProcessHeap(), 0, filenameW); 54 55 return hr; 56 } 57 58 HRESULT WINAPI D3DXLoadVolumeFromFileW(IDirect3DVolume9 *dst_volume, 59 const PALETTEENTRY *dst_palette, 60 const D3DBOX *dst_box, 61 const WCHAR *filename, 62 const D3DBOX *src_box, 63 DWORD filter, 64 D3DCOLOR color_key, 65 D3DXIMAGE_INFO *info) 66 { 67 HRESULT hr; 68 void *data; 69 UINT data_size; 70 71 TRACE("(%p, %p, %p, %s, %p, %#x, %#x, %p)\n", 72 dst_volume, dst_palette, dst_box, debugstr_w(filename), src_box, 73 filter, color_key, info); 74 75 if (!dst_volume || !filename) return D3DERR_INVALIDCALL; 76 77 if (FAILED(map_view_of_file(filename, &data, &data_size))) 78 return D3DXERR_INVALIDDATA; 79 80 hr = D3DXLoadVolumeFromFileInMemory(dst_volume, dst_palette, dst_box, 81 data, data_size, src_box, filter, color_key, info); 82 UnmapViewOfFile(data); 83 84 return hr; 85 } 86 87 HRESULT WINAPI D3DXLoadVolumeFromMemory(IDirect3DVolume9 *dst_volume, 88 const PALETTEENTRY *dst_palette, 89 const D3DBOX *dst_box, 90 const void *src_memory, 91 D3DFORMAT src_format, 92 UINT src_row_pitch, 93 UINT src_slice_pitch, 94 const PALETTEENTRY *src_palette, 95 const D3DBOX *src_box, 96 DWORD filter, 97 D3DCOLOR color_key) 98 { 99 HRESULT hr; 100 D3DVOLUME_DESC desc; 101 D3DLOCKED_BOX locked_box; 102 struct volume dst_size, src_size; 103 const struct pixel_format_desc *src_format_desc, *dst_format_desc; 104 105 TRACE("(%p, %p, %p, %p, %#x, %u, %u, %p, %p, %x, %x)\n", dst_volume, dst_palette, dst_box, 106 src_memory, src_format, src_row_pitch, src_slice_pitch, src_palette, src_box, 107 filter, color_key); 108 109 if (!dst_volume || !src_memory || !src_box) return D3DERR_INVALIDCALL; 110 111 if (src_format == D3DFMT_UNKNOWN 112 || src_box->Left >= src_box->Right 113 || src_box->Top >= src_box->Bottom 114 || src_box->Front >= src_box->Back) 115 return E_FAIL; 116 117 if (filter == D3DX_DEFAULT) 118 filter = D3DX_FILTER_TRIANGLE | D3DX_FILTER_DITHER; 119 120 IDirect3DVolume9_GetDesc(dst_volume, &desc); 121 122 src_size.width = src_box->Right - src_box->Left; 123 src_size.height = src_box->Bottom - src_box->Top; 124 src_size.depth = src_box->Back - src_box->Front; 125 126 if (!dst_box) 127 { 128 dst_size.width = desc.Width; 129 dst_size.height = desc.Height; 130 dst_size.depth = desc.Depth; 131 } 132 else 133 { 134 if (dst_box->Left >= dst_box->Right || dst_box->Right > desc.Width) 135 return D3DERR_INVALIDCALL; 136 if (dst_box->Top >= dst_box->Bottom || dst_box->Bottom > desc.Height) 137 return D3DERR_INVALIDCALL; 138 if (dst_box->Front >= dst_box->Back || dst_box->Back > desc.Depth) 139 return D3DERR_INVALIDCALL; 140 141 dst_size.width = dst_box->Right - dst_box->Left; 142 dst_size.height = dst_box->Bottom - dst_box->Top; 143 dst_size.depth = dst_box->Back - dst_box->Front; 144 } 145 146 src_format_desc = get_format_info(src_format); 147 if (src_format_desc->type == FORMAT_UNKNOWN) 148 return E_NOTIMPL; 149 150 dst_format_desc = get_format_info(desc.Format); 151 if (dst_format_desc->type == FORMAT_UNKNOWN) 152 return E_NOTIMPL; 153 154 if (desc.Format == src_format 155 && dst_size.width == src_size.width 156 && dst_size.height == src_size.height 157 && dst_size.depth == src_size.depth 158 && color_key == 0) 159 { 160 const BYTE *src_addr; 161 162 if (src_box->Left & (src_format_desc->block_width - 1) 163 || src_box->Top & (src_format_desc->block_height - 1) 164 || (src_box->Right & (src_format_desc->block_width - 1) 165 && src_size.width != desc.Width) 166 || (src_box->Bottom & (src_format_desc->block_height - 1) 167 && src_size.height != desc.Height)) 168 { 169 FIXME("Source box (%u, %u, %u, %u) is misaligned\n", 170 src_box->Left, src_box->Top, src_box->Right, src_box->Bottom); 171 return E_NOTIMPL; 172 } 173 174 src_addr = src_memory; 175 src_addr += src_box->Front * src_slice_pitch; 176 src_addr += (src_box->Top / src_format_desc->block_height) * src_row_pitch; 177 src_addr += (src_box->Left / src_format_desc->block_width) * src_format_desc->block_byte_count; 178 179 hr = IDirect3DVolume9_LockBox(dst_volume, &locked_box, dst_box, 0); 180 if (FAILED(hr)) return hr; 181 182 copy_pixels(src_addr, src_row_pitch, src_slice_pitch, 183 locked_box.pBits, locked_box.RowPitch, locked_box.SlicePitch, 184 &dst_size, dst_format_desc); 185 186 IDirect3DVolume9_UnlockBox(dst_volume); 187 } 188 else 189 { 190 const BYTE *src_addr; 191 192 if (!is_conversion_from_supported(src_format_desc) 193 || !is_conversion_to_supported(dst_format_desc)) 194 { 195 FIXME("Pixel format conversion is not implemented %#x -> %#x\n", 196 src_format_desc->format, dst_format_desc->format); 197 return E_NOTIMPL; 198 } 199 200 src_addr = src_memory; 201 src_addr += src_box->Front * src_slice_pitch; 202 src_addr += src_box->Top * src_row_pitch; 203 src_addr += src_box->Left * src_format_desc->bytes_per_pixel; 204 205 hr = IDirect3DVolume9_LockBox(dst_volume, &locked_box, dst_box, 0); 206 if (FAILED(hr)) return hr; 207 208 if ((filter & 0xf) == D3DX_FILTER_NONE) 209 { 210 convert_argb_pixels(src_memory, src_row_pitch, src_slice_pitch, &src_size, src_format_desc, 211 locked_box.pBits, locked_box.RowPitch, locked_box.SlicePitch, &dst_size, dst_format_desc, color_key, 212 src_palette); 213 } 214 else 215 { 216 if ((filter & 0xf) != D3DX_FILTER_POINT) 217 FIXME("Unhandled filter %#x.\n", filter); 218 219 point_filter_argb_pixels(src_addr, src_row_pitch, src_slice_pitch, &src_size, src_format_desc, 220 locked_box.pBits, locked_box.RowPitch, locked_box.SlicePitch, &dst_size, dst_format_desc, color_key, 221 src_palette); 222 } 223 224 IDirect3DVolume9_UnlockBox(dst_volume); 225 } 226 227 return D3D_OK; 228 } 229 230 HRESULT WINAPI D3DXLoadVolumeFromFileInMemory(IDirect3DVolume9 *dst_volume, 231 const PALETTEENTRY *dst_palette, 232 const D3DBOX *dst_box, 233 const void *src_data, 234 UINT src_data_size, 235 const D3DBOX *src_box, 236 DWORD filter, 237 D3DCOLOR color_key, 238 D3DXIMAGE_INFO *src_info) 239 { 240 HRESULT hr; 241 D3DBOX box; 242 D3DXIMAGE_INFO image_info; 243 244 TRACE("dst_volume %p, dst_palette %p, dst_box %p, src_data %p, src_data_size %u, src_box %p, " 245 "filter %#x, color_key 0x%08x, src_info %p.\n", 246 dst_volume, dst_palette, dst_box, src_data, src_data_size, src_box, 247 filter, color_key, src_info); 248 249 if (!dst_volume || !src_data) 250 return D3DERR_INVALIDCALL; 251 252 if (FAILED(hr = D3DXGetImageInfoFromFileInMemory(src_data, src_data_size, &image_info))) 253 return hr; 254 255 if (src_box) 256 { 257 if (src_box->Right > image_info.Width 258 || src_box->Bottom > image_info.Height 259 || src_box->Back > image_info.Depth) 260 return D3DERR_INVALIDCALL; 261 262 box = *src_box; 263 } 264 else 265 { 266 box.Left = 0; 267 box.Top = 0; 268 box.Right = image_info.Width; 269 box.Bottom = image_info.Height; 270 box.Front = 0; 271 box.Back = image_info.Depth; 272 273 } 274 275 if (image_info.ImageFileFormat != D3DXIFF_DDS) 276 { 277 FIXME("File format %#x is not supported yet\n", image_info.ImageFileFormat); 278 return E_NOTIMPL; 279 } 280 281 hr = load_volume_from_dds(dst_volume, dst_palette, dst_box, src_data, &box, 282 filter, color_key, &image_info); 283 if (FAILED(hr)) return hr; 284 285 if (src_info) 286 *src_info = image_info; 287 288 return D3D_OK; 289 } 290 291 HRESULT WINAPI D3DXLoadVolumeFromVolume(IDirect3DVolume9 *dst_volume, 292 const PALETTEENTRY *dst_palette, 293 const D3DBOX *dst_box, 294 IDirect3DVolume9 *src_volume, 295 const PALETTEENTRY *src_palette, 296 const D3DBOX *src_box, 297 DWORD filter, 298 D3DCOLOR color_key) 299 { 300 HRESULT hr; 301 D3DBOX box; 302 D3DVOLUME_DESC desc; 303 D3DLOCKED_BOX locked_box; 304 305 TRACE("(%p, %p, %p, %p, %p, %p, %#x, %#x)\n", 306 dst_volume, dst_palette, dst_box, src_volume, src_palette, src_box, 307 filter, color_key); 308 309 if (!dst_volume || !src_volume) return D3DERR_INVALIDCALL; 310 311 IDirect3DVolume9_GetDesc(src_volume, &desc); 312 313 if (!src_box) 314 { 315 box.Left = box.Top = 0; 316 box.Right = desc.Width; 317 box.Bottom = desc.Height; 318 box.Front = 0; 319 box.Back = desc.Depth; 320 } 321 else box = *src_box; 322 323 hr = IDirect3DVolume9_LockBox(src_volume, &locked_box, NULL, D3DLOCK_READONLY); 324 if (FAILED(hr)) return hr; 325 326 hr = D3DXLoadVolumeFromMemory(dst_volume, dst_palette, dst_box, 327 locked_box.pBits, desc.Format, locked_box.RowPitch, locked_box.SlicePitch, 328 src_palette, &box, filter, color_key); 329 330 IDirect3DVolume9_UnlockBox(src_volume); 331 return hr; 332 } 333