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

D3d_main.cpp

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

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