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 }