BMP8.CPP 6.1 KB

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