Main Page | Alphabetical List | Compound List | File List | Compound Members | File Members

D3d_main.cpp

Go to the documentation of this file.
00001 /****************************************************************************************/
00002 /*  D3D_Main.cpp                                                                        */
00003 /*                                                                                      */
00004 /*  Author: John Pollard                                                                */
00005 /*  Description: DD/D3D wrapper                                                         */
00006 /*                                                                                      */
00007 /*  The contents of this file are subject to the Genesis3D Public License               */
00008 /*  Version 1.01 (the "License"); you may not use this file except in                   */
00009 /*  compliance with the License. You may obtain a copy of the License at                */
00010 /*  http://www.genesis3d.com                                                            */
00011 /*                                                                                      */
00012 /*  Software distributed under the License is distributed on an "AS IS"                 */
00013 /*  basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See                */
00014 /*  the License for the specific language governing rights and limitations              */
00015 /*  under the License.                                                                  */
00016 /*                                                                                      */
00017 /*  The Original Code is Genesis3D, released March 25, 1999.                            */
00018 /*Genesis3D Version 1.1 released November 15, 1999                            */
00019 /*  Copyright (C) 1999 WildTangent, Inc. All Rights Reserved           */
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 //      Globals
00054 //================================================================================
00055 App_Info        AppInfo;                                // Our global structure that knows all... (once initialized)
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 //      Local static functions
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                 // Restore all the surfaces
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         // Force an update in the cache system
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 //      BPPToDDBD
00130 //      Convert an integer bit per pixel number to a DirectDraw bit depth flag
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;          // Shutup compiler warning
00155 }
00156 
00157 //================================================================================
00158 //      D3DMain_InitD3D
00159 //      Does all what is needed to get an app ready to go at a specified with height
00160 //      NOTE - It only makes 16 bit modes availible
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         // Create DD
00185         ATTEMPT(D3DMain_CreateDDFromName(DriverName));
00186         
00187         ATTEMPT(D3DMain_GetTextureMemory());
00188 
00189         // We must do this after the DD object is created!!!
00190         ATTEMPT(D3DMain_RememberOldMode(hWnd));         // Store old mode
00191 
00192         // Get available fullscreen display modes
00193         ATTEMPT(D3DMain_EnumDisplayModes());
00194 
00195         // Create D3D, and enum it's devices
00196         ATTEMPT(D3DMain_CreateD3D());
00197         ATTEMPT(D3DMain_EnumDevices());
00198 
00199         if (Width == -1 && Height == -1)                // Window Mode
00200         {
00201                 // Force Width/Height to client window area size
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         // Pick a device we will be happy with
00213         ATTEMPT(D3DMain_PickDevice());
00214 
00215         // Create front/back buffer
00216         ATTEMPT(D3DMain_CreateBuffers());               
00217         
00218         // For some reason, we have to create the zbuffer BEFORE the device??? Why???
00219         ATTEMPT(D3DMain_CreateZBuffer());
00220 
00221         // Create the device and viewport
00222         ATTEMPT(D3DMain_CreateDevice());
00223         ATTEMPT(D3DMain_CreateViewPort(Width, Height));
00224 
00225         // Get the surface formats for textures, and 2d surfaces
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         // Set some defaults render states
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         //D3DMain_SetFogEnable(GE_TRUE, 255.0f, 0.0f, 0.0f, 500.0f, 1500.0f);
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         //AppInfo.lpD3DDevice->SetRenderState(D3DRENDERSTATE_ZFUNC, D3DCMP_GREATEREQUAL);
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 //      D3DMain_ShutdownD3D
00310 //================================================================================
00311 BOOL D3DMain_ShutdownD3D(void)
00312 {
00313         D3DMain_Log("\n--- D3DMain_ShutdownD3D ---\n");
00314 
00315         THandle_Shutdown();
00316 
00317         // Destroys all objects including Direct Draw.
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 //      D3DMain_Log
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 //      CompareModes
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 //      EnumDisplayModesCallback
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         // Save this mode at the end of the mode array and increment mode count
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 //      D3DMain_EnumDisplayModes
00448 //================================================================================
00449 BOOL D3DMain_EnumDisplayModes(void)
00450 {
00451         HRESULT         LastError;
00452 
00453         D3DMain_Log("--- D3DMain_EnumDisplayModes ---\n");
00454 
00455         // Get a list of available display modes from DirectDraw
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         // Sort the list of display modes
00468         qsort((void *)&AppInfo.Modes[0], (size_t)AppInfo.NumModes, sizeof(App_Mode), CompareModes);
00469         
00470         return TRUE;
00471 }
00472 
00473 
00474 
00475 //================================================================================
00476 //      D3DMain_CreateD3D
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 #define MUST_BLEND (D3DPBLENDCAPS_BOTHINVSRCALPHA | \
00501                                         D3DPBLENDCAPS_BOTHSRCALPHA | \
00502                                         D3DPBLENDCAPS_DESTALPHA | \
00503                                         D3DPBLENDCAPS_DESTCOLOR | \
00504                                         D3DPBLENDCAPS_INVDESTALPHA | \
00505                                         D3DPBLENDCAPS_INVDESTCOLOR | \
00506                                         D3DPBLENDCAPS_INVSRCALPHA | \
00507                                         D3DPBLENDCAPS_INVSRCCOLOR | \
00508                                         D3DPBLENDCAPS_ONE | \
00509                                         D3DPBLENDCAPS_SRCALPHA | \
00510                                         D3DPBLENDCAPS_SRCALPHASAT | \
00511                                         D3DPBLENDCAPS_SRCCOLOR | \
00512                                         D3DPBLENDCAPS_ZERO)
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 //      EnumDeviceFunc
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         // Record the D3D driver's inforamation
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         // Is this a hardware device or software emulation?  Checking the color
00571         // model for a valid model works.
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                 // Skip if this is not a hardware driver
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         // Skip if it does not support alpha blending
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         //if (!(lpHWDesc->dpcTriCaps.dwTextureAddressCaps & D3DPTADDRESSCAPS_CLAMP))
00612         //      Good = FALSE;
00613         //else
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         // Stop as soon as we find a driver that can render into a window
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         // Store if we can use this driver
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         // Tell global structure that we found a good device
00647         AppInfo.FoundGoodDevice = TRUE;
00648         
00649         // If all was good, increment the number of drivers
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 //      EnumDevices
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 //      CreateSurface
00684 //================================================================================
00685 static HRESULT CreateSurface(LPDDSURFACEDESC2 lpDDSurfDesc, LPDIRECTDRAWSURFACE4 FAR *lpDDSurface) 
00686 {
00687         HRESULT Result;
00688         
00689         //if (AppInfo.OnlySystemMemory)
00690         //      lpDDSurfDesc->ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY;
00691 
00692         Result = AppInfo.lpDD->CreateSurface(lpDDSurfDesc, lpDDSurface, NULL);
00693         
00694         return Result;
00695 }
00696 
00697 //================================================================================
00698 //      GetSurfDesc
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 //      D3DMain_CreateViewPort
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         // Create the D3D viewport object
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         // Add the viewport to the D3D device
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         // Setup the viewport for a reasonable viewing area
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     // Create the material that will be used for the background
00765         {
00766                 D3DMATERIAL                     Material;
00767                 D3DMATERIALHANDLE       MatHandle;
00768 
00769                 // Create the material
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                 // Fill in the material with the data
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; // A default ramp size
00786 
00787             AppInfo.BackgroundMaterial->SetMaterial(&Material);
00788 
00789                 // Attach the material to the viewport
00790                 AppInfo.BackgroundMaterial->GetHandle( AppInfo.lpD3DDevice, &MatHandle);
00791             AppInfo.lpD3DViewport->SetBackground(MatHandle);
00792         }
00793 
00794         return TRUE;
00795 }
00796 
00797 //================================================================================
00798 //      EnumTextureFormatsCallback
00799 //      Record information about each texture format the current D3D driver can
00800 //      support. Choose one as the default format and return it through lpContext.
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         // Clear out this texture format slot
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         // Record the PixelFormat of this texture
00867         memcpy(&pTexFormat->ddsd.ddpfPixelFormat, lpddpfPixelFormat, sizeof(DDPIXELFORMAT));
00868 
00869         AppInfo.NumTextureFormats++;
00870 
00871         return DDENUMRET_OK;
00872 }
00873 
00874 //================================================================================
00875 //      Main_EnumTextureFormats
00876 //      Get a list of available texture map formats from the Direct3D driver by
00877 //      enumeration.  Choose a default format.
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 //      EnumSurfaceFormatsCallback
00902 //================================================================================
00903 HRESULT WINAPI EnumSurfaceFormatsCallback(LPDIRECTDRAWSURFACE4 lpDDSurface, LPDDSURFACEDESC2 lpDDSurfaceDesc, LPVOID lpContext)
00904 {
00905         LPDDPIXELFORMAT         lpddpfPixelFormat;
00906         DDMain_SurfFormat       *pSurfFormat;
00907 
00908         // Don't need this.
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         // Clear out this texture format slot
00922         memset(pSurfFormat, 0, sizeof(DDMain_SurfFormat));
00923 
00924         if(lpddpfPixelFormat->dwFlags & DDPF_ALPHAPIXELS) 
00925         {
00926                 if(lpddpfPixelFormat->dwRGBAlphaBitMask == 0x8000) 
00927                 {
00928                         // 1555
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                         // 4444
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         // Record the PixelFormat of this texture
00964         memcpy(&pSurfFormat->ddsd.ddpfPixelFormat, lpddpfPixelFormat,sizeof(DDPIXELFORMAT));
00965 
00966         AppInfo.NumSurfFormats++;
00967 
00968         return DDENUMRET_OK;
00969 }
00970   
00971 //================================================================================
00972 //      Main_EnumSurfaceFormats
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 // Name: EnumZBufferFormatsCallback()
00998 // Desc: Enumeration function to report valid pixel formats for z-buffers.
00999 //-----------------------------------------------------------------------------
01000 static HRESULT WINAPI EnumZBufferFormatsCallback( DDPIXELFORMAT* pddpf,
01001                                                   VOID* pddpfDesired )
01002 {
01003     if( NULL==pddpf || NULL==pddpfDesired )
01004         return D3DENUMRET_CANCEL;
01005 
01006     // If the current pixel format's match the desired ones (DDPF_ZBUFFER and
01007     // possibly DDPF_STENCILBUFFER), lets copy it and return. This function is
01008     // not choosy...it accepts the first valid format that comes along.
01009     if( pddpf->dwFlags == ((DDPIXELFORMAT*)pddpfDesired)->dwFlags )
01010     {
01011         memcpy( pddpfDesired, pddpf, sizeof(DDPIXELFORMAT) );
01012 
01013                 // We're happy with a 16-bit z-buffer. Otherwise, keep looking.
01014                 if( pddpf->dwZBufferBitDepth == 16 )
01015                         return D3DENUMRET_CANCEL;
01016     }
01017 
01018     return D3DENUMRET_OK;
01019 }
01020 
01021 //================================================================================
01022 //      D3DMain_ClearBuffers
01023 //================================================================================
01024 static BOOL D3DMain_ClearBuffers(void)
01025 {
01026         DDSURFACEDESC2  ddsd;
01027         RECT                    dst;
01028         DDBLTFX                 ddbltfx;
01029         HRESULT                 LastError;
01030 
01031         // Find the width and height of the front buffer by getting its
01032         // DDSURFACEDESC2
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                 // Clear the front buffer to black
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                 // Find the width and height of the back buffer by getting its
01073                 // DDSURFACEDESC2
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                 // Clear the back buffer to black
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 //      Main_ShowBackBuffer
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                 // Flip the back and front buffers
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                         //AppInfo.lpFrontBuffer->Restore();
01136                         //AppInfo.lpBackBuffer->Restore();
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 //      Main_ClearBackBuffer
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     // Default to clear nothing
01201         ClearFlags = 0;
01202 
01203         // Then set in what callers wants to clear
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 //      Surface manipulation
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 //      GetSurfacePixelMask
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         // Derive shift, width values from masks
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         // Pass all requested values back to the caller
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 //      MyRGB
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    // Get shift constants for current video mode
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    // Shift R,G, and B into one value
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 //      D3DMain_GetSurfaceFormats
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         // Now get the 3d surface formats
01449 
01450         // Get 1555
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     // Get 4444
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         // Get either 555, or 565.
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                 // For now, force 3d textures with RGB only info to be either 565 or 555
01496                 // We could enum all formats and let the caller pick between several different RGB formats...
01497                 if (lpddpfPixelFormat->dwFlags & DDPF_ALPHAPIXELS)
01498                         continue;               // We don't want any surface that has alpha, just pure RGB...
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                 // This is it
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 //      Main_CheckDD
01527 //      Checks to see if current DD driver has any usable D3D Devices...
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())                     // See if we can enumerate at least one good device for this DD Driver
01547                 return FALSE;
01548 
01549         if (!AppInfo.FoundGoodDevice)           // Return FALSE if not...
01550                 return FALSE;
01551 
01552         return TRUE;    // Found at least one!!!
01553 }
01554 
01555 //==========================================================================================
01556 //      OutputDriverInfo
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 //      D3DMain_GetTextureMemory
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         //ddsCaps.dwSize = sizeof(DDSCAPS2);
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                 // Get shift constants for current video mode/pixel format
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                 // Get shift constants for current video mode/pixel format
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                 // Get shift constants for current video mode/pixel format
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 //      D3DMain_UpdateWindow
01735 //====================================================================================================
01736 geBoolean DRIVERCC D3DMain_UpdateWindow(void)
01737 {
01738         D3DMain_GetClientWindowOffset(AppInfo.hWnd);
01739         return GE_TRUE;
01740 }
01741 
01742 //====================================================================================================
01743 //      D3DMain_SetActive
01744 //====================================================================================================
01745 geBoolean DRIVERCC D3DMain_SetActive(geBoolean wParam)
01746 {
01747         if (AppInfo.lpFrontBuffer)
01748                 AppInfo.RenderingIsOK = wParam;
01749 
01750         if(AppInfo.RenderingIsOK)                                                       // Regaining focus
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);                // Dx doesn't restore it
01769                         }
01770                         else
01771                                 OutputDebugString("D3DMain_SetActive: No surfaces lost...\n");
01772                 }
01773         }
01774 
01775         return  GE_TRUE;
01776 }
01777 
01778 //========================================================================================================
01779 //      D3DMain_SetFogEnable
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         // Fill in the material with the data
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; // A default ramp size
01811 
01812         AppInfo.BackgroundMaterial->SetMaterial(&Material);
01813 
01814         return GE_TRUE;
01815 }
01816 
01817 //================================================================================
01818 //      D3DMain_GetClientWindowOffset
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 //      D3DMain_RememberOldMode
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         // Get old fulscreen width/height/bpp
01860         AppInfo.OldWidth = ddsd.dwWidth;
01861         AppInfo.OldHeight = ddsd.dwHeight;
01862         AppInfo.OldBpp = ddsd.ddpfPixelFormat.dwRGBBitCount;
01863 
01864         // Get old window width/pos
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 //      D3DMain_SetDisplayMode
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);// | DDSCL_ALLOWREBOOT);
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                 // Set window boundaries to cover entire desktop, and show it
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 //      D3DMain_PickDevice
01964 //================================================================================
01965 static BOOL D3DMain_PickDevice(void)
01966 {
01967         int32   i;
01968         DWORD   Depths;
01969 
01970         D3DMain_Log("--- D3DMain_PickDevice ---\n");
01971 
01972         // Find a device with the same bpp as the mode set
01973         Depths = BPPToDDBD(AppInfo.CurrentBpp);
01974 
01975         for (i = 0; i < AppInfo.NumDrivers; i++)
01976         {
01977                 if (!(AppInfo.Drivers[i].IsHardware))           // ONLY hardware
01978                         continue;
01979 
01980                 // Only choose drivers that can support our draw buffer bpp
01981                 if (!(AppInfo.Drivers[i].Desc.dwDeviceRenderBitDepth & Depths))
01982                         continue;
01983 
01984                 // Only choose drivers that can create the zbuffer we need
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                 // Remember the current driver
01995                 AppInfo.CurrentDriver = i;
01996 
01997                 return TRUE;
01998         }
01999 
02000         return FALSE;
02001 }
02002 
02003 //================================================================================
02004 //      D3DMain_CreateDevice
02005 //================================================================================
02006 static BOOL D3DMain_CreateDevice(void)
02007 {
02008         HRESULT                                 Error;
02009 
02010         D3DMain_Log("--- D3DMain_CreateDevice ---\n");
02011 
02012         // Release old device
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                 // Get some info from the device
02028                 D3DDEVICEDESC hw, sw;
02029 
02030                 hw.dwSize = sw.dwSize = D3DDEVICEDESCSIZE;
02031     
02032                 AppInfo.lpD3DDevice->GetCaps(&hw, &sw);
02033         }
02034         #endif
02035         
02036         // Get Device Identifier
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         // Print the debug ID
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 //      D3DMain_CreateBuffers
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         // Release any old objects that might be lying around.  This should have
02064         // already been taken care of, but just in case...
02065         RELEASE(AppInfo.lpClipper);
02066         RELEASE(AppInfo.lpBackBuffer);
02067         RELEASE(AppInfo.lpFrontBuffer);
02068   
02069         if (AppInfo.FullScreen) 
02070         {
02071                 // Create a complex flipping surface for fullscreen mode with one
02072                 // back buffer.
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                 // Obtain a pointer to the back buffer surface created above so we
02100                 // can use it later.  For now, just check to see if it ended up in
02101                 // video memory (FYI).
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;    // Save the format of the back buffer
02125         }
02126         else 
02127         {       
02128                 // In the window case, create a front buffer which is the primary
02129                 // surface and a back buffer which is an offscreen plane surface.
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                 // Check to see if the back buffer is in video memory (FYI).
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                 // Create the DirectDraw Clipper object and attach it to the window
02188                 // and front buffer.
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;            // Save the format of the back buffer
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 //      D3DMain_DestroyBuffers
02234 //================================================================================
02235 static void D3DMain_DestroyBuffers(void)
02236 {
02237         RELEASE(AppInfo.lpClipper);
02238         RELEASE(AppInfo.lpBackBuffer);
02239         RELEASE(AppInfo.lpFrontBuffer);
02240 }
02241 
02242 //================================================================================
02243 //      D3DMain_CreateZBuffer
02244 //      Create a Z-Buffer of the appropriate depth and attach it to the back buffer.
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         // Release any Z-Buffer that might be around just in case.
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;//DDSD_ZBUFFERBITDEPTH;
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     // Find a valid zbuffer, from the current device
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         // Attach the Z-buffer to the back buffer so D3D will find it
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         // Find out if it ended up in video memory.
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 //      D3DMain_DestroyZBuffer
02333 //================================================================================
02334 static void D3DMain_DestroyZBuffer(void)
02335 {
02336         RELEASE(AppInfo.lpZBuffer)
02337 }
02338 
02339 //================================================================================
02340 //      D3DMain_RestoreDisplayMode
02341 //       Does nothing if mode has not been set yet
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         // Restore window width/height
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 //      Enum drivers
02394 //
02395 
02396 D3D_DRIVER      Drivers[MAX_DRIVERS];
02397 
02398 //========================================================================================================
02399 //      EnumDriversCB2
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         // Save name
02430         //sprintf(pDriver->Name, "(D3D)%s", lpDriverDesc);
02431         sprintf(pDriver->Name, "WireFrame (D3D)");
02432 
02433         return DDENUMRET_OK;
02434 }
02435 
02436 //========================================================================================================
02437 //      EnumSubDrivers2
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                 // Create the DD object for this driver
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                                 //D3DMain_ShutdownD3D();
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                 //D3DMain_ShutdownD3D();
02483                 RELEASE(AppInfo.lpDD);
02484                 AppInfo.lpDD = NULL;
02485                 memset(&AppInfo, 0, sizeof(AppInfo));
02486         }
02487         
02488         //Cb(i, "(D3D)HackDriver", Context);
02489 
02490         return TRUE;
02491 }       
02492 
02493 //========================================================================================================
02494 //      EnumModes2
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         //Cb(0, "HackMode 2", 640, 480, Context);
02504         //return GE_TRUE;
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                 // Get the width/height of mode
02535                 Width = AppInfo.Modes[i].Width;
02536                 Height = AppInfo.Modes[i].Height;
02537 
02538                 // Make a unique name
02539                 sprintf(ModeName, "%ix%i", Width, Height);
02540 
02541                 // Call their callback with this driver mode
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 //      DDEnumCallback
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;            // Next... This is not the one they wanted
02581 
02582         pDD1 = NULL;
02583         hr = DirectDrawCreate( lpGUID, &pDD1, NULL );
02584                 
02585         if(FAILED( hr ))
02586                 return DDENUMRET_CANCEL;                // Assume this is bad, and stop
02587 
02588         assert(pDD1);
02589 
02590         // Get a ptr to an IDirectDraw4 interface. This interface to DirectDraw
02591         // represents the DX6 version of the API.
02592         hr = pDD1->QueryInterface( IID_IDirectDraw4, (VOID**)&pDD6);
02593 
02594         // Don't need this anymore
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         // Make sure it's a 3d compatible device
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;        // We are done
02627 }
02628 
02629 //================================================================================
02630 //      D3DMain_CreateDDFromName
02631 //      Creates DD, searching for the specified DD name using DriverName
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         // Save the DD object
02691         strcpy(AppInfo.DDName, DriverName);
02692         
02693         return TRUE;
02694 }
02695 
02696 //========================================================================================================
02697 //      CreateDDFromDriver
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         // Get a ptr to an IDirectDraw4 interface. This interface to DirectDraw
02715         // represents the DX6 version of the API.
02716         hr = pDD1->QueryInterface(IID_IDirectDraw4, (VOID**)&AppInfo.lpDD);
02717 
02718         // Don't need this guy anymore
02719         RELEASE(pDD1);
02720 
02721         if(FAILED(hr))
02722                 return GE_FALSE;
02723 
02724         return GE_TRUE;
02725 }
02726 
02727 //========================================================================================================
02728 //      CreateDDFromName
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         // Create the DD object for this driver
02744         if (!CreateDDFromDriver(&Info->Drivers[i]))
02745                 return GE_FALSE;
02746 
02747         return GE_TRUE;
02748 }
02749 

Generated on Tue Sep 30 12:35:32 2003 for GTestAndEngine by doxygen 1.3.2