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