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

DIBDisplay.c

Go to the documentation of this file.
00001 /****************************************************************************************/
00002 /*  DIBDisplay.C                                                                        */
00003 /*                                                                                      */
00004 /*  Author:  Mike Sandige                                                               */
00005 /*  Description:  display surface manager for windows with a DIB as the frame buffer    */
00006 /*                Code fragments contributed by John Miles                              */
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 #define WIN32_LEAN_AND_MEAN
00025 #pragma warning(disable : 4201 4214 4115)
00026 #include <windows.h>
00027 #pragma warning(default : 4201 4214 4115; disable : 4514)
00028 
00029 #include "DIBDisplay.h"
00030 #include "CPUInfo.h"
00031 #include <assert.h>
00032 #include <stdio.h>                      // vsprintf()
00033 #include <malloc.h>                     // malloc(),free()
00034 
00035 
00036 #ifdef GENESIS_VERSION_2
00037 #include "errorlog.h"
00038 #else
00039 #define geErrorLog_AddString(Error,xx,yy) 
00040 #define geErrorLog_Add(Error,xx) 
00041 #endif
00042 
00043 
00044 #define DIBDISPLAY_DESCRIPTION_STRING "Software (Window)"
00045 
00046 typedef struct
00047 {
00048    uint32 r;
00049    uint32 g;
00050    uint32 b;
00051    int32 alpha;
00052 }
00053 DIBDisplay_RGB32;
00054 
00055 
00056         // data needed for DIB section (and some cached info about bitmasks
00057 typedef struct
00058 {
00059         uint32          DIB_R_bitmask;                  // DIB high-color pixel format
00060         uint32          DIB_G_bitmask;
00061         uint32          DIB_B_bitmask;
00062 
00063         BITMAPINFO  *pbmi;                                      // BITMAPINFO structure
00064         HBITMAP         hDIB;                                   // Handle returned from CreateDIBSection
00065 
00066         uint8           *lpDIBBuffer;                   // DIB image buffer
00067 } DIBDisplay_DIBInfo;   
00068 
00069 
00070 
00071 typedef struct DIBDisplay 
00072 {
00073         HWND                            hWnd;                                   // Handle to application window
00074         geBoolean                       Locked;                                 // is display 'locked'
00075         int32                           BitsPerPixel;                   // Mode info set by last call to 
00076         int32                           Pitch;                                  // (BitsPerPixel/8) * Size_X
00077         int32                           Size_X;                                 // size of window rounded up to the nearest multiple of 4
00078         int32                           Size_Y;
00079         uint32                          Flags;                                  // display flags (currently unused)
00080         DIBDisplay_DIBInfo      DIBInfo;
00081 } DIBDisplay;
00082 
00083 
00084 void DIBDisplay_GetDisplayFormat(       const DIBDisplay *D,
00085                                                                         int32   *Width, 
00086                                                                         int32   *Height,
00087                                                                         int32   *BitsPerPixel,
00088                                                                         uint32  *Flags)
00089 {
00090         assert( D            != NULL );
00091         assert( Width        != NULL );
00092         assert( Height       != NULL );
00093         assert( BitsPerPixel != NULL );
00094         assert( Flags        != NULL );
00095 
00096         *Width        = D->Size_X;
00097         *Height       = D->Size_Y;
00098         *BitsPerPixel = D->BitsPerPixel;
00099         *Flags        = D->Flags;
00100 }       
00101 
00102 
00103 geBoolean DIBDisplay_GetDisplayInfo(    char                    *DescriptionString, 
00104                                                                                 unsigned int     DescriptionStringMaxLength,
00105                                                                                 DisplayModeInfo *Info)
00106 {
00107         int BitsPerPixel;
00108 
00109         assert( Info != NULL );
00110         assert( DescriptionString != NULL );
00111         assert( DescriptionStringMaxLength > 0 );
00112         if (strlen(DIBDISPLAY_DESCRIPTION_STRING) >= DescriptionStringMaxLength)
00113                 {
00114                         geErrorLog_AddString(GE_ERR_BAD_PARAMETER,"DIBDisplay_GetDescriptionString: description string too short",NULL);
00115                         return GE_FALSE;
00116                 }
00117 
00118         strcpy(DescriptionString,DIBDISPLAY_DESCRIPTION_STRING);
00119 
00120 //      if ( CPUInfo_TestFor3DNow()==GE_TRUE)
00121 //              BitsPerPixel = 32;
00122 //      else
00123                 BitsPerPixel = 16;
00124 
00125         if (DisplayModeInfo_AddEntry(Info,-1,-1,BitsPerPixel,0)==GE_FALSE)
00126                 {
00127                         geErrorLog_AddString(GE_ERR_SUBSYSTEM_FAILURE,"DIBDisplay_GetDescriptionString: unable to add mode entry",NULL);
00128                         return GE_FALSE;
00129                 }
00130         return GE_TRUE;
00131 }
00132 
00133 
00134 //------------------------------------------------
00135 static void DIBDisplay_DebugPrintf(char *fmt, ...)
00136 {
00137         static char work_string[4096];
00138 
00139         if ((fmt == NULL) || (strlen(fmt) > sizeof(work_string)))
00140                 {
00141                         strcpy(work_string, "(String missing or too large)");
00142                 }
00143         else
00144                 {
00145                         va_list ap;
00146 
00147                         va_start(ap,fmt);
00148 
00149                         vsprintf(work_string, fmt, ap);
00150 
00151                         va_end  (ap);
00152                 }
00153 
00154         #if 0  // log to file
00155         {
00156                 FILE       *log;
00157                 log = fopen("DEBUG.LOG","a+t");
00158 
00159                 if (log != NULL)
00160                         {
00161                                 fprintf(log,"%s\n",work_string);
00162                                 fclose(log);
00163                         }
00164         }
00165         #endif
00166 
00167         OutputDebugString(work_string);
00168 }
00169 
00170 
00171 //------------------------------------------------
00172 #ifndef NDEBUG
00173 static geBoolean DIBDisplay_IsValid(const DIBDisplay *D)
00174 {
00175         if (D == NULL)
00176                 return GE_FALSE;
00177 
00178         if (D->DIBInfo.pbmi == NULL)
00179                 return GE_FALSE;
00180         if (D->DIBInfo.hDIB == NULL)
00181                 return GE_FALSE;
00182         if (D->DIBInfo.lpDIBBuffer == NULL)
00183                 return GE_FALSE;
00184 
00185         return GE_TRUE;
00186 }
00187 #endif
00188 
00189 
00190 //------------------------------------------------
00191 static geBoolean DIBDisplay_FindDesktopRGBMasks(        HDC             hdc,
00192                                                                 int32   desktop_bpp,
00193                                                                 uint32  *desktop_R_bitmask,
00194                                                                 uint32  *desktop_G_bitmask,
00195                                                                 uint32  *desktop_B_bitmask)
00196 {
00197         assert( hdc != NULL );
00198         assert( desktop_R_bitmask != NULL );
00199         assert( desktop_G_bitmask != NULL );
00200         assert( desktop_B_bitmask != NULL );
00201 
00202         if(desktop_bpp > 8)
00203                 {
00204                         COLORREF                color,save;
00205                         HBITMAP                 TempBmp;
00206                         OSVERSIONINFO   WinVer;
00207 
00208                         memset(&WinVer, 0, sizeof(OSVERSIONINFO));
00209                         WinVer.dwOSVersionInfoSize      =sizeof(OSVERSIONINFO);
00210 
00211                         GetVersionEx(&WinVer);
00212                         if(WinVer.dwPlatformId == VER_PLATFORM_WIN32_NT)
00213                                 {
00214                                         TempBmp =CreateCompatibleBitmap(hdc, 8, 8);
00215                                         if(TempBmp)
00216                                                 {
00217                                                         BITMAPINFO              *TempInfo;
00218                                                         int HeaderSize =  sizeof(BITMAPINFO) + sizeof(RGBQUAD)*2;
00219                                                         TempInfo = malloc(HeaderSize);
00220                                                         if (TempInfo == NULL)
00221                                                                 {
00222                                                                         geErrorLog_Add(DIBDisplay_FindDesktopRGBMasks,"Failed to allocate header for NT mask test");
00223                                                                         DeleteObject(TempBmp);
00224                                                                         return GE_FALSE;
00225                                                                 }
00226                                                         memset(TempInfo, 0, HeaderSize);
00227                                                         TempInfo->bmiHeader.biSize              =sizeof(BITMAPINFO);
00228                                                         TempInfo->bmiHeader.biBitCount  =(uint16)desktop_bpp;
00229                                                         TempInfo->bmiHeader.biCompression       =BI_BITFIELDS;
00230                                                         if(GetDIBits(hdc, TempBmp, 0, 0, NULL, TempInfo, DIB_RGB_COLORS))
00231                                                                 {
00232                                                                         *desktop_R_bitmask      =*((uint32 *)&TempInfo->bmiColors[0]);
00233                                                                         *desktop_G_bitmask      =*((uint32 *)&TempInfo->bmiColors[1]);
00234                                                                         *desktop_B_bitmask      =*((uint32 *)&TempInfo->bmiColors[2]);
00235                                                                         DIBDisplay_DebugPrintf("(%x-%x-%x)\n", *desktop_R_bitmask, *desktop_G_bitmask, *desktop_B_bitmask);
00236                                                                 }
00237                                                         else
00238                                                                 {
00239                                                                         free(TempInfo);
00240                                                                         DeleteObject(TempBmp);
00241                                                                         geErrorLog_AddString(GE_ERR_WINDOWS_API_FAILURE,"DIBDisplay_FindDesktopRGBMasks:  Unable to get bit format from desktop compatible bitmap",NULL);
00242                                                                         return GE_FALSE;
00243                                                                 }
00244                                                         free(TempInfo);
00245                                                         DeleteObject(TempBmp);
00246                                                 }
00247                                         else
00248                                                 {
00249                                                         geErrorLog_AddString(GE_ERR_WINDOWS_API_FAILURE,"DIBDisplay_FindDesktopRGBMasks:  Unable to create desktop compatible bitmap",NULL);
00250                                                         return GE_FALSE;
00251                                                 }
00252                                         // detect failure (Win2000 only?)
00253                                         if (((*desktop_R_bitmask | *desktop_G_bitmask | *desktop_B_bitmask)&0x7FFF) != 0x7FFF)
00254                                                 {
00255                                                         SetLastError(0);
00256                                                         geErrorLog_AddString(GE_ERR_WINDOWS_API_FAILURE,"DIBDisplay_FindDesktopRGBMasks:  GetDIBits didn't return proper masking information.",NULL);
00257                                                         return GE_FALSE;
00258                                                 }
00259 
00260                                 }
00261                         else
00262                                 {
00263                                         HDC hdc2;
00264                                         
00265                                         hdc2 = CreateDC("Display", NULL, NULL,NULL);
00266                                         if (hdc2==NULL)
00267                                                 {
00268                                                         geErrorLog_AddString(GE_ERR_WINDOWS_API_FAILURE,"DIBDisplay_FindDesktopRGBMasks: Unable to create compatible hdc",NULL);
00269                                                         return GE_FALSE;
00270                                                 }
00271                                                 
00272                                         save = GetPixel(hdc2,0,0);
00273                                         if ( save == CLR_INVALID )
00274                                                 {
00275                                                         geErrorLog_AddString(GE_ERR_WINDOWS_API_FAILURE,"DIBDisplay_FindDesktopRGBMasks:  Unable to get pixel from desktop",NULL);
00276                                                         DeleteDC(hdc2);
00277                                                         return GE_FALSE;
00278                                                 }
00279                                                         
00280 
00281                                         if (SetPixel(hdc2,0,0,RGB(0x08,0x08,0x08))==-1)
00282                                                 {
00283                                                         geErrorLog_AddString(GE_ERR_WINDOWS_API_FAILURE,"DIBDisplay_FindDesktopRGBMasks: Unable to select bitmap",NULL);
00284                                                         DeleteDC(hdc2);
00285                                                         return GE_FALSE;
00286                                                 }
00287                                         
00288                                         color = GetPixel(hdc2,0,0) & 0xffffff;
00289                                         if ( color == CLR_INVALID )
00290                                                 {
00291                                                         geErrorLog_AddString(GE_ERR_WINDOWS_API_FAILURE,"DIBDisplay_FindDesktopRGBMasks:  Unable to get test pixel from desktop",NULL);
00292                                                         DeleteDC(hdc2);
00293                                                         return GE_FALSE;
00294                                                 }
00295 
00296                                         SetPixel(hdc,0,0,save);         // ignore an error here.
00297                                         DeleteDC(hdc2);
00298 
00299                                         DIBDisplay_DebugPrintf("DIBDisplay: Desktop pixel format = 0x%X ",color);
00300                                         
00301 
00302                                         switch (color)
00303                                                 {
00304                                                         case 0x000000:                                          // 0x000000 = 5-5-5
00305                                                                 DIBDisplay_DebugPrintf("(5-5-5)\n");
00306 
00307                                                                 *desktop_R_bitmask = 0x007c00;
00308                                                                 *desktop_G_bitmask = 0x0003e0;
00309                                                                 *desktop_B_bitmask = 0x00001f;
00310                                                                 break;
00311 
00312                                                         case 0x000800:                                          // 0x000800 = 5-6-5
00313                                                         DIBDisplay_DebugPrintf("(5-6-5)\n");
00314 
00315                                                                 *desktop_R_bitmask = 0x00f800;
00316                                                                 *desktop_G_bitmask = 0x0007e0;
00317                                                                 *desktop_B_bitmask = 0x00001f;
00318                                                                 break;
00319                                 
00320                                                         case 0x080808:                                          // 0x080808 = 8-8-8
00321                                                                 DIBDisplay_DebugPrintf("(8-8-8)\n");
00322 
00323                                                                 *desktop_R_bitmask = 0xff0000;
00324                                                                 *desktop_G_bitmask = 0x00ff00;
00325                                                                 *desktop_B_bitmask = 0x0000ff;
00326                                                                 break;
00327 
00328                                                         default:
00329                                                                 DIBDisplay_DebugPrintf("(Unsupported, using 5-6-5)\n");
00330 
00331                                                                 if ((desktop_bpp == 15) || (desktop_bpp == 16))
00332                                                                    {
00333                                                                            *desktop_R_bitmask = 0x00f800;
00334                                                                            *desktop_G_bitmask = 0x0007e0;
00335                                                                            *desktop_B_bitmask = 0x00001f;
00336                                                                         }
00337                                                                 else
00338                                                                         {
00339                                                                                 geErrorLog_AddString(GE_ERR_DISPLAY_RESOURCE,"DIBDisplay_FindDesktopRGBMasks:  Unsupported desktop format.",NULL);
00340                                                                                 return GE_FALSE;
00341                                                                         }
00342                                                                 break;
00343                                                         }
00344 
00345                                 }
00346                 }
00347         return GE_TRUE;
00348 }
00349 
00350 
00351 
00352 
00353 //------------------------------------------------
00354 static void DIBDisplay_DestroyDIB(DIBDisplay_DIBInfo *DI)
00355 {
00356         assert( DI != NULL );
00357 
00358         if (DI->pbmi != NULL)
00359                 {
00360                         free(DI->pbmi);
00361                         DI->pbmi = NULL;
00362                 }
00363 
00364         if (DI->hDIB != NULL)
00365                 {
00366                         DeleteObject(DI->hDIB);
00367                         DI->hDIB = NULL;
00368                 }
00369 }
00370 
00371 //------------------------------------------------
00372 static geBoolean DIBDisplay_CreateDIB( 
00373                                 int32   display_size_X,
00374                 int32   display_size_Y,
00375                 int32   display_bpp,
00376                                 HWND    hWnd,
00377                                 DIBDisplay_DIBInfo *DI)
00378 {
00379         HDC      hdc;
00380         BITMAPINFOHEADER *pbmih;              // Pointer to pbmi header
00381         uint32          desktop_R_bitmask;        // Desktop high-color pixel format
00382         uint32          desktop_G_bitmask;        
00383         uint32          desktop_B_bitmask;
00384         int32           desktop_bpp;              // Windows video mode BPP
00385         
00386         assert( display_size_X > 0 );
00387         assert( display_size_Y > 0 );
00388         assert( (display_bpp == 16) || (display_bpp == 24));
00389         assert( DI != NULL );
00390 
00391         DI->hDIB        = NULL;
00392         DI->lpDIBBuffer = NULL;
00393 
00394         DI->pbmi = (BITMAPINFO *) 
00395                                 malloc(sizeof (BITMAPINFOHEADER) + (sizeof (RGBQUAD) * 256));
00396 
00397         if (DI->pbmi == NULL)
00398                 {
00399                         // geErrorLog_AddString("failed to allocate bitmap header",NULL);
00400                         return GE_FALSE;
00401                 }
00402 
00403         memset(DI->pbmi, 0, sizeof (BITMAPINFOHEADER) + (sizeof (RGBQUAD) * 256));
00404 
00405         pbmih = &(DI->pbmi->bmiHeader);
00406 
00407         pbmih->biSize          =  sizeof(BITMAPINFOHEADER);
00408         pbmih->biWidth         =  display_size_X;
00409         pbmih->biHeight        = -(display_size_Y);
00410         pbmih->biPlanes        =  1;
00411         pbmih->biBitCount      =  (uint16) display_bpp;
00412         pbmih->biSizeImage     =  0;
00413         pbmih->biXPelsPerMeter =  0;
00414         pbmih->biYPelsPerMeter =  0;
00415         pbmih->biClrUsed       =  0;
00416         pbmih->biClrImportant  =  0;
00417 
00418         //
00419         // Get Windows desktop display format (and masks, in high-color modes)
00420         //
00421 
00422         hdc = GetDC(hWnd);
00423         if ( hdc == NULL )
00424                 {
00425                         // geErrorLog_AddString("unable to get desktop HDC");
00426                         return GE_FALSE;
00427                 }
00428 
00429         desktop_bpp = GetDeviceCaps(hdc, BITSPIXEL) * 
00430                                   GetDeviceCaps(hdc, PLANES);
00431 
00432         DIBDisplay_DebugPrintf("DIBDisplay: Desktop %d BPP\n", desktop_bpp);
00433 
00434         if (DIBDisplay_FindDesktopRGBMasks( hdc,
00435                                                                                 desktop_bpp,
00436                                                                                 &desktop_R_bitmask,
00437                                                                                 &desktop_G_bitmask,
00438                                                                                 &desktop_B_bitmask)==GE_FALSE)
00439                 {
00440                         //geErrorLog_AddString("unable to determine desktop bit format");
00441                         //ReleaseDC(hWnd, hdc);
00442                         //return GE_FALSE;
00443                         desktop_R_bitmask = 0x00f800;
00444                         desktop_G_bitmask = 0x0007e0;
00445                         desktop_B_bitmask = 0x00001f;
00446                 }
00447                         
00448 
00449         //
00450         // If DIB and desktop are both in 15/16-BPP mode, set DIB to desktop
00451         // pixel format for maximum throughput
00452         // 
00453         // Otherwise, set DIB to 5-6-5 mode if 16BPP DIB requested, or 8-8-8 mode
00454         // if 24BPP DIB requested
00455         //
00456         // Finally, if 8BPP DIB requested, create GDI palette object based on 
00457         // current logical palette
00458         //
00459 
00460         switch (display_bpp)
00461         {
00462                 case 16:
00463 
00464                         pbmih->biCompression = BI_BITFIELDS;
00465 
00466                         if ((desktop_bpp == 15) || (desktop_bpp == 16))
00467                                 {
00468                                         DI->DIB_R_bitmask = desktop_R_bitmask;
00469                                         DI->DIB_G_bitmask = desktop_G_bitmask;
00470                                         DI->DIB_B_bitmask = desktop_B_bitmask;
00471                                 }
00472                         else
00473                                 {
00474                                         DI->DIB_R_bitmask = 0x00f800;
00475                                         DI->DIB_G_bitmask = 0x0007e0;
00476                                         DI->DIB_B_bitmask = 0x00001f;
00477                                 }
00478                         break;
00479 
00480                 case 24:
00481 
00482                         pbmih->biCompression = BI_BITFIELDS;
00483                         DI->DIB_R_bitmask = 0xff0000;
00484                         DI->DIB_G_bitmask = 0x00ff00;
00485                         DI->DIB_B_bitmask = 0x0000ff;
00486                         break;
00487         }
00488 
00489         *(uint32 *) (&(DI->pbmi->bmiColors[0])) = DI->DIB_R_bitmask;
00490         *(uint32 *) (&(DI->pbmi->bmiColors[1])) = DI->DIB_G_bitmask;
00491         *(uint32 *) (&(DI->pbmi->bmiColors[2])) = DI->DIB_B_bitmask;
00492 
00493 
00494         //
00495         // Allocate the DIB section ("back buffer")
00496         //
00497 
00498         DI->hDIB = CreateDIBSection(hdc,                                                        // Device context
00499                                                                 DI->pbmi,                                               // BITMAPINFO structure
00500                                                                 DIB_RGB_COLORS,                                 // Color data type
00501                                                                 (void **) &(DI->lpDIBBuffer),   // Address of image map pointer
00502                                                                 NULL,                                                   // File
00503                                                                 0);                                                             // Bitmap file offset
00504 
00505         ReleaseDC(hWnd, hdc);
00506 
00507         if (DI->hDIB == NULL)
00508                 {
00509                         //geErrorLog_AddString("CreateDIBSection failed");
00510                         return GE_FALSE;
00511                 }
00512 
00513         return GE_TRUE;
00514         
00515 }
00516 
00517 //------------------------------------------------
00518 geBoolean DIBDisplay_Blit(DIBDisplay *D)
00519 {
00520         HDC hdc;
00521         assert( DIBDisplay_IsValid(D) != GE_FALSE );
00522 
00523         hdc = GetDC(D->hWnd);
00524         if (hdc == NULL)
00525                 {
00526                         //geErrorLog_AddString("Unable to get HDC for blit");
00527                         return GE_FALSE;
00528                 }
00529 
00530         #if 0
00531                 if (desktop_bpp == 8)
00532                         {
00533                         //
00534                         // Select palette if desktop running in 8-bit mode
00535                         //
00536                         // If palette has changed, realize it
00537                         //
00538 
00539                                 //probably want to set up a halftone palette, and dither down into the 8 bbp desktop.
00540 
00541                                 SelectPalette(  hdc,  hPalette, 0);
00542 
00543                                 if (palette_change_request != GE_FALSE)
00544                                         {
00545                                                 palette_change_request = GE_FALSE;
00546                                                 RealizePalette(hdc);
00547                                         }
00548                         }
00549         #endif
00550 
00551 
00552         //
00553         // Disable Boolean operations during stretching
00554         //
00555 
00556         if (SetStretchBltMode(hdc, COLORONCOLOR)==0)
00557                 {
00558                         //geErrorLog_AddString("unable to set stretch blit mode");
00559                         return GE_FALSE;
00560                 }
00561 
00562         StretchDIBits(hdc,            // Destination DC
00563                                   0,              // Destination X
00564                                   0,              // Destination Y
00565                                   D->Size_X,     // Destination (client area) width
00566                                   D->Size_Y,    // Destination (client area) height 
00567                                   0,              // Source X
00568                                   0,              // Source Y
00569                                   D->Size_X, // Source (back buffer) width
00570                                   D->Size_Y, // Source (back buffer) height
00571                                   D->DIBInfo.lpDIBBuffer,    // Pointer to source (back buffer)
00572                                   D->DIBInfo.pbmi,           // Bitmap info for back buffer
00573                                   DIB_RGB_COLORS, // Bitmap contains index values
00574                                   SRCCOPY);       // Do normal copy with stretching
00575 
00576         ReleaseDC(D->hWnd, hdc);
00577         return GE_TRUE;
00578 }
00579 
00580 
00581 //------------------------------------------------
00582 geBoolean DIBDisplay_Wipe       (       DIBDisplay   *D,
00583                                                                 uint32        color)
00584 {
00585         assert( DIBDisplay_IsValid(D) != GE_FALSE );
00586         if (!D->Locked)
00587                 {
00588                         //gegeErrorLog_AddString(Add(,"Display must be locked to clear",NULL);
00589                         return GE_FALSE;
00590                 }
00591 
00592         if (color==0)
00593                 memset(D->DIBInfo.lpDIBBuffer, color, D->Size_Y * D->Pitch);
00594         else
00595                 {
00596                         int i;
00597                         int16 *Ptr = (int16 *)D->DIBInfo.lpDIBBuffer;
00598                         int16 C    = (int16)color;
00599                         for (i=(D->Size_X * D->Size_Y); i>0; i--)
00600                                 {
00601                                         *(Ptr++) = C;
00602                                 }
00603                 }
00604                                                 
00605         return GE_TRUE;
00606 }
00607 
00608 
00609 
00610 //------------------------------------------------
00611 DIBDisplay *DIBDisplay_Create   (       HWND hWindow,
00612                                                                         int Width,
00613                                                                         int Height,
00614                                                                         int   display_bpp,
00615                                                                         uint32  Flags )
00616 {
00617         DIBDisplay *D;
00618         RECT    window_rect;
00619         BOOL    result;
00620         Flags;  Width;  Height; // avoid unused formal parameter warnings
00621 
00622         assert( display_bpp    > 0);
00623 
00624         D= malloc(sizeof(*D));
00625         if (D==NULL)
00626                 {
00627                         // errlogAdd("failed to allocate DIBDisplay object");
00628                         return NULL;
00629                 }
00630 
00631 
00632         result = GetClientRect(hWindow, &window_rect);
00633 
00634         if( !result )
00635                 {
00636                         //errlogAdd("failed to get client rect");
00637                         return NULL;
00638                 }
00639         assert ( window_rect.left  == 0 );
00640         assert ( window_rect.top == 0 );
00641         
00642         #pragma message ("getting size from window!")
00643         D->Size_X = ((window_rect.right  - window_rect.left)+3)&~3;
00644         D->Size_Y = (window_rect.bottom - window_rect.top);
00645 
00646         if ( D->Size_X <=0 )
00647                 {
00648                         //errlogAdd("bad window client width");
00649                         return NULL;
00650                 }
00651         if ( D->Size_Y <=0 )
00652                 {
00653                         //errlogAdd("bad widndow client height");
00654                         return NULL;
00655                 }
00656 
00657         D->Locked                               = GE_FALSE;   
00658         D->BitsPerPixel                 = display_bpp;
00659         D->Pitch                                = (D->BitsPerPixel / 8 ) * D->Size_X;
00660         D->hWnd                                 = hWindow;
00661 
00662         D->DIBInfo.pbmi                                 = NULL;
00663         D->DIBInfo.hDIB                                 = NULL;
00664         D->DIBInfo.lpDIBBuffer                  = NULL;
00665         
00666         if (DIBDisplay_CreateDIB(D->Size_X, D->Size_Y, display_bpp,
00667                                                                 hWindow,
00668                                                                 &(D->DIBInfo)) ==GE_FALSE)
00669                 {
00670                         // errlogAdd("failed to create Dib section")
00671                         DIBDisplay_Destroy(&D);
00672                         return NULL;
00673                 }
00674         
00675         return D;
00676 }
00677 
00678 
00679 //------------------------------------------------
00680 void DIBDisplay_Destroy(DIBDisplay **pD)
00681 {
00682         DIBDisplay *D;
00683 
00684         assert( *pD != NULL );
00685         assert( pD  != NULL );
00686 
00687         D = *pD;
00688 
00689         assert( DIBDisplay_IsValid(D) != GE_FALSE );
00690         
00691         DIBDisplay_DestroyDIB(&(D->DIBInfo));
00692         free( D );
00693 
00694         *pD = NULL;
00695 }
00696 
00697 
00698 
00699 //------------------------------------------------
00700 geBoolean DIBDisplay_Lock      (DIBDisplay *D,
00701                                                                 uint8       **ptr,
00702                                                                 int32       *pitch)
00703 {
00704         assert( DIBDisplay_IsValid(D) != GE_FALSE );
00705         assert( ptr    != NULL );
00706         assert( pitch  != NULL );
00707         assert( D->Locked == GE_FALSE );
00708 
00709         *ptr    = D->DIBInfo.lpDIBBuffer;
00710         *pitch  = D->Pitch;
00711 
00712         D->Locked = GE_TRUE;
00713         return GE_TRUE;
00714 }
00715 
00716 
00717 geBoolean DIBDisplay_Unlock        (DIBDisplay *D)
00718 {
00719         assert( DIBDisplay_IsValid(D) != GE_FALSE );
00720         assert( D->Locked == GE_TRUE );
00721         D->Locked = GE_FALSE;
00722         return GE_TRUE;
00723 }
00724 
00725 
00726 //------------------------------------------------
00727 geBoolean DIBDisplay_GetPixelFormat(    const DIBDisplay *D,
00728                                                                                 //int32 *pixel_pitch, 
00729                                                                                 int32 *bytes_per_pixel,
00730                                                                                 int32 *R_shift,
00731                                                                                 uint32 *R_mask,
00732                                                                                 int32 *R_width,
00733                                                                                 int32 *G_shift,
00734                                                                                 uint32 *G_mask,
00735                                                                                 int32 *G_width,
00736                                                                                 int32 *B_shift,
00737                                                                                 uint32 *B_mask,
00738                                                                                 int32 *B_width)
00739 {
00740         int32 red_shift=0;
00741         uint32 red_mask;
00742         int32 red_width=0;
00743         int32 grn_shift=0;
00744         uint32 grn_mask;
00745         int32 grn_width=0;
00746         int32 blu_shift=0;
00747         uint32 blu_mask;
00748         int32 blu_width=0;
00749         int32 i;
00750 
00751         assert( DIBDisplay_IsValid(D) != GE_FALSE );
00752 
00753         //assert( pixel_pitch     != NULL );
00754         assert( bytes_per_pixel != NULL );
00755         assert( R_shift         != NULL );
00756         assert( R_mask          != NULL );
00757         assert( R_width         != NULL );
00758         assert( G_shift         != NULL );
00759         assert( G_mask          != NULL );
00760         assert( G_width         != NULL );
00761         assert( B_shift         != NULL );
00762         assert( B_mask          != NULL );
00763         assert( B_width         != NULL );
00764         
00765 
00766 
00767         //*pixel_pitch     = (D->BitsPerPixel / 8);
00768         *bytes_per_pixel = (D->BitsPerPixel / 8);
00769                 
00770         red_mask = D->DIBInfo.DIB_R_bitmask;
00771         grn_mask = D->DIBInfo.DIB_G_bitmask;
00772         blu_mask = D->DIBInfo.DIB_B_bitmask;
00773         
00774         //
00775         // Derive shift, width values from masks
00776         //
00777 
00778         for (i=31; i >= 0; i--)
00779                 {
00780                         if (red_mask & (1 << i))
00781                                 {
00782                                         red_shift = i;
00783                                 }
00784 
00785                         if (grn_mask & (1 << i))
00786                                 {
00787                                         grn_shift = i;
00788                                 }
00789 
00790                         if (blu_mask & (1 << i))
00791                                 {
00792                                         blu_shift = i;
00793                                 }
00794                 }
00795 
00796         for (i=0; i <= 31; i++)
00797                 {
00798                         if (red_mask & (1 << i))
00799                                 {
00800                                         red_width = i - red_shift + 1;
00801                                 }
00802 
00803                         if (grn_mask & (1 << i))
00804                                 {
00805                                         grn_width = i - grn_shift + 1;
00806                                 }
00807 
00808                         if (blu_mask & (1 << i))
00809                                 {
00810                                         blu_width = i - blu_shift + 1;
00811                                 }
00812                 }
00813         //
00814         // Pass all requested values back to the caller
00815         //
00816 
00817         *R_shift = red_shift;
00818         *G_shift = grn_shift;
00819         *B_shift = blu_shift;
00820 
00821         *R_mask  = red_mask;
00822         *G_mask  = grn_mask;
00823         *B_mask  = blu_mask;
00824 
00825         *R_width = red_width;
00826         *G_width = grn_width;
00827         *B_width = blu_width;
00828                 
00829         return GE_TRUE;
00830 }
00831 
00832 
00833 
00834 

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