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