CnC_Remastered_Collection

Command and Conquer: Red Alert
Log | Files | Refs | README | LICENSE

BMP8.CPP (6278B)


      1 //
      2 // Copyright 2020 Electronic Arts Inc.
      3 //
      4 // TiberianDawn.DLL and RedAlert.dll and corresponding source code is free 
      5 // software: you can redistribute it and/or modify it under the terms of 
      6 // the GNU General Public License as published by the Free Software Foundation, 
      7 // either version 3 of the License, or (at your option) any later version.
      8 
      9 // TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed 
     10 // in the hope that it will be useful, but with permitted additional restrictions 
     11 // under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT 
     12 // distributed with this program. You should have received a copy of the 
     13 // GNU General Public License along with permitted additional restrictions 
     14 // with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection
     15 
     16 
     17 #include "bmp8.h"
     18 
     19 //***********************************************************************************************
     20 BMP8::~BMP8()
     21 {
     22 	// free resources
     23 	if( hBitmap )
     24 		::DeleteObject( hBitmap );
     25 	if( hPal )
     26 		::DeleteObject( hPal );
     27 }
     28 
     29 //***********************************************************************************************
     30 bool BMP8::Init( const char* szFile, HWND hWnd )
     31 {
     32   int                  i;
     33   char                 string[128];
     34   DWORD                dwRead;
     35   BITMAPFILEHEADER     bitmapHeader;
     36   BITMAPINFOHEADER     bitmapInfoHeader;
     37   LPLOGPALETTE         lpLogPalette;
     38   char                *palData;
     39   HGLOBAL              hmem2;
     40   LPVOID               lpvBits;
     41   PAINTSTRUCT          ps;
     42   HDC                  hdc;
     43   HPALETTE             select;
     44   UINT                 realize;
     45   RECT                 rect;
     46 
     47 
     48 	//	Remember window handle for use later.
     49 	this->hWnd = hWnd;
     50 
     51 	//	Retrieve a handle identifying the file. 
     52 	HANDLE hFile = ::CreateFile(
     53 		szFile,
     54 		GENERIC_READ,
     55 		FILE_SHARE_READ,
     56 		(LPSECURITY_ATTRIBUTES)NULL,
     57 		OPEN_EXISTING,
     58 		FILE_ATTRIBUTE_READONLY,
     59 		(HANDLE)NULL );
     60 
     61 	if(	!hFile )
     62 		return false;
     63 
     64 	// Retrieve the BITMAPFILEHEADER structure. 
     65 	::ReadFile( hFile, &bitmapHeader, sizeof(BITMAPFILEHEADER), &dwRead, (LPOVERLAPPED)NULL );
     66 
     67 	// Retrieve the BITMAPFILEHEADER structure. 
     68 	::ReadFile( hFile, &bitmapInfoHeader, sizeof(BITMAPINFOHEADER), &dwRead, (LPOVERLAPPED)NULL );
     69  
     70 	// Allocate memory for the BITMAPINFO structure. 
     71 	HGLOBAL infoHeaderMem = ::GlobalAlloc( GHND, sizeof(BITMAPINFOHEADER) + ((1<<bitmapInfoHeader.biBitCount) * sizeof(RGBQUAD)) );
     72  
     73 	LPBITMAPINFO lpHeaderMem = (LPBITMAPINFO)::GlobalLock( infoHeaderMem ); 
     74  
     75 	// Load BITMAPINFOHEADER into the BITMAPINFO structure. 
     76 	lpHeaderMem->bmiHeader.biSize          = bitmapInfoHeader.biSize; 
     77 	lpHeaderMem->bmiHeader.biWidth         = bitmapInfoHeader.biWidth; 
     78 	lpHeaderMem->bmiHeader.biHeight        = bitmapInfoHeader.biHeight; 
     79 	lpHeaderMem->bmiHeader.biPlanes        = bitmapInfoHeader.biPlanes; 
     80 	lpHeaderMem->bmiHeader.biBitCount      = bitmapInfoHeader.biBitCount; 
     81 	lpHeaderMem->bmiHeader.biCompression   = bitmapInfoHeader.biCompression; 
     82 	lpHeaderMem->bmiHeader.biSizeImage     = bitmapInfoHeader.biSizeImage; 
     83 	lpHeaderMem->bmiHeader.biXPelsPerMeter = bitmapInfoHeader.biXPelsPerMeter; 
     84 	lpHeaderMem->bmiHeader.biYPelsPerMeter = bitmapInfoHeader.biYPelsPerMeter; 
     85 	lpHeaderMem->bmiHeader.biClrUsed       = bitmapInfoHeader.biClrUsed; 
     86 	lpHeaderMem->bmiHeader.biClrImportant  = bitmapInfoHeader.biClrImportant; 
     87 
     88 	// Retrieve the color table. 
     89 	// 1 << bitmapInfoHeader.biBitCount == 2 ^ bitmapInfoHeader.biBitCount 
     90 	::ReadFile( hFile, lpHeaderMem->bmiColors, ((1<<bitmapInfoHeader.biBitCount) * sizeof(RGBQUAD)),
     91 				&dwRead, (LPOVERLAPPED)NULL );
     92 
     93 
     94 	lpLogPalette = (LPLOGPALETTE)new char[ (sizeof(LOGPALETTE) + sizeof(PALETTEENTRY)*256) ];
     95 	lpLogPalette->palVersion=0x300;
     96 	lpLogPalette->palNumEntries=256;
     97 
     98 	palData = (char*)lpHeaderMem->bmiColors;
     99 
    100 	for( i = 0; i < 256; i++ )
    101 	{
    102 		lpLogPalette->palPalEntry[i].peRed = *palData++;
    103 		lpLogPalette->palPalEntry[i].peGreen = *palData++;
    104 		lpLogPalette->palPalEntry[i].peBlue = *palData++;
    105 		lpLogPalette->palPalEntry[i].peFlags = *palData++;
    106 	}
    107 	hPal = ::CreatePalette( lpLogPalette );
    108 	delete [] lpLogPalette;
    109 
    110 	// Allocate memory for the required number of bytes. 
    111 	hmem2 = ::GlobalAlloc( GHND, (bitmapHeader.bfSize - bitmapHeader.bfOffBits) );
    112  
    113 	lpvBits = ::GlobalLock( hmem2 );
    114  
    115 	// Retrieve the bitmap data. 
    116 	::ReadFile( hFile, lpvBits, (bitmapHeader.bfSize - bitmapHeader.bfOffBits), &dwRead, (LPOVERLAPPED)NULL );
    117  
    118 	// Create a bitmap from the data stored in the .BMP file. 
    119 	hdc = ::GetDC( hWnd );
    120 	select = ::SelectPalette( hdc, hPal, 0 );
    121 	if( !select )
    122 		return false;
    123 	realize = ::RealizePalette( hdc );
    124 	if( realize == GDI_ERROR )
    125 		return false;
    126 
    127 	hBMP = ::CreateDIBitmap( hdc, &bitmapInfoHeader, CBM_INIT, lpvBits, lpHeaderMem, DIB_RGB_COLORS );
    128 	::ReleaseDC( hWnd, hdc );
    129 
    130 	// Unlock the global memory objects and close the .BMP file.  
    131 	::GlobalUnlock( infoHeaderMem );
    132 	::GlobalUnlock( hmem2 );
    133 	::CloseHandle( hFile );
    134  
    135 	if( !hBMP )
    136 		return false;
    137  
    138 	return true;
    139 }
    140 
    141 
    142 bit8 BMP8::drawBmp(void)
    143 {
    144   // Paint the window (and draw the bitmap). 
    145  
    146   PAINTSTRUCT ps;
    147   HDC         hdc;
    148   char        string[128];
    149 
    150   InvalidateRect(WindowHandle_,NULL,FALSE); // keep windows from screwing up the
    151                                            //  redrawing (as much).
    152   hdc=BeginPaint(WindowHandle_,&ps);
    153 
    154   //Do palette stuff
    155   HPALETTE select=SelectPalette(ps.hdc,PalHandle_,0);
    156   if (select==NULL)
    157   {
    158     sprintf(string,"Select Pal Fail: %d",GetLastError());
    159     MessageBox(NULL,string,"OK",MB_OK);
    160   }
    161   UINT realize=RealizePalette(ps.hdc);
    162   if (realize==GDI_ERROR)
    163   {
    164     sprintf(string,"Realize Pal Fail: %d",GetLastError());
    165     MessageBox(NULL,string,"OK",MB_OK);
    166   }
    167 
    168   HDC hdcMem = CreateCompatibleDC(ps.hdc); 
    169   SelectObject(hdcMem, BitmapHandle_); 
    170   BITMAP bm;
    171   GetObject(BitmapHandle_, sizeof(BITMAP), (LPSTR) &bm);
    172   
    173   /// for non-stretching version
    174   ///////BitBlt(ps.hdc, 0, 0, bm.bmWidth, bm.bmHeight, hdcMem, 0, 0, SRCCOPY); 
    175 
    176   RECT clientRect;
    177   GetClientRect(WindowHandle_,&clientRect);
    178   SetStretchBltMode(ps.hdc,COLORONCOLOR);
    179   StretchBlt(ps.hdc,0,0,clientRect.right,clientRect.bottom,hdcMem,0,0,bm.bmWidth,
    180     bm.bmHeight,SRCCOPY);
    181 
    182 
    183   DeleteDC(hdcMem); 
    184   EndPaint(WindowHandle_,&ps);
    185   return(TRUE);
    186 }