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

DDRAWDisplay.c

Go to the documentation of this file.
00001 /****************************************************************************************/
00002 /*  DDRAWDisplay.C                                                                      */
00003 /*                                                                                      */
00004 /*  Author:  Mike Sandige                                                               */
00005 /*  Description:  display surface manager for full screen Direct Draw using a direct    */
00006 /*                draw surface for the the frame buffer                                 */
00007 /*                                                                                      */
00008 /*  The contents of this file are subject to the Genesis3D Public License               */
00009 /*  Version 1.01 (the "License"); you may not use this file except in                   */
00010 /*  compliance with the License. You may obtain a copy of the License at                */
00011 /*  http://www.genesis3d.com                                                            */
00012 /*                                                                                      */
00013 /*  Software distributed under the License is distributed on an "AS IS"                 */
00014 /*  basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See                */
00015 /*  the License for the specific language governing rights and limitations              */
00016 /*  under the License.                                                                  */
00017 /*                                                                                      */
00018 /*  The Original Code is Genesis3D, released March 25, 1999.                            */
00019 /*Genesis3D Version 1.1 released November 15, 1999                            */
00020 /*  Copyright (C) 1999 WildTangent, Inc. All Rights Reserved           */
00021 /*                                                                                      */
00022 /****************************************************************************************/
00023 
00024 #pragma warning(disable : 4201 4214 4115)
00025 #include <windows.h>
00026 #include <assert.h>
00027 #include "ddraw.h"
00028 #include <stdio.h>
00029 #pragma warning(default : 4201 4214 4115; disable : 4514)
00030 
00031 #include "DDRAWDisplay.h" 
00032 
00033 #ifdef GENESIS_VERSION_2
00034 #include "errorlog.h"
00035 #else
00036 #define geErrorLog_AddString(Error,xx,yy) 
00037 #endif
00038 
00039 
00040 #define DDRAWDISPLAY_DESCRIPTION_STRING "Software (Full Screen)  "
00041 
00042 typedef struct 
00043 {
00044         LPDIRECTDRAW4                   lpDD4;
00045         HANDLE                                  ddrawinst;
00046 } DDRAWDisplay_DLLHooks;
00047 
00048 typedef struct DDRAWDisplay 
00049 {
00050         DDRAWDisplay_DLLHooks  DLL;
00051 
00052         LPDIRECTDRAWSURFACE4    lpDDSPrimary;   // DirectDraw primary surface
00053         LPDIRECTDRAWSURFACE4    lpDDSBack;              // DirectDraw back surface
00054         BOOL                                    bActive;
00055 
00056         int                             Width;
00057         int                             Height;
00058         int                             BitsPerPixel;
00059         int                             ModeFlags;
00060 
00061         HWND                    hWnd;
00062         geBoolean               Locked;
00063         uint8                   *Buffer;
00064         int32                   Pitch;
00065 } DDRAWDisplay;
00066 
00067 typedef HRESULT (WINAPI *LPDIRECTDRAWCREATE)( GUID FAR *lpGUID, LPDIRECTDRAW FAR *lplpDD, IUnknown FAR *pUnkOuter );
00068 
00069 
00070 static geBoolean DDRAWDisplay_IsValid(DDRAWDisplay *D)
00071 {
00072         if ( D == NULL )
00073                 return GE_FALSE;
00074 
00075         if (D->DLL.ddrawinst == NULL )
00076                 return GE_FALSE;
00077 
00078         if (D->DLL.lpDD4 == NULL)
00079                 return GE_FALSE;
00080 
00081         if (D->hWnd == NULL )
00082                 return GE_FALSE;
00083 
00084         return GE_TRUE;
00085 }
00086 
00087 static void DDRAWDisplay_UnloadDLL( DDRAWDisplay_DLLHooks *H )
00088 {
00089         assert( H != NULL );
00090         if (H->lpDD4)
00091                 {
00092                         H->lpDD4->lpVtbl->Release(H->lpDD4);
00093                         H->lpDD4 = NULL;
00094                 }
00095         if (H->ddrawinst)
00096                 {
00097                         FreeLibrary(H->ddrawinst);
00098                         H->ddrawinst = NULL;
00099                 }
00100 }
00101 
00102 static geBoolean DDRAWDisplay_LoadDLL( DDRAWDisplay_DLLHooks *H )
00103 {
00104         LPDIRECTDRAW                    lpDD       = NULL;                      // DirectDraw object
00105         LPDIRECTDRAWCREATE              lpDDCreate = NULL;
00106         HRESULT ddrval;
00107         assert( H != NULL );
00108         
00109         H->ddrawinst = NULL;
00110         H->lpDD4         = NULL;
00111 
00112 
00113         H->ddrawinst    =LoadLibrary("ddraw.dll");
00114 
00115         if(!H->ddrawinst)
00116         {
00117                 geErrorLog_AddString(-1,"failed to load","ddraw.dll");
00118                 goto LoadDLL_ERROR;
00119         }
00120         
00121         lpDDCreate      =(LPDIRECTDRAWCREATE)GetProcAddress(H->ddrawinst, "DirectDrawCreate");
00122         if(lpDDCreate)
00123                 {
00124                         ddrval  =lpDDCreate(NULL, &(lpDD), NULL);
00125                         if((ddrval != DD_OK) || ((lpDD)==NULL))
00126                                 {
00127                                         geErrorLog_AddString(-1,"ddraw lpDDCreate failed",  geErrorLog_IntToString(ddrval));
00128                                         goto LoadDLL_ERROR;
00129                                 }
00130                 }
00131         else
00132                 {
00133                         geErrorLog_AddString(-1 ,"Unable to find DirectDrawCreate entry into ddraw.dll",NULL);
00134                         goto LoadDLL_ERROR;
00135                 }
00136         
00137         ddrval = lpDD->lpVtbl->QueryInterface(lpDD, &IID_IDirectDraw4, (LPVOID *)&(H->lpDD4));
00138         if(ddrval!=DD_OK)
00139         {
00140                 geErrorLog_AddString(-1,"QueryInterface failed", geErrorLog_IntToString(ddrval));
00141                 goto LoadDLL_ERROR;
00142         }
00143         
00144         lpDD->lpVtbl->Release(lpDD);
00145         lpDD    =NULL;
00146 
00147 
00148         return GE_TRUE;
00149 
00150 
00151         LoadDLL_ERROR:
00152                 if (lpDD != NULL )
00153                         {
00154                                 lpDD->lpVtbl->Release(lpDD);
00155                                 lpDD    =NULL;
00156                         }
00157                 DDRAWDisplay_UnloadDLL(H);
00158         return GE_FALSE;
00159 }
00160         
00161 void DDRAWDisplay_GetDisplayFormat(     const DDRAWDisplay *D,
00162                                                                         int32   *Width, 
00163                                                                         int32   *Height,
00164                                                                         int32   *BitsPerPixel,
00165                                                                         uint32  *Flags)
00166 {
00167         assert( D            != NULL );
00168         assert( Width        != NULL );
00169         assert( Height       != NULL );
00170         assert( BitsPerPixel != NULL );
00171         assert( Flags        != NULL );
00172 
00173         *Width        = D->Width;
00174         *Height       = D->Height;
00175         *BitsPerPixel = D->BitsPerPixel;
00176         *Flags        = D->ModeFlags;
00177 }       
00178 
00179 void    DDRAWDisplay_Destroy(DDRAWDisplay **pD)
00180 {
00181         DDRAWDisplay *D;
00182 
00183         assert( pD );
00184         assert( DDRAWDisplay_IsValid(*pD)!=GE_FALSE );
00185         D = *pD;
00186 
00187         if (D->Locked == GE_TRUE)
00188                 DDRAWDisplay_Unlock(D);
00189 
00190         if (D->ModeFlags & FLIP)
00191         {
00192                 D->lpDDSBack    =NULL;
00193         }
00194         else
00195         {
00196                 if(D->lpDDSBack)
00197                 {
00198                         D->lpDDSBack->lpVtbl->Release(D->lpDDSBack);
00199                         D->lpDDSBack    =NULL;
00200                 }
00201         }
00202         if(D->lpDDSPrimary)
00203         {
00204                 D->lpDDSPrimary->lpVtbl->Release(D->lpDDSPrimary);
00205                 D->lpDDSPrimary =NULL;
00206         }
00207 
00208         DDRAWDisplay_UnloadDLL(&(D->DLL));
00209         
00210         free(D);
00211         *pD = NULL;
00212 }
00213 
00214 static geBoolean DDRAWDisplay_RestoreAll(DDRAWDisplay *D)
00215 {
00216         HRESULT ddrval;
00217         assert( DDRAWDisplay_IsValid(D)!=GE_FALSE );
00218 
00219         ddrval  =D->DLL.lpDD4->lpVtbl->SetCooperativeLevel(D->DLL.lpDD4, D->hWnd, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
00220         if(ddrval!=DD_OK)
00221         {
00222                 geErrorLog_AddString(-1,"DDRAWDisplay_RestoreAll(): ddraw SetCooperativeLevel", geErrorLog_IntToString(ddrval));
00223                 return  GE_FALSE;
00224         }
00225 
00226         ddrval  =D->DLL.lpDD4->lpVtbl->SetDisplayMode(D->DLL.lpDD4, D->Width, D->Height, D->BitsPerPixel, 0, 0);
00227         if(ddrval!=DD_OK)
00228         {
00229                 geErrorLog_AddString(-1,"DDRAWDisplay_RestoreAll: ddraw SetDisplayMode", geErrorLog_IntToString(ddrval));
00230                 return  GE_FALSE;
00231         }
00232         ddrval  =D->DLL.lpDD4->lpVtbl->RestoreAllSurfaces(D->DLL.lpDD4);
00233         if(ddrval!=DD_OK)
00234         {
00235                 geErrorLog_AddString(-1,"DDRAWDisplay_RestoreAll: ddraw RestoreAllSurfaces", geErrorLog_IntToString(ddrval));
00236                 return  GE_FALSE;
00237         }
00238         return  GE_TRUE;
00239 }
00240 
00241 
00242 geBoolean       DDRAWDisplay_Lock(DDRAWDisplay *D, uint8 **Buffer, int32 *Pitch)
00243 {
00244         HRESULT                 ddrval;
00245         DDSURFACEDESC2  ddsd;
00246         RECT                    wrect;
00247         int Forever = 1;
00248         assert( DDRAWDisplay_IsValid(D)!=GE_FALSE );
00249 
00250         if(!D->bActive)
00251                 return GE_TRUE;
00252                 // <> should probably be GE_FALSE, but this stays compatible with the existing convention
00253 
00254         assert( Buffer != NULL );
00255         assert( Pitch  != NULL );
00256 
00257         if (D->Locked != GE_FALSE)
00258                 {
00259                         geErrorLog_AddString(-1,"DDRAWDisplay_Lock: already locked",NULL );
00260                         return GE_FALSE;
00261                 }
00262         
00263         memset(&ddsd, 0, sizeof(DDSCAPS2));
00264         ddsd.dwSize     =sizeof(ddsd);
00265         ddsd.dwFlags=DDSD_HEIGHT | DDSD_WIDTH;
00266 
00267         D->lpDDSBack->lpVtbl->GetSurfaceDesc(D->lpDDSBack, &ddsd);
00268         wrect.left   = 0;
00269         wrect.top    = 0;
00270         wrect.right  = ddsd.dwWidth-1;
00271         wrect.bottom = ddsd.dwHeight-1;
00272 
00273         while(Forever)
00274         {
00275                 ddrval  =D->lpDDSBack->lpVtbl->Lock(D->lpDDSBack, &wrect, &ddsd, DDLOCK_SURFACEMEMORYPTR, NULL);
00276                 if(ddrval==DD_OK)
00277                 {
00278                         break;
00279                 }
00280 
00281                 if(ddrval==DDERR_SURFACELOST)
00282                 {
00283                         if (DDRAWDisplay_RestoreAll(D) == GE_FALSE) 
00284                         {
00285                                 geErrorLog_AddString(-1,"DDRAWDisplay_Lock: lost ddraw surface", NULL);
00286                                 return  GE_FALSE;
00287                         }
00288                 }
00289                 else if(ddrval!=DDERR_WASSTILLDRAWING)
00290                 {
00291                         geErrorLog_AddString(-1,"DDRAWDisplay_Lock: was still drawing",geErrorLog_IntToString(ddrval));
00292                         return  GE_FALSE;
00293                 }
00294         }
00295         *Buffer = (uint8 *)ddsd.lpSurface;
00296         *Pitch  = ddsd.lPitch;
00297         D->Locked = GE_TRUE;
00298         D->Buffer = *Buffer;
00299         D->Pitch  = *Pitch;
00300         return GE_TRUE;
00301 }
00302 
00303 geBoolean       DDRAWDisplay_Unlock(DDRAWDisplay *D)
00304 {
00305         int Forever=1;
00306         HRESULT                 ddrval  =DD_OK;
00307         assert( DDRAWDisplay_IsValid(D)!=GE_FALSE );
00308 
00309         if(!D->bActive)
00310                 return GE_TRUE;
00311                 // <> should probably be GE_FALSE, but this stays compatible with the existing convention
00312 
00313         if (D->Locked != GE_TRUE)
00314                 {
00315                         geErrorLog_AddString(-1,"DDRAWDisplay_Unlock: surface not locked",NULL);
00316                         return GE_FALSE;
00317                 }
00318         
00319         D->Locked = GE_FALSE;
00320         
00321         while(Forever)
00322         {
00323                 ddrval  =D->lpDDSBack->lpVtbl->Unlock(D->lpDDSBack, NULL);
00324                 if(ddrval==DD_OK)
00325                         break;
00326 
00327                 #pragma message (" can you loose a locked surface?")
00328                 if(ddrval==DDERR_SURFACELOST)           
00329                 {
00330                         if (DDRAWDisplay_RestoreAll(D) == GE_FALSE)
00331                         {
00332                                 geErrorLog_AddString(-1,"DDRAWDisplay_Unlock: surface lost\n",NULL);
00333                                 return  GE_FALSE;
00334                         }
00335                 }
00336                 else if(ddrval!=DDERR_WASSTILLDRAWING)
00337                 {
00338                         geErrorLog_AddString(-1,"DDRAWDisplay_Unlock: was still drawing.",geErrorLog_IntToString(ddrval));
00339                         return  GE_FALSE;
00340                 }
00341         }
00342 
00343         D->Locked = GE_FALSE;
00344         return GE_TRUE;
00345 }
00346 
00347 geBoolean       DDRAWDisplay_Blit(DDRAWDisplay *D)
00348 {
00349         HRESULT                 ddrval;
00350         DDSURFACEDESC2  ddsd;
00351         RECT                    rDest, rSrc;
00352         int                             Forever=1;
00353         assert( DDRAWDisplay_IsValid(D)!=GE_FALSE );
00354 
00355         if(!D->bActive)
00356         {
00357                 return  GE_TRUE;
00358         }
00359 
00360         memset(&ddsd, 0, sizeof(DDSCAPS2));
00361         ddsd.dwSize     =sizeof(ddsd);
00362         ddsd.dwFlags=DDSD_HEIGHT | DDSD_WIDTH; 
00363 
00364         D->lpDDSBack->lpVtbl->GetSurfaceDesc(D->lpDDSBack, &ddsd);
00365         rDest.left      =rDest.top      =0;
00366         rDest.right     =ddsd.dwWidth-1;
00367         rDest.bottom=ddsd.dwHeight-1;
00368 
00369         memset(&ddsd, 0, sizeof(DDSCAPS2));
00370         ddsd.dwSize     =sizeof(ddsd);
00371         ddsd.dwFlags=DDSD_HEIGHT | DDSD_WIDTH;
00372 
00373         D->lpDDSPrimary->lpVtbl->GetSurfaceDesc(D->lpDDSPrimary, &ddsd);
00374         rSrc.left       =rSrc.top       =0;
00375         rSrc.right      =ddsd.dwWidth-1;
00376         rSrc.bottom     =ddsd.dwHeight-1;
00377 
00378         ddrval  =DD_OK;
00379         if((D->ModeFlags & VIDEO) && (D->ModeFlags & FASTBLT))
00380         {
00381                 while(Forever)
00382                 {
00383                         ddrval  =D->lpDDSPrimary->lpVtbl->BltFast(D->lpDDSPrimary, 0, 0, D->lpDDSBack, NULL, 0);
00384                         if(ddrval==DD_OK)
00385                         {
00386                                 break;
00387                         }
00388 
00389                         if(ddrval==DDERR_SURFACELOST)
00390                         {
00391                                 if (DDRAWDisplay_RestoreAll(D) == GE_FALSE)
00392                                 {
00393                                         geErrorLog_AddString(-1,"DDRAWDisplay_Blit: lost surface",NULL);
00394                                         return  GE_FALSE;
00395                                 }
00396                         }
00397                         else if(ddrval!=DDERR_WASSTILLDRAWING)
00398                         {
00399                                 geErrorLog_AddString(-1,"DDRAWDisplay_Blit: was still drawing",NULL);
00400                                 return  GE_FALSE;
00401                         }
00402                 }
00403         }
00404         else if(D->ModeFlags & FLIP)
00405         {
00406                 while(Forever)
00407                 {
00408                         ddrval  =D->lpDDSPrimary->lpVtbl->Flip(D->lpDDSPrimary, D->lpDDSBack, DDFLIP_NOVSYNC);
00409                         if(ddrval==DD_OK)
00410                         {
00411                                 break;
00412                         }
00413 
00414                         if(ddrval==DDERR_SURFACELOST)
00415                         {
00416                                 if (DDRAWDisplay_RestoreAll(D)==GE_FALSE)
00417                                 {
00418                                         geErrorLog_AddString(-1,"DDRAWDisplay_Blit: lost surface",NULL);
00419                                         return  GE_FALSE;
00420                                 }
00421                         }
00422                         else if(ddrval!=DDERR_WASSTILLDRAWING)
00423                         {
00424                                 geErrorLog_AddString(-1,"DDRAWDisplay_Blit: was still drawing",NULL);
00425                                 return  GE_FALSE;
00426                         }
00427                 }
00428         }
00429         else    //safe blt
00430         {
00431                 while(Forever)
00432                 {
00433                         ddrval  =D->lpDDSPrimary->lpVtbl->Blt(D->lpDDSPrimary, NULL, D->lpDDSBack, NULL, DDBLT_WAIT, NULL);
00434                         if(ddrval==DD_OK)
00435                                 break;
00436 
00437                         if(ddrval==DDERR_SURFACELOST)
00438                         {
00439                                 if (DDRAWDisplay_RestoreAll(D)==GE_FALSE)
00440                                 {
00441                                         geErrorLog_AddString(-1,"DDRAWDisplay_Blit: lost surface",NULL);
00442                                         return  GE_FALSE;
00443                                 }
00444                         }
00445                         else if(ddrval!=DDERR_WASSTILLDRAWING)
00446                         {
00447                                 geErrorLog_AddString(-1,"DDRAWDisplay_Blit: was still drawing",NULL);
00448                                 return  GE_FALSE;
00449                         }
00450                 }
00451         }
00452         return GE_TRUE;
00453 }
00454 
00455 //my best guess for best performance is fast, blt, flip
00456 //dma is off for now because it ran horribly on the machine
00457 //I tested it on.  If people get 500mhz agp bus action in a few
00458 //years it might be useful perhaps
00459 static geBoolean DDRAWDisplay_SetMode(DDRAWDisplay *D, int width, int height, int bpp, uint32 flags)
00460 {
00461         HRESULT                 ddrval;
00462         DDSURFACEDESC2  ddsd;
00463         DDSCAPS2                ddscaps;
00464 
00465         assert( DDRAWDisplay_IsValid(D)!=GE_FALSE );
00466 
00467 
00468         D->ModeFlags = 0;
00469 
00470         ddrval  =D->DLL.lpDD4->lpVtbl->SetDisplayMode(D->DLL.lpDD4, width, height, bpp, 0, 0);
00471         
00472         D->Height       =height;
00473         D->Width        =width;
00474         D->BitsPerPixel =bpp;
00475 
00476         if(!(flags & MODEXMODE))
00477         {
00478 
00479                 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
00480                 ddsd.dwSize                     =sizeof(ddsd);
00481                 ddsd.dwFlags            =DDSD_CAPS;
00482                 ddsd.ddsCaps.dwCaps     =DDSCAPS_PRIMARYSURFACE | DDSCAPS_VIDEOMEMORY;
00483 
00484                 ddrval  =D->DLL.lpDD4->lpVtbl->CreateSurface(D->DLL.lpDD4, &ddsd, &D->lpDDSPrimary, NULL);
00485                 if(ddrval==DD_OK)
00486                 {
00487 
00488                         memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
00489                         ddsd.dwSize             =sizeof(ddsd);
00490                         ddsd.dwFlags    =DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
00491                         ddsd.ddsCaps.dwCaps     =DDSCAPS_SYSTEMMEMORY;
00492                         //ddsd.ddsCaps.dwCaps = DDSCAPS_VIDEOMEMORY;
00493                         ddsd.dwHeight   =height;
00494                         ddsd.dwWidth    =width;
00495 
00496                         ddrval  =D->DLL.lpDD4->lpVtbl->CreateSurface(D->DLL.lpDD4, &ddsd, &D->lpDDSBack, NULL);
00497                         if(ddrval==DD_OK)
00498                         {
00499                                 
00500                                 //both were created, make sure they are in vidram
00501                                 memset(&ddscaps, 0, sizeof(DDSCAPS2));
00502                                 D->lpDDSPrimary->lpVtbl->GetCaps(D->lpDDSPrimary, &ddscaps);
00503                                 if(ddscaps.dwCaps & DDSCAPS_VIDEOMEMORY)
00504                                 {
00505                                         memset(&ddscaps, 0, sizeof(DDSCAPS2));
00506                                         D->lpDDSBack->lpVtbl->GetCaps(D->lpDDSBack, &ddscaps);
00507                                         if(ddscaps.dwCaps & DDSCAPS_VIDEOMEMORY)
00508                                         {
00509 
00510                                                 //both are good to go
00511                                                 D->ModeFlags   |=VIDEO;
00512 
00513                                                 //mark fastblt unless it's stretching
00514                                                 if(!(flags & STRETCHMODE))
00515                                                 {
00516                                                         D->ModeFlags    |=FASTBLT;
00517                                                 }
00518                                         }
00519                                 }
00520                         }
00521                 }
00522                         #pragma message ("this cant be set can it?")
00523                 else if(!(D->ModeFlags & VIDEO)
00524                         && !(D->ModeFlags & STRETCHMODE))
00525                 {
00526                         if(D->lpDDSBack)                D->lpDDSBack->lpVtbl->Release(D->lpDDSBack);
00527                         if(D->lpDDSPrimary)     D->lpDDSPrimary->lpVtbl->Release(D->lpDDSPrimary);
00528 
00529                         memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
00530                         ddsd.dwSize                     =sizeof(ddsd);
00531                         ddsd.dwFlags            =DDSD_CAPS;
00532                         ddsd.ddsCaps.dwCaps     =DDSCAPS_PRIMARYSURFACE;
00533 
00534                         ddrval  =D->DLL.lpDD4->lpVtbl->CreateSurface(D->DLL.lpDD4, &ddsd, &D->lpDDSPrimary, NULL);
00535                         if(ddrval==DD_OK)
00536                         {
00537                                 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
00538                                 ddsd.dwSize             =sizeof(ddsd);
00539                                 ddsd.dwFlags    =DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
00540                                 ddsd.dwHeight   =height;
00541                                 ddsd.dwWidth    =width;
00542 
00543                                 ddrval  =D->DLL.lpDD4->lpVtbl->CreateSurface(D->DLL.lpDD4, &ddsd, &D->lpDDSBack, NULL);
00544                                 if(ddrval==DD_OK)
00545                                 {
00546                                         //both were created good enough
00547                                         D->ModeFlags    |=SYSTEM|SAFEBLT;
00548                                 }
00549                         }
00550                 }
00551         }       //flip 
00552         if((flags & MODEXMODE)  || D->lpDDSBack==NULL)
00553         {
00554                 if(D->lpDDSBack)                D->lpDDSBack->lpVtbl->Release(D->lpDDSBack);
00555                 if(D->lpDDSPrimary)     D->lpDDSPrimary->lpVtbl->Release(D->lpDDSPrimary);
00556 
00557                 //try flip
00558                 memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
00559                 ddsd.dwSize                             =sizeof(ddsd);
00560                 ddsd.dwFlags                    =DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
00561                 ddsd.ddsCaps.dwCaps             =DDSCAPS_PRIMARYSURFACE |
00562                                                                         DDSCAPS_COMPLEX | DDSCAPS_FLIP;
00563                 ddsd.dwBackBufferCount  =1;
00564 
00565                 ddrval  =D->DLL.lpDD4->lpVtbl->CreateSurface(D->DLL.lpDD4, &ddsd, &D->lpDDSPrimary, NULL);
00566                 if(ddrval==DD_OK)
00567                 {
00568                         memset(&ddscaps, 0, sizeof(DDSCAPS2));
00569                         ddscaps.dwCaps  =DDSCAPS_BACKBUFFER;
00570                         ddrval  =D->lpDDSPrimary->lpVtbl->GetAttachedSurface(D->lpDDSPrimary, &ddscaps, &D->lpDDSBack);
00571                         if(ddrval==DD_OK)
00572                         {
00573                                 D->ModeFlags    |=SYSTEM|FLIP;
00574                         }
00575                         else
00576                         {
00577                                 geErrorLog_AddString(-1,"Unable to create primary buffer",NULL);
00578                                 return GE_FALSE;
00579                         }
00580                 }               
00581         }
00582         return GE_TRUE;
00583 }
00584 
00585 
00586          
00587 
00588 DDRAWDisplay *DDRAWDisplay_Create(HWND hwnd, int Width, int Height, int BPP, uint32 Flags)
00589 {
00590         DDRAWDisplay *D = NULL;
00591         
00592         HRESULT                         ddrval     = 0;
00593 
00594         D = malloc(sizeof(DDRAWDisplay));
00595         if (D == NULL)
00596                 {
00597                         geErrorLog_AddString(-1,"Failed to create DDRAWDisplay object",NULL);
00598                         return NULL;
00599                 }
00600 
00601         memset(D,0,sizeof(DDRAWDisplay));
00602 
00603 
00604         if (DDRAWDisplay_LoadDLL(&(D->DLL))==GE_FALSE)
00605                 {
00606                         geErrorLog_AddString(-1,"failed to load ddraw dll",NULL);
00607                         goto Create_ERROR;
00608                 }
00609         D->hWnd = hwnd;
00610         D->bActive = GE_FALSE;
00611                 
00612         ddrval  =D->DLL.lpDD4->lpVtbl->SetCooperativeLevel(D->DLL.lpDD4, hwnd, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
00613         if(ddrval!=DD_OK)
00614         {
00615                 geErrorLog_AddString(-1,"DDRAWDisplay_Create: failed to set cooperative level", geErrorLog_IntToString(ddrval));
00616                 goto Create_ERROR;
00617         }
00618         
00619         if (DDRAWDisplay_SetMode(D, Width, Height, BPP, Flags)==GE_FALSE)
00620                 {
00621                         geErrorLog_AddString(-1,"Failed to create buffers",NULL);
00622                         goto Create_ERROR;
00623                 }
00624         
00625         assert( DDRAWDisplay_IsValid(D)!=GE_FALSE );
00626         return D;       
00627 
00628         Create_ERROR:
00629         if (D)
00630                 {
00631                         DDRAWDisplay_UnloadDLL(&(D->DLL));
00632                         free(D);
00633                 }
00634         return NULL;
00635 }
00636 
00637 
00638 
00639 
00640 geBoolean       DDRAWDisplay_GetPixelFormat(    DDRAWDisplay *D,
00641                                                                                         //int32 *pixel_pitch, 
00642                                                                                         int32 *bytes_per_pixel,
00643                                                                                         int32 *R_shift,
00644                                                                                         uint32 *R_mask,
00645                                                                                         int32 *R_width,
00646                                                                                         int32 *G_shift,
00647                                                                                         uint32 *G_mask,
00648                                                                                         int32 *G_width,
00649                                                                                         int32 *B_shift,
00650                                                                                         uint32 *B_mask,
00651                                                                                         int32 *B_width)
00652 {
00653         DDPIXELFORMAT   ddpf;
00654         uint32                  i, j;
00655 
00656         assert( DDRAWDisplay_IsValid(D)!=GE_FALSE );
00657         //assert( pixel_pitch     != NULL );
00658         assert( bytes_per_pixel != NULL );
00659         assert( R_shift         != NULL );
00660         assert( R_mask          != NULL );
00661         assert( R_width         != NULL );
00662         assert( G_shift         != NULL );
00663         assert( G_mask          != NULL );
00664         assert( G_width         != NULL );
00665         assert( B_shift         != NULL );
00666         assert( B_mask          != NULL );
00667         assert( B_width         != NULL );
00668 
00669         ddpf.dwSize     =sizeof(ddpf);
00670         D->lpDDSPrimary->lpVtbl->GetPixelFormat(D->lpDDSPrimary, &ddpf);
00671 
00672         if(!(ddpf.dwFlags & DDPF_RGB))
00673         {
00674                 return GE_FALSE;
00675         }
00676         *bytes_per_pixel        =ddpf.dwRGBBitCount / 8;
00677         *R_mask         =ddpf.dwRBitMask;
00678         *G_mask         =ddpf.dwGBitMask;
00679         *B_mask         =ddpf.dwBBitMask;
00680 
00681         for(j=0,i=ddpf.dwRBitMask;!(i & 1);i>>=1,j++);
00682         *R_shift        =j;
00683 
00684         for(j=0,i=ddpf.dwGBitMask;!(i & 1);i>>=1,j++);
00685         *G_shift        =j;
00686 
00687         for(j=0,i=ddpf.dwBBitMask;!(i & 1);i>>=1,j++);
00688         *B_shift        =j;
00689 
00690         for(i=(ddpf.dwRBitMask>>*R_shift),*R_width=0;i;i >>= 1, (*R_width)++);
00691         for(i=(ddpf.dwGBitMask>>*G_shift),*G_width=0;i;i >>= 1, (*G_width)++);
00692         for(i=(ddpf.dwBBitMask>>*B_shift),*B_width=0;i;i >>= 1, (*B_width)++);
00693         return GE_TRUE;
00694 }
00695 
00696 
00697 geBoolean       DDRAWDisplay_Wipe(DDRAWDisplay *D,uint32 color)
00698 {
00699         DDSURFACEDESC2  ddsd;
00700         int                             Width, Height;
00701 
00702         assert( DDRAWDisplay_IsValid(D)!=GE_FALSE );
00703 
00704         if(!D->bActive)
00705         {
00706                 return GE_FALSE;
00707         }
00708 
00709         if (!D->Locked)
00710                 {
00711                         geErrorLog_AddString(-1,"DDRAWDisplay_Wipe: surface not locked",NULL );
00712                         return GE_FALSE;
00713                 }
00714         memset(&ddsd, 0, sizeof(DDSCAPS2));
00715         ddsd.dwSize     =sizeof(ddsd);
00716         ddsd.dwFlags=DDSD_HEIGHT | DDSD_WIDTH;
00717         #pragma message ("this may not be necessary")
00718         D->lpDDSBack->lpVtbl->GetSurfaceDesc(D->lpDDSBack, &ddsd);
00719 
00720         Width   =ddsd.dwWidth;
00721         Height  =ddsd.dwHeight;
00722 
00723         memset(D->Buffer, color, (Height*D->Pitch));
00724         return GE_TRUE;
00725 }
00726 
00727 geBoolean DDRAWDisplay_SetActive(DDRAWDisplay *D, geBoolean wParam)
00728 {
00729         assert( D != NULL );
00730 
00731         D->bActive      =wParam;
00732 
00733         if(D->bActive)
00734         {       
00735                 if(D->lpDDSPrimary->lpVtbl->IsLost(D->lpDDSPrimary)==DDERR_SURFACELOST)
00736                 {
00737                         if(DDRAWDisplay_RestoreAll(D)!=GE_FALSE)
00738                         {
00739                                 ShowWindow(D->hWnd, SW_SHOWNORMAL);     //dx doesn't restore it
00740                         }
00741                         else
00742                         {
00743                                 geErrorLog_AddString(-1,"DDRAWDisplay_SetActive: Couldn't restore surfaces",NULL);
00744                                 return GE_FALSE;
00745                         }
00746                 }
00747         }
00748         return  GE_TRUE;
00749 }
00750 
00751 // -----------------------------------------------------------
00752 
00753 
00754 static HRESULT WINAPI DDRAWDisplay_ModeCallback(LPDDSURFACEDESC2 pdds, LPVOID lParam)
00755 {
00756         DisplayModeInfo *Info =(DisplayModeInfo *)lParam;
00757 
00758         #pragma message ("only 16 bit display is supported")
00759         if(pdds->ddpfPixelFormat.dwRGBBitCount==16)             
00760         {
00761                 DisplayModeInfo_AddEntry(Info,
00762                                 pdds->dwWidth,
00763                                 pdds->dwHeight,
00764                                 pdds->ddpfPixelFormat.dwRGBBitCount,
00765                                 pdds->ddpfPixelFormat.dwRGBBitCount);
00766         }
00767         return  S_FALSE;
00768 }
00769 
00770 geBoolean DDRAWDisplay_GetDescriptionString(char *DescriptionString, unsigned int DescriptionStringMaxLength)
00771 {
00772         DDRAWDisplay_DLLHooks DLL={NULL,0};
00773 
00774         DDDEVICEIDENTIFIER      DDDeviceIdentifier;
00775         HRESULT                         hRet;
00776 
00777         assert( DescriptionString != NULL );
00778         
00779         if (DDRAWDisplay_LoadDLL(&DLL)==GE_FALSE)
00780                 {       
00781                         geErrorLog_AddString(-1,"unable to load ddraw dll",NULL);
00782                         goto GetDescriptionString_ERROR;
00783                 }
00784         
00785         memset(&DDDeviceIdentifier, 0, sizeof(DDDeviceIdentifier));
00786 
00787         hRet    =DLL.lpDD4->lpVtbl->GetDeviceIdentifier(DLL.lpDD4, &DDDeviceIdentifier,0);
00788         
00789         if(hRet != DD_OK)
00790         {
00791                 geErrorLog_AddString(-1,"DDRAWDisplay_GetDescriptionString: ddraw GetDeviceIdentifier() failed", NULL);
00792                 goto GetDescriptionString_ERROR;
00793         }
00794 
00795         DDRAWDisplay_UnloadDLL(&DLL);           
00796         if (strlen(DDDeviceIdentifier.szDescription) + strlen(DDRAWDISPLAY_DESCRIPTION_STRING) >= DescriptionStringMaxLength)
00797                 {
00798                         geErrorLog_AddString(-1,"DDRAWDisplay_GetDescriptionString: description string too short",NULL);
00799                         goto GetDescriptionString_ERROR;
00800                 }
00801 
00802         strcpy(DescriptionString,DDRAWDISPLAY_DESCRIPTION_STRING);
00803         //strcat(DescriptionString,DDDeviceIdentifier.szDescription);
00804 
00805         return  GE_TRUE;
00806 
00807         //------
00808         GetDescriptionString_ERROR:
00809                 DDRAWDisplay_UnloadDLL(&DLL);
00810                 return GE_FALSE;
00811 }
00812 
00813 
00814 geBoolean DDRAWDisplay_GetDisplayInfo(  char                    *DescriptionString, 
00815                                                                                 unsigned int     DescriptionStringMaxLength,
00816                                                                                 DisplayModeInfo *Info)
00817 {
00818         DDDEVICEIDENTIFIER      DDDeviceIdentifier;
00819         DDRAWDisplay_DLLHooks DLL={NULL,0};
00820         HRESULT                         ddrval = 0;
00821         
00822         assert( Info != NULL );
00823 
00824         if (DDRAWDisplay_LoadDLL( &DLL )==GE_FALSE)
00825                 {
00826                         geErrorLog_AddString(-1,"failed to load DDRAW dll",NULL);
00827                         return GE_FALSE;
00828                 }
00829         
00830         #if 0
00831                 {
00832                         //test for general dma support
00833                         DDCAPS                          ddcaps;
00834                         memset(&ddcaps, 0, sizeof(DDCAPS));
00835                         ddcaps.dwSize   =sizeof(ddcaps);
00836                         DLL.lpDD4->lpVtbl->GetCaps(DLL.lpDD4, &ddcaps, NULL);
00837 
00838                         if(ddcaps.dwCaps & DDCAPS_CANBLTSYSMEM)
00839                         {
00840                                 //System to video blits supported
00841                                 if(ddcaps.dwSVBCaps & DDCAPS_BLTQUEUE)
00842                                 {
00843                                         D->bDMA =TRUE;  //      DMA Asynch System to Video blits supported
00844                                 }
00845                         }
00846                 }
00847         #endif
00848 
00849 
00850         #if 0           // need this?
00851                 ddrval  =DLL.lpDD4->lpVtbl->SetCooperativeLevel(DLL.lpDD4, ActiveWnd,
00852                         DDSCL_ALLOWMODEX | DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
00853                 if(ddrval != DD_OK)
00854                         {
00855                                 geErrorLog_Add(-1,"Failed to set Cooperative Level",NULL);
00856                                 goto GetDisplayInfo_ERROR;
00857                         }
00858         #endif
00859         
00860         memset(&DDDeviceIdentifier, 0, sizeof(DDDeviceIdentifier));
00861 
00862         ddrval  =DLL.lpDD4->lpVtbl->GetDeviceIdentifier(DLL.lpDD4, &DDDeviceIdentifier,0);
00863         
00864         if(ddrval != DD_OK)
00865         {
00866                 geErrorLog_AddString(-1,"ddraw GetDeviceIdentifier() failed", NULL);
00867                 goto GetDisplayInfo_ERROR;
00868         }
00869 
00870         if (strlen(DDDeviceIdentifier.szDescription) + strlen(DDRAWDISPLAY_DESCRIPTION_STRING) >= DescriptionStringMaxLength)
00871                 {
00872                         geErrorLog_AddString(-1,"description string too short",NULL);
00873                         goto GetDisplayInfo_ERROR;
00874                 }
00875 
00876         strcpy(DescriptionString,DDRAWDISPLAY_DESCRIPTION_STRING);
00877 //      strcat(DescriptionString,DDDeviceIdentifier.szDescription);
00878 
00879 
00880         DLL.lpDD4->lpVtbl->EnumDisplayModes(DLL.lpDD4, 0, NULL, (LPVOID)Info, DDRAWDisplay_ModeCallback);
00881 
00882         DDRAWDisplay_UnloadDLL(&DLL);
00883         return          GE_TRUE;        
00884 
00885         GetDisplayInfo_ERROR:
00886                 DDRAWDisplay_UnloadDLL(&DLL);
00887                 return GE_FALSE;
00888 
00889 }
00890 
00891 

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