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

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