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