00001
00002 #include "revolt.h"
00003 #include "dx.h"
00004 #include "dxerrors.h"
00005 #include "main.h"
00006 #include "texture.h"
00007 #include "input.h"
00008 #include "camera.h"
00009 #include "play.h"
00010 #include "registry.h"
00011 #include "timing.h"
00012
00013
00014
00015 DX_STATE DxState;
00016 IDirectDraw4 *DD = NULL;
00017 IDirectDrawSurface4 *FrontBuffer = NULL;
00018 IDirectDrawSurface4 *BackBuffer = NULL;
00019 IDirectDrawSurface4 *ZedBuffer = NULL;
00020 IDirectDrawGammaControl *GammaControl = NULL;
00021 IDirect3D3 *D3D = NULL;
00022 IDirect3DDevice3 *D3Ddevice = NULL;
00023 IDirect3DViewport3 *D3Dviewport;
00024 DDCAPS DDcaps;
00025 D3DDEVICEDESC D3Dcaps;
00026 DDPIXELFORMAT ZedBufferFormat;
00027 DWORD ScreenXsize;
00028 DWORD ScreenYsize;
00029 DWORD ScreenBpp;
00030 DWORD ScreenRefresh;
00031 long GammaFlag = GAMMA_UNAVAILABLE;
00032 long NoColorKey = FALSE;
00033 long DrawDeviceNum, CurrentDrawDevice;
00034 long DisplayModeCount;
00035 DRAW_DEVICE DrawDevices[MAX_DRAW_DEVICES];
00036 long RenderStateChange, TextureStateChange;
00037
00038 short RenderTP = -1;
00039 short RenderTP2 = -1;
00040 short RenderFog = FALSE;
00041 short RenderAlpha = FALSE;
00042 short RenderAlphaSrc = -1;
00043 short RenderAlphaDest = -1;
00044 short RenderZbuffer = D3DZB_TRUE;
00045 short RenderZwrite = TRUE;
00046 short RenderZcmp = D3DCMP_LESSEQUAL;
00047
00048 static DWORD TotalScreenMem, TotalTexMem;
00049 static DWORD BackgroundColor;
00050 static long PolyClear;
00051
00053
00055
00056 BOOL InitDD(void)
00057 {
00058 HRESULT r;
00059 DDSCAPS2 ddscaps2;
00060 DWORD temp;
00061
00062
00063
00064 ReleaseDX();
00065
00066
00067
00068 DirectDrawEnumerate(CreateDrawDeviceCallback, NULL);
00069 CurrentDrawDevice = RegistrySettings.DrawDevice;
00070
00071
00072
00073 ZeroMemory(&DDcaps, sizeof(DDcaps));
00074 DDcaps.dwSize = sizeof(DDcaps);
00075
00076 r = DD->GetCaps(&DDcaps, NULL);
00077 if (r != DD_OK)
00078 {
00079 ErrorDX(r, "Can't get DD device caps");
00080 return FALSE;
00081 }
00082
00083
00084
00085 ddscaps2.dwCaps = DDSCAPS_PRIMARYSURFACE;
00086 DD->GetAvailableVidMem(&ddscaps2, &TotalScreenMem, &temp);
00087
00088 ddscaps2.dwCaps = DDSCAPS_TEXTURE;
00089 DD->GetAvailableVidMem(&ddscaps2, &TotalTexMem, &temp);
00090
00091
00092
00093 if (FullScreen)
00094 {
00095 r = DD->SetCooperativeLevel(hwnd, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN | DDSCL_ALLOWMODEX | DDSCL_ALLOWREBOOT | DDSCL_FPUSETUP);
00096 if (r != DD_OK)
00097 {
00098 ErrorDX(r, "Can't set coop level");
00099 return FALSE;
00100 }
00101 }
00102 else
00103 {
00104 r = DD->SetCooperativeLevel(hwnd, DDSCL_NORMAL | DDSCL_ALLOWREBOOT | DDSCL_FPUSETUP);
00105 if (r != DD_OK)
00106 {
00107 ErrorDX(r, "Can't set coop level");
00108 return FALSE;
00109 }
00110 }
00111
00112
00113
00114 r = DD->QueryInterface(IID_IDirect3D3, (void**)&D3D);
00115 if (r != DD_OK)
00116 {
00117 ErrorDX(r, "DirectX 6 is not installed");
00118 return FALSE;
00119 }
00120
00121
00122
00123 return TRUE;
00124 }
00125
00127
00129
00130 BOOL InitD3D(DWORD width, DWORD height, DWORD bpp, DWORD refresh)
00131 {
00132 long i, start, end, time1, time2;
00133 HRESULT r;
00134 DDSURFACEDESC2 ddsd2;
00135 DDSCAPS2 ddscaps2;
00136 D3DVIEWPORT2 vd;
00137 D3DDEVICEDESC hal, hel;
00138 IDirectDrawClipper *clipper;
00139 char buf[128];
00140
00141
00142
00143 ReleaseD3D();
00144
00145
00146
00147 ScreenXsize = width;
00148 ScreenYsize = height;
00149 ScreenBpp = bpp;
00150 ScreenRefresh = refresh;
00151
00152
00153
00154 ZeroMemory(&ZedBufferFormat, sizeof(ZedBufferFormat));
00155 D3D->EnumZBufferFormats(IID_IDirect3DHALDevice, EnumZedBufferCallback, NULL);
00156 if (!ZedBufferFormat.dwZBufferBitDepth)
00157 {
00158 Box(NULL, "No Zbuffer available!", MB_OK);
00159 return FALSE;
00160 }
00161
00162
00163
00164 if (FullScreen)
00165 {
00166 r = DD->SetDisplayMode(ScreenXsize, ScreenYsize, ScreenBpp, ScreenRefresh, 0);
00167 if (r != DD_OK)
00168 {
00169 wsprintf(buf, "Can't set display mode %dx%dx%d", ScreenXsize, ScreenYsize, ScreenBpp);
00170 ErrorDX(r, buf);
00171 return FALSE;
00172 }
00173 }
00174
00175
00176
00177 ZeroMemory(&ddsd2, sizeof(ddsd2));
00178 ddsd2.dwSize = sizeof(ddsd2);
00179 ddsd2.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_PIXELFORMAT;
00180 ddsd2.dwWidth = ScreenXsize;
00181 ddsd2.dwHeight = ScreenYsize;
00182 ddsd2.ddsCaps.dwCaps = DDSCAPS_ZBUFFER | DDSCAPS_VIDEOMEMORY;
00183 ddsd2.ddsCaps.dwCaps2 = 0;
00184 ddsd2.ddpfPixelFormat = ZedBufferFormat;
00185
00186 r = DD->CreateSurface(&ddsd2, &ZedBuffer, NULL);
00187 if (r != DD_OK)
00188 {
00189 ErrorDX(r, "Can't create Z buffer");
00190 return FALSE;
00191 }
00192
00193
00194
00195 if (FullScreen)
00196 {
00197 ZeroMemory(&ddsd2, sizeof(ddsd2));
00198 ddsd2.dwSize = sizeof(ddsd2);
00199 ddsd2.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
00200 ddsd2.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP | DDSCAPS_COMPLEX | DDSCAPS_3DDEVICE | DDSCAPS_VIDEOMEMORY;
00201 ddsd2.ddsCaps.dwCaps2 = 0;
00202
00203 ddsd2.dwBackBufferCount = 2;
00204 r = DD->CreateSurface(&ddsd2, &FrontBuffer, NULL);
00205 if (r != DD_OK)
00206 {
00207 ddsd2.dwBackBufferCount = 1;
00208 r = DD->CreateSurface(&ddsd2, &FrontBuffer, NULL);
00209 if (r != DD_OK)
00210 {
00211 ErrorDX(r, "Can't create draw surfaces!");
00212 return FALSE;
00213 }
00214 }
00215
00216 ddscaps2.dwCaps = DDSCAPS_BACKBUFFER;
00217 r = FrontBuffer->GetAttachedSurface(&ddscaps2, &BackBuffer);
00218 if (r != DD_OK)
00219 {
00220 ErrorDX(r, "Can't attach back buffer!");
00221 return FALSE;
00222 }
00223 }
00224 else
00225 {
00226 ZeroMemory(&ddsd2, sizeof(ddsd2));
00227 ddsd2.dwSize = sizeof(ddsd2);
00228 ddsd2.dwFlags = DDSD_CAPS;
00229 ddsd2.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_VIDEOMEMORY;
00230 ddsd2.ddsCaps.dwCaps2 = 0;
00231
00232 r = DD->CreateSurface(&ddsd2, &FrontBuffer, NULL);
00233 if (r != DD_OK)
00234 {
00235 ErrorDX(r, "Can't create primary surface!");
00236 return FALSE;
00237 }
00238
00239 ddsd2.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
00240 ddsd2.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE | DDSCAPS_VIDEOMEMORY;
00241 ddsd2.dwWidth = ScreenXsize;
00242 ddsd2.dwHeight = ScreenYsize;
00243
00244 r = DD->CreateSurface(&ddsd2, &BackBuffer, NULL);
00245 if (r != DD_OK)
00246 {
00247 ErrorDX(r, "Can't create back buffer!");
00248 return FALSE;
00249 }
00250
00251 r = DD->CreateClipper(0, &clipper, NULL);
00252 if (r != DD_OK)
00253 {
00254 ErrorDX(r, "Can't create clipper!");
00255 return FALSE;
00256 }
00257
00258 clipper->SetHWnd(0, hwnd);
00259 FrontBuffer->SetClipper(clipper);
00260 RELEASE(clipper);
00261 }
00262
00263
00264
00265 r = BackBuffer->AddAttachedSurface(ZedBuffer);
00266 if (r != DD_OK)
00267 {
00268 ErrorDX(r, "Can't attach Z buffer");
00269 return FALSE;
00270 }
00271
00272
00273
00274 r = D3D->CreateDevice(IID_IDirect3DHALDevice, BackBuffer, &D3Ddevice, NULL);
00275 if (r != DD_OK)
00276 {
00277 ErrorDX(r, "Can't create a 3D device!");
00278 return FALSE;
00279 }
00280
00281
00282
00283 ZeroMemory(&hal, sizeof(hal));
00284 hal.dwSize = sizeof(hal);
00285
00286 ZeroMemory(&hel, sizeof(hel));
00287 hel.dwSize = sizeof(hel);
00288
00289 r = D3Ddevice->GetCaps(&hal, &hel);
00290
00291 if (r != DD_OK)
00292 {
00293 ErrorDX(r, "Can't get D3D device caps");
00294 return FALSE;
00295 }
00296
00297 D3Dcaps = hal;
00298
00299
00300
00301 r = D3D->CreateViewport(&D3Dviewport, NULL);
00302 if (r != DD_OK)
00303 {
00304 ErrorDX(r, "Can't create a viewport");
00305 return FALSE;
00306 }
00307
00308 r = D3Ddevice->AddViewport(D3Dviewport);
00309 if (r != DD_OK)
00310 {
00311 ErrorDX(r, "Can't attach viewport to 3D device");
00312 return FALSE;
00313 }
00314
00315 ZeroMemory(&vd, sizeof(vd));
00316 vd.dwSize = sizeof(vd);
00317 vd.dwX = 0;
00318 vd.dwY = 0;
00319 vd.dwWidth = ScreenXsize;
00320 vd.dwHeight = ScreenYsize;
00321
00322 vd.dvClipX = 0;
00323 vd.dvClipY = 0;
00324 vd.dvClipWidth = (float)ScreenXsize;
00325 vd.dvClipHeight = (float)ScreenYsize;
00326 vd.dvMinZ = 0;
00327 vd.dvMaxZ = 1;
00328
00329 r = D3Dviewport->SetViewport2(&vd);
00330 if (r != DD_OK)
00331 {
00332 ErrorDX(r, "Can't set viewport");
00333 return FALSE;
00334 }
00335
00336 r = D3Ddevice->SetCurrentViewport(D3Dviewport);
00337 if (r != DD_OK)
00338 {
00339 ErrorDX(r, "Can't set current viewport");
00340 return FALSE;
00341 }
00342
00343
00344
00345 if (NoGamma | !(DDcaps.dwCaps2 & DDCAPS2_PRIMARYGAMMA))
00346 {
00347 GammaFlag = GAMMA_UNAVAILABLE;
00348 }
00349 else
00350 {
00351 r = FrontBuffer->QueryInterface(IID_IDirectDrawGammaControl, (void**)&GammaControl);
00352 if (r != DD_OK)
00353 {
00354 ErrorDX(r, "Can't get gamma interface");
00355 return FALSE;
00356 }
00357
00358
00359
00360
00361 GammaFlag = GAMMA_AVAILABLE;
00362
00363 SetGamma(RegistrySettings.Brightness, RegistrySettings.Contrast);
00364 }
00365
00366
00367
00368 BackgroundColor = 0x000000;
00369 ViewportRect.x1 = 0;
00370 ViewportRect.y1 = 0;
00371 ViewportRect.x2 = ScreenXsize;
00372 ViewportRect.y2 = ScreenYsize;
00373
00374 PolyClear = FALSE;
00375 start = CurrentTimer();
00376
00377 for (i = 0 ; i < 50 ; i++)
00378 {
00379 FlipBuffers();
00380 ClearBuffers();
00381 }
00382
00383 end = CurrentTimer();
00384 time1 = end - start;
00385
00386 PolyClear = TRUE;
00387 start = CurrentTimer();
00388
00389 for (i = 0 ; i < 50 ; i++)
00390 {
00391 FlipBuffers();
00392 ClearBuffers();
00393 }
00394
00395 end = CurrentTimer();
00396 time2 = end - start;
00397
00398 PolyClear = (time2 < time1);
00399
00400
00401
00402 CULL_OFF();
00403 SPECULAR_OFF();
00404 TEXTURE_ADDRESS(D3DTADDRESS_CLAMP);
00405 MIPMAP_LODBIAS(-0.02f);
00406
00407
00408
00409 return TRUE;
00410 }
00411
00413
00415
00416 void SetGamma(long brightness, long contrast)
00417 {
00418 long i;
00419 float step, middle, n;
00420 DDGAMMARAMP ramp;
00421
00422
00423
00424 if (GammaFlag == GAMMA_UNAVAILABLE)
00425 return;
00426
00427
00428
00429 step = (float)brightness * (float)contrast / 256.0f;
00430 middle = (float)brightness * 128.0f;
00431
00432 for (i = 0 ; i < 256 ; i++)
00433 {
00434 n = ((float)i - 128.0f) * step + middle;
00435
00436 if (n < 0) n = 0;
00437 else if (n > 65535.0f) n = 65535.0f;
00438
00439 ramp.red[i] = (WORD)n;
00440 ramp.green[i] = (WORD)n;
00441 ramp.blue[i] = (WORD)n;
00442 }
00443
00444 if (GammaFlag == GAMMA_AUTO)
00445 GammaControl->SetGammaRamp(DDSGR_CALIBRATE, &ramp);
00446 else
00447 GammaControl->SetGammaRamp(0, &ramp);
00448 }
00449
00451
00453
00454 HRESULT CALLBACK EnumZedBufferCallback(DDPIXELFORMAT *ddpf, void *user)
00455 {
00456
00457
00458
00459 if (!ddpf)
00460 return DDENUMRET_CANCEL;
00461
00462
00463
00464 if (ddpf->dwFlags != DDPF_ZBUFFER)
00465 return DDENUMRET_OK;
00466
00467
00468
00469 if (!ZedBufferFormat.dwZBufferBitDepth)
00470 {
00471 ZedBufferFormat = *ddpf;
00472 return DDENUMRET_OK;
00473 }
00474
00475
00476
00477 if (ddpf->dwZBufferBitDepth == 16)
00478 {
00479 ZedBufferFormat = *ddpf;
00480 return DDENUMRET_CANCEL;
00481 }
00482
00483
00484
00485 return DDENUMRET_OK;
00486 }
00487
00489
00491
00492 void CheckSurfaces(void)
00493 {
00494 char i;
00495 HRESULT r;
00496 TEXINFO texinfo;
00497
00498
00499
00500 if (!AppRestore)
00501 return;
00502
00503 AppRestore = FALSE;
00504
00505
00506
00507 r = FrontBuffer->IsLost();
00508 if (r == DDERR_SURFACELOST)
00509 {
00510 r = FrontBuffer->Restore();
00511 if (r != DD_OK)
00512 {
00513 ErrorDX(r, "Can't restore primary display");
00514 QuitGame = TRUE;
00515 return;
00516 }
00517 }
00518
00519
00520
00521 r = ZedBuffer->IsLost();
00522 if (r == DDERR_SURFACELOST)
00523 {
00524 r = ZedBuffer->Restore();
00525 if (r != DD_OK)
00526 {
00527 ErrorDX(r, "Can't restore zed buffer");
00528 QuitGame = TRUE;
00529 return;
00530 }
00531 }
00532
00533
00534
00535 for (i = 0 ; i < TPAGE_NUM ; i++) if (TexInfo[i].Active)
00536 {
00537 r = TexInfo[i].Surface->IsLost();
00538 if (r == DDERR_SURFACELOST)
00539 {
00540 texinfo = TexInfo[i];
00541 FreeOneTexture(i);
00542
00543 if (!texinfo.MipCount)
00544 LoadTexture(texinfo.File, i, texinfo.Width, texinfo.Height, texinfo.Stage);
00545 else
00546 LoadMipTexture(texinfo.File, i, texinfo.Width, texinfo.Height, texinfo.Stage, texinfo.MipCount);
00547 }
00548 }
00549 }
00550
00552
00554
00555 void FlipBuffers(void)
00556 {
00557 RECT dest;
00558 long bx, by, cy;
00559
00560 if (FullScreen)
00561 {
00562 while (FrontBuffer->Flip(NULL, DDFLIP_NOVSYNC) == DDERR_WASSTILLDRAWING);
00563 }
00564 else
00565 {
00566 GetWindowRect(hwnd, &dest);
00567 bx = GetSystemMetrics(SM_CXSIZEFRAME);
00568 by = GetSystemMetrics(SM_CYSIZEFRAME);
00569 cy = GetSystemMetrics(SM_CYCAPTION);
00570
00571 dest.left += bx;
00572 dest.right -= bx;
00573 dest.top += cy + by;
00574 dest.bottom -= by;
00575
00576 FrontBuffer->Blt(&dest, BackBuffer, NULL, DDBLT_WAIT, NULL);
00577 }
00578 }
00579
00581
00583
00584 void ClearBuffers(void)
00585 {
00586 float zres, z;
00587
00588 if (!PolyClear)
00589 {
00590 D3Dviewport->Clear2(1, &ViewportRect, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, BackgroundColor, 1.0f, 0);
00591 }
00592 else
00593 {
00594 zres = (float)(1 << ZedBufferFormat.dwZBufferBitDepth);
00595 z = (zres - 1.0f) / zres;
00596
00597 DrawVertsTEX0[0].sx = (float)ViewportRect.x1;
00598 DrawVertsTEX0[0].sy = (float)ViewportRect.y1;
00599 DrawVertsTEX0[0].sz = z;
00600 DrawVertsTEX0[0].rhw = 1.0f;
00601 DrawVertsTEX0[0].color = BackgroundColor;
00602
00603 DrawVertsTEX0[1].sx = (float)ViewportRect.x2;
00604 DrawVertsTEX0[1].sy = (float)ViewportRect.y1;
00605 DrawVertsTEX0[1].sz = z;
00606 DrawVertsTEX0[1].rhw = 1.0f;
00607 DrawVertsTEX0[1].color = BackgroundColor;
00608
00609 DrawVertsTEX0[2].sx = (float)ViewportRect.x2;
00610 DrawVertsTEX0[2].sy = (float)ViewportRect.y2;
00611 DrawVertsTEX0[2].sz = z;
00612 DrawVertsTEX0[2].rhw = 1.0f;
00613 DrawVertsTEX0[2].color = BackgroundColor;
00614
00615 DrawVertsTEX0[3].sx = (float)ViewportRect.x1;
00616 DrawVertsTEX0[3].sy = (float)ViewportRect.y2;
00617 DrawVertsTEX0[3].sz = z;
00618 DrawVertsTEX0[3].rhw = 1.0f;
00619 DrawVertsTEX0[3].color = BackgroundColor;
00620
00621 SET_TPAGE(-1);
00622
00623 ZCMP(D3DCMP_ALWAYS);
00624 D3Ddevice->DrawPrimitive(D3DPT_TRIANGLEFAN, FVF_TEX0, DrawVertsTEX0, 4, D3DDP_DONOTUPDATEEXTENTS | D3DDP_DONOTCLIP);
00625 ZCMP(D3DCMP_LESSEQUAL);
00626 }
00627 }
00628
00630
00632
00633 void SetFrontBufferRGB(long rgb)
00634 {
00635 DDBLTFX bltfx;
00636
00637 bltfx.dwSize = sizeof(bltfx);
00638 bltfx.dwFillColor = rgb;
00639 FrontBuffer->Blt(NULL, NULL, NULL, DDBLT_COLORFILL, &bltfx);
00640 }
00641
00643
00645
00646 void SetBackgroundColor(long col)
00647 {
00648 BackgroundColor = col;
00649 }
00650
00652
00654
00655 void ReleaseDX(void)
00656 {
00657 RELEASE(D3D);
00658 RELEASE(DD);
00659 }
00660
00662
00664
00665 void ReleaseD3D(void)
00666 {
00667 RELEASE(D3Ddevice);
00668 RELEASE(GammaControl);
00669 RELEASE(D3Dviewport);
00670 RELEASE(GammaControl);
00671 RELEASE(ZedBuffer);
00672 RELEASE(BackBuffer);
00673 RELEASE(FrontBuffer);
00674 }
00675
00677
00679
00680 void ErrorDX(HRESULT r, char *mess)
00681 {
00682 ERRORDX *p = ErrorListDX;
00683
00684 while (p->Result != DD_OK && p->Result != r) p++;
00685 Box(p->Error, mess, MB_OK);
00686 }
00687
00689
00691
00692 void SetupDxState(void)
00693 {
00694 long i;
00695
00696
00697
00698 DxState.WireframeEnabled = TRUE;
00699 DxState.Wireframe = D3DFILL_SOLID;
00700
00701 WIREFRAME_ON();
00702
00703
00704
00705 if (D3Dcaps.dwFlags & D3DDD_TRICAPS && D3Dcaps.dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE)
00706 {
00707 DxState.PerspectiveEnabled = TRUE;
00708 DxState.Perspective = TRUE;
00709 }
00710 else
00711 {
00712 DxState.PerspectiveEnabled = FALSE;
00713 DxState.Perspective = FALSE;
00714 }
00715
00716 PERSPECTIVE_ON();
00717
00718
00719
00720 DxState.TextureFilterFlag = 1;
00721
00722 if (D3Dcaps.dwFlags & D3DDD_TRICAPS && D3Dcaps.dpcTriCaps.dwTextureFilterCaps & D3DPTFILTERCAPS_LINEAR) DxState.TextureFilterFlag |= 2;
00723 if (D3Dcaps.dwFlags & D3DDD_TRICAPS && D3Dcaps.dpcTriCaps.dwRasterCaps & D3DPRASTERCAPS_ANISOTROPY) DxState.TextureFilterFlag |= 4;
00724
00725 for (i = 0 ; i < 3 ; i++) if (DxState.TextureFilterFlag & (1 << i)) DxState.TextureFilter = i;
00726
00727 TEXTUREFILTER_ON();
00728
00729
00730
00731 DxState.MipMapFlag = 1;
00732
00733 if (D3Dcaps.dwFlags & D3DDD_TRICAPS && D3Dcaps.dpcTriCaps.dwTextureFilterCaps & (D3DPTFILTERCAPS_MIPNEAREST | D3DPTFILTERCAPS_MIPLINEAR)) DxState.MipMapFlag |= 2;
00734 if (D3Dcaps.dwFlags & D3DDD_TRICAPS && D3Dcaps.dpcTriCaps.dwTextureFilterCaps & (D3DPTFILTERCAPS_LINEARMIPNEAREST | D3DPTFILTERCAPS_LINEARMIPLINEAR)) DxState.MipMapFlag |= 4;
00735
00736 for (i = 0 ; i < 3 ; i++) if (DxState.MipMapFlag & (1 << i)) DxState.MipMap = i;
00737
00738 MIPMAP_ON();
00739
00740
00741
00742 if (D3Dcaps.dwFlags & D3DDD_TRICAPS && D3Dcaps.dpcTriCaps.dwShadeCaps & D3DPSHADECAPS_FOGGOURAUD)
00743 {
00744 DxState.FogEnabled = TRUE;
00745 DxState.Fog = TRUE;
00746 }
00747 else
00748 {
00749 DxState.FogEnabled = FALSE;
00750 DxState.Fog = FALSE;
00751 }
00752
00753 FOG_OFF();
00754
00755
00756
00757 if (D3Dcaps.dwFlags & D3DDD_TRICAPS && D3Dcaps.dpcTriCaps.dwRasterCaps & D3DPRASTERCAPS_DITHER)
00758 {
00759 DxState.DitherEnabled = TRUE;
00760 DxState.Dither = TRUE;
00761 }
00762 else
00763 {
00764 DxState.DitherEnabled = FALSE;
00765 DxState.Dither = FALSE;
00766 }
00767
00768 DITHER_ON();
00769
00770
00771
00772 if (D3Dcaps.dwFlags & D3DDD_TRICAPS && D3Dcaps.dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_TRANSPARENCY && !NoColorKey)
00773 {
00774 DxState.ColorKeyEnabled = TRUE;
00775 DxState.ColorKey = TRUE;
00776 }
00777 else
00778 {
00779 DxState.ColorKeyEnabled = FALSE;
00780 DxState.ColorKey = FALSE;
00781 }
00782
00783 COLORKEY_ON();
00784
00785
00786
00787 if (D3Dcaps.dwFlags & D3DDD_TRICAPS && D3Dcaps.dpcTriCaps.dwRasterCaps & D3DPRASTERCAPS_ANTIALIASSORTINDEPENDENT)
00788 {
00789 DxState.AntiAliasEnabled = TRUE;
00790 DxState.AntiAlias = D3DANTIALIAS_NONE;
00791 }
00792 else
00793 {
00794 DxState.AntiAliasEnabled = FALSE;
00795 DxState.AntiAlias = D3DANTIALIAS_NONE;
00796 }
00797
00798 ANTIALIAS_ON();
00799 }
00800
00802
00804
00805 void GetDrawDevices(void)
00806 {
00807
00808
00809
00810 DrawDeviceNum = 0;
00811 DirectDrawEnumerate(GetDrawDeviceCallback, NULL);
00812
00813
00814
00815 if (RegistrySettings.DrawDevice >= (DWORD)DrawDeviceNum)
00816 RegistrySettings.DrawDevice = 0;
00817
00818 DisplayModeCount = DrawDevices[RegistrySettings.DrawDevice].BestDisplayMode;
00819 }
00820
00822
00824
00825 BOOL CALLBACK GetDrawDeviceCallback(GUID *lpGUID, LPSTR szName, LPSTR szDevice, LPVOID lParam)
00826 {
00827 HRESULT r;
00828
00829
00830
00831 if (DrawDeviceNum == MAX_DRAW_DEVICES)
00832 {
00833 return DDENUMRET_CANCEL;
00834 }
00835
00836
00837
00838 r = CoCreateInstance(CLSID_DirectDraw, NULL, CLSCTX_ALL, IID_IDirectDraw4, (void**)&DD);
00839 if (r != S_OK)
00840 {
00841 Box(NULL, "Can't create draw device", MB_OK);
00842 return DDENUMRET_CANCEL;
00843 }
00844
00845 r = DD->Initialize(lpGUID);
00846 if (r != DD_OK)
00847 {
00848 ErrorDX(r, "Can't init draw device");
00849 return DDENUMRET_CANCEL;
00850 }
00851
00852
00853
00854 memcpy(DrawDevices[DrawDeviceNum].Name, szName, MAX_DRAW_DEVICE_NAME);
00855
00856
00857
00858 DrawDevices[DrawDeviceNum].DisplayModeNum = 0;
00859 DD->EnumDisplayModes(0, NULL, NULL, DisplayModesCallback);
00860
00861
00862
00863 DrawDeviceNum++;
00864
00865
00866
00867 RELEASE(DD);
00868
00869
00870
00871 return DDENUMRET_OK;
00872 }
00873
00875
00877
00878 BOOL CALLBACK CreateDrawDeviceCallback(GUID *lpGUID, LPSTR szName, LPSTR szDevice, LPVOID lParam)
00879 {
00880 HRESULT r;
00881 char buf[128];
00882
00883
00884
00885 if (strcmp(szName, DrawDevices[RegistrySettings.DrawDevice].Name))
00886 return DDENUMRET_OK;
00887
00888
00889
00890 r = CoCreateInstance(CLSID_DirectDraw, NULL, CLSCTX_ALL, IID_IDirectDraw4, (void**)&DD);
00891 if (r != S_OK)
00892 {
00893 wsprintf(buf, "Can't create draw device '%s'", szName);
00894 Box(NULL, buf, MB_OK);
00895 return DDENUMRET_CANCEL;
00896 }
00897
00898 r = DD->Initialize(lpGUID);
00899 if (r != DD_OK)
00900 {
00901 wsprintf(buf, "Can't init draw device '%s'", szName);
00902 ErrorDX(r, buf);
00903 return DDENUMRET_CANCEL;
00904 }
00905
00906 return DDENUMRET_CANCEL;
00907 }
00908
00910
00912
00913 HRESULT CALLBACK DisplayModesCallback(DDSURFACEDESC2 *Mode, void *UserArg)
00914 {
00915
00916
00917
00918 if (DrawDevices[DrawDeviceNum].DisplayModeNum >= MAX_DISPLAY_MODES)
00919 return DDENUMRET_CANCEL;
00920
00921
00922
00923 if (!(Mode->ddpfPixelFormat.dwFlags & DDPF_RGB) || Mode->ddpfPixelFormat.dwRGBBitCount < 16)
00924 return DDENUMRET_OK;
00925
00926
00927
00928 DrawDevices[DrawDeviceNum].DisplayMode[DrawDevices[DrawDeviceNum].DisplayModeNum].Width = Mode->dwWidth;
00929 DrawDevices[DrawDeviceNum].DisplayMode[DrawDevices[DrawDeviceNum].DisplayModeNum].Height = Mode->dwHeight;
00930 DrawDevices[DrawDeviceNum].DisplayMode[DrawDevices[DrawDeviceNum].DisplayModeNum].Bpp = Mode->ddpfPixelFormat.dwRGBBitCount;
00931 DrawDevices[DrawDeviceNum].DisplayMode[DrawDevices[DrawDeviceNum].DisplayModeNum].Refresh = Mode->dwRefreshRate;
00932 wsprintf(DrawDevices[DrawDeviceNum].DisplayMode[DrawDevices[DrawDeviceNum].DisplayModeNum].DisplayText, "%dx%dx%d", (short)Mode->dwWidth, (short)Mode->dwHeight, (short)Mode->ddpfPixelFormat.dwRGBBitCount);
00933
00934
00935
00936 if (Mode->dwWidth <= RegistrySettings.ScreenWidth && Mode->dwHeight <= RegistrySettings.ScreenHeight && Mode->ddpfPixelFormat.dwRGBBitCount <= RegistrySettings.ScreenBpp)
00937 DrawDevices[DrawDeviceNum].BestDisplayMode = DrawDevices[DrawDeviceNum].DisplayModeNum;
00938
00939
00940
00941 DrawDevices[DrawDeviceNum].DisplayModeNum++;
00942 return DDENUMRET_OK;
00943 }