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
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++; } } }