World of Might and Magic  0.2.0
Open reimplementation of Might and Magic 6 7 8 game engine
RenderD3D.cpp
См. документацию.
2 
3 #include <cstdio>
4 
5 #include "Platform/OSWindow.h"
6 
7 #include "Engine/LOD.h"
8 
9 HRESULT __stdcall DDrawDisplayModesEnumerator(DDSURFACEDESC2 *pSurfaceDesc,
10  __int16 *found_compatible_mode) {
11  if (pSurfaceDesc->ddsCaps.dwCaps | DDSCAPS_3DDEVICE) {
12  *found_compatible_mode = 1;
13  return S_OK;
14  }
15  return 1;
16 }
17 
18 HRESULT __stdcall D3DDeviceEnumerator(
19  const GUID *lpGUID, const char *lpDeviceDesc, const char *lpDeviceName,
20  D3DDEVICEDESC *pHWDesc, D3DDEVICEDESC *pSWDesc, RenderD3D_aux *a6) {
21  int v7 = -1;
22  if (pHWDesc->dwFlags) {
23  if (!a6->ptr_4->pGUID) v7 = 0;
24  if (pHWDesc->dwFlags && a6->ptr_4->pGUID) v7 = 1;
25  }
26  if (!strcmp(lpDeviceName, "RGB Emulation") && !a6->ptr_4->pGUID) v7 = 2;
27  if (!strcmp(lpDeviceName, "Reference Rasterizer") && !a6->ptr_4->pGUID)
28  v7 = 3;
29  if (v7 != -1) {
30  a6->pInfo[v7].bIsDeviceCompatible = 1;
31  a6->pInfo[v7].uCaps = 0;
32  if (!(pHWDesc->dpcTriCaps.dwSrcBlendCaps & 0x10))
33  a6->pInfo[v7].uCaps |= 2;
34  if (!(pHWDesc->dpcTriCaps.dwSrcBlendCaps & 2)) a6->pInfo[v7].uCaps |= 4;
35  if (!(pHWDesc->dpcTriCaps.dwSrcBlendCaps & 1)) a6->pInfo[v7].uCaps |= 8;
36  if (!(pHWDesc->dpcTriCaps.dwDestBlendCaps & 0x20))
37  a6->pInfo[v7].uCaps |= 16;
38  if (!(pHWDesc->dpcTriCaps.dwDestBlendCaps & 2))
39  a6->pInfo[v7].uCaps |= 32;
40  if (!(pHWDesc->dpcTriCaps.dwDestBlendCaps & 4))
41  a6->pInfo[v7].uCaps |= 64;
42  if (!(pHWDesc->dwDevCaps & 0x1000)) a6->pInfo[v7].uCaps |= 0x100;
43  if (pHWDesc->dpcTriCaps.dwTextureCaps & 0x20)
44  a6->pInfo[v7].uCaps |= 0x80;
45 
46  a6->pInfo[v7].pName = new char[strlen(lpDeviceName) + 1];
47  strcpy(a6->pInfo[v7].pName, lpDeviceName);
48 
49  a6->pInfo[v7].pDescription = new char[strlen(lpDeviceDesc) + 1];
50  strcpy(a6->pInfo[v7].pDescription, lpDeviceDesc);
51 
52  a6->pInfo[v7].pGUID = new GUID;
53  memcpy(a6->pInfo[v7].pGUID, lpGUID, 0x10);
54 
55  a6->pInfo[v7].pDriverName = strdup(a6->ptr_4->pDriverName);
56  a6->pInfo[v7].pDeviceDesc = strdup(a6->ptr_4->pDeviceDesc);
57  a6->pInfo[v7].pDDraw4DevDesc = strdup(a6->ptr_4->pDDraw4DevDesc);
58 
59  if (a6->ptr_4->pGUID) {
60  a6->pInfo[v7].pDirectDrawGUID = new GUID;
61  memcpy(a6->pInfo[v7].pDirectDrawGUID, a6->ptr_4->pGUID, 0x10);
62  } else {
63  a6->pInfo[v7].pDirectDrawGUID = 0;
64  }
65  a6->pInfo[v7].uVideoMem = a6->ptr_4->uVideoMem;
66  }
67  return 1;
68 }
69 
70 int __stdcall RenderD3D__DeviceEnumerator(GUID *lpGUID, const char *lpDevDesc,
71  const char *lpDriverName,
72  RenderD3D__DevInfo *pOut) {
73  size_t v5; // eax@1
74  size_t v7; // eax@13
75  DDDEVICEIDENTIFIER ddDevId; // [sp+4h] [bp-4F8h]@11
76  DDSURFACEDESC2 v10; // [sp+42Ch] [bp-D0h]@16
77  DDSCAPS2 ddsCaps; // [sp+4A8h] [bp-54h]@14
78  unsigned int uFreeVideoMem; // [sp+4B8h] [bp-44h]@14
79  RenderD3D_aux aux; // [sp+4BCh] [bp-40h]@19
80  IDirect3D3 *pDirect3D3; // [sp+4C4h] [bp-38h]@18
81  int is_there_a_compatible_screen_mode; // [sp+4C8h] [bp-34h]@16
82  IDirectDraw4 *pDirectDraw4; // [sp+4F8h] [bp-4h]@7
83 
84  RenderD3D_D3DDevDesc v20 = {0};
85  size_t v4 = strlen(lpDriverName);
86  v20.pDriverName = new char[v4 + 1];
87  v5 = strlen(lpDevDesc);
88  v20.pDeviceDesc = new char[v5 + 1];
89  strcpy(v20.pDriverName, lpDriverName);
90  strcpy(v20.pDeviceDesc, lpDevDesc);
91  if (lpGUID) {
92  v20.pGUID = new GUID;
93  memcpy(v20.pGUID, lpGUID, 0x10);
94  } else {
95  v20.pGUID = 0;
96  }
97 
98  LPDIRECTDRAW pDirectDraw = nullptr;
99  if (FAILED(DirectDrawCreate(v20.pGUID, &pDirectDraw, 0))) {
100  delete[] v20.pDriverName;
101  delete[] v20.pDeviceDesc;
102  delete v20.pGUID;
103  } else {
104  if (FAILED(pDirectDraw->QueryInterface(IID_IDirectDraw4,
105  (LPVOID *)&pDirectDraw4))) {
106  delete[] v20.pDriverName;
107  delete[] v20.pDeviceDesc;
108  delete v20.pGUID;
109  pDirectDraw->Release();
110  } else {
111  pDirectDraw->Release();
112  if (FAILED(pDirectDraw4->GetDeviceIdentifier(&ddDevId, 1))) {
113  v20.pDDraw4DevDesc = 0;
114  } else {
115  v7 = strlen(ddDevId.szDescription);
116  v20.pDDraw4DevDesc = new char[v7 + 1];
117  strcpy(v20.pDDraw4DevDesc, ddDevId.szDescription);
118  }
119  memset(&ddsCaps, 0, sizeof(ddsCaps));
120  if (FAILED(pDirectDraw4->GetAvailableVidMem(
121  &ddsCaps, (LPDWORD)&v20.uVideoMem,
122  (LPDWORD)&uFreeVideoMem)))
123  v20.uVideoMem = 0;
124  memset(&v10, 0, sizeof(v10));
125  v10.dwSize = 124;
126  v10.dwFlags = 6;
127  v10.dwHeight = window->GetWidth();
128  v10.dwWidth = window->GetHeight();
129  v10.ddpfPixelFormat.dwSize = 32;
130 
131  is_there_a_compatible_screen_mode = false;
132  if (FAILED(pDirectDraw4->EnumDisplayModes(
133  0, 0, &is_there_a_compatible_screen_mode,
134  (LPDDENUMMODESCALLBACK2)DDrawDisplayModesEnumerator)) ||
135  !is_there_a_compatible_screen_mode ||
136  FAILED(pDirectDraw4->QueryInterface(IID_IDirect3D3,
137  (LPVOID *)&pDirect3D3))) {
138  delete[] v20.pDriverName;
139  delete[] v20.pDeviceDesc;
140  // free(v20.pDDraw4DevDesc);
141  delete[] v20.pDDraw4DevDesc;
142  delete v20.pGUID;
143  pDirectDraw4->Release();
144  } else {
145  aux.pInfo = pOut;
146  aux.ptr_4 = &v20;
147  pDirect3D3->EnumDevices(
148  (LPD3DENUMDEVICESCALLBACK)D3DDeviceEnumerator, &aux);
149  delete[] v20.pDriverName;
150  delete[] v20.pDeviceDesc;
151  delete[] v20.pDDraw4DevDesc;
152  delete v20.pGUID;
153  pDirectDraw4->Release();
154  pDirectDraw4 = 0;
155  pDirect3D3->Release();
156  }
157  }
158  }
159  return 1;
160 }
161 
162 HRESULT __stdcall D3DZBufferFormatEnumerator(DDPIXELFORMAT *Src,
163  DDPIXELFORMAT *Dst) {
164  if (Src->dwFlags & (0x400 | 0x2000)) {
165  if (Src->dwRGBBitCount == 16 && !Src->dwRBitMask) {
166  memcpy(Dst, Src, sizeof(DDPIXELFORMAT));
167  return 0;
168  }
169  if (!Dst->dwSize) {
170  memcpy(Dst, Src, sizeof(DDPIXELFORMAT));
171  return 1;
172  }
173  }
174  return 1;
175 }
176 
178  RenderD3D__DevInfo *v2; // eax@1
179 
180  v2 = new RenderD3D__DevInfo[4]; // 4 items
181  *pOutDevices = v2;
182  memset(v2, 0, sizeof(v2));
183  DirectDrawEnumerateExA((LPDDENUMCALLBACKEXA)RenderD3D__DeviceEnumerator,
184  *pOutDevices, DDENUM_ATTACHEDSECONDARYDEVICES);
185 }
186 
188  this->pHost = nullptr;
189  this->pDirect3D = nullptr;
190  this->pUnk = nullptr;
191  this->pBackBuffer = nullptr;
192  this->pFrontBuffer = nullptr;
193  this->pZBuffer = nullptr;
194  this->pDevice = nullptr;
195  this->pViewport = nullptr;
196  this->field_40 = 1;
197  this->field_44 = 10;
199 }
200 
202  if (!this->bWindowed) {
203  if (this->pHost) {
204  this->pHost->RestoreDisplayMode();
205  this->pHost->SetCooperativeLevel(this->hWindow, DDSCL_NORMAL);
206  this->pHost->FlipToGDISurface();
207  }
208  }
209 
210  for (int i = 0; i < 4; i++) {
211  if (this->pAvailableDevices[i].pDriverName) {
212  delete[] this->pAvailableDevices[i].pDriverName;
213  this->pAvailableDevices[i].pDriverName = nullptr;
214  }
215 
216  if (this->pAvailableDevices[i].pDeviceDesc) {
217  delete[] this->pAvailableDevices[i].pDeviceDesc;
218  this->pAvailableDevices[i].pDeviceDesc = nullptr;
219  }
220 
221  if (this->pAvailableDevices[i].pDDraw4DevDesc) {
222  delete[] this->pAvailableDevices[i].pDDraw4DevDesc;
223  this->pAvailableDevices[i].pDDraw4DevDesc = nullptr;
224  }
225 
226  if (this->pAvailableDevices[i].pDirectDrawGUID) {
227  delete this->pAvailableDevices[i].pDirectDrawGUID;
228  this->pAvailableDevices[i].pDirectDrawGUID = nullptr;
229  }
230 
231  if (this->pAvailableDevices[i].pName) {
232  delete[] this->pAvailableDevices[i].pName;
233  this->pAvailableDevices[i].pName = nullptr;
234  }
235 
236  if (this->pAvailableDevices[i].pDescription) {
237  delete[] this->pAvailableDevices[i].pDescription;
238  this->pAvailableDevices[i].pDescription = nullptr;
239  }
240 
241  if (this->pAvailableDevices[i].pGUID) {
242  delete this->pAvailableDevices[i].pGUID;
243  this->pAvailableDevices[i].pGUID = nullptr;
244  }
245  }
246 
247  delete[] this->pAvailableDevices;
248  this->pAvailableDevices = NULL;
249 
250  if (this->pViewport) {
251  this->pViewport->Release();
252  this->pViewport = NULL;
253  }
254 
255  if (this->pUnk) {
256  this->pUnk->Release();
257  this->pUnk = NULL;
258  }
259 
260  if (this->pZBuffer) {
261  this->pZBuffer->Release();
262  this->pZBuffer = NULL;
263  }
264 
265  if (this->pDevice) {
266  this->pDevice->Release();
267  this->pDevice = NULL;
268  }
269 
270  if (this->pDirect3D) {
271  this->pDirect3D->Release();
272  this->pDirect3D = NULL;
273  }
274 
275  if (this->pBackBuffer) {
276  this->pBackBuffer->Release();
277  this->pBackBuffer = NULL;
278  }
279 
280  if (this->pFrontBuffer) {
281  this->pFrontBuffer->Release();
282  this->pFrontBuffer = NULL;
283  }
284 
285  if (this->pHost) {
286  this->pHost->Release();
287  this->pHost = NULL;
288  }
289 }
290 
291 bool RenderD3D::CreateDevice(unsigned int uDeviceID, int bWindowed,
292  OSWindow *window) {
293  DWORD v26; // [sp-4h] [bp-DCh]@30
294  DDSCAPS2 v27; // [sp+Ch] [bp-CCh]@37
295  DDSURFACEDESC2 ddsd2; // [sp+1Ch] [bp-BCh]@11
296  D3DVIEWPORT2 d3dvp2; // [sp+98h] [bp-40h]@28
297  IDirectDrawClipper *lpddclipper; // [sp+C4h] [bp-14h]@18
298  LPDIRECTDRAW lpDD; // [sp+C8h] [bp-10h]@1
299 
300  auto hWnd = (HWND)window->GetWinApiHandle();
301  int game_width = window->GetWidth();
302  int game_height = window->GetHeight();
303 
304  this->bWindowed = bWindowed;
305  this->hWindow = hWnd;
306 
307  //Создание объекта DirectDraw
308  if (FAILED(DirectDrawCreate(pAvailableDevices[uDeviceID].pDirectDrawGUID,
309  &lpDD, NULL))) {
310  sprintf(pErrorMessage,
311  "Init - Failed to create DirectDraw interface.\n");
312  return 0;
313  }
314 
315  //Запрос интерфейса IDirectDraw4
316  if (FAILED(lpDD->QueryInterface(IID_IDirectDraw4, (LPVOID *)&pHost))) {
317  sprintf(pErrorMessage,
318  "Init - Failed to create DirectDraw4 interface.\n");
319  if (lpDD) lpDD->Release();
320  return 0;
321  }
322  lpDD->Release();
323  lpDD = NULL;
324 
325  //Задаём уровень совместного доступа для приложения DirectDraw в оконном
326  //режиме
327  if (bWindowed && !pAvailableDevices[uDeviceID].pDirectDrawGUID) {
328  if (FAILED(pHost->SetCooperativeLevel(
329  hWnd, DDSCL_MULTITHREADED | DDSCL_NORMAL))) {
330  sprintf(pErrorMessage, "Init - Failed to set cooperative level.\n");
331  if (pHost) {
332  pHost->Release();
333  pHost = NULL;
334  }
335  return 0;
336  }
337 
338  //
339  memset(&ddsd2, 0, sizeof(DDSURFACEDESC2));
340  ddsd2.dwSize = sizeof(DDSURFACEDESC2);
341  ddsd2.dwFlags = DDSD_CAPS;
342  ddsd2.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
343  //Создаём первичную поверхность
344  if (FAILED(pHost->CreateSurface(&ddsd2, &pFrontBuffer, NULL))) {
345  sprintf(pErrorMessage, "Init - Failed to create front buffer.\n");
346  if (pHost) {
347  pHost->Release();
348  pHost = NULL;
349  }
350  return 0;
351  }
352  ddsd2.dwSize = sizeof(DDSURFACEDESC2);
353  pHost->GetDisplayMode(&ddsd2);
354 
355  ddsd2.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
356  ddsd2.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE;
357  ddsd2.dwWidth = game_width;
358  ddsd2.dwHeight = game_height;
359  if (pHost->CreateSurface(&ddsd2, &pBackBuffer, NULL)) {
360  sprintf(pErrorMessage, "Init - Failed to create back buffer.\n");
361  if (pFrontBuffer) {
362  pFrontBuffer->Release();
363  pFrontBuffer = NULL;
364  }
365  if (pHost) {
366  pHost->Release();
367  pHost = NULL;
368  }
369  return 0;
370  }
371  //Создание отсекателя DirectDraw
372  if (pHost->CreateClipper(0, &lpddclipper, NULL)) {
373  sprintf(pErrorMessage, "Init - Failed to create clipper.\n");
374  if (pBackBuffer) {
375  pBackBuffer->Release();
376  pBackBuffer = NULL;
377  }
378  if (pFrontBuffer) {
379  pFrontBuffer->Release();
380  pFrontBuffer = NULL;
381  }
382  if (pHost) {
383  pHost->Release();
384  pHost = NULL;
385  }
386  return 0;
387  }
388  lpddclipper->SetHWnd(0, hWnd);
389  pFrontBuffer->SetClipper(lpddclipper);
390 
391  lpddclipper->Release();
392  lpddclipper = NULL;
393  //
394 
395  pHost->QueryInterface(IID_IDirect3D3, (LPVOID *)&pDirect3D);
396 
397  ddsd2.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
398  ddsd2.ddsCaps.dwCaps = DDSCAPS_ZBUFFER;
399  ddsd2.dwWidth = game_width;
400  ddsd2.dwHeight = game_height;
401 
402  if (pDirect3D->EnumZBufferFormats(
403  *pAvailableDevices[uDeviceID].pGUID,
404  (HRESULT(__stdcall *)(DDPIXELFORMAT *,
406  &ddsd2.ddpfPixelFormat)) {
407  sprintf(pErrorMessage,
408  "Init - Failed to enumerate Z buffer formats.\n");
409  if (pBackBuffer) {
410  pBackBuffer->Release();
411  pBackBuffer = NULL;
412  }
413  if (pFrontBuffer) {
414  pFrontBuffer->Release();
415  pFrontBuffer = NULL;
416  }
417  if (pHost) {
418  pHost->Release();
419  pHost = NULL;
420  }
421  return 0;
422  }
423  if (uDeviceID == 2 || uDeviceID == 3)
424  ddsd2.ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY;
425 
426  if (!pHost->CreateSurface(&ddsd2, &pZBuffer, NULL)) {
427  if (!pBackBuffer->AddAttachedSurface(pZBuffer)) {
428  if (!pDirect3D->CreateDevice(
429  *pAvailableDevices[uDeviceID].pGUID, pBackBuffer,
430  &pDevice, 0)) {
431  memset(&d3dvp2, 0, sizeof(D3DVIEWPORT2));
432  d3dvp2.dvClipWidth = 2.0;
433  d3dvp2.dvClipY = 1.0;
434  d3dvp2.dvClipHeight = 2.0;
435  d3dvp2.dvMaxZ = 1.0;
436  d3dvp2.dvMinZ = 0.0;
437  goto LABEL_54;
438  }
439  sprintf(pErrorMessage, "Init - Failed to create D3D device.\n");
440  if (pDirect3D) {
441  pDirect3D->Release();
442  pDirect3D = NULL;
443  }
444  if (pZBuffer) {
445  pZBuffer->Release();
446  pZBuffer = NULL;
447  }
448  if (pBackBuffer) {
449  pBackBuffer->Release();
450  pBackBuffer = NULL;
451  }
452  if (pFrontBuffer) {
453  pFrontBuffer->Release();
454  pFrontBuffer = NULL;
455  }
456  if (pHost) {
457  pHost->Release();
458  pHost = NULL;
459  }
460  return 0;
461  }
462  sprintf(pErrorMessage,
463  "Init - Failed to attach z-buffer to back buffer.\n");
464  if (pZBuffer) {
465  pZBuffer->Release();
466  pZBuffer = NULL;
467  }
468  if (pBackBuffer) {
469  pBackBuffer->Release();
470  pBackBuffer = NULL;
471  }
472  if (pFrontBuffer) {
473  pFrontBuffer->Release();
474  pFrontBuffer = NULL;
475  }
476  if (pHost) {
477  pHost->Release();
478  pHost = NULL;
479  }
480  return 0;
481  }
482  sprintf(pErrorMessage, "Init - Failed to create z-buffer.\n");
483  if (pBackBuffer) {
484  pBackBuffer->Release();
485  pBackBuffer = NULL;
486  }
487  if (pFrontBuffer) {
488  pFrontBuffer->Release();
489  pFrontBuffer = NULL;
490  }
491  if (pHost) {
492  pHost->Release();
493  pHost = NULL;
494  }
495  return 0;
496  }
497  if (uDeviceID == 1)
498  v26 = 1045;
499  else
500  v26 = 1041;
501  if (pHost->SetCooperativeLevel(hWnd, v26)) {
502  sprintf(pErrorMessage, "Init - Failed to set cooperative level.\n");
503  if (pHost) {
504  pHost->Release();
505  pHost = NULL;
506  }
507  return 0;
508  }
509  if (pHost->SetDisplayMode(window->GetWidth(), window->GetHeight(), 16, 0,
510  0)) {
511  sprintf(pErrorMessage, "Init - Failed to set display mode.\n");
512  if (pHost) {
513  pHost->Release();
514  pHost = NULL;
515  }
516  return 0;
517  }
518 
519  memset(&ddsd2, 0, sizeof(DDSURFACEDESC2));
520  ddsd2.dwSize = sizeof(DDSURFACEDESC2);
521  //Подключение полей с достоверными данными
522  ddsd2.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
523  //Запрос сложной структуры с возможностью переключения
524  ddsd2.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_3DDEVICE |
525  DDSCAPS_FLIP | DDSCAPS_COMPLEX;
526  //Присвоение полю счётчика задних буферов значения 1
527  ddsd2.dwBackBufferCount = 1;
528  if (pHost->CreateSurface(&ddsd2, &pFrontBuffer, NULL)) {
529  sprintf(pErrorMessage, "Init - Failed to create front buffer.\n");
530  if (pHost) {
531  pHost->Release();
532  pHost = NULL;
533  }
534  return 0;
535  }
536  // a3a = &pBackBuffer;
537  // v14 = *v34;
538  memset(&v27, 0, sizeof(DDSCAPS2));
539 
540  v27.dwCaps = DDSCAPS_BACKBUFFER;
541  // v33 = (IDirect3DDevice3 **)v14->GetAttachedSurface(&v27, &pBackBuffer);
542  // hWnda = &pDirect3D;
543  pHost->QueryInterface(IID_IDirect3D3, (LPVOID *)&pDirect3D);
544 
545  if (FAILED(pFrontBuffer->GetAttachedSurface(&v27, &pBackBuffer))) {
546  sprintf(pErrorMessage, "Init - Failed to get D3D interface.\n");
547  if (pBackBuffer) {
548  pBackBuffer->Release();
549  pBackBuffer = NULL;
550  }
551  if (pFrontBuffer) {
552  pFrontBuffer->Release();
553  pFrontBuffer = NULL;
554  }
555  if (pHost) {
556  pHost->Release();
557  pHost = NULL;
558  }
559  return 0;
560  }
561 
562  ddsd2.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
563  ddsd2.ddsCaps.dwCaps = DDSCAPS_ZBUFFER;
564  ddsd2.dwWidth = 640;
565  ddsd2.dwHeight = 480;
566  if (pDirect3D->EnumZBufferFormats(
567  *pAvailableDevices[uDeviceID].pGUID,
568  (HRESULT(__stdcall *)(DDPIXELFORMAT *,
570  &ddsd2.ddpfPixelFormat)) {
571  sprintf(pErrorMessage,
572  "Init - Failed to enumerate Z buffer formats.\n");
573  if (pBackBuffer) {
574  pBackBuffer->Release();
575  pBackBuffer = 0;
576  }
577  if (pFrontBuffer) {
578  pFrontBuffer->Release();
579  pFrontBuffer = 0;
580  }
581  if (pHost) {
582  pHost->Release();
583  pHost = 0;
584  }
585  return 0;
586  }
587  if (uDeviceID == 2 || uDeviceID == 3) ddsd2.ddsCaps.dwCaps |= 8;
588  // uDeviceIDa = &pZBuffer;
589  if (pHost->CreateSurface(&ddsd2, &pZBuffer, NULL)) {
590  sprintf(pErrorMessage, "Init - Failed to create z-buffer.\n");
591  if (pBackBuffer) {
592  pBackBuffer->Release();
593  pBackBuffer = 0;
594  }
595  if (pFrontBuffer) {
596  pFrontBuffer->Release();
597  pFrontBuffer = 0;
598  }
599  if (pHost) {
600  pHost->Release();
601  pHost = 0;
602  }
603  return 0;
604  }
605 
606  if (pBackBuffer->AddAttachedSurface(pZBuffer)) {
607  sprintf(pErrorMessage,
608  "Init - Failed to attach z-buffer to back buffer.\n");
609  if (pZBuffer) {
610  pZBuffer->Release();
611  pZBuffer = 0;
612  }
613  if (pBackBuffer) {
614  pBackBuffer->Release();
615  pBackBuffer = 0;
616  }
617  if (pFrontBuffer) {
618  pFrontBuffer->Release();
619  pFrontBuffer = 0;
620  }
621  if (pHost) {
622  pHost->Release();
623  pHost = 0;
624  }
625  return 0;
626  }
627  // v33 = &pDevice;
628  if (pDirect3D->CreateDevice(*pAvailableDevices[uDeviceID].pGUID,
629  pBackBuffer, &pDevice, 0)) {
630  sprintf(pErrorMessage, "Init - Failed to create D3D device.\n");
631  if (pDirect3D) {
632  pDirect3D->Release();
633  pDirect3D = 0;
634  }
635  if (pZBuffer) {
636  pZBuffer->Release();
637  pZBuffer = 0;
638  }
639  if (pBackBuffer) {
640  pBackBuffer->Release();
641  pBackBuffer = 0;
642  }
643  if (pFrontBuffer) {
644  pFrontBuffer->Release();
645  pFrontBuffer = 0;
646  }
647  if (pHost) {
648  pHost->Release();
649  pHost = 0;
650  }
651  return 0;
652  }
653  memset(&d3dvp2, 0, sizeof(D3DVIEWPORT2));
654  d3dvp2.dvClipWidth = 2.0;
655  d3dvp2.dvClipY = 1.0;
656  d3dvp2.dvClipHeight = 2.0;
657  d3dvp2.dvMaxZ = 1.0;
658 
659 LABEL_54:
660  d3dvp2.dwSize = sizeof(D3DVIEWPORT2);
661  // v17 = *hWnda;
662  d3dvp2.dwWidth = game_width;
663  d3dvp2.dwHeight = game_height;
664  d3dvp2.dvClipX = -1.0;
665  // v18 = v17->lpVtbl;
666  // v32 = &v4->pViewport;
667  if (pDirect3D->CreateViewport(&pViewport, 0)) {
668  sprintf(pErrorMessage, "Init - Failed to create viewport.\n");
669  if (pDevice) {
670  pDevice->Release();
671  pDevice = 0;
672  }
673  if (pDirect3D) {
674  pDirect3D->Release();
675  pDirect3D = 0;
676  }
677  if (pZBuffer) {
678  pZBuffer->Release();
679  pZBuffer = 0;
680  }
681  if (pBackBuffer) {
682  pBackBuffer->Release();
683  pBackBuffer = 0;
684  }
685  if (pFrontBuffer) {
686  pFrontBuffer->Release();
687  pFrontBuffer = 0;
688  }
689  if (pHost) {
690  pHost->Release();
691  pHost = 0;
692  }
693  return 0;
694  }
695 
696  pDevice->AddViewport(pViewport);
697  pViewport->SetViewport2(&d3dvp2);
698  pDevice->SetCurrentViewport(pViewport);
699  return 1;
700 }
701 
702 unsigned int RenderD3D::GetDeviceCaps() {
703  unsigned int v1; // ebx@1
704  unsigned int result; // eax@2
705  D3DDEVICEDESC refCaps; // [sp+Ch] [bp-1F8h]@1
706  D3DDEVICEDESC halCaps; // [sp+108h] [bp-FCh]@1
707 
708  v1 = 0;
709 
710  memset(&halCaps, 0, sizeof(halCaps));
711  halCaps.dwSize = sizeof(halCaps);
712 
713  memset(&refCaps, 0, sizeof(refCaps));
714  refCaps.dwSize = sizeof(refCaps);
715 
716  if (this->pDevice->GetCaps(&halCaps, &refCaps)) {
717  result = 1;
718  } else {
719  if (!(halCaps.dpcTriCaps.dwSrcBlendCaps & D3DPBLENDCAPS_SRCALPHA))
720  v1 = 2;
721  if (!(halCaps.dpcTriCaps.dwSrcBlendCaps & D3DPBLENDCAPS_ONE)) v1 |= 4;
722  if (!(halCaps.dpcTriCaps.dwSrcBlendCaps & D3DPBLENDCAPS_ZERO)) v1 |= 8;
723  if (!(halCaps.dpcTriCaps.dwDestBlendCaps & D3DPBLENDCAPS_INVSRCALPHA))
724  v1 |= 16;
725  if (!(halCaps.dpcTriCaps.dwDestBlendCaps & D3DPBLENDCAPS_ONE)) v1 |= 32;
726  if (!(halCaps.dpcTriCaps.dwDestBlendCaps & D3DPBLENDCAPS_SRCCOLOR))
727  v1 |= 64;
728  if (halCaps.dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_SQUAREONLY)
729  v1 |= 128;
730  result = v1;
731  }
732  return result;
733 }
734 
735 void RenderD3D::ClearTarget(unsigned int bClearColor, unsigned int uClearColor,
736  unsigned int bClearDepth, float z_clear) {
737  unsigned int uClearFlags = 0;
738 
739  if (bClearColor) uClearFlags |= D3DCLEAR_TARGET;
740  if (bClearDepth) uClearFlags |= D3DCLEAR_ZBUFFER;
741 
742  D3DRECT rects[] = {{0, 0, (LONG)window->GetWidth(), (LONG)window->GetHeight()}};
743  if (uClearFlags)
744  pViewport->Clear2(1, rects, uClearFlags, uClearColor, z_clear, 0);
745 }
746 
747 void RenderD3D::Present(bool bForceBlit) {
748  RECT source_rect; // [sp+18h] [bp-18h]@1
749  struct tagPOINT Point; // [sp+28h] [bp-8h]@4
750 
751  source_rect.left = 0;
752  source_rect.top = 0;
753  source_rect.bottom =
754  480; // window->GetHeight(); //Ritor1: проблема с кнопкой "развернуть"
755  source_rect.right = 640; // window->GetWidth();
756 
757  if (bWindowed || bForceBlit) {
758  RECT dest_rect;
759  GetClientRect(hWindow, &dest_rect);
760  Point.y = 0;
761  Point.x = 0;
762  ClientToScreen(hWindow, &Point);
763  OffsetRect(&dest_rect, Point.x, Point.y);
764  pFrontBuffer->Blt(&dest_rect, pBackBuffer, &source_rect, DDBLT_WAIT,
765  NULL);
766  } else {
767  pFrontBuffer->Flip(NULL, DDFLIP_WAIT);
768  }
769 }
770 
771 unsigned int GetMaxMipLevels(unsigned int uDim) {
772  int v2 = 0;
773  unsigned int v3 = uDim - 1;
774  while (v3 & 1) {
775  v3 >>= 1;
776  ++v2;
777  }
778  return v3 == 0 ? v2 : 0;
779 }
780 
781 bool RenderD3D::CreateTexture(unsigned int uTextureWidth,
782  unsigned int uTextureHeight,
783  IDirectDrawSurface4 **pOutSurface,
784  IDirect3DTexture2 **pOutTexture,
785  bool bAlphaChannel, bool bMipmaps,
786  unsigned int uMinDeviceTexDim) {
787  DDSURFACEDESC2 ddsd2 = { 0 };
788  ddsd2.dwSize = sizeof(ddsd2);
789  ddsd2.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
790  ddsd2.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
791  ddsd2.ddsCaps.dwCaps2 = DDSCAPS2_TEXTUREMANAGE;
792  ddsd2.dwHeight = uTextureHeight;
793  ddsd2.dwWidth = uTextureWidth;
794  if (bMipmaps) {
795  if (uTextureHeight <= uTextureWidth) {
796  ddsd2.dwMipMapCount = GetMaxMipLevels(uTextureHeight) -
797  GetMaxMipLevels(uMinDeviceTexDim);
798  if (ddsd2.dwMipMapCount) {
799  ddsd2.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH |
800  DDSD_PIXELFORMAT | DDSD_MIPMAPCOUNT;
801  ddsd2.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
802  }
803  goto LABEL_12;
804  }
805  if (uTextureWidth < uMinDeviceTexDim) {
806  ddsd2.dwMipMapCount = GetMaxMipLevels(uMinDeviceTexDim);
807  if (ddsd2.dwMipMapCount) {
808  ddsd2.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH |
809  DDSD_PIXELFORMAT | DDSD_MIPMAPCOUNT;
810  ddsd2.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
811  }
812  goto LABEL_12;
813  }
814  unsigned int v9 = GetMaxMipLevels(uTextureWidth);
815  unsigned int v10 = GetMaxMipLevels(uMinDeviceTexDim);
816  ddsd2.dwMipMapCount = v9 - v10;
817  if (ddsd2.dwMipMapCount == 0) {
818  ddsd2.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
819  ddsd2.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX;
820  goto LABEL_12;
821  }
822  } else {
823  ddsd2.dwMipMapCount = 1;
824  }
825  ddsd2.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT |
826  DDSD_MIPMAPCOUNT;
827  ddsd2.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
828 LABEL_12:
829  ddsd2.ddpfPixelFormat.dwRGBBitCount = 16;
830  ddsd2.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
831  if (bAlphaChannel) {
832  ddsd2.ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
833  ddsd2.ddpfPixelFormat.dwRBitMask = 0x7C00;
834  ddsd2.ddpfPixelFormat.dwGBitMask = 0x03E0;
835  ddsd2.ddpfPixelFormat.dwBBitMask = 0x001F;
836  ddsd2.ddpfPixelFormat.dwRGBAlphaBitMask = 0x8000;
837  } else {
838  ddsd2.ddpfPixelFormat.dwFlags = DDPF_RGB;
839  ddsd2.ddpfPixelFormat.dwRBitMask = 0xF800;
840  ddsd2.ddpfPixelFormat.dwGBitMask = 0x07E0;
841  ddsd2.ddpfPixelFormat.dwBBitMask = 0x001F;
842  ddsd2.ddpfPixelFormat.dwRGBAlphaBitMask = 0;
843  }
844  if (FAILED(pHost->CreateSurface(&ddsd2, pOutSurface, NULL))) {
845  return false;
846  }
847 
848  if (FAILED((*pOutSurface)->QueryInterface(IID_IDirect3DTexture2, (void**)pOutTexture))) {
849  (*pOutSurface)->Release();
850  *pOutSurface = 0;
851  return false;
852  }
853  return true;
854 }
855 
859 }
OSWindow.h
RenderD3D::pDirect3D
IDirect3D3 * pDirect3D
Definition: RenderD3D.h:93
D3DZBufferFormatEnumerator
HRESULT __stdcall D3DZBufferFormatEnumerator(DDPIXELFORMAT *Src, DDPIXELFORMAT *Dst)
Definition: RenderD3D.cpp:162
RenderD3D::GetAvailableDevices
void GetAvailableDevices(RenderD3D__DevInfo **pOutDevices)
Definition: RenderD3D.cpp:177
LOD.h
RenderD3D::pFrontBuffer
IDirectDrawSurface4 * pFrontBuffer
Definition: RenderD3D.h:96
pSprites_LOD
LODFile_Sprites * pSprites_LOD
Definition: LOD.cpp:20
RenderD3D__DevInfo::pGUID
GUID * pGUID
Definition: RenderD3D.h:35
RenderD3D__DevInfo
Definition: RenderD3D.h:19
RenderD3D::pErrorMessage
char pErrorMessage[48]
Definition: RenderD3D.h:102
RenderD3D::pHost
IDirectDraw4 * pHost
Definition: RenderD3D.h:92
RenderD3D_D3DDevDesc::pDeviceDesc
char * pDeviceDesc
Definition: RenderD3D.h:54
RenderD3D::field_44
int field_44
Definition: RenderD3D.h:101
RenderD3D::pZBuffer
IDirectDrawSurface4 * pZBuffer
Definition: RenderD3D.h:97
Point::x
unsigned int x
Definition: Point.h:7
RenderD3D.h
RenderD3D__DevInfo::pName
char * pName
Definition: RenderD3D.h:33
RenderD3D::RenderD3D
RenderD3D()
Definition: RenderD3D.cpp:187
RenderD3D__DevInfo::pDirectDrawGUID
GUID * pDirectDrawGUID
Definition: RenderD3D.h:40
result
GLuint64EXT * result
Definition: SDL_opengl_glext.h:9435
OSWindow
Definition: OSWindow.h:12
RenderD3D::field_40
int field_40
Definition: RenderD3D.h:100
RenderD3D::pAvailableDevices
RenderD3D__DevInfo * pAvailableDevices
Definition: RenderD3D.h:91
LODFile_IconsBitmaps::ReleaseLostHardwareTextures
void ReleaseLostHardwareTextures()
Definition: LOD.cpp:1017
RenderD3D__DevInfo::pDDraw4DevDesc
char * pDDraw4DevDesc
Definition: RenderD3D.h:39
RenderD3D::bWindowed
unsigned int bWindowed
Definition: RenderD3D.h:84
RenderD3D::HandleLostResources
void HandleLostResources()
Definition: RenderD3D.cpp:856
v1
GLfloat GLfloat v1
Definition: SDL_opengl_glext.h:694
RenderD3D::pDevice
IDirect3DDevice3 * pDevice
Definition: RenderD3D.h:98
RenderD3D__DevInfo::pDescription
char * pDescription
Definition: RenderD3D.h:34
RenderD3D__DeviceEnumerator
int __stdcall RenderD3D__DeviceEnumerator(GUID *lpGUID, const char *lpDevDesc, const char *lpDriverName, RenderD3D__DevInfo *pOut)
Definition: RenderD3D.cpp:70
window
EGLSurface EGLNativeWindowType * window
Definition: SDL_egl.h:1580
RenderD3D::CreateDevice
bool CreateDevice(unsigned int uDeviceID, int bWindowed, OSWindow *window)
Definition: RenderD3D.cpp:291
RenderD3D_aux::ptr_4
RenderD3D_D3DDevDesc * ptr_4
Definition: RenderD3D.h:62
RenderD3D_D3DDevDesc::pDriverName
char * pDriverName
Definition: RenderD3D.h:53
RenderD3D_D3DDevDesc
Definition: RenderD3D.h:47
RenderD3D__DevInfo::uVideoMem
int uVideoMem
Definition: RenderD3D.h:41
RenderD3D::pViewport
IDirect3DViewport3 * pViewport
Definition: RenderD3D.h:99
RenderD3D_D3DDevDesc::pDDraw4DevDesc
char * pDDraw4DevDesc
Definition: RenderD3D.h:55
RenderD3D::Release
void Release()
Definition: RenderD3D.cpp:201
rects
EGLSurface EGLint * rects
Definition: SDL_egl.h:1016
RenderD3D::GetDeviceCaps
unsigned int GetDeviceCaps()
Definition: RenderD3D.cpp:702
RenderD3D::pBackBuffer
IDirectDrawSurface4 * pBackBuffer
Definition: RenderD3D.h:95
LODFile_Sprites::ReleaseLostHardwareSprites
void ReleaseLostHardwareSprites()
Definition: LOD.cpp:200
RenderD3D::Present
void Present(bool bForceBlit)
Definition: RenderD3D.cpp:747
Point::y
unsigned int y
Definition: Point.h:8
GetMaxMipLevels
unsigned int GetMaxMipLevels(unsigned int uDim)
Definition: RenderD3D.cpp:771
v2
GLfloat GLfloat GLfloat v2
Definition: SDL_opengl_glext.h:695
v3
GLfloat GLfloat GLfloat GLfloat v3
Definition: SDL_opengl_glext.h:696
D3DDeviceEnumerator
HRESULT __stdcall D3DDeviceEnumerator(const GUID *lpGUID, const char *lpDeviceDesc, const char *lpDeviceName, D3DDEVICEDESC *pHWDesc, D3DDEVICEDESC *pSWDesc, RenderD3D_aux *a6)
Definition: RenderD3D.cpp:18
pBitmaps_LOD
LODFile_IconsBitmaps * pBitmaps_LOD
Definition: LOD.cpp:16
RenderD3D::pUnk
IUnknown * pUnk
Definition: RenderD3D.h:94
RenderD3D_aux
Definition: RenderD3D.h:60
RenderD3D__DevInfo::bIsDeviceCompatible
unsigned int bIsDeviceCompatible
Definition: RenderD3D.h:32
RenderD3D__DevInfo::pDeviceDesc
char * pDeviceDesc
Definition: RenderD3D.h:38
DDrawDisplayModesEnumerator
HRESULT __stdcall DDrawDisplayModesEnumerator(DDSURFACEDESC2 *pSurfaceDesc, __int16 *found_compatible_mode)
Definition: RenderD3D.cpp:9
Point
Definition: Point.h:3
RenderD3D::ClearTarget
void ClearTarget(unsigned int bClearColor, unsigned int uClearColor, unsigned int bClearDepth, float z_clear)
Definition: RenderD3D.cpp:735
RenderD3D_aux::pInfo
RenderD3D__DevInfo * pInfo
Definition: RenderD3D.h:61
RenderD3D::hWindow
HWND hWindow
Definition: RenderD3D.h:87
RenderD3D_D3DDevDesc::uVideoMem
unsigned int uVideoMem
Definition: RenderD3D.h:57
RenderD3D__DevInfo::uCaps
unsigned int uCaps
Definition: RenderD3D.h:36
RenderD3D::CreateTexture
bool CreateTexture(unsigned int uTextureWidth, unsigned int uTextureHeight, IDirectDrawSurface4 **pOutSurface, IDirect3DTexture2 **pOutTexture, bool bAlphaChannel, bool bMipmaps, unsigned int uMinDeviceTexDim)
Definition: RenderD3D.cpp:781
RenderD3D_D3DDevDesc::pGUID
GUID * pGUID
Definition: RenderD3D.h:56
RenderD3D__DevInfo::pDriverName
char * pDriverName
Definition: RenderD3D.h:37