Exemple #1
0
HRESULT STDMETHODCALLTYPE SetPalette(LPDIRECTDRAWSURFACE7 surface, LPDIRECTDRAWPALETTE lpDDPalette)
{
    //logOutput << CurrentTimeString() << "Hooked SetPalette()" << endl;

    ddrawSurfaceSetPalette.Unhook();
    HRESULT hr = surface->SetPalette(lpDDPalette);
    ddrawSurfaceSetPalette.Rehook();

    if (getFrontSurface(surface))
    {
        if (lpDDPalette)
            lpDDPalette->AddRef();
        SetupPalette(lpDDPalette);
    }

    return hr;
}
int Game_Init(void *parms = NULL, int num_parms = 0)
{
// this is called once after the initial window is created and
// before the main event loop is entered, do all your initialization
// here

// seed random number generator
srand(GetTickCount());

// create IDirectDraw interface 7.0 object and test for error
if (FAILED(DirectDrawCreateEx(NULL, (void **)&lpdd, IID_IDirectDraw7, NULL)))
   return(0);

// set cooperation to full screen
if (FAILED(lpdd->SetCooperativeLevel(main_window_handle, 
                                      DDSCL_FULLSCREEN | DDSCL_ALLOWMODEX | 
                                      DDSCL_EXCLUSIVE | DDSCL_ALLOWREBOOT)))
   return(0);

// set display mode to 640x480x8
if (FAILED(lpdd->SetDisplayMode(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP,0,0)))
   return(0);


// clear ddsd and set size
DDRAW_INIT_STRUCT(ddsd); 

// enable valid fields
ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;

// set the backbuffer count field to 1, use 2 for triple buffering
ddsd.dwBackBufferCount = 1;

// request a complex, flippable
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_COMPLEX | DDSCAPS_FLIP;

// create the primary surface
if (FAILED(lpdd->CreateSurface(&ddsd, &lpddsprimary, NULL)))
   return(0);

// now query for attached surface from the primary surface

// this line is needed by the call
ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER;

// get the attached back buffer surface
if (FAILED(lpddsprimary->GetAttachedSurface(&ddsd.ddsCaps, &lpddsback)))
  return(0);


// build up the palette data array
for (int color=1; color < 255; color++)
    {
    // fill with random RGB values
    palette[color].peRed   = rand()%256;
    palette[color].peGreen = rand()%256;
    palette[color].peBlue  = rand()%256;

    // set flags field to PC_NOCOLLAPSE
    palette[color].peFlags = PC_NOCOLLAPSE;
    } // end for color

// now fill in entry 0 and 255 with black and white
palette[0].peRed     = 0;
palette[0].peGreen   = 0;
palette[0].peBlue    = 0;
palette[0].peFlags   = PC_NOCOLLAPSE;

palette[255].peRed   = 255;
palette[255].peGreen = 255;
palette[255].peBlue  = 255;
palette[255].peFlags = PC_NOCOLLAPSE;

// create the palette object
if (FAILED(lpdd->CreatePalette(DDPCAPS_8BIT | DDPCAPS_ALLOW256 | 
                                DDPCAPS_INITIALIZE, 
                                palette,&lpddpal, NULL)))
return(0);

// finally attach the palette to the primary surface
if (FAILED(lpddsprimary->SetPalette(lpddpal)))
   return(0);

// clear the surfaces out
DDraw_Fill_Surface(lpddsprimary, 0 );
DDraw_Fill_Surface(lpddsback, 0 );

// define points of asteroid
VERTEX2DF asteroid_vertices[8] = {33,-3, 9,-18, -12,-9, -21,-12, -9,6, -15,15, -3,27, 21,21};


// loop and initialize all asteroids
for (int curr_index = 0; curr_index < NUM_ASTEROIDS; curr_index++)
    {

    // initialize the asteroid
    asteroids[curr_index].state       = 1;   // turn it on
    asteroids[curr_index].num_verts   = 8;  
    asteroids[curr_index].x0          = rand()%SCREEN_WIDTH; // position it
    asteroids[curr_index].y0          = rand()%SCREEN_HEIGHT;
    asteroids[curr_index].xv          = -8 + rand()%17;
    asteroids[curr_index].yv          = -8 + rand()%17;
    asteroids[curr_index].color       = rand()%256;
    asteroids[curr_index].vlist       = new VERTEX2DF [asteroids[curr_index].num_verts];
 
   for (int index = 0; index < asteroids[curr_index].num_verts; index++)
        asteroids[curr_index].vlist[index] = asteroid_vertices[index];

   } // end for curr_index

// create sin/cos lookup table

// generate the tables
for (int ang = 0; ang < 360; ang++)
    {
    // convert ang to radians
    float theta = (float)ang*PI/(float)180;

    // insert next entry into table
    cos_look[ang] = cos(theta);
    sin_look[ang] = sin(theta);

    } // end for ang


// return success or failure or your own return code here
return(1);

} // end Game_Init
int Game_Init(void *parms = NULL, int num_parms = 0)
{
   // this is called once after the initial window is created and
   // before the main event loop is entered, do all your initialization
   // here
   
   // create IDirectDraw interface 7.0 object and test for error
   if (FAILED(DirectDrawCreateEx(NULL, (void **)&lpdd, IID_IDirectDraw7, NULL)))
      return(0);
   
   // set cooperation to full screen
   if (FAILED(lpdd->SetCooperativeLevel(main_window_handle, 
                                         DDSCL_FULLSCREEN | DDSCL_ALLOWMODEX | 
                                         DDSCL_EXCLUSIVE | DDSCL_ALLOWREBOOT)))
      return(0);
   
   // set display mode to 640x480x8
   if (FAILED(lpdd->SetDisplayMode(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP,0,0)))
      return(0);
   

   // clear ddsd and set size
   DDRAW_INIT_STRUCT(ddsd); 
   
   // enable valid fields
   ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
   
   // set the backbuffer count field to 1, use 2 for triple buffering
   ddsd.dwBackBufferCount = 1;
   
   // request a complex, flippable
   ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_COMPLEX | DDSCAPS_FLIP;
   
   // create the primary surface
   if (FAILED(lpdd->CreateSurface(&ddsd, &lpddsprimary, NULL)))
      return(0);
   
   // now query for attached surface from the primary surface
   
   // this line is needed by the call
   ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER;
   
   // get the attached back buffer surface
   if (FAILED(lpddsprimary->GetAttachedSurface(&ddsd.ddsCaps, &lpddsback)))
     return(0);
   
   // build up the palette data array
   for (int color=1; color < 255; color++)
   {
      // fill with random RGB values
      palette[color].peRed   = 0;
      palette[color].peGreen = 0;
      palette[color].peBlue  = color;
      
      // set flags field to PC_NOCOLLAPSE
      palette[color].peFlags = PC_NOCOLLAPSE;
   } // end for color

   // now fill in entry 0 and 255 with black and white
   palette[0].peRed     = 0;
   palette[0].peGreen   = 0;
   palette[0].peBlue    = 0;
   palette[0].peFlags   = PC_NOCOLLAPSE;
   
   palette[255].peRed   = 255;
   palette[255].peGreen = 255;
   palette[255].peBlue  = 255;
   palette[255].peFlags = PC_NOCOLLAPSE;
   
   // create the palette object
   if (FAILED(lpdd->CreatePalette(DDPCAPS_8BIT | DDPCAPS_ALLOW256 | 
                                   DDPCAPS_INITIALIZE, 
                                   palette,&lpddpal, NULL)))
   {
      return(0);
   }

   // finally attach the palette to the primary surface
   if (FAILED(lpddsprimary->SetPalette(lpddpal)))
      return(0);

   // return success or failure or your own return code here
   return(1);

} // end Game_Init
int Game_Init(void *parms = NULL, int num_parms = 0)
{
// this is called once after the initial window is created and
// before the main event loop is entered, do all your initialization
// here

// create IDirectDraw interface 7.0 object and test for error
if (FAILED(DirectDrawCreateEx(NULL, (void **)&lpdd, IID_IDirectDraw7, NULL)))
   return(0);

// set cooperation to full screen
if (FAILED(lpdd->SetCooperativeLevel(main_window_handle, 
                                      DDSCL_FULLSCREEN | DDSCL_ALLOWMODEX | 
                                      DDSCL_EXCLUSIVE | DDSCL_ALLOWREBOOT)))
   return(0);

// set display mode to 640x480x8
if (FAILED(lpdd->SetDisplayMode(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP,0,0)))
   return(0);

// we need a complex surface system with a primary and backbuffer

// clear ddsd and set size
DDRAW_INIT_STRUCT(ddsd); 

// enable valid fields
ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;

// set the backbuffer count field to 1, use 2 for triple buffering
ddsd.dwBackBufferCount = 1;

// request a complex, flippable
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_COMPLEX | DDSCAPS_FLIP;

// create the primary surface
if (FAILED(lpdd->CreateSurface(&ddsd, &lpddsprimary, NULL)))
   return(0);

// now query for attached surface from the primary surface

// this line is needed by the call
ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER;

// get the attached back buffer surface
if (FAILED(lpddsprimary->GetAttachedSurface(&ddsd.ddsCaps, &lpddsback)))
  return(0);

// build up the palette data array
for (int color=1; color < 255; color++)
    {
    // fill with random RGB values
    palette[color].peRed   = rand()%256;
    palette[color].peGreen = rand()%256;
    palette[color].peBlue  = rand()%256;

    // set flags field to PC_NOCOLLAPSE
    palette[color].peFlags = PC_NOCOLLAPSE;
    } // end for color

// now fill in entry 0 and 255 with black and white
palette[0].peRed     = 0;
palette[0].peGreen   = 0;
palette[0].peBlue    = 0;
palette[0].peFlags   = PC_NOCOLLAPSE;

palette[255].peRed   = 255;
palette[255].peGreen = 255;
palette[255].peBlue  = 255;
palette[255].peFlags = PC_NOCOLLAPSE;

// create the palette object
if (FAILED(lpdd->CreatePalette(DDPCAPS_8BIT | DDPCAPS_ALLOW256 | 
                                DDPCAPS_INITIALIZE, 
                                palette,&lpddpal, NULL)))
return(0);

// finally attach the palette to the primary surface
if (FAILED(lpddsprimary->SetPalette(lpddpal)))
   return(0);

// set clipper up on back buffer since that's where well clip
RECT screen_rect= {0,0,SCREEN_WIDTH-1,SCREEN_HEIGHT-1};
lpddclipper = DDraw_Attach_Clipper(lpddsback,1,&screen_rect);

// load the 8-bit image
if (!Load_Bitmap_File(&bitmap,"alley8.bmp"))
   return(0);

// load it's palette into directdraw
if (FAILED(lpddpal->SetEntries(0,0,MAX_COLORS_PALETTE,bitmap.palette)))
   return(0);

// clean the surfaces
DDraw_Fill_Surface(lpddsprimary,0);
DDraw_Fill_Surface(lpddsback,0);

// create the buffer to hold the background
lpddsbackground = DDraw_Create_Surface(640,480,0,-1);

// copy the background bitmap image to the background surface 

// lock the surface
lpddsbackground->Lock(NULL,&ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT,NULL);

// get video pointer to primary surfce
UCHAR *image_buffer = (UCHAR *)ddsd.lpSurface;       

// test if memory is linear
if (ddsd.lPitch == SCREEN_WIDTH)
   {
   // copy memory from double buffer to primary buffer
   memcpy((void *)image_buffer, (void *)bitmap.buffer, SCREEN_WIDTH*SCREEN_HEIGHT);
   } // end if
else
   { // non-linear

   // make copy of source and destination addresses
   UCHAR *dest_ptr = image_buffer;
   UCHAR *src_ptr  = bitmap.buffer;

   // memory is non-linear, copy line by line
   for (int y=0; y < SCREEN_HEIGHT; y++)
       {
       // copy line
       memcpy((void *)dest_ptr, (void *)src_ptr, SCREEN_WIDTH);

       // advance pointers to next line
       dest_ptr+=ddsd.lPitch;
       src_ptr +=SCREEN_WIDTH;
       } // end for

   } // end else

// now unlock the primary surface
if (FAILED(lpddsbackground->Unlock(NULL)))
   return(0);

// unload the bitmap file, we no longer need it
Unload_Bitmap_File(&bitmap);

// seed random number generator
srand(GetTickCount());

// initialize all the aliens (in real life do this in a loop or function)

// alien on level 1 of complex

aliens[0].x              = rand()%SCREEN_WIDTH;
aliens[0].y              = 116 - 72;                  
aliens[0].velocity       = 2+rand()%4;
aliens[0].current_frame  = 0;             
aliens[0].counter        = 0;       
aliens[0].width          = 72; // set real size
aliens[0].height         = 80;
aliens[0].scale          = ((float)(1+rand()%20))/10; // scale from 0.1 to 2.0
// fix up feet so they still contact floor
aliens[0].y+=(72 - aliens[0].scale*72);

// alien on level 2 of complex

aliens[1].x              = rand()%SCREEN_WIDTH;
aliens[1].y              = 246 - 72;                  
aliens[1].velocity       = 2+rand()%4;
aliens[1].current_frame  = 0;             
aliens[1].counter        = 0;  
aliens[1].width          = 72; // set real size
aliens[1].height         = 80;
aliens[1].scale          = ((float)(1+rand()%20))/10; // scale from 0.1 to 2.0
// fix up feet so they still contact floor
aliens[1].y+=(72 - aliens[1].scale*72);



// alien on level 3 of complex

aliens[2].x              = rand()%SCREEN_WIDTH;
aliens[2].y              = 382 - 72;                  
aliens[2].velocity       = 2+rand()%4;
aliens[2].current_frame  = 0;             
aliens[2].counter        = 0;  
aliens[2].width          = 72; // set real size
aliens[2].height         = 80;
aliens[2].scale          = ((float)(1+rand()%20))/10; // scale from 0.1 to 2.0

// fix up feet so they still contact floor
aliens[2].y+=(72 - aliens[2].scale*72);


// now load the bitmap containing the alien imagery
// then scan the images out into the surfaces of alien[0]
// and copy then into the other two, be careful of reference counts!

// load the 8-bit image
if (!Load_Bitmap_File(&bitmap,"dedsp0.bmp"))
   return(0);

// create each surface and load bits
for (int index = 0; index < 3; index++)
    {
    // create surface to hold image
    aliens[0].frames[index] = DDraw_Create_Surface(72,80,0);

    // now load bits...
    Scan_Image_Bitmap(&bitmap,                 // bitmap file to scan image data from
                      aliens[0].frames[index], // surface to hold data
                      index, 0);               // cell to scan image from    

    } // end for index

// unload the bitmap file, we no longer need it
Unload_Bitmap_File(&bitmap);

// now for the tricky part. There is no need to create more surfaces with the same
// data, so I'm going to copy the surface pointers member for member to each alien
// however, be careful, since the reference counts do NOT go up, you still only need
// to release() each surface once!

for (index = 0; index < 3; index++)
    aliens[1].frames[index] = aliens[2].frames[index] = aliens[0].frames[index];

// return success or failure or your own return code here
return(1);

} // end Game_Init
int DD_Init(int width, int height, int bpp)
{
// this function initializes directdraw
int index; // looping variable

// create object and test for error
if (DirectDrawCreateEx(NULL, (void **)&lpdd, IID_IDirectDraw7, NULL)!=DD_OK)
   return(0);

// set cooperation level to windowed mode normal
if (lpdd->SetCooperativeLevel(main_window_handle,
           DDSCL_ALLOWMODEX | DDSCL_FULLSCREEN | 
           DDSCL_EXCLUSIVE | DDSCL_ALLOWREBOOT)!=DD_OK)
    return(0);

// set the display mode
if (lpdd->SetDisplayMode(width,height,bpp,0,0)!=DD_OK)
   return(0);

// set globals
screen_height = height;
screen_width  = width;
screen_bpp    = bpp;

// Create the primary surface
memset(&ddsd,0,sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;

// we need to let dd know that we want a complex 
// flippable surface structure, set flags for that
ddsd.ddsCaps.dwCaps = 
  DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP | DDSCAPS_COMPLEX;

// set the backbuffer count to 1
ddsd.dwBackBufferCount = 1;

// create the primary surface
lpdd->CreateSurface(&ddsd,&lpddsprimary,NULL);

// query for the backbuffer i.e the secondary surface
ddscaps.dwCaps = DDSCAPS_BACKBUFFER;
lpddsprimary->GetAttachedSurface(&ddscaps,&lpddsback);

// create and attach palette

// create palette data
// clear all entries defensive programming
memset(palette,0,256*sizeof(PALETTEENTRY));

// create a R,G,B,GR gradient palette
for (index=0; index < 256; index++)
    {
    // set each entry
    if (index < 64) 
        palette[index].peRed = index*4; 
    else           // shades of green
    if (index >= 64 && index < 128) 
        palette[index].peGreen = (index-64)*4;
    else           // shades of blue
    if (index >= 128 && index < 192) 
       palette[index].peBlue = (index-128)*4;
    else           // shades of grey
    if (index >= 192 && index < 256) 
        palette[index].peRed = palette[index].peGreen = 
        palette[index].peBlue = (index-192)*4;
    
    // set flags
    palette[index].peFlags = PC_NOCOLLAPSE;
    } // end for index

// now create the palette object
if (lpdd->CreatePalette(DDPCAPS_8BIT | DDPCAPS_INITIALIZE | DDPCAPS_ALLOW256,
                         palette,&lpddpal,NULL)!=DD_OK)
   return(0);

// attach the palette to the primary
if (lpddsprimary->SetPalette(lpddpal)!=DD_OK)
   return(0);

// clear out both primary and secondary surfaces
DD_Fill_Surface(lpddsprimary,0);
DD_Fill_Surface(lpddsback,0);

// attach a clipper to the screen
RECT screen_rect = {0,0,screen_width,screen_height};
lpddclipper = DD_Attach_Clipper(lpddsback,1,&screen_rect);

// return success
return(1);
} // end DD_Init
Exemple #6
0
HRESULT CTextureHolder::CopyBitmapToSurface(){

    // Get a DDraw object to create a temporary surface
    LPDIRECTDRAW7 pDD;
    m_pddsSurface->GetDDInterface( (VOID**)&pDD );

    // Get the bitmap structure (to extract width, height, and bpp)
    BITMAP bm;
    GetObject( m_hbmBitmap, sizeof(BITMAP), &bm );

    // Setup the new surface desc
    DDSURFACEDESC2 ddsd;
    ddsd.dwSize = sizeof(ddsd);
    m_pddsSurface->GetSurfaceDesc( &ddsd );
    ddsd.dwFlags          = DDSD_CAPS|DDSD_HEIGHT|DDSD_WIDTH|DDSD_PIXELFORMAT|
                            DDSD_TEXTURESTAGE;
    ddsd.ddsCaps.dwCaps   = DDSCAPS_TEXTURE|DDSCAPS_SYSTEMMEMORY;
    ddsd.ddsCaps.dwCaps2  = 0L;
    ddsd.dwWidth          = bm.bmWidth;
    ddsd.dwHeight         = bm.bmHeight;

    // Create a new surface for the texture
    LPDIRECTDRAWSURFACE7 pddsTempSurface;
    HRESULT hr;
    if( FAILED( hr = pDD->CreateSurface( &ddsd, &pddsTempSurface, NULL ) ) )
    {
        pDD->Release();
        return hr;
    }

    // Get a DC for the bitmap
    HDC hdcBitmap = CreateCompatibleDC( NULL );
    if( NULL == hdcBitmap )
    {
        pddsTempSurface->Release();
        pDD->Release();
        return hr; // bug? return E_FAIL?
    }
    SelectObject( hdcBitmap, m_hbmBitmap );

    // Handle palettized textures. Need to attach a palette
    if( ddsd.ddpfPixelFormat.dwRGBBitCount == 8 )
    {
        LPDIRECTDRAWPALETTE  pPalette;
        DWORD dwPaletteFlags = DDPCAPS_8BIT|DDPCAPS_ALLOW256;
        DWORD pe[256];
        WORD  wNumColors     = GetDIBColorTable( hdcBitmap, 0, 256, (RGBQUAD*)pe );

        // Create the color table
        for( WORD i=0; i<wNumColors; i++ )
        {
            pe[i] = RGB( GetBValue(pe[i]), GetGValue(pe[i]), GetRValue(pe[i]) );

            // Handle textures with transparent pixels
            if( m_dwFlags & (D3DTEXTR_TRANSPARENTWHITE|D3DTEXTR_TRANSPARENTBLACK) )
            {
                // Set alpha for opaque pixels
                if( m_dwFlags & D3DTEXTR_TRANSPARENTBLACK )
                {
                    if( pe[i] != 0x00000000 )
                        pe[i] |= 0xff000000;
                }
                else if( m_dwFlags & D3DTEXTR_TRANSPARENTWHITE )
                {
                    if( pe[i] != 0x00ffffff )
                        pe[i] |= 0xff000000;
                }
            }
        }
        // Add DDPCAPS_ALPHA flag for textures with transparent pixels
        if( m_dwFlags & (D3DTEXTR_TRANSPARENTWHITE|D3DTEXTR_TRANSPARENTBLACK) )
            dwPaletteFlags |= DDPCAPS_ALPHA;

        // Create & attach a palette
        pDD->CreatePalette( dwPaletteFlags, (PALETTEENTRY*)pe, &pPalette, NULL );
        pddsTempSurface->SetPalette( pPalette );
        m_pddsSurface->SetPalette( pPalette );
        SAFE_RELEASE( pPalette );
    }

    // Copy the bitmap image to the surface.
    HDC hdcSurface;
    if( SUCCEEDED( pddsTempSurface->GetDC( &hdcSurface ) ) )
    {
        BitBlt( hdcSurface, 0, 0, bm.bmWidth, bm.bmHeight, hdcBitmap, 0, 0,
                SRCCOPY );
        pddsTempSurface->ReleaseDC( hdcSurface );
    }
    DeleteDC( hdcBitmap );

    // Copy the temp surface to the real texture surface
    m_pddsSurface->Blt( NULL, pddsTempSurface, NULL, DDBLT_WAIT, NULL );

    // Done with the temp surface
    pddsTempSurface->Release();

    // For textures with real alpha (not palettized), set transparent bits
    if( ddsd.ddpfPixelFormat.dwRGBAlphaBitMask )
    {
        if( m_dwFlags & (D3DTEXTR_TRANSPARENTWHITE|D3DTEXTR_TRANSPARENTBLACK) )
        {
            // Lock the texture surface
            DDSURFACEDESC2 ddsd;
            ddsd.dwSize = sizeof(ddsd);
            while( m_pddsSurface->Lock( NULL, &ddsd, 0, NULL ) ==
                   DDERR_WASSTILLDRAWING );

            DWORD dwAlphaMask = ddsd.ddpfPixelFormat.dwRGBAlphaBitMask;
            DWORD dwRGBMask   = ( ddsd.ddpfPixelFormat.dwRBitMask |
                                  ddsd.ddpfPixelFormat.dwGBitMask |
                                  ddsd.ddpfPixelFormat.dwBBitMask );
            DWORD dwColorkey  = 0x00000000; // Colorkey on black
            if( m_dwFlags & D3DTEXTR_TRANSPARENTWHITE )
                dwColorkey = dwRGBMask;     // Colorkey on white

            // Add an opaque alpha value to each non-colorkeyed pixel
            for( DWORD y=0; y<ddsd.dwHeight; y++ )
            {
                WORD*  p16 =  (WORD*)((BYTE*)ddsd.lpSurface + y*ddsd.lPitch);
                DWORD* p32 = (DWORD*)((BYTE*)ddsd.lpSurface + y*ddsd.lPitch);

                for( DWORD x=0; x<ddsd.dwWidth; x++ )
                {
                    if( ddsd.ddpfPixelFormat.dwRGBBitCount == 16 )
                    {
                        if( ( *p16 &= dwRGBMask ) != dwColorkey )
                            *p16 |= dwAlphaMask;
                        p16++;
                    }
                    if( ddsd.ddpfPixelFormat.dwRGBBitCount == 32 )
                    {
                        if( ( *p32 &= dwRGBMask ) != dwColorkey )
                            *p32 |= dwAlphaMask;
                        p32++;
                    }
                }
            }
            m_pddsSurface->Unlock( NULL );
        }
				else if( m_bHasMyAlpha ){
					
					DDSURFACEDESC2 ddsd;
					ddsd.dwSize = sizeof(ddsd);
					while( m_pddsSurface->Lock( NULL, &ddsd, 0, NULL ) ==
						DDERR_WASSTILLDRAWING );
					
					DWORD dwRGBMask   = ( ddsd.ddpfPixelFormat.dwRBitMask |
						ddsd.ddpfPixelFormat.dwGBitMask |
						ddsd.ddpfPixelFormat.dwBBitMask );

					DWORD rMask = ddsd.ddpfPixelFormat.dwRBitMask;
					DWORD gMask = ddsd.ddpfPixelFormat.dwGBitMask;
					DWORD bMask = ddsd.ddpfPixelFormat.dwBBitMask;
					DWORD aMask = ddsd.ddpfPixelFormat.dwRGBAlphaBitMask;

					DWORD rShift = GetShift( rMask );
					DWORD gShift = GetShift( gMask );
					DWORD bShift = GetShift( bMask );
					DWORD aShift = GetShift( aMask );

					DWORD maxRVal = rMask >> rShift;
					DWORD maxGVal = gMask >> gShift;
					DWORD maxBVal = bMask >> bShift;
					DWORD maxAVal = aMask >> aShift;

					DWORD rVal, gVal, bVal, aVal;
					FLOAT min, max;
					
					// Add an opaque alpha value to each non-colorkeyed pixel
					for( DWORD y=0; y<ddsd.dwHeight; y++ ){

						WORD*  p16 =  (WORD*)((BYTE*)ddsd.lpSurface + y*ddsd.lPitch);
						DWORD* p32 = (DWORD*)((BYTE*)ddsd.lpSurface + y*ddsd.lPitch);
						
						for( DWORD x=0; x<ddsd.dwWidth; x++ ){

							if( ddsd.ddpfPixelFormat.dwRGBBitCount == 32 ){
								
								*p32 &= dwRGBMask; // set alpha to zero

								if( *p32 == 0 ){} // black is 100% transparent, so leave alpha at 0%

								else if( *p32 == dwRGBMask ){ // white is opaque, so set alpha to 100%
									*p32 |= aMask;
								}

								else{ // set alpha to equal intensity of brightest hue

									rVal = ( *p32 & rMask ) >> rShift;
									gVal = ( *p32 & gMask ) >> gShift;
									bVal = ( *p32 & bMask ) >> bShift;

									max = max( (FLOAT)rVal / maxRVal, max( (FLOAT)gVal / maxGVal, (FLOAT)bVal / maxBVal ) );
//									min = min( (FLOAT)rVal / maxRVal, min( (FLOAT)gVal / maxGVal, (FLOAT)bVal / maxBVal ) );
									
									aVal = max * 255;

									//if( rVal == gVal && gVal == bVal ){ // white fading to black
									//	*p32 = dwRGBMask; // set color to white
									//}

									// maximize luminosity and saturation
									rVal /= max;
									gVal /= max;
									bVal /= max;

									*p32 = ( aVal << aShift ) | ( rVal << rShift ) | ( gVal << gShift ) | ( bVal << bShift );
								}
								p32++;
							}
							else if( ddsd.ddpfPixelFormat.dwRGBBitCount == 16 ){
								
								*p16 &= dwRGBMask; // set alpha to zero

								if( *p16 == 0 ){} // black is 100% transparent, so leave alpha at 0%

								else if( *p16 == dwRGBMask ){ // white is opaque, so set alpha to 100%
									*p16 |= aMask;
								}

								else{ // set alpha to equal intensity of brightest hue

									rVal = ( *p16 & rMask ) >> rShift;
									gVal = ( *p16 & gMask ) >> gShift;
									bVal = ( *p16 & bMask ) >> bShift;

									aVal = STATSTEXTURE_ALPHA * max( (FLOAT)rVal / maxRVal, max( (FLOAT)gVal / maxGVal, (FLOAT)bVal / maxBVal ) );

									if( aVal < STATSTEXTURE_ALPHA ){ // semi-tranparent white
										*p16 = dwRGBMask;
									}

									*p16 |= aVal << aShift;
								}
								p16++;
							}

						}
					}