00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #include <Windows.h>
00033 #include <Assert.h>
00034 #include <stdio.h>
00035 #include <DDraw.h>
00036 #include <D3D.h>
00037 #include <Math.h>
00038
00039 #include "D3D_Main.h"
00040 #include "D3D_Err.h"
00041 #include "D3D_fx.h"
00042 #include "d3dcache.h"
00043
00044 #include "Render.h"
00045 #include "D3DCache.h"
00046 #include "THandle.h"
00047 #include "PCache.h"
00048
00049 #undef ATTEMPT
00050 #define ATTEMPT(x) if (!(x)) goto exit_with_error
00051
00052 #undef RELEASE
00053 #define RELEASE(x) if (x) { x->Release(); x = NULL; }
00054
00055 static BOOL bInitDone =FALSE;
00056 #ifdef STRICT
00057 WNDPROC pOldWndProc;
00058 #else
00059 FARPROC pOldWndProc;
00060 #endif
00061
00062
00063
00064
00065 App_Info AppInfo;
00066
00067
00068 int BPP32 = 16;
00069 int ZbufferD = 16;
00070 FILE *stream;
00071 int gWidth, gHeight;
00072
00073
00074 #define MAX_DRIVERS 64
00075
00076 typedef struct
00077 {
00078 geBoolean IsPrimary;
00079 GUID Guid;
00080 char Name[MAX_DRIVER_NAME];
00081 } D3D_DRIVER;
00082
00083 typedef struct
00084 {
00085 int32 NumDrivers;
00086 D3D_DRIVER *Drivers;
00087 } DDEnumInfo;
00088
00089
00090
00091
00092 static BOOL D3DMain_CreateD3D(void);
00093 static BOOL D3DMain_EnumDevices(void);
00094 static BOOL D3DMain_CreateViewPort(int w, int h);
00095 static BOOL D3DMain_ClearBuffers(void);
00096 static BOOL OutputDriverInfo(const char *Filename, DDMain_D3DDriver *Driver);
00097 static BOOL D3DMain_RememberOldMode(HWND hWnd);
00098 static BOOL D3DMain_SetDisplayMode(HWND hWnd, int w, int h, int bpp, BOOL FullScreen);
00099 static BOOL D3DMain_PickDevice(void);
00100 static BOOL D3DMain_CreateDevice(void);
00101 static BOOL D3DMain_CreateBuffers(void);
00102 static void D3DMain_DestroyBuffers(void);
00103 static BOOL D3DMain_CreateZBuffer(void);
00104 static void D3DMain_DestroyZBuffer(void);
00105 static BOOL D3DMain_RestoreDisplayMode(void);
00106 static BOOL D3DMain_CreateDDFromName(const char *DriverName);
00107 static geBoolean CreateDDFromDriver(D3D_DRIVER *pDriver);
00108 static geBoolean CreateDDFromName(const char *DriverName, const DDEnumInfo *Info);
00109
00110 BOOL D3DMain_RestoreAllSurfaces(void)
00111 {
00112 HRESULT ddrval;
00113
00114 #ifdef _DEBUG
00115 OutputDebugString("--- D3DMain_RestoreAllSurfaces ---\n");
00116 #endif
00117
00118 if (AppInfo.lpDD)
00119 {
00120 if (!D3DMain_SetDisplayMode(AppInfo.hWnd, AppInfo.CurrentWidth, AppInfo.CurrentHeight, AppInfo.CurrentBpp, AppInfo.FullScreen))
00121 return FALSE;
00122
00123
00124 ddrval = AppInfo.lpDD->RestoreAllSurfaces();
00125
00126 if(ddrval!=DD_OK)
00127 {
00128 D3DMain_Log("D3DMain_RestoreAllSurfaces: AppInfo.lpDD->RestoreAllSurfaces() failed:\n %s\n", D3DErrorToString(ddrval));
00129 return FALSE;
00130 }
00131 }
00132
00133
00134 if (TextureCache)
00135 if (!D3DCache_EvictAllSurfaces(TextureCache))
00136 return FALSE;
00137
00138 if (LMapCache)
00139 if (!D3DCache_EvictAllSurfaces(LMapCache))
00140 return FALSE;
00141
00142 return TRUE;
00143 }
00144
00145
00146
00147
00148
00149 static DWORD BPPToDDBD(int bpp)
00150 {
00151 switch(bpp)
00152 {
00153 case 1:
00154 return DDBD_1;
00155 case 2:
00156 return DDBD_2;
00157 case 4:
00158 return DDBD_4;
00159 case 8:
00160 return DDBD_8;
00161 case 16:
00162 return DDBD_16;
00163 case 24:
00164 return DDBD_24;
00165 case 32:
00166 return DDBD_32;
00167 default:
00168 assert(!"BOGUS bpp");
00169 }
00170
00171 return DDBD_1;
00172 }
00173
00174
00175
00176
00177
00178
00179 BOOL D3DMain_InitD3D(HWND hWnd, const char *DriverName, int32 Width, int32 Height)
00180 {
00181 HRESULT LastError;
00182 SYSTEMTIME Time;
00183
00184 memset(&AppInfo, 0, sizeof(App_Info));
00185
00186 GetSystemTime(&Time);
00187
00188 unlink(D3DMAIN_LOG_FILENAME);
00189
00190 D3DMain_Log("=================================================================\n");
00191 D3DMain_Log(" D3DDrv v%i.%i\n", DRV_VERSION_MAJOR, DRV_VERSION_MINOR);
00192 D3DMain_Log(" Build Date: "__DATE__", Time: "__TIME__"\n");
00193 D3DMain_Log("=================================================================\n\n");
00194
00195 D3DMain_Log("Current Time: %2i:%2i:%2i\n", Time.wHour, Time.wMinute, Time.wSecond);
00196 D3DMain_Log("Current Date: %2i-%2i-%4i\n", Time.wMonth, Time.wDay, Time.wYear);
00197 D3DMain_Log("\n ** D3D Driver Initializing **\n\n");
00198
00199 AppInfo.hWnd = hWnd;
00200
00201
00202 ATTEMPT(D3DMain_CreateDDFromName(DriverName));
00203
00204 ATTEMPT(D3DMain_GetTextureMemory());
00205
00206
00207 ATTEMPT(D3DMain_RememberOldMode(hWnd));
00208
00209
00210 ATTEMPT(D3DMain_EnumDisplayModes());
00211
00212
00213 ATTEMPT(D3DMain_CreateD3D());
00214 ATTEMPT(D3DMain_EnumDevices());
00215
00216
00217
00218 stream = fopen("D3D24.ini","r");
00219 if(stream)
00220 {
00221 fscanf(stream,"%d",&BPP32);
00222 fscanf(stream,"%d",&ZbufferD);
00223 fclose(stream);
00224 }
00225 else
00226 {
00227 BPP32 = 16;
00228 ZbufferD = 16;
00229 }
00230
00231
00232 gWidth = Width;
00233 gHeight = Height;
00234
00235 if (Width == -1 && Height == -1)
00236 {
00237
00238 Width = AppInfo.OldWindowWidth;
00239 Height = AppInfo.OldWindowHeight;
00240
00241 ATTEMPT(D3DMain_SetDisplayMode(hWnd, Width, Height, AppInfo.OldBpp, FALSE));
00242 }
00243 else
00244 {
00245 ATTEMPT(D3DMain_SetDisplayMode(hWnd, Width, Height, BPP32, TRUE));
00246 }
00247
00248
00249
00250 ATTEMPT(D3DMain_PickDevice());
00251
00252
00253 ATTEMPT(D3DMain_CreateBuffers());
00254
00255
00256 ATTEMPT(D3DMain_CreateZBuffer());
00257
00258
00259 ATTEMPT(D3DMain_CreateDevice());
00260 ATTEMPT(D3DMain_CreateViewPort(Width, Height));
00261
00262
00263 ATTEMPT(D3DMain_GetSurfaceFormats());
00264
00265 #if 0 // For selective debugging
00266 AppInfo.CanDoMultiTexture = GE_FALSE;
00267 #else
00268 AppInfo.CanDoMultiTexture = (AppInfo.Drivers[AppInfo.CurrentDriver].MaxSimultaneousTextures > 1) ? GE_TRUE : GE_FALSE;
00269 #endif
00270
00271 D3DMain_Log("--- D3DMain_SetRenderState --- \n");
00272
00273
00274 LastError = AppInfo.lpD3DDevice->BeginScene();
00275
00276 if (LastError != D3D_OK)
00277 {
00278 D3DMain_Log("D3DMain_InitD3D: BeginScene failed.\n %s\n",
00279 D3DErrorToString(LastError));
00280 goto exit_with_error;
00281 }
00282
00283 LastError = AppInfo.lpD3DDevice->SetCurrentViewport(AppInfo.lpD3DViewport);
00284
00285 if (LastError != D3D_OK)
00286 {
00287 D3DMain_Log("D3DMain_InitD3D: SetViewport failed.\n %s\n",
00288 D3DErrorToString(LastError));
00289 goto exit_with_error;
00290 }
00291
00292
00293 D3DMain_SetFogEnable(GE_FALSE, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f);
00294
00295 AppInfo.lpD3DDevice->SetRenderState(D3DRENDERSTATE_ZFUNC, D3DCMP_LESSEQUAL);
00296
00297
00298 AppInfo.lpD3DDevice->SetRenderState(D3DRENDERSTATE_TEXTUREPERSPECTIVE, TRUE);
00299 AppInfo.lpD3DDevice->SetRenderState(D3DRENDERSTATE_SPECULARENABLE, FALSE);
00300
00301 AppInfo.lpD3DDevice->SetRenderState(D3DRENDERSTATE_DITHERENABLE, TRUE);
00302
00303 #if 0
00304 AppInfo.lpD3DDevice->SetRenderState(D3DRENDERSTATE_ANTIALIAS, D3DANTIALIAS_SORTINDEPENDENT);
00305 AppInfo.lpD3DDevice->SetRenderState(D3DRENDERSTATE_EDGEANTIALIAS, TRUE);
00306 #endif
00307
00308 AppInfo.lpD3DDevice->SetRenderState(D3DRENDERSTATE_SHADEMODE, D3DSHADE_GOURAUD);
00309 AppInfo.lpD3DDevice->SetRenderState(D3DRENDERSTATE_CULLMODE, D3DCULL_NONE);
00310 AppInfo.lpD3DDevice->SetRenderState(D3DRENDERSTATE_COLORKEYENABLE, TRUE);
00311
00312 AppInfo.lpD3DDevice->SetRenderState(D3DRENDERSTATE_TEXTUREMIN, D3DFILTER_LINEARMIPNEAREST);
00313 AppInfo.lpD3DDevice->SetRenderState(D3DRENDERSTATE_TEXTUREMAG, D3DFILTER_LINEAR);
00314
00315 LastError = AppInfo.lpD3DDevice->EndScene();
00316
00317 if (LastError != D3D_OK)
00318 {
00319 D3DMain_Log("D3DMain_InitD3D: EndScene failed.\n %s\n",
00320 D3DErrorToString(LastError));
00321 goto exit_with_error;
00322 }
00323
00324 AppInfo.RenderingIsOK = TRUE;
00325
00326 ATTEMPT(D3DMain_ClearBuffers());
00327 ATTEMPT(D3DMain_GetTextureMemory());
00328
00329 if (!THandle_Startup())
00330 return GE_FALSE;
00331
00332 D3DViewport (0, 0, Width, Height);
00333 D3DDepthRange (0.0f, 1.0f);
00334
00335 D3DMain_Log("\n ** Initialization was successful **\n\n");
00336
00337 return TRUE;
00338
00339 exit_with_error:;
00340 D3DMain_Log(" ** Initialization was NOT successful **\n");
00341 D3DMain_ShutdownD3D();
00342 return FALSE;
00343 }
00344
00345
00346
00347
00348 BOOL D3DMain_ShutdownD3D(void)
00349 {
00350 D3DMain_Log("\n--- D3DMain_ShutdownD3D ---\n");
00351
00352 THandle_Shutdown();
00353
00354
00355 AppInfo.RenderingIsOK = FALSE;
00356
00357 if (AppInfo.lpD3DViewport)
00358 {
00359 assert(AppInfo.lpD3DDevice);
00360 AppInfo.lpD3DDevice->DeleteViewport(AppInfo.lpD3DViewport);
00361 RELEASE(AppInfo.lpD3DViewport);
00362 }
00363
00364 RELEASE(AppInfo.lpD3DDevice);
00365
00366 RELEASE(AppInfo.BackgroundMaterial);
00367
00368 if (AppInfo.lpZBuffer)
00369 {
00370 assert(AppInfo.lpBackBuffer);
00371 AppInfo.lpBackBuffer->DeleteAttachedSurface(0, AppInfo.lpZBuffer);
00372 RELEASE(AppInfo.lpZBuffer);
00373 }
00374
00375 if (AppInfo.lpFrontBuffer)
00376 AppInfo.lpFrontBuffer->SetClipper(NULL);
00377
00378 RELEASE(AppInfo.lpClipper);
00379 RELEASE(AppInfo.lpBackBuffer);
00380 RELEASE(AppInfo.lpFrontBuffer);
00381
00382 D3DMain_RestoreDisplayMode();
00383
00384 RELEASE(AppInfo.lpD3D);
00385 RELEASE(AppInfo.lpDD);
00386
00387 memset(&AppInfo, 0, sizeof(App_Info));
00388
00389 D3DMain_Log(" Shutdown was successful...\n\n");
00390
00391 return TRUE;
00392 }
00393
00394 extern uint32 CurrentLRU;
00395
00396
00397 geBoolean D3DMain_Reset(void)
00398 {
00399 THandle_Shutdown();
00400 PCache_Reset();
00401
00402 if (!THandle_Startup())
00403 return GE_FALSE;
00404
00405 CurrentLRU = 0;
00406
00407 return GE_TRUE;
00408 }
00409
00410
00411
00412
00413 void D3DMain_Log(LPSTR Str, ... )
00414 {
00415 char Buffer[2048];
00416 FILE *f;
00417
00418 wvsprintf(Buffer, Str, (char*)(&Str+1));
00419
00420 f = fopen(D3DMAIN_LOG_FILENAME, "a+t");
00421
00422 if (!f)
00423 return;
00424
00425 fprintf(f, "%s", Buffer);
00426
00427 fclose(f);
00428 }
00429
00430
00431
00432
00433 static int CompareModes(const void* element1, const void* element2)
00434 {
00435 App_Mode *lpMode1, *lpMode2;
00436
00437 lpMode1 = (App_Mode*)element1;
00438 lpMode2 = (App_Mode*)element2;
00439
00440 if (lpMode1->Bpp > lpMode2->Bpp)
00441 return -1;
00442 else if (lpMode2->Bpp > lpMode1->Bpp)
00443 return 1;
00444 else if (lpMode1->Width > lpMode2->Width)
00445 return -1;
00446 else if (lpMode2->Width > lpMode1->Width)
00447 return 1;
00448 else if (lpMode1->Height > lpMode2->Height)
00449 return -1;
00450 else if (lpMode2->Height > lpMode1->Height)
00451 return 1;
00452 else
00453 return 0;
00454 }
00455
00456
00457
00458
00459 static HRESULT CALLBACK EnumDisplayModesCallback(LPDDSURFACEDESC2 pddsd, LPVOID lpContext)
00460 {
00461 App_Mode *pMode;
00462
00463 if (!pddsd)
00464 return DDENUMRET_OK;
00465
00466 if (pddsd->dwWidth > 1024 || pddsd->dwHeight > 768)
00467 return DDENUMRET_OK;
00468
00469 if (AppInfo.NumModes >= MAX_APP_MODES)
00470 return DDENUMRET_CANCEL;
00471
00472 pMode = &AppInfo.Modes[AppInfo.NumModes++];
00473
00474
00475 pMode->Width = pddsd->dwWidth;
00476 pMode->Height = pddsd->dwHeight;
00477 pMode->Bpp = pddsd->ddpfPixelFormat.dwRGBBitCount;
00478 pMode->ThisDriverCanDo = FALSE;
00479
00480 return DDENUMRET_OK;
00481 }
00482
00483
00484
00485
00486 BOOL D3DMain_EnumDisplayModes(void)
00487 {
00488 HRESULT LastError;
00489
00490 D3DMain_Log("--- D3DMain_EnumDisplayModes ---\n");
00491
00492
00493 AppInfo.NumModes = 0;
00494
00495 LastError = AppInfo.lpDD->EnumDisplayModes(0, NULL, 0, EnumDisplayModesCallback);
00496
00497 if(LastError != DD_OK )
00498 {
00499 D3DMain_Log("EnumDisplayModes failed.\n %s\n", D3DErrorToString(LastError));
00500 AppInfo.NumModes = 0;
00501 return FALSE;
00502 }
00503
00504
00505 qsort((void *)&AppInfo.Modes[0], (size_t)AppInfo.NumModes, sizeof(App_Mode), CompareModes);
00506
00507 return TRUE;
00508 }
00509
00510
00511
00512
00513
00514
00515 static BOOL D3DMain_CreateD3D(void)
00516 {
00517 HRESULT LastError;
00518
00519 assert(AppInfo.lpDD);
00520
00521 D3DMain_Log("--- D3DMain_CreateD3D ---\n");
00522
00523 LastError = AppInfo.lpDD->QueryInterface(IID_IDirect3D3, (LPVOID*)&AppInfo.lpD3D);
00524
00525 if (LastError != DD_OK)
00526 {
00527 D3DMain_Log("Creation of IDirect3D failed.\n %s\n", D3DErrorToString(LastError));
00528 goto exit_with_error;
00529 }
00530
00531 return TRUE;
00532
00533 exit_with_error:
00534 return FALSE;
00535 }
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551 #if 0
00552 #define MUST_BLEND_SRC (D3DPBLENDCAPS_SRCALPHA | \
00553 D3DPBLENDCAPS_INVSRCALPHA | \
00554 D3DPBLENDCAPS_DESTCOLOR | \
00555 D3DPBLENDCAPS_ONE | \
00556 D3DPBLENDCAPS_ZERO)
00557
00558 #define MUST_BLEND_DEST (D3DPBLENDCAPS_SRCALPHA | \
00559 D3DPBLENDCAPS_INVSRCALPHA | \
00560 D3DPBLENDCAPS_SRCCOLOR | \
00561 D3DPBLENDCAPS_ONE | \
00562 D3DPBLENDCAPS_ZERO)
00563
00564 #else
00565 #define MUST_BLEND_SRC (D3DPBLENDCAPS_SRCALPHA | \
00566 D3DPBLENDCAPS_DESTCOLOR | \
00567 D3DPBLENDCAPS_ONE | \
00568 D3DPBLENDCAPS_ZERO)
00569
00570 #define MUST_BLEND_DEST (D3DPBLENDCAPS_INVSRCALPHA | \
00571 D3DPBLENDCAPS_ONE | \
00572 D3DPBLENDCAPS_ZERO)
00573 #endif
00574
00575
00576
00577
00578 static HRESULT WINAPI EnumDeviceFunc(LPGUID lpGuid, LPSTR lpDeviceDescription,
00579 LPSTR lpDeviceName, LPD3DDEVICEDESC lpHWDesc,
00580 LPD3DDEVICEDESC lpHELDesc, LPVOID lpContext)
00581 {
00582 DDMain_D3DDriver *Driver;
00583 BOOL Good;
00584
00585 if (!lpGuid|| !lpDeviceDescription || !lpDeviceName || !lpHWDesc || !lpHELDesc)
00586 return (D3DENUMRET_OK);
00587
00588 if (strlen(lpDeviceDescription) >= MAX_DRIVER_NAME)
00589 return (D3DENUMRET_OK);
00590
00591 if (strlen(lpDeviceName) >= MAX_DRIVER_NAME)
00592 return (D3DENUMRET_OK);
00593
00594 lpContext = lpContext;
00595
00596 Good = TRUE;
00597
00598 AppInfo.CurrentDriver = AppInfo.NumDrivers;
00599
00600 Driver = &AppInfo.Drivers[AppInfo.NumDrivers];
00601
00602
00603 memcpy(&AppInfo.Drivers[AppInfo.NumDrivers].Guid, lpGuid, sizeof(GUID));
00604 lstrcpy(AppInfo.Drivers[AppInfo.NumDrivers].About, lpDeviceDescription);
00605 lstrcpy(AppInfo.Drivers[AppInfo.NumDrivers].Name, lpDeviceName);
00606
00607
00608
00609 if (lpHWDesc->dcmColorModel)
00610 {
00611 AppInfo.Drivers[AppInfo.NumDrivers].IsHardware = TRUE;
00612 memcpy(&AppInfo.Drivers[AppInfo.NumDrivers].Desc, lpHWDesc, sizeof(D3DDEVICEDESC));
00613 }
00614 else
00615 {
00616
00617 AppInfo.Drivers[AppInfo.NumDrivers].IsHardware = FALSE;
00618 memcpy(&AppInfo.Drivers[AppInfo.NumDrivers].Desc, lpHELDesc, sizeof(D3DDEVICEDESC));
00619 Good = FALSE;
00620 }
00621
00622 LPD3DDEVICEDESC Desc = &AppInfo.Drivers[AppInfo.NumDrivers].Desc;
00623
00624 Driver->MaxTextureBlendStages = Desc->wMaxTextureBlendStages;
00625 Driver->MaxSimultaneousTextures = Desc->wMaxSimultaneousTextures;
00626
00627 if (!(Desc->dwDeviceZBufferBitDepth))
00628 Good = FALSE;
00629 else
00630 AppInfo.Drivers[AppInfo.NumDrivers].DoesZBuffer = TRUE;
00631
00632 if (!(Desc->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_PERSPECTIVE))
00633 Good = FALSE;
00634 else
00635 AppInfo.Drivers[AppInfo.NumDrivers].DoesTextures = TRUE;
00636
00637
00638 if (!(Desc->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_ALPHA))
00639 Good = FALSE;
00640 else
00641 AppInfo.Drivers[AppInfo.NumDrivers].DoesAlpha = TRUE;
00642
00643 if (!(Desc->dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_TRANSPARENCY))
00644 Good = FALSE;
00645 else
00646 AppInfo.Drivers[AppInfo.NumDrivers].DoesTransparency = TRUE;
00647
00648
00649
00650
00651 AppInfo.Drivers[AppInfo.NumDrivers].DoesClamping = TRUE;
00652
00653 if ((Desc->dpcTriCaps.dwSrcBlendCaps & MUST_BLEND_SRC) != MUST_BLEND_SRC)
00654 Good = FALSE;
00655 else
00656 AppInfo.Drivers[AppInfo.NumDrivers].DoesSrcBlending = TRUE;
00657
00658 if ((Desc->dpcTriCaps.dwDestBlendCaps & MUST_BLEND_DEST) != MUST_BLEND_DEST)
00659 Good = FALSE;
00660 else
00661 AppInfo.Drivers[AppInfo.NumDrivers].DoesDestBlending = TRUE;
00662
00663
00664 if ((Desc->dwDeviceRenderBitDepth & BPPToDDBD(AppInfo.OldBpp)) && AppInfo.IsPrimary && Good)
00665 {
00666 AppInfo.Drivers[AppInfo.NumDrivers].CanDoWindow = TRUE;
00667 AppInfo.CanDoWindow = TRUE;
00668 }
00669 else
00670 AppInfo.Drivers[AppInfo.NumDrivers].CanDoWindow = FALSE;
00671
00672
00673 AppInfo.Drivers[AppInfo.NumDrivers].CanUse = Good;
00674
00675 #if 0
00676 if (AppInfo.LogToFile)
00677 OutputDriverInfo(D3DMAIN_LOG_FILENAME, &AppInfo.Drivers[AppInfo.NumDrivers]);
00678 #endif
00679
00680 if (!Good)
00681 return (D3DENUMRET_OK);
00682
00683
00684 AppInfo.FoundGoodDevice = TRUE;
00685
00686
00687 AppInfo.NumDrivers++;
00688
00689 if (AppInfo.NumDrivers+1 >= DDMAIN_MAX_D3D_DRIVERS)
00690 return (D3DENUMRET_CANCEL);
00691
00692 return (D3DENUMRET_OK);
00693 }
00694
00695
00696
00697
00698 static BOOL D3DMain_EnumDevices(void)
00699 {
00700 HRESULT LastError;
00701
00702 D3DMain_Log("--- D3DMain_EnumDevices ---\n");
00703
00704 AppInfo.NumDrivers = 0;
00705
00706 LastError = AppInfo.lpD3D->EnumDevices(EnumDeviceFunc, NULL);
00707
00708 if (LastError != DD_OK)
00709 {
00710 D3DMain_Log("Enumeration of drivers failed.\n %s\n", D3DErrorToString(LastError));
00711 return FALSE;
00712 }
00713
00714 AppInfo.CurrentDriver = 0;
00715
00716 return TRUE;
00717 }
00718
00719
00720
00721
00722 static HRESULT CreateSurface(LPDDSURFACEDESC2 lpDDSurfDesc, LPDIRECTDRAWSURFACE4 FAR *lpDDSurface)
00723 {
00724 HRESULT Result;
00725
00726
00727
00728
00729 Result = AppInfo.lpDD->CreateSurface(lpDDSurfDesc, lpDDSurface, NULL);
00730
00731 return Result;
00732 }
00733
00734
00735
00736
00737 static HRESULT GetSurfDesc(LPDDSURFACEDESC2 lpDDSurfDesc, LPDIRECTDRAWSURFACE4 lpDDSurf)
00738 {
00739 HRESULT Result;
00740
00741 memset(lpDDSurfDesc, 0, sizeof(DDSURFACEDESC2));
00742
00743 lpDDSurfDesc->dwSize = sizeof(DDSURFACEDESC2);
00744
00745 Result = lpDDSurf->GetSurfaceDesc(lpDDSurfDesc);
00746
00747 return Result;
00748 }
00749
00750
00751
00752
00753 static BOOL D3DMain_CreateViewPort(int w, int h)
00754 {
00755 LPDIRECT3DVIEWPORT3 lpD3DViewport;
00756 HRESULT rval;
00757
00758 D3DMain_Log("--- D3DMain_CreateViewPort ---\n");
00759
00760
00761 rval = AppInfo.lpD3D->CreateViewport(&lpD3DViewport, NULL);
00762
00763 if (rval != D3D_OK)
00764 {
00765 D3DMain_Log("Create D3D viewport failed.\n %s\n", D3DErrorToString(rval));
00766 return FALSE;
00767 }
00768
00769
00770 rval = AppInfo.lpD3DDevice->AddViewport(lpD3DViewport);
00771 if (rval != D3D_OK)
00772 {
00773 D3DMain_Log("Add D3D viewport failed.\n %s\n", D3DErrorToString(rval));
00774 return FALSE;
00775 }
00776
00777
00778 D3DVIEWPORT2 viewData;
00779
00780 memset(&viewData, 0, sizeof(D3DVIEWPORT2));
00781 viewData.dwSize = sizeof(D3DVIEWPORT2);
00782 viewData.dwX = viewData.dwY = 0;
00783 viewData.dwWidth = w;
00784 viewData.dwHeight = h;
00785 viewData.dvClipX = -1.0f;
00786 viewData.dvClipWidth = 2.0f;
00787 viewData.dvClipHeight = h * 2.0f / w;
00788 viewData.dvClipY = viewData.dvClipHeight / 2.0f;
00789 viewData.dvMinZ = 0.0f;
00790 viewData.dvMaxZ = 1.0f;
00791
00792 rval = lpD3DViewport->SetViewport2(&viewData);
00793 if (rval != D3D_OK)
00794 {
00795 D3DMain_Log("SetViewport failed.\n %s\n", D3DErrorToString(rval));
00796 return FALSE;
00797 }
00798
00799 AppInfo.lpD3DViewport = lpD3DViewport;
00800
00801
00802 {
00803 D3DMATERIAL Material;
00804 D3DMATERIALHANDLE MatHandle;
00805
00806
00807 rval = AppInfo.lpD3D->CreateMaterial(&AppInfo.BackgroundMaterial, NULL );
00808
00809 if (rval != D3D_OK)
00810 {
00811 D3DMain_Log("D3DMain_CreateViewPort: CreateMaterial failed.\n %s\n", D3DErrorToString(rval));
00812 return FALSE;
00813 }
00814
00815
00816 memset(&Material, 0, sizeof(D3DMATERIAL));
00817
00818 Material.dwSize = sizeof(D3DMATERIAL);
00819 Material.dcvDiffuse.r = Material.dcvAmbient.r = 255.0f;
00820 Material.dcvDiffuse.g = Material.dcvAmbient.g = 255.0f;
00821 Material.dcvDiffuse.b = Material.dcvAmbient.b = 255.0f;
00822 Material.dwRampSize = 16L;
00823
00824 AppInfo.BackgroundMaterial->SetMaterial(&Material);
00825
00826
00827 AppInfo.BackgroundMaterial->GetHandle( AppInfo.lpD3DDevice, &MatHandle);
00828 AppInfo.lpD3DViewport->SetBackground(MatHandle);
00829 }
00830
00831 return TRUE;
00832 }
00833
00834
00835
00836
00837
00838
00839 static HRESULT CALLBACK EnumTextureFormatsCallback(LPDDPIXELFORMAT lpddpfPixelFormat, LPVOID lpContext)
00840 {
00841 DDMain_SurfFormat *pTexFormat;
00842
00843 if(!lpddpfPixelFormat)
00844 return DDENUMRET_OK;
00845
00846 if (AppInfo.NumTextureFormats+1 >= DDMAIN_MAX_TEXTURE_FORMATS )
00847 {
00848 return DDENUMRET_CANCEL;
00849 }
00850
00851 pTexFormat = &AppInfo.TextureFormats[AppInfo.NumTextureFormats];
00852
00853
00854 memset(pTexFormat, 0, sizeof(DDMain_SurfFormat));
00855
00856 if(lpddpfPixelFormat->dwFlags & DDPF_ALPHAPIXELS)
00857 {
00858 if(lpddpfPixelFormat->dwRGBAlphaBitMask == 0x8000)
00859 {
00860 if(lpddpfPixelFormat->dwRBitMask != 0x7c00 ||
00861 lpddpfPixelFormat->dwGBitMask != 0x3e0 ||
00862 lpddpfPixelFormat->dwBBitMask != 0x1f)
00863 return DDENUMRET_OK;
00864
00865 pTexFormat->HasOneBitAlpha = TRUE;
00866 pTexFormat->HasFourBitAlpha = FALSE;
00867 }
00868 else if(lpddpfPixelFormat->dwRGBAlphaBitMask == 0xf000)
00869 {
00870 if(lpddpfPixelFormat->dwRBitMask != 0xf00 ||
00871 lpddpfPixelFormat->dwGBitMask != 0xf0 ||
00872 lpddpfPixelFormat->dwBBitMask != 0xf)
00873 return DDENUMRET_OK;
00874
00875 pTexFormat->HasOneBitAlpha = FALSE;
00876 pTexFormat->HasFourBitAlpha = TRUE;
00877 }
00878 else
00879 {
00880 pTexFormat->HasOneBitAlpha = FALSE;
00881 pTexFormat->HasFourBitAlpha = FALSE;
00882 }
00883 }
00884 else
00885 {
00886 if(!(lpddpfPixelFormat->dwFlags & DDPF_RGB))
00887 return DDENUMRET_OK;
00888
00889 #if 0
00890 if(lpddpfPixelFormat->dwRGBBitCount != 16)
00891 return DDENUMRET_OK;
00892
00893 if( (lpddpfPixelFormat->dwRBitMask != 0xf800 && lpddpfPixelFormat->dwRBitMask != 0x7c00) ||
00894 (lpddpfPixelFormat->dwGBitMask != 0x7e0 && lpddpfPixelFormat->dwGBitMask != 0x3e0) ||
00895 (lpddpfPixelFormat->dwBBitMask != 0x1f))
00896 return DDENUMRET_OK;
00897 #endif
00898
00899 pTexFormat->HasOneBitAlpha = FALSE;
00900 pTexFormat->HasFourBitAlpha = FALSE;
00901 }
00902
00903
00904 memcpy(&pTexFormat->ddsd.ddpfPixelFormat, lpddpfPixelFormat, sizeof(DDPIXELFORMAT));
00905
00906 AppInfo.NumTextureFormats++;
00907
00908 return DDENUMRET_OK;
00909 }
00910
00911
00912
00913
00914
00915
00916 BOOL Main_EnumTextureFormats(void)
00917 {
00918 HRESULT LastError;
00919
00920 assert(AppInfo.lpD3DDevice);
00921
00922 AppInfo.NumTextureFormats = 0;
00923
00924 LastError = AppInfo.lpD3DDevice->EnumTextureFormats(EnumTextureFormatsCallback, NULL);
00925
00926 if (LastError != DD_OK)
00927 {
00928 D3DMain_Log("Main_EnumTextureFormats: Enumeration of texture formats failed.\n %s\n",
00929 D3DErrorToString(LastError));
00930 return FALSE;
00931 }
00932
00933 return TRUE;
00934 }
00935
00936
00937
00938
00939
00940 HRESULT WINAPI EnumSurfaceFormatsCallback(LPDIRECTDRAWSURFACE4 lpDDSurface, LPDDSURFACEDESC2 lpDDSurfaceDesc, LPVOID lpContext)
00941 {
00942 LPDDPIXELFORMAT lpddpfPixelFormat;
00943 DDMain_SurfFormat *pSurfFormat;
00944
00945
00946 RELEASE(lpDDSurface);
00947
00948 lpddpfPixelFormat = &lpDDSurfaceDesc->ddpfPixelFormat;
00949
00950 if(!lpddpfPixelFormat)
00951 return DDENUMRET_OK;
00952
00953 if (AppInfo.NumSurfFormats+1 >= DDMAIN_MAX_SURFACE_FORMATS )
00954 return DDENUMRET_CANCEL;
00955
00956 pSurfFormat = &AppInfo.SurfFormats[AppInfo.NumSurfFormats];
00957
00958
00959 memset(pSurfFormat, 0, sizeof(DDMain_SurfFormat));
00960
00961 if(lpddpfPixelFormat->dwFlags & DDPF_ALPHAPIXELS)
00962 {
00963 if(lpddpfPixelFormat->dwRGBAlphaBitMask == 0x8000)
00964 {
00965
00966 if(lpddpfPixelFormat->dwRBitMask != 0x7c00 ||
00967 lpddpfPixelFormat->dwGBitMask != 0x3e0 ||
00968 lpddpfPixelFormat->dwBBitMask != 0x1f)
00969 return DDENUMRET_OK;
00970
00971 pSurfFormat->HasOneBitAlpha = TRUE;
00972 pSurfFormat->HasFourBitAlpha = FALSE;
00973 }
00974 else if(lpddpfPixelFormat->dwRGBAlphaBitMask == 0xf000)
00975 {
00976
00977 if(lpddpfPixelFormat->dwRBitMask != 0xf00 ||
00978 lpddpfPixelFormat->dwGBitMask != 0xf0 ||
00979 lpddpfPixelFormat->dwBBitMask != 0xf)
00980 return DDENUMRET_OK;
00981
00982 pSurfFormat->HasOneBitAlpha = FALSE;
00983 pSurfFormat->HasFourBitAlpha = TRUE;
00984 }
00985 else
00986 {
00987 pSurfFormat->HasOneBitAlpha = FALSE;
00988 pSurfFormat->HasFourBitAlpha = FALSE;
00989 }
00990 }
00991 else
00992 {
00993 if(!(lpddpfPixelFormat->dwFlags & DDPF_RGB))
00994 return DDENUMRET_OK;
00995
00996 pSurfFormat->HasOneBitAlpha = FALSE;
00997 pSurfFormat->HasFourBitAlpha = FALSE;
00998 }
00999
01000
01001 memcpy(&pSurfFormat->ddsd.ddpfPixelFormat, lpddpfPixelFormat,sizeof(DDPIXELFORMAT));
01002
01003 AppInfo.NumSurfFormats++;
01004
01005 return DDENUMRET_OK;
01006 }
01007
01008
01009
01010
01011 BOOL Main_EnumSurfaceFormats(void)
01012 {
01013 HRESULT LastError;
01014
01015 assert(AppInfo.lpDD);
01016
01017 AppInfo.NumSurfFormats = 0;
01018
01019 LastError = AppInfo.lpDD->EnumSurfaces(DDENUMSURFACES_DOESEXIST|DDENUMSURFACES_ALL,
01020 NULL, NULL, EnumSurfaceFormatsCallback);
01021
01022 if (LastError != DD_OK)
01023 {
01024 D3DMain_Log("Main_EnumSurfaceFormats: Enumeration of texture formats failed.\n %s\n",
01025 D3DErrorToString(LastError));
01026 return FALSE;
01027 }
01028
01029 return TRUE;
01030 }
01031
01032
01033
01034
01035
01036
01037 static HRESULT WINAPI EnumZBufferFormatsCallback( DDPIXELFORMAT* pddpf,
01038 VOID* pddpfDesired )
01039 {
01040 if( NULL==pddpf || NULL==pddpfDesired )
01041 return D3DENUMRET_CANCEL;
01042
01043
01044
01045
01046 if( pddpf->dwFlags == ((DDPIXELFORMAT*)pddpfDesired)->dwFlags )
01047 {
01048 memcpy( pddpfDesired, pddpf, sizeof(DDPIXELFORMAT) );
01049
01050
01051 if( pddpf->dwZBufferBitDepth == 16 )
01052 return D3DENUMRET_CANCEL;
01053 }
01054
01055 return D3DENUMRET_OK;
01056 }
01057
01058
01059
01060
01061 static BOOL D3DMain_ClearBuffers(void)
01062 {
01063 DDSURFACEDESC2 ddsd;
01064 RECT dst;
01065 DDBLTFX ddbltfx;
01066 HRESULT LastError;
01067
01068
01069
01070 if (AppInfo.lpFrontBuffer)
01071 {
01072 LastError = GetSurfDesc(&ddsd, AppInfo.lpFrontBuffer);
01073 if (LastError != DD_OK)
01074 {
01075 D3DMain_Log("D3DMain_ClearBuffers: Failure getting the surface description of the front buffer before clearing.\n %s\n",
01076 D3DErrorToString(LastError));
01077 return FALSE;
01078 }
01079
01080
01081 memset(&ddbltfx, 0, sizeof(ddbltfx));
01082
01083 ddbltfx.dwSize = sizeof(DDBLTFX);
01084 SetRect(&dst, 0, 0, ddsd.dwWidth, ddsd.dwHeight);
01085
01086 LastError = AppInfo.lpFrontBuffer->Blt(&dst, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT,
01087 &ddbltfx);
01088
01089 if (LastError != DD_OK)
01090 {
01091 if(LastError==DDERR_SURFACELOST)
01092 {
01093 if (!D3DMain_RestoreAllSurfaces())
01094 {
01095 D3DMain_Log("D3DMain_ClearBuffers: D3DMain_RestoreAllSurfaces failed...\n");
01096 return FALSE;
01097 }
01098 }
01099 else
01100 {
01101 D3DMain_Log("D3DMain_ClearBuffers: Clearing the front buffer failed.\n %s\n",
01102 D3DErrorToString(LastError));
01103 return FALSE;
01104 }
01105 }
01106 }
01107
01108 if (AppInfo.lpBackBuffer)
01109 {
01110
01111
01112
01113 LastError = GetSurfDesc(&ddsd, AppInfo.lpBackBuffer);
01114
01115 if (LastError != DD_OK)
01116 {
01117 D3DMain_Log("D3DMain_ClearBuffers: Failure while getting the surface description of the back buffer before clearing.\n %s\n",
01118 D3DErrorToString(LastError));
01119 return FALSE;
01120 }
01121
01122
01123 memset(&ddbltfx, 0, sizeof(ddbltfx));
01124
01125 ddbltfx.dwSize = sizeof(DDBLTFX);
01126 SetRect(&dst, 0, 0, ddsd.dwWidth, ddsd.dwHeight);
01127 LastError = AppInfo.lpBackBuffer->Blt(&dst, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT,
01128 &ddbltfx);
01129
01130 if (LastError != DD_OK)
01131 {
01132 if(LastError==DDERR_SURFACELOST)
01133 {
01134 if (!D3DMain_RestoreAllSurfaces())
01135 {
01136 D3DMain_Log("D3DMain_ClearBuffers: D3DMain_RestoreAllSurfaces failed.\n");
01137 return FALSE;
01138 }
01139 }
01140 else
01141 {
01142 D3DMain_Log("D3DMain_ClearBuffers: Clearing the back buffer failed.\n %s\n",
01143 D3DErrorToString(LastError));
01144 return FALSE;
01145 }
01146 }
01147 }
01148
01149 return TRUE;
01150 }
01151
01152
01153
01154
01155 BOOL Main_ShowBackBuffer(void)
01156 {
01157 HRESULT LastError;
01158
01159 if (!AppInfo.RenderingIsOK)
01160 return TRUE;
01161
01162 if (AppInfo.FullScreen)
01163 {
01164
01165 #if 1
01166 LastError = AppInfo.lpFrontBuffer->Flip(AppInfo.lpBackBuffer, DDFLIP_WAIT);
01167 #else
01168 LastError = AppInfo.lpFrontBuffer->Flip(AppInfo.lpBackBuffer, DDFLIP_NOVSYNC);
01169 #endif
01170
01171 if (LastError == DDERR_SURFACELOST)
01172 {
01173 D3DMain_RestoreAllSurfaces();
01174
01175
01176
01177 D3DMain_ClearBuffers();
01178
01179 }
01180 else if (LastError == DDERR_WASSTILLDRAWING)
01181 {
01182 }
01183 else if (LastError != DD_OK)
01184 {
01185 D3DMain_Log("Flipping complex display surface failed.\n %s\n", D3DErrorToString(LastError));
01186 return FALSE;
01187 }
01188 }
01189 else
01190 {
01191 RECT FRect, BRect;
01192
01193 FRect.left = AppInfo.WindowXOffset;
01194 FRect.right = FRect.left + AppInfo.CurrentWidth;
01195 FRect.top = AppInfo.WindowYOffset;
01196 FRect.bottom = FRect.top + AppInfo.CurrentHeight;
01197
01198 BRect.left = 0;
01199 BRect.right = AppInfo.CurrentWidth;
01200 BRect.top = 0;
01201 BRect.bottom = AppInfo.CurrentHeight;
01202
01203 LastError = AppInfo.lpFrontBuffer->Blt(&FRect, AppInfo.lpBackBuffer,
01204 &BRect, DDBLT_WAIT, NULL);
01205
01206 if (LastError != DD_OK)
01207 {
01208 if(LastError==DDERR_SURFACELOST)
01209 {
01210 if (!D3DMain_RestoreAllSurfaces())
01211 {
01212 D3DMain_Log("Main_ShowBackBuffer: D3DMain_RestoreAllSurfaces.\n");
01213 return FALSE;
01214 }
01215 }
01216 else
01217 {
01218 D3DMain_Log("Main_ShowBackBuffer: Blt of back buffer to front buffer failed.\n %s\n", D3DErrorToString(LastError));
01219 return FALSE;
01220 }
01221 }
01222 }
01223
01224 return TRUE;
01225 }
01226
01227
01228
01229
01230 BOOL Main_ClearBackBuffer(BOOL Clear, BOOL ClearZ)
01231 {
01232 int ClearFlags;
01233 D3DRECT Dummy;
01234 HRESULT LastError;
01235
01236 if (!AppInfo.RenderingIsOK)
01237 return TRUE;
01238
01239
01240 ClearFlags = 0;
01241
01242
01243 if (Clear)
01244 ClearFlags |= D3DCLEAR_TARGET;
01245
01246 if (ClearZ)
01247 ClearFlags |= D3DCLEAR_ZBUFFER;
01248
01249 Dummy.x1 = Dummy.y1 = 0;
01250 Dummy.x2 = AppInfo.CurrentWidth;
01251 Dummy.y2 = AppInfo.CurrentHeight;
01252
01253 LastError = AppInfo.lpD3DViewport->Clear(1, &Dummy, ClearFlags);
01254
01255 if (LastError != D3D_OK)
01256 {
01257 D3DMain_Log("Viewport clear failed.\n %s\n",
01258 D3DErrorToString(LastError));
01259 return FALSE;
01260 }
01261
01262 return TRUE;
01263 }
01264
01265
01266
01267
01268
01269 typedef struct
01270 {
01271 unsigned char r, g, b;
01272 } MY_D3D_RGB;
01273
01274 typedef struct
01275 {
01276 DWORD R_Shift;
01277 DWORD G_Shift;
01278 DWORD B_Shift;
01279 DWORD A_Shift;
01280
01281 DWORD R_Mask;
01282 DWORD G_Mask;
01283 DWORD B_Mask;
01284 DWORD A_Mask;
01285
01286 DWORD R_Width;
01287 DWORD G_Width;
01288 DWORD B_Width;
01289 DWORD A_Width;
01290 } D3D_PixelMask;
01291
01292
01293
01294
01295 static void GetSurfacePixelMask(DDSURFACEDESC2 *ddsd, D3D_PixelMask *PixelMask)
01296 {
01297 DWORD red_mask, grn_mask, blu_mask, a_mask;
01298 DWORD red_shift, grn_shift, blu_shift, a_shift;
01299 DWORD red_width, grn_width, blu_width, a_width;
01300 int i;
01301
01302 red_mask = ddsd->ddpfPixelFormat.dwRBitMask;
01303 grn_mask = ddsd->ddpfPixelFormat.dwGBitMask;
01304 blu_mask = ddsd->ddpfPixelFormat.dwBBitMask;
01305 a_mask = ddsd->ddpfPixelFormat.dwRGBAlphaBitMask;
01306
01307
01308
01309
01310
01311 for (i=31; i >= 0; i--)
01312 {
01313 if (red_mask & (1 << i))
01314 red_shift = i;
01315
01316 if (grn_mask & (1 << i))
01317 grn_shift = i;
01318
01319 if (blu_mask & (1 << i))
01320 blu_shift = i;
01321
01322 if (a_mask & (1 << i))
01323 a_shift = i;
01324 }
01325
01326 for (i=0; i <= 31; i++)
01327 {
01328 if (red_mask & (1 << i))
01329 red_width = i - red_shift + 1;
01330
01331 if (grn_mask & (1 << i))
01332 grn_width = i - grn_shift + 1;
01333
01334 if (blu_mask & (1 << i))
01335 blu_width = i - blu_shift + 1;
01336
01337 if (a_mask & (1 << i))
01338 a_width = i - a_shift + 1;
01339 }
01340
01341
01342
01343
01344 PixelMask->R_Shift = red_shift;
01345 PixelMask->G_Shift = grn_shift;
01346 PixelMask->B_Shift = blu_shift;
01347 PixelMask->A_Shift = a_shift;
01348
01349 PixelMask->R_Mask = red_mask;
01350 PixelMask->G_Mask = grn_mask;
01351 PixelMask->B_Mask = blu_mask;
01352 PixelMask->A_Mask = a_mask;
01353
01354 PixelMask->R_Width = red_width;
01355 PixelMask->G_Width = grn_width;
01356 PixelMask->B_Width = blu_width;
01357 PixelMask->A_Width = a_width;
01358 }
01359
01360
01361
01362
01363 static unsigned int MyRGB(DWORD R, DWORD G, DWORD B, D3D_PixelMask *PixelMask)
01364 {
01365 DWORD R_Left, G_Left, B_Left;
01366 DWORD R_Right, G_Right, B_Right;
01367
01368
01369
01370 R_Left = PixelMask->R_Shift;
01371 G_Left = PixelMask->G_Shift;
01372 B_Left = PixelMask->B_Shift;
01373
01374 R_Right = 8 - PixelMask->R_Width;
01375 G_Right = 8 - PixelMask->G_Width;
01376 B_Right = 8 - PixelMask->B_Width;
01377
01378 return(
01379 (((((unsigned int) R) >> R_Right) << R_Left) & PixelMask->R_Mask) |
01380 (((((unsigned int) G) >> G_Right) << G_Left) & PixelMask->G_Mask) |
01381 (((((unsigned int) B) >> B_Right) << B_Left) & PixelMask->B_Mask)
01382 );
01383 }
01384
01385
01386
01387
01388 BOOL D3DMain_GetSurfaceFormats(void)
01389 {
01390 int32 i;
01391
01392 D3DMain_Log("--- D3DMain_GetSurfaceFormats ---\n");
01393
01394 if (!Main_EnumTextureFormats())
01395 {
01396 D3DMain_Log("D3DMain_GetSurfaceFormats: Main_EnumTextureFormats failed.\n");
01397 return FALSE;
01398 }
01399
01400 if (!Main_EnumSurfaceFormats())
01401 {
01402 D3DMain_Log("D3DMain_GetSurfaceFormats: Main_EnumSurfaceFormats failed.\n");
01403 return FALSE;
01404 }
01405
01406 #if 1
01407 for(i = 0; i < AppInfo.NumSurfFormats; i++)
01408 {
01409 LPDDPIXELFORMAT lpddpfPixelFormat;
01410
01411 lpddpfPixelFormat = &AppInfo.SurfFormats[i].ddsd.ddpfPixelFormat;
01412
01413 if(lpddpfPixelFormat->dwRGBBitCount != AppInfo.ddsd.ddpfPixelFormat.dwRGBBitCount)
01414 continue;
01415
01416 if (lpddpfPixelFormat->dwRGBAlphaBitMask != AppInfo.ddsd.ddpfPixelFormat.dwRGBAlphaBitMask)
01417 continue;
01418 if (lpddpfPixelFormat->dwRBitMask != AppInfo.ddsd.ddpfPixelFormat.dwRBitMask)
01419 continue;
01420 if (lpddpfPixelFormat->dwGBitMask != AppInfo.ddsd.ddpfPixelFormat.dwGBitMask)
01421 continue;
01422 if (lpddpfPixelFormat->dwBBitMask != AppInfo.ddsd.ddpfPixelFormat.dwBBitMask)
01423 continue;
01424
01425 #if 0 // For debugging (This is the surface it is going to use for 2d decals)
01426 D3DMain_Log("Bits: %i, A:%x, R:%x, G:%x, B:%x\n", AppInfo.ddsd.ddpfPixelFormat.dwRGBBitCount,
01427 AppInfo.ddsd.ddpfPixelFormat.dwRGBAlphaBitMask,
01428 AppInfo.ddsd.ddpfPixelFormat.dwRBitMask,
01429 AppInfo.ddsd.ddpfPixelFormat.dwGBitMask,
01430 AppInfo.ddsd.ddpfPixelFormat.dwBBitMask);
01431 return FALSE;
01432 #endif
01433
01434
01435 AppInfo.ddSurfFormat = AppInfo.SurfFormats[i].ddsd;
01436
01437 break;
01438 }
01439
01440 if(i == AppInfo.NumSurfFormats)
01441 {
01442 D3DMain_Log("D3DMain_GetSurfaceFormats: Unable to find a 2d surface format that matches current bit depth.\n");
01443 return FALSE;
01444 }
01445
01446 #else
01447 for(i = 0; i < AppInfo.NumTextureFormats; i++)
01448 {
01449 LPDDPIXELFORMAT lpddpfPixelFormat;
01450
01451 lpddpfPixelFormat = &AppInfo.TextureFormats[i].ddsd.ddpfPixelFormat;
01452
01453 if(lpddpfPixelFormat->dwRGBBitCount != AppInfo.ddsd.ddpfPixelFormat.dwRGBBitCount)
01454 continue;
01455
01456 if (lpddpfPixelFormat->dwRGBAlphaBitMask != AppInfo.ddsd.ddpfPixelFormat.dwRGBAlphaBitMask)
01457 continue;
01458 if (lpddpfPixelFormat->dwRBitMask != AppInfo.ddsd.ddpfPixelFormat.dwRBitMask)
01459 continue;
01460 if (lpddpfPixelFormat->dwGBitMask != AppInfo.ddsd.ddpfPixelFormat.dwGBitMask)
01461 continue;
01462 if (lpddpfPixelFormat->dwBBitMask != AppInfo.ddsd.ddpfPixelFormat.dwBBitMask)
01463 continue;
01464
01465 #if 0 // For debugging (This is the surface it is going to use for 2d decals)
01466 D3DMain_Log("Bits: %i, A:%x, R:%x, G:%x, B:%x\n", AppInfo.ddsd.ddpfPixelFormat.dwRGBBitCount,
01467 AppInfo.ddsd.ddpfPixelFormat.dwRGBAlphaBitMask,
01468 AppInfo.ddsd.ddpfPixelFormat.dwRBitMask,
01469 AppInfo.ddsd.ddpfPixelFormat.dwGBitMask,
01470 AppInfo.ddsd.ddpfPixelFormat.dwBBitMask);
01471 return FALSE;
01472 #endif
01473
01474
01475 AppInfo.ddSurfFormat = AppInfo.TextureFormats[i].ddsd;
01476
01477 break;
01478 }
01479
01480 if(i == AppInfo.NumTextureFormats)
01481 {
01482 D3DMain_Log("D3DMain_GetSurfaceFormats: Unable to find a 2d surface format that matches current bit depth.\n");
01483 return FALSE;
01484 }
01485 #endif
01486
01487
01488
01489
01490 for(i = 0; i < AppInfo.NumTextureFormats; i++)
01491 {
01492 if(AppInfo.TextureFormats[i].HasOneBitAlpha == TRUE)
01493 {
01494 AppInfo.ddOneBitAlphaSurfFormat = AppInfo.TextureFormats[i].ddsd;
01495 break;
01496 }
01497 }
01498
01499 if(i == AppInfo.NumTextureFormats)
01500 {
01501 D3DMain_Log("D3DMain_GetSurfaceFormats: Unable to find 1555 texture support.\n");
01502 return FALSE;
01503 }
01504
01505
01506 for(i = 0; i < AppInfo.NumTextureFormats; i++)
01507 {
01508 if(AppInfo.TextureFormats[i].HasFourBitAlpha == TRUE)
01509 {
01510 AppInfo.ddFourBitAlphaSurfFormat = AppInfo.TextureFormats[i].ddsd;
01511 break;
01512 }
01513 }
01514
01515 if(i == AppInfo.NumTextureFormats)
01516 {
01517 D3DMain_Log("D3DMain_GetSurfaceFormats: Unable to find 4444 texture support.\n");
01518 return FALSE;
01519 }
01520
01521
01522 for(i = 0; i < AppInfo.NumTextureFormats; i++)
01523 {
01524 LPDDPIXELFORMAT lpddpfPixelFormat;
01525
01526 if(AppInfo.TextureFormats[i].HasOneBitAlpha == TRUE)
01527 continue;
01528
01529 if (AppInfo.TextureFormats[i].HasFourBitAlpha == TRUE)
01530 continue;
01531
01532 lpddpfPixelFormat = &AppInfo.TextureFormats[i].ddsd.ddpfPixelFormat;
01533
01534
01535
01536 if (lpddpfPixelFormat->dwFlags & DDPF_ALPHAPIXELS)
01537 continue;
01538
01539 if(lpddpfPixelFormat->dwRGBBitCount != 16)
01540 continue;
01541
01542 if( (lpddpfPixelFormat->dwRBitMask != 0xf800 && lpddpfPixelFormat->dwRBitMask != 0x7c00) ||
01543 (lpddpfPixelFormat->dwGBitMask != 0x7e0 && lpddpfPixelFormat->dwGBitMask != 0x3e0) ||
01544 (lpddpfPixelFormat->dwBBitMask != 0x1f))
01545 continue;
01546
01547
01548
01549 AppInfo.ddTexFormat = AppInfo.TextureFormats[i].ddsd;
01550 break;
01551 }
01552
01553 if(i == AppInfo.NumTextureFormats)
01554 {
01555 D3DMain_Log("D3DMain_GetSurfaceFormats: Unable to find 555 or 565 texture support.\n");
01556 return FALSE;
01557 }
01558
01559 Main_BuildRGBGammaTables(1.0f);
01560
01561 return TRUE;
01562 }
01563
01564
01565
01566
01567
01568 BOOL Main_CheckDD(void)
01569 {
01570 AppInfo.NumDrivers = 0;
01571 AppInfo.CurrentDriver = 0;
01572 AppInfo.FoundGoodDevice = FALSE;
01573 AppInfo.CanDoWindow = FALSE;
01574
01575 assert(AppInfo.lpDD);
01576
01577 if (!D3DMain_RememberOldMode(GetDesktopWindow()))
01578 return FALSE;
01579
01580 memset(AppInfo.Drivers, 0, sizeof(DDMain_D3DDriver)*DDMAIN_MAX_D3D_DRIVERS);
01581
01582 if (!D3DMain_CreateD3D())
01583 return FALSE;
01584
01585 if (!D3DMain_EnumDevices())
01586 return FALSE;
01587
01588 if (!AppInfo.FoundGoodDevice)
01589 return FALSE;
01590
01591 return TRUE;
01592 }
01593
01594
01595
01596
01597 static BOOL OutputDriverInfo(const char *FileName, DDMain_D3DDriver *Driver)
01598 {
01599 FILE *f;
01600 SYSTEMTIME Time;
01601 char YesNo[2][10];
01602
01603 f = fopen(FileName, "a+t");
01604
01605 if (!f)
01606 return FALSE;
01607
01608 GetSystemTime(&Time);
01609
01610 strcpy(YesNo[0], "No\n");
01611 strcpy(YesNo[1], "Yes\n");
01612
01613 fprintf(f,"=================================================================\n");
01614 fprintf(f,"Time: %2i:%2i:%2i\n", Time.wHour, Time.wMinute, Time.wSecond);
01615 fprintf(f,"Date: %2i-%2i-%4i\n", Time.wMonth, Time.wDay, Time.wYear);
01616
01617 fprintf(f, "DirectDraw Name: \n");
01618 fprintf(f, " %s\n", AppInfo.DDName);
01619
01620 fprintf(f, "D3D Driver Name: \n");
01621 fprintf(f, " %s\n", Driver->Name);
01622
01623 fprintf(f, "D3D Driver Description: \n");
01624 fprintf(f, " %s\n", Driver->About);
01625
01626 fprintf(f, "3D Acceleration : %s", YesNo[Driver->IsHardware]);
01627 fprintf(f, "Texture Support : %s", YesNo[Driver->DoesTextures]);
01628 fprintf(f, "Transparency Support : %s", YesNo[Driver->DoesTransparency]);
01629 fprintf(f, "Alpha Support : %s", YesNo[Driver->DoesAlpha]);
01630 fprintf(f, "UV Clamping Support : %s", YesNo[Driver->DoesClamping]);
01631 fprintf(f, "Src Blending Support : %s", YesNo[Driver->DoesSrcBlending]);
01632 fprintf(f, "Dest Blending Support : %s", YesNo[Driver->DoesDestBlending]);
01633 fprintf(f, "Window Support : %s", YesNo[Driver->CanDoWindow]);
01634 fprintf(f, "Can Use : %s", YesNo[Driver->CanUse]);
01635
01636 fclose(f);
01637
01638 return TRUE;
01639 }
01640
01641
01642
01643
01644 BOOL D3DMain_GetTextureMemory(void)
01645 {
01646
01647 DDSCAPS2 ddsCaps;
01648 DWORD dwTotal;
01649 DWORD dwFree;
01650 HRESULT Error;
01651
01652 D3DMain_Log("--- D3DMain_GetTextureMemory ---\n");
01653
01654 memset(&ddsCaps, 0, sizeof(ddsCaps));
01655
01656
01657 ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM;
01658
01659 Error = AppInfo.lpDD->GetAvailableVidMem(&ddsCaps, &dwTotal, &dwFree);
01660
01661 if(Error !=DD_OK)
01662 {
01663 D3DMain_Log("Getting DD capabilities failed while checking total video memory.\n %s\n", D3DErrorToString(Error));
01664 return FALSE;
01665 }
01666
01667 AppInfo.VidMemFree = dwFree;
01668
01669 D3DMain_Log(" Ram free: %i\n", AppInfo.VidMemFree);
01670
01671 return TRUE;
01672 }
01673
01674
01675
01676
01677 void Main_BuildRGBGammaTables(geFloat Gamma)
01678 {
01679 int32 i, Val;
01680 int32 GammaTable[256];
01681 D3D_PixelMask PixelMask;
01682 DWORD R_Left, G_Left, B_Left, A_Left;
01683 DWORD R_Right, G_Right, B_Right, A_Right;
01684
01685
01686 AppInfo.Gamma = Gamma;
01687
01688 if (Gamma == 1.0)
01689 {
01690 for (i=0 ; i<256 ; i++)
01691 GammaTable[i] = i;
01692 }
01693 else for (i=0 ; i<256 ; i++)
01694 {
01695 geFloat Ratio = (i+0.5f)/255.5f;
01696
01697 geFloat RGB = (geFloat)(255.0 * pow((double)Ratio, 1.0/(double)Gamma) + 0.5);
01698
01699 if (RGB < 0.0f)
01700 RGB = 0.0f;
01701 if (RGB > 255.0f)
01702 RGB = 255.0f;
01703
01704 GammaTable[i] = (int32)RGB;
01705 }
01706
01707 GetSurfacePixelMask(&AppInfo.ddTexFormat, &PixelMask);
01708 for (i=0; i< 256; i++)
01709 {
01710
01711 R_Left = PixelMask.R_Shift;
01712 G_Left = PixelMask.G_Shift;
01713 B_Left = PixelMask.B_Shift;
01714 A_Left = PixelMask.A_Shift;
01715
01716 R_Right = 8 - PixelMask.R_Width;
01717 G_Right = 8 - PixelMask.G_Width;
01718 B_Right = 8 - PixelMask.B_Width;
01719 A_Right = 8 - PixelMask.A_Width;
01720
01721 Val = GammaTable[i];
01722
01723 AppInfo.Lut1.R[i] = (((uint32)Val >> R_Right) << R_Left) & PixelMask.R_Mask;
01724 AppInfo.Lut1.G[i] = (((uint32)Val >> G_Right) << G_Left) & PixelMask.G_Mask;
01725 AppInfo.Lut1.B[i] = (((uint32)Val >> B_Right) << B_Left) & PixelMask.B_Mask;
01726 AppInfo.Lut1.A[i] = (((uint32) i >> A_Right) << A_Left) & PixelMask.A_Mask;
01727 }
01728 GetSurfacePixelMask(&AppInfo.ddFourBitAlphaSurfFormat, &PixelMask);
01729 for (i=0; i< 256; i++)
01730 {
01731
01732 R_Left = PixelMask.R_Shift;
01733 G_Left = PixelMask.G_Shift;
01734 B_Left = PixelMask.B_Shift;
01735 A_Left = PixelMask.A_Shift;
01736
01737 R_Right = 8 - PixelMask.R_Width;
01738 G_Right = 8 - PixelMask.G_Width;
01739 B_Right = 8 - PixelMask.B_Width;
01740 A_Right = 8 - PixelMask.A_Width;
01741
01742 Val = GammaTable[i];
01743
01744 AppInfo.Lut2.R[i] = (((uint32)Val >> R_Right) << R_Left) & PixelMask.R_Mask;
01745 AppInfo.Lut2.G[i] = (((uint32)Val >> G_Right) << G_Left) & PixelMask.G_Mask;
01746 AppInfo.Lut2.B[i] = (((uint32)Val >> B_Right) << B_Left) & PixelMask.B_Mask;
01747 AppInfo.Lut2.A[i] = (((uint32) i >> A_Right) << A_Left) & PixelMask.A_Mask;
01748 }
01749 GetSurfacePixelMask(&AppInfo.ddOneBitAlphaSurfFormat, &PixelMask);
01750 for (i=0; i< 256; i++)
01751 {
01752
01753 R_Left = PixelMask.R_Shift;
01754 G_Left = PixelMask.G_Shift;
01755 B_Left = PixelMask.B_Shift;
01756 A_Left = PixelMask.A_Shift;
01757
01758 R_Right = 8 - PixelMask.R_Width;
01759 G_Right = 8 - PixelMask.G_Width;
01760 B_Right = 8 - PixelMask.B_Width;
01761 A_Right = 8 - PixelMask.A_Width;
01762
01763 Val = GammaTable[i];
01764
01765 AppInfo.Lut3.R[i] = (((uint32)Val >> R_Right) << R_Left) & PixelMask.R_Mask;
01766 AppInfo.Lut3.G[i] = (((uint32)Val >> G_Right) << G_Left) & PixelMask.G_Mask;
01767 AppInfo.Lut3.B[i] = (((uint32)Val >> B_Right) << B_Left) & PixelMask.B_Mask;
01768 AppInfo.Lut3.A[i] = (((uint32) i >> A_Right) << A_Left) & PixelMask.A_Mask;
01769 }
01770 }
01771
01772
01773
01774
01775 geBoolean DRIVERCC D3DMain_UpdateWindow(void)
01776 {
01777 D3DMain_GetClientWindowOffset(AppInfo.hWnd);
01778 return GE_TRUE;
01779 }
01780
01781
01782
01783
01784 geBoolean DRIVERCC D3DMain_SetActive(geBoolean wParam)
01785 {
01786 if (AppInfo.lpFrontBuffer)
01787 AppInfo.RenderingIsOK = wParam;
01788
01789 if(AppInfo.RenderingIsOK)
01790 {
01791 HRESULT Result;
01792
01793 if (AppInfo.lpFrontBuffer)
01794 {
01795 Result = AppInfo.lpFrontBuffer->IsLost();
01796
01797 if(Result == DDERR_SURFACELOST)
01798 {
01799 if(!D3DMain_RestoreAllSurfaces())
01800 {
01801 OutputDebugString("Couldn't restore surfaces!\n");
01802 return GE_FALSE;
01803 }
01804
01805 OutputDebugString("D3DMain_SetActive: Regained Focus...\n");
01806
01807 ShowWindow(AppInfo.hWnd, SW_SHOWNORMAL);
01808 }
01809 else
01810 OutputDebugString("D3DMain_SetActive: No surfaces lost...\n");
01811 }
01812 }
01813
01814 return GE_TRUE;
01815 }
01816
01817
01818
01819
01820 geBoolean DRIVERCC D3DMain_SetFogEnable(geBoolean Enable, geFloat r, geFloat g, geFloat b, geFloat Start, geFloat End)
01821 {
01822 D3DMATERIAL Material;
01823
01824 AppInfo.FogEnable = Enable;
01825 AppInfo.FogR = r;
01826 AppInfo.FogG = g;
01827 AppInfo.FogB = b;
01828 AppInfo.FogStart = Start;
01829 AppInfo.FogEnd = End;
01830
01831
01832 memset(&Material, 0, sizeof(D3DMATERIAL));
01833
01834 Material.dwSize = sizeof(D3DMATERIAL);
01835
01836 if (Enable)
01837 {
01838 Material.dcvDiffuse.r = Material.dcvAmbient.r = r/255.0f;
01839 Material.dcvDiffuse.g = Material.dcvAmbient.g = g/255.0f;
01840 Material.dcvDiffuse.b = Material.dcvAmbient.b = b/255.0f;
01841 }
01842 else
01843 {
01844 Material.dcvDiffuse.r = Material.dcvAmbient.r = 0.0f;
01845 Material.dcvDiffuse.g = Material.dcvAmbient.g = 0.0f;
01846 Material.dcvDiffuse.b = Material.dcvAmbient.b = 0.0f;
01847 }
01848
01849 Material.dwRampSize = 16L;
01850
01851 AppInfo.BackgroundMaterial->SetMaterial(&Material);
01852
01853 return GE_TRUE;
01854 }
01855
01856
01857
01858
01859 BOOL D3DMain_GetClientWindowOffset(HWND hWnd)
01860 {
01861 POINT CPoint;
01862
01863 CPoint.x = CPoint.y = 0;
01864
01865 ClientToScreen(hWnd, &CPoint);
01866
01867 AppInfo.WindowXOffset = CPoint.x;
01868 AppInfo.WindowYOffset = CPoint.y;
01869
01870 return TRUE;
01871 }
01872
01873
01874
01875
01876 static BOOL D3DMain_RememberOldMode(HWND hWnd)
01877 {
01878 DDSURFACEDESC2 ddsd;
01879 HRESULT LastError;
01880 RECT CRect;
01881
01882 D3DMain_Log("--- D3DMain_RememberOldMode ---\n");
01883
01884 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
01885
01886 ddsd.dwSize = sizeof(DDSURFACEDESC2);
01887
01888 LastError = AppInfo.lpDD->GetDisplayMode(&ddsd);
01889
01890 if (LastError != DD_OK)
01891 {
01892 D3DMain_Log("Getting the current display mode failed.\n %s\n", D3DErrorToString(LastError));
01893 return FALSE;
01894 }
01895
01896 GetClientRect(hWnd, &CRect);
01897
01898
01899 AppInfo.OldWidth = ddsd.dwWidth;
01900 AppInfo.OldHeight = ddsd.dwHeight;
01901 AppInfo.OldBpp = ddsd.ddpfPixelFormat.dwRGBBitCount;
01902
01903
01904 AppInfo.OldWindowWidth = CRect.right;
01905 AppInfo.OldWindowHeight = CRect.bottom;
01906
01907 GetWindowRect(hWnd, &CRect);
01908 AppInfo.OldWindowRect = CRect;
01909
01910 AppInfo.OldGWL_STYLE = GetWindowLong(hWnd, GWL_STYLE);
01911
01912 D3DMain_GetClientWindowOffset(hWnd);
01913
01914 return TRUE;
01915 }
01916
01917
01918
01919
01920 static BOOL D3DMain_SetDisplayMode(HWND hWnd, int w, int h, int bpp, BOOL FullScreen)
01921 {
01922 HRESULT LastError;
01923 int DWidth, DHeight;
01924 char YN[2][32];
01925
01926 strcpy(YN[0], "NO");
01927 strcpy(YN[1], "YES");
01928
01929 D3DMain_Log("--- D3DMain_SetDisplayMode ---\n");
01930 D3DMain_Log(" W: %i, H: %i, Bpp: %i, FullScreen: %s\n", w, h, bpp, YN[FullScreen]);
01931
01932 if (FullScreen)
01933 {
01934 LastError = AppInfo.lpDD->SetCooperativeLevel(hWnd, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
01935
01936 if(LastError != DD_OK )
01937 {
01938 D3DMain_Log("SetCooperativeLevel to fullscreen failed.\n %s\n",
01939 D3DErrorToString(LastError));
01940 return FALSE;
01941 }
01942
01943 LastError = AppInfo.lpDD->SetDisplayMode(w, h, bpp,0,0);
01944
01945 if(LastError != DD_OK )
01946 {
01947 D3DMain_Log("SetFullScreenDisplayMode: Mode %dx%dx%d failed\n %s\n", w, h, bpp, D3DErrorToString(LastError));
01948 return FALSE;
01949 }
01950
01951 DWidth = GetSystemMetrics(SM_CXSCREEN);
01952 DHeight = GetSystemMetrics(SM_CYSCREEN);
01953
01954
01955
01956
01957 SetWindowLong(hWnd, GWL_STYLE, AppInfo.OldGWL_STYLE | WS_POPUP);
01958
01959 SetWindowLong(hWnd, GWL_STYLE, AppInfo.OldGWL_STYLE &
01960 ~(WS_OVERLAPPED |
01961 WS_CAPTION |
01962 WS_SYSMENU |
01963 WS_MINIMIZEBOX |
01964 WS_MAXIMIZEBOX |
01965 WS_THICKFRAME));
01966
01967
01968 SetWindowPos(AppInfo.hWnd,
01969 HWND_TOP,
01970 0,
01971 0,
01972 DWidth,
01973 DHeight,
01974 SWP_NOCOPYBITS | SWP_NOZORDER);
01975
01976 ShowWindow(AppInfo.hWnd, SW_SHOWNORMAL);
01977 }
01978 else
01979 {
01980 LastError = AppInfo.lpDD->SetCooperativeLevel(hWnd, DDSCL_NORMAL);
01981
01982 if(LastError != DD_OK )
01983 {
01984 D3DMain_Log("SetCooperativeLevel to normal failed.\n %s\n",
01985 D3DErrorToString(LastError));
01986 return FALSE;
01987 }
01988 }
01989
01990 AppInfo.hWnd = hWnd;
01991 AppInfo.CurrentWidth = w;
01992 AppInfo.CurrentHeight = h;
01993 AppInfo.CurrentBpp = bpp;
01994 AppInfo.FullScreen = FullScreen;
01995
01996 AppInfo.ModeSet = GE_TRUE;
01997
01998 return TRUE;
01999 }
02000
02001
02002
02003
02004 static BOOL D3DMain_PickDevice(void)
02005 {
02006 int32 i;
02007 DWORD Depths;
02008
02009 D3DMain_Log("--- D3DMain_PickDevice ---\n");
02010
02011
02012
02013
02014 if (gWidth == -1 && gHeight == -1)
02015 {
02016
02017 Depths = BPPToDDBD(AppInfo.CurrentBpp);
02018 }
02019 else
02020 {
02021
02022 Depths = BPPToDDBD(BPP32);
02023 }
02024
02025
02026
02027
02028 for (i = 0; i < AppInfo.NumDrivers; i++)
02029 {
02030 if (!(AppInfo.Drivers[i].IsHardware))
02031 continue;
02032
02033
02034 if (!(AppInfo.Drivers[i].Desc.dwDeviceRenderBitDepth & Depths))
02035 continue;
02036
02037
02038
02039
02040
02041 if ( ZbufferD == 24)
02042 {
02043
02044 if (!(AppInfo.Drivers[i].Desc.dwDeviceZBufferBitDepth & DDBD_24))
02045 continue;
02046 }
02047 else
02048 {
02049
02050 if (!(AppInfo.Drivers[i].Desc.dwDeviceZBufferBitDepth & DDBD_16))
02051 continue;
02052 }
02053
02054
02055
02056
02057 if (!(AppInfo.Drivers[i].Desc.dcmColorModel & D3DCOLOR_RGB))
02058 continue;
02059
02060 if (!AppInfo.Drivers[i].CanDoWindow && !AppInfo.FullScreen)
02061 continue;
02062
02063
02064 AppInfo.CurrentDriver = i;
02065
02066 return TRUE;
02067 }
02068
02069 return FALSE;
02070 }
02071
02072
02073
02074
02075 static BOOL D3DMain_CreateDevice(void)
02076 {
02077 HRESULT Error;
02078
02079 D3DMain_Log("--- D3DMain_CreateDevice ---\n");
02080
02081
02082 RELEASE(AppInfo.lpD3DDevice);
02083
02084 Error = AppInfo.lpD3D->CreateDevice(AppInfo.Drivers[AppInfo.CurrentDriver].Guid,
02085 AppInfo.lpBackBuffer,
02086 &AppInfo.lpD3DDevice,NULL);
02087
02088 if (Error != DD_OK)
02089 {
02090 D3DMain_Log("D3DMain_CreateDevice: lpD3D->CreateDevice failed:\n %s\n", D3DErrorToString(Error));
02091 return FALSE;
02092 }
02093
02094 #if 0
02095 {
02096
02097 D3DDEVICEDESC hw, sw;
02098
02099 hw.dwSize = sw.dwSize = D3DDEVICEDESCSIZE;
02100
02101 AppInfo.lpD3DDevice->GetCaps(&hw, &sw);
02102 }
02103 #endif
02104
02105
02106 Error = AppInfo.lpDD->GetDeviceIdentifier(&AppInfo.DeviceIdentifier, 0);
02107
02108 if (Error != DD_OK)
02109 {
02110 D3DMain_Log("D3DMain_CreateDevice: lpDD->GetDeviceIdentifier failed:\n %s\n", D3DErrorToString(Error));
02111 return FALSE;
02112 }
02113
02114
02115 D3DMain_Log(" Vender ID = %6i\n", AppInfo.DeviceIdentifier.dwVendorId);
02116 D3DMain_Log(" Device ID = %6i\n", AppInfo.DeviceIdentifier.dwDeviceId);
02117
02118 return TRUE;
02119 }
02120
02121
02122
02123
02124 static BOOL D3DMain_CreateBuffers(void)
02125 {
02126 DDSURFACEDESC2 ddsd;
02127 DDSCAPS2 ddscaps;
02128 HRESULT LastError;
02129
02130 D3DMain_Log("--- D3DMain_CreateBuffers ---\n");
02131
02132
02133
02134 RELEASE(AppInfo.lpClipper);
02135 RELEASE(AppInfo.lpBackBuffer);
02136 RELEASE(AppInfo.lpFrontBuffer);
02137
02138 if (AppInfo.FullScreen)
02139 {
02140
02141
02142 memset(&ddsd,0,sizeof(DDSURFACEDESC2));
02143 ddsd.dwSize = sizeof( ddsd );
02144 ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
02145 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP |
02146 DDSCAPS_3DDEVICE | DDSCAPS_COMPLEX;
02147 ddsd.dwBackBufferCount = 1;
02148
02149 ddsd.ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY;
02150
02151 LastError = CreateSurface(&ddsd, &AppInfo.lpFrontBuffer);
02152
02153 if(LastError != DD_OK)
02154 {
02155 if (LastError == DDERR_OUTOFMEMORY || LastError == DDERR_OUTOFVIDEOMEMORY)
02156 {
02157 D3DMain_Log("CreateBuffers: There was not enough video memory to create the rendering surface.\n Please restart the program and try another fullscreen mode with less resolution or lower bit depth.\n");
02158 }
02159 else
02160 {
02161 D3DMain_Log("CreateBuffers: CreateSurface for fullscreen flipping surface failed.\n %s\n",
02162 D3DErrorToString(LastError));
02163 }
02164
02165 goto exit_with_error;
02166 }
02167
02168
02169
02170
02171 ddscaps.dwCaps = DDSCAPS_BACKBUFFER;
02172 LastError = AppInfo.lpFrontBuffer->GetAttachedSurface(&ddscaps, &AppInfo.lpBackBuffer);
02173
02174 if(LastError != DD_OK)
02175 {
02176 D3DMain_Log("CreateBuffers: GetAttachedSurface failed to get back buffer.\n %s\n",
02177 D3DErrorToString(LastError));
02178 goto exit_with_error;
02179 }
02180
02181 LastError = GetSurfDesc(&ddsd, AppInfo.lpBackBuffer);
02182
02183 if (LastError != DD_OK)
02184 {
02185 D3DMain_Log("CreateBuffers: Failed to get surface description of back buffer.\n %s\n",
02186 D3DErrorToString(LastError));
02187 goto exit_with_error;
02188 }
02189
02190 AppInfo.BackBufferInVideo =
02191 (ddsd.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY) ? TRUE : FALSE;
02192
02193 AppInfo.ddsd = ddsd;
02194 }
02195 else
02196 {
02197
02198
02199
02200 memset(&ddsd,0,sizeof(DDSURFACEDESC2));
02201 ddsd.dwSize = sizeof(DDSURFACEDESC2);
02202 ddsd.dwFlags = DDSD_CAPS;
02203 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_3DDEVICE;
02204
02205 LastError = AppInfo.lpDD->CreateSurface(&ddsd, &AppInfo.lpFrontBuffer, NULL);
02206
02207 if(LastError != DD_OK )
02208 {
02209 if (LastError == DDERR_OUTOFMEMORY || LastError == DDERR_OUTOFVIDEOMEMORY)
02210 {
02211 D3DMain_Log("CreateBuffers: There was not enough video memory to create the rendering surface.\n To run this program in a window of this size, please adjust your display settings for a smaller desktop area or a lower palette size and restart the program.\n");
02212 }
02213 else
02214 {
02215 D3DMain_Log("CreateBuffers: CreateSurface for window front buffer failed.\n %s\n",
02216 D3DErrorToString(LastError));
02217 }
02218 goto exit_with_error;
02219 }
02220
02221 ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS;
02222 ddsd.dwWidth = AppInfo.CurrentWidth;
02223 ddsd.dwHeight = AppInfo.CurrentHeight;
02224 ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE;
02225
02226 ddsd.ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY;
02227
02228 LastError = CreateSurface(&ddsd, &AppInfo.lpBackBuffer);
02229
02230 if (LastError != DD_OK)
02231 {
02232 if (LastError == DDERR_OUTOFMEMORY || LastError == DDERR_OUTOFVIDEOMEMORY)
02233 {
02234 D3DMain_Log("CreateBuffers: There was not enough video memory to create the rendering surface.\n To run this program in a window of this size, please adjust your display settings for a smaller desktop area or a lower palette size and restart the program.\n");
02235 }
02236 else
02237 {
02238 D3DMain_Log("CreateBuffers: CreateSurface for window back buffer failed.\n %s\n",
02239 D3DErrorToString(LastError));
02240 }
02241 goto exit_with_error;
02242 }
02243
02244
02245 LastError = GetSurfDesc(&ddsd, AppInfo.lpBackBuffer);
02246
02247 if (LastError != DD_OK)
02248 {
02249 D3DMain_Log("CreateBuffers: Failed to get surface description for back buffer.\n %s\n",
02250 D3DErrorToString(LastError));
02251 goto exit_with_error;
02252 }
02253
02254 AppInfo.BackBufferInVideo = (ddsd.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY) ? TRUE : FALSE;
02255
02256
02257
02258 LastError = AppInfo.lpDD->CreateClipper(0, &AppInfo.lpClipper, NULL);
02259
02260 if(LastError != DD_OK )
02261 {
02262 D3DMain_Log("CreateBuffers: CreateClipper failed.\n %s\n",
02263 D3DErrorToString(LastError));
02264 goto exit_with_error;
02265 }
02266
02267 LastError = AppInfo.lpClipper->SetHWnd(0, AppInfo.hWnd);
02268
02269 if(LastError != DD_OK )
02270 {
02271 D3DMain_Log("CreateBuffers: Attaching clipper to window failed.\n %s\n",
02272 D3DErrorToString(LastError));
02273 goto exit_with_error;
02274 }
02275
02276
02277 LastError = AppInfo.lpFrontBuffer->SetClipper(AppInfo.lpClipper);
02278
02279 if(LastError != DD_OK )
02280 {
02281 D3DMain_Log("CreateBuffers: Attaching clipper to front buffer failed.\n %s\n",
02282 D3DErrorToString(LastError));
02283 goto exit_with_error;
02284 }
02285
02286 AppInfo.ddsd = ddsd;
02287 }
02288
02289 D3DMain_ClearBuffers();
02290
02291 return TRUE;
02292
02293 exit_with_error:
02294
02295 RELEASE(AppInfo.lpFrontBuffer);
02296 RELEASE(AppInfo.lpBackBuffer);
02297 RELEASE(AppInfo.lpClipper);
02298 return FALSE;
02299 }
02300
02301
02302
02303
02304 static void D3DMain_DestroyBuffers(void)
02305 {
02306 RELEASE(AppInfo.lpClipper);
02307 RELEASE(AppInfo.lpBackBuffer);
02308 RELEASE(AppInfo.lpFrontBuffer);
02309 }
02310
02311
02312
02313
02314
02315 static BOOL D3DMain_CreateZBuffer(void)
02316 {
02317 DDSURFACEDESC2 ddsd;
02318 HRESULT LastError;
02319
02320 assert(AppInfo.lpBackBuffer);
02321
02322 D3DMain_Log("--- D3DMain_CreateZBuffer ---\n");
02323
02324
02325 RELEASE(AppInfo.lpZBuffer);
02326
02327 memset(&ddsd, 0 ,sizeof(DDSURFACEDESC2));
02328 ddsd.dwSize = sizeof( ddsd );
02329 ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_PIXELFORMAT;
02330 ddsd.ddsCaps.dwCaps = DDSCAPS_ZBUFFER | DDSCAPS_VIDEOMEMORY;
02331 ddsd.dwWidth = AppInfo.CurrentWidth;
02332 ddsd.dwHeight = AppInfo.CurrentHeight;
02333
02334 ddsd.ddpfPixelFormat.dwFlags = DDPF_ZBUFFER;
02335
02336
02337 AppInfo.lpD3D->EnumZBufferFormats(AppInfo.Drivers[AppInfo.CurrentDriver].Guid, EnumZBufferFormatsCallback,
02338 (VOID*)&ddsd.ddpfPixelFormat);
02339
02340
02341 if( sizeof(DDPIXELFORMAT) != ddsd.ddpfPixelFormat.dwSize )
02342 {
02343 D3DMain_Log("CreateZBuffer: No zbuffer found for 3d device.\n");
02344 return FALSE;
02345 }
02346
02347 LastError = AppInfo.lpDD->CreateSurface(&ddsd, &AppInfo.lpZBuffer, NULL);
02348
02349 if(LastError != DD_OK)
02350 {
02351 if (LastError == DDERR_OUTOFMEMORY || LastError == DDERR_OUTOFVIDEOMEMORY)
02352 {
02353 if (AppInfo.FullScreen)
02354 {
02355 D3DMain_Log("CreateZBuffer: There was not enough video memory to create the Z-buffer surface.\n Please try another mode with less resolution.\n");
02356 }
02357 else
02358 {
02359 D3DMain_Log("CreateZBuffer: There was not enough video memory to create the Z-buffer surface.\n Please try another mode with less resolution.\n");
02360 }
02361 }
02362 else
02363 {
02364 D3DMain_Log("CreateZBuffer: CreateSurface for Z-buffer failed.\n %s\n",
02365 D3DErrorToString(LastError));
02366 }
02367
02368 goto exit_with_error;
02369 }
02370
02371
02372 LastError = AppInfo.lpBackBuffer->AddAttachedSurface(AppInfo.lpZBuffer);
02373
02374 if(LastError != DD_OK)
02375 {
02376 D3DMain_Log("CreateZBuffer: AddAttachedBuffer failed for Z-Buffer.\n %s\n",
02377 D3DErrorToString(LastError));
02378 goto exit_with_error;
02379 }
02380
02381
02382 LastError = GetSurfDesc(&ddsd, AppInfo.lpZBuffer);
02383
02384 if (LastError != DD_OK)
02385 {
02386 D3DMain_Log("CreateZBuffer: Failed to get surface description of Z buffer.\n %s\n",
02387 D3DErrorToString(LastError));
02388 goto exit_with_error;
02389 }
02390
02391 AppInfo.ZBufferInVideo = (ddsd.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY) ? TRUE : FALSE;
02392
02393 return TRUE;
02394
02395 exit_with_error:
02396 RELEASE(AppInfo.lpZBuffer);
02397 return FALSE;
02398 }
02399
02400
02401
02402
02403 static void D3DMain_DestroyZBuffer(void)
02404 {
02405 RELEASE(AppInfo.lpZBuffer)
02406 }
02407
02408
02409
02410
02411
02412 static BOOL D3DMain_RestoreDisplayMode(void)
02413 {
02414 HRESULT LastError;
02415
02416 if (!AppInfo.ModeSet)
02417 return TRUE;
02418
02419 AppInfo.ModeSet = GE_FALSE;
02420
02421 assert(AppInfo.lpDD);
02422
02423 if (AppInfo.FullScreen)
02424 {
02425 LastError = AppInfo.lpDD->RestoreDisplayMode();
02426
02427 if (LastError != DD_OK)
02428 {
02429 D3DMain_Log("D3DMain_RestoreDisplayMode: RestoreDisplayMode failed.\n %s\n",
02430 D3DErrorToString(LastError));
02431 return FALSE;
02432 }
02433
02434 LastError = AppInfo.lpDD->SetCooperativeLevel(AppInfo.hWnd, DDSCL_NORMAL);
02435
02436 if(LastError != DD_OK )
02437 {
02438 D3DMain_Log("SetCooperativeLevel to normal failed.\n %s\n",
02439 D3DErrorToString(LastError));
02440 return FALSE;
02441 }
02442 }
02443
02444
02445 SetWindowLong(AppInfo.hWnd, GWL_STYLE, AppInfo.OldGWL_STYLE);
02446
02447 SetWindowPos(AppInfo.hWnd,
02448 HWND_TOP,
02449 AppInfo.OldWindowRect.left,
02450 AppInfo.OldWindowRect.top,
02451 (AppInfo.OldWindowRect.right - AppInfo.OldWindowRect.left),
02452 (AppInfo.OldWindowRect.bottom - AppInfo.OldWindowRect.top),
02453 SWP_NOCOPYBITS | SWP_NOZORDER);
02454
02455 ShowWindow(AppInfo.hWnd, SW_SHOWNORMAL);
02456
02457 return TRUE;
02458 }
02459
02460
02461
02462
02463
02464
02465 D3D_DRIVER Drivers[MAX_DRIVERS];
02466
02467
02468
02469
02470 BOOL FAR PASCAL EnumDriversCB2(GUID FAR *lpGUID, LPSTR lpDriverDesc, LPSTR lpDriverName, LPVOID lpContext)
02471 {
02472 DDEnumInfo *Info;
02473 D3D_DRIVER *pDriver;
02474
02475 if (!lpDriverDesc || !lpDriverName)
02476 return (D3DENUMRET_OK);
02477
02478 if (strlen(lpDriverDesc) + 5 >= MAX_DRIVER_NAME)
02479 return DDENUMRET_OK;
02480
02481 Info = (DDEnumInfo*)lpContext;
02482
02483 if (Info->NumDrivers >= MAX_DRIVERS)
02484 return DDENUMRET_CANCEL;
02485
02486 pDriver = &Info->Drivers[Info->NumDrivers++];
02487
02488 if (lpGUID)
02489 {
02490 pDriver->IsPrimary = GE_FALSE;
02491 memcpy(&pDriver->Guid, lpGUID, sizeof(GUID));
02492 }
02493 else
02494 {
02495 pDriver->IsPrimary = GE_TRUE;
02496 }
02497
02498
02499 sprintf(pDriver->Name, "(D3D)%s", lpDriverDesc);
02500
02501 return DDENUMRET_OK;
02502 }
02503
02504
02505
02506
02507 BOOL DRIVERCC EnumSubDrivers2(DRV_ENUM_DRV_CB *Cb, void *Context)
02508 {
02509 HRESULT hr;
02510 int32 i;
02511 DDEnumInfo Info;
02512
02513 unlink(D3DMAIN_LOG_FILENAME);
02514
02515 Info.Drivers = Drivers;
02516 Info.NumDrivers = 0;
02517
02518 hr = DirectDrawEnumerate(EnumDriversCB2, &Info);
02519
02520 if (hr != DD_OK)
02521 {
02522 D3DMain_Log("D3DMain_EnumSubDrivers: DirectDrawEnumerate failed.\n");
02523 return FALSE;
02524 }
02525
02526 for (i=0; i< Info.NumDrivers; i++)
02527 {
02528
02529 if (!CreateDDFromDriver(&Info.Drivers[i]))
02530 return GE_FALSE;
02531
02532 if (Main_CheckDD())
02533 {
02534 if (!Cb(i, Info.Drivers[i].Name, Context))
02535 {
02536 RELEASE(AppInfo.lpD3D);
02537 AppInfo.lpD3D = NULL;
02538
02539
02540 RELEASE(AppInfo.lpDD);
02541 AppInfo.lpDD = NULL;
02542 memset(&AppInfo, 0, sizeof(AppInfo));
02543 break;
02544 }
02545 }
02546
02547 RELEASE(AppInfo.lpD3D);
02548 AppInfo.lpD3D = NULL;
02549
02550
02551 RELEASE(AppInfo.lpDD);
02552 AppInfo.lpDD = NULL;
02553 memset(&AppInfo, 0, sizeof(AppInfo));
02554 }
02555
02556
02557
02558 return TRUE;
02559 }
02560
02561
02562
02563
02564 BOOL DRIVERCC EnumModes2(int32 Driver, char *DriverName, DRV_ENUM_MODES_CB *Cb, void *Context)
02565 {
02566 HRESULT hr;
02567 int32 i, Width, Height;
02568 char ModeName[MAX_DRIVER_NAME];
02569 DDEnumInfo Info;
02570
02571
02572
02573
02574 Info.Drivers = Drivers;
02575 Info.NumDrivers = 0;
02576
02577 hr = DirectDrawEnumerate(EnumDriversCB2, &Info);
02578
02579 if (hr != DD_OK)
02580 {
02581 D3DMain_Log("D3DMain_EnumModes: DirectDrawEnumerate failed.\n");
02582 return FALSE;
02583 }
02584
02585
02586 if (!CreateDDFromName(DriverName, &Info))
02587 return GE_FALSE;
02588
02589 if (!D3DMain_EnumDisplayModes())
02590 {
02591 D3DMain_ShutdownD3D();
02592
02593 D3DMain_Log("D3DMain_EnumModes: D3DMain_EnumDisplayModes failed.\n");
02594 return FALSE;
02595 }
02596
02597 for (i=0; i< AppInfo.NumModes; i++)
02598 {
02599 if (AppInfo.Modes[i].Bpp != 16)
02600 continue;
02601
02602
02603 Width = AppInfo.Modes[i].Width;
02604 Height = AppInfo.Modes[i].Height;
02605
02606
02607 sprintf(ModeName, "%ix%i", Width, Height);
02608
02609
02610 if (!Cb(i, ModeName, Width, Height, Context))
02611 {
02612 D3DMain_ShutdownD3D();
02613 return GE_TRUE;
02614 }
02615 }
02616
02617 if (AppInfo.CanDoWindow)
02618 {
02619 if (!Cb(i, "WindowMode", -1, -1, Context))
02620 {
02621 D3DMain_ShutdownD3D();
02622 return GE_TRUE;
02623 }
02624 }
02625
02626 D3DMain_ShutdownD3D();
02627
02628 return TRUE;
02629 }
02630
02631
02632
02633
02634 static BOOL FAR PASCAL DDEnumCallback( GUID FAR* lpGUID,
02635 LPSTR lpDriverDesc,
02636 LPSTR lpDriverName,
02637 LPVOID lpContext)
02638 {
02639 LPDIRECTDRAW4 pDD6;
02640 DDCAPS DriverCaps, HELCaps;
02641 DD_Enum *DDEnum;
02642 LPDIRECTDRAW pDD1;
02643 HRESULT hr;
02644
02645 DDEnum = (DD_Enum*)lpContext;
02646
02647 if(strncmp(lpDriverDesc, DDEnum->DriverName, strlen(DDEnum->DriverName)))
02648 return DDENUMRET_OK;
02649
02650 pDD1 = NULL;
02651 hr = DirectDrawCreate( lpGUID, &pDD1, NULL );
02652
02653 if(FAILED( hr ))
02654 return DDENUMRET_CANCEL;
02655
02656 assert(pDD1);
02657
02658
02659
02660 hr = pDD1->QueryInterface( IID_IDirectDraw4, (VOID**)&pDD6);
02661
02662
02663 RELEASE(pDD1);
02664
02665 if( FAILED( hr ) )
02666 return DDENUMRET_CANCEL;
02667
02668 memset(&DriverCaps, 0, sizeof(DDCAPS));
02669 DriverCaps.dwSize = sizeof(DDCAPS);
02670 memset(&HELCaps, 0, sizeof(DDCAPS));
02671 HELCaps.dwSize = sizeof(DDCAPS);
02672
02673 if (FAILED(pDD6->GetCaps(&DriverCaps, &HELCaps)))
02674 {
02675 RELEASE(pDD6);
02676 return DDENUMRET_CANCEL;
02677 }
02678
02679
02680 if (!(DriverCaps.dwCaps & DDCAPS_3D))
02681 {
02682 RELEASE(pDD6);
02683 return DDENUMRET_CANCEL;
02684 }
02685
02686 if (!lpGUID)
02687 AppInfo.IsPrimary = TRUE;
02688 else
02689 AppInfo.IsPrimary = FALSE;
02690
02691 DDEnum->lpDD = pDD6;
02692 DDEnum->FoundDD = TRUE;
02693
02694 return DDENUMRET_CANCEL;
02695 }
02696
02697
02698
02699
02700
02701 static BOOL D3DMain_CreateDDFromName(const char *DriverName)
02702 {
02703 HRESULT hr;
02704 DDCAPS DriverCaps, HELCaps;
02705 DDEnumInfo Info;
02706
02707 D3DMain_Log("--- D3DMain_CreateDDFromName ---\n");
02708
02709 if (strlen(DriverName) >= MAX_DRIVER_NAME)
02710 return GE_FALSE;
02711
02712 D3DMain_Log(" Name: %s\n", DriverName);
02713
02714 Info.Drivers = Drivers;
02715 Info.NumDrivers = 0;
02716
02717 hr = DirectDrawEnumerate(EnumDriversCB2, &Info);
02718
02719 if (hr != DD_OK)
02720 {
02721 D3DMain_Log("D3DMain_CreateDDFromName: DirectDrawEnumerate failed.\n");
02722 return FALSE;
02723 }
02724
02725 {
02726 char TempName[1024];
02727
02728 sprintf(TempName, "(D3D)%s", DriverName);
02729
02730 if (!CreateDDFromName(TempName, &Info))
02731 return GE_FALSE;
02732 }
02733
02734 assert(AppInfo.lpDD);
02735
02736 memset(&DriverCaps, 0, sizeof(DDCAPS));
02737 DriverCaps.dwSize = sizeof(DDCAPS);
02738 memset(&HELCaps, 0, sizeof(DDCAPS));
02739 HELCaps.dwSize = sizeof(DDCAPS);
02740
02741 if (FAILED(AppInfo.lpDD->GetCaps(&DriverCaps, &HELCaps)))
02742 {
02743 D3DMain_Log("D3DMain_CreateDDFromName: GetCaps failed.\n");
02744 D3DMain_ShutdownD3D();
02745 return FALSE;
02746 }
02747
02748 if (DriverCaps.dwCaps2 & DDCAPS2_CANRENDERWINDOWED)
02749 D3DMain_Log(" DDCAPS2_CANRENDERWINDOWED : YES\n");
02750 else
02751 D3DMain_Log(" DDCAPS2_CANRENDERWINDOWED : NO\n");
02752
02753 if (DriverCaps.dwCaps2 & DDCAPS2_NO2DDURING3DSCENE)
02754 D3DMain_Log(" DDCAPS2_NO2DDURING3DSCENE : YES\n");
02755 else
02756 D3DMain_Log(" DDCAPS2_NO2DDURING3DSCENE : NO\n");
02757
02758
02759 strcpy(AppInfo.DDName, DriverName);
02760
02761 return TRUE;
02762 }
02763
02764
02765
02766
02767 static geBoolean CreateDDFromDriver(D3D_DRIVER *pDriver)
02768 {
02769 LPDIRECTDRAW pDD1;
02770 HRESULT hr;
02771
02772 AppInfo.IsPrimary = pDriver->IsPrimary;
02773
02774 if (pDriver->IsPrimary)
02775 hr = DirectDrawCreate(NULL, &pDD1, NULL );
02776 else
02777 hr = DirectDrawCreate(&pDriver->Guid, &pDD1, NULL );
02778
02779 if( FAILED( hr ) )
02780 return GE_FALSE;
02781
02782
02783
02784 hr = pDD1->QueryInterface(IID_IDirectDraw4, (VOID**)&AppInfo.lpDD);
02785
02786
02787 RELEASE(pDD1);
02788
02789 if(FAILED(hr))
02790 return GE_FALSE;
02791
02792 return GE_TRUE;
02793 }
02794
02795
02796
02797
02798 static geBoolean CreateDDFromName(const char *DriverName, const DDEnumInfo *Info)
02799 {
02800 int32 i;
02801
02802 for (i=0; i < Info->NumDrivers; i++)
02803 {
02804 if (!strcmp(Info->Drivers[i].Name, DriverName))
02805 break;
02806 }
02807
02808 if (i == Info->NumDrivers)
02809 return GE_FALSE;
02810
02811
02812 if (!CreateDDFromDriver(&Info->Drivers[i]))
02813 return GE_FALSE;
02814
02815 return GE_TRUE;
02816 }
02817