CnC_Red_Alert/LAUNCHER/256BMP.C

213 lines
5.1 KiB
C

/*
** Command & Conquer Red Alert(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <windows.h>
#include <windowsx.h>
#include <alloc.h>
DWORD GetDibInfoHeaderSize (BYTE huge *);
WORD GetDibWidth (BYTE huge *);
WORD GetDibHeight (BYTE huge *);
BYTE huge * GetDibBitsAddr (BYTE huge *);
BYTE huge * ReadDib(char *);
//-------------------------------------------------------------//
DWORD GetDibInfoHeaderSize (BYTE huge * lpDib)
{
return ((BITMAPINFOHEADER huge *) lpDib)->biSize ;
}
WORD GetDibWidth (BYTE huge * lpDib)
{
if (GetDibInfoHeaderSize (lpDib) == sizeof (BITMAPCOREHEADER))
return (WORD) (((BITMAPCOREHEADER huge *) lpDib)->bcWidth) ;
else
return (WORD) (((BITMAPINFOHEADER huge *) lpDib)->biWidth) ;
}
WORD GetDibHeight (BYTE huge * lpDib)
{
if (GetDibInfoHeaderSize (lpDib) == sizeof (BITMAPCOREHEADER))
return (WORD) (((BITMAPCOREHEADER huge *) lpDib)->bcHeight) ;
else
return (WORD) (((BITMAPINFOHEADER huge *) lpDib)->biHeight) ;
}
BYTE huge * GetDibBitsAddr (BYTE huge * lpDib)
{
DWORD dwNumColors, dwColorTableSize ;
WORD wBitCount ;
if (GetDibInfoHeaderSize (lpDib) == sizeof (BITMAPCOREHEADER))
{
wBitCount = ((BITMAPCOREHEADER huge *) lpDib)->bcBitCount ;
if (wBitCount != 24)
dwNumColors = 1L << wBitCount ;
else
dwNumColors = 0 ;
dwColorTableSize = dwNumColors * sizeof (RGBTRIPLE) ;
}
else
{
wBitCount = ((BITMAPINFOHEADER huge *) lpDib)->biBitCount ;
if (GetDibInfoHeaderSize (lpDib) >= 36)
dwNumColors = ((BITMAPINFOHEADER huge *) lpDib)->biClrUsed ;
else
dwNumColors = 0 ;
if (dwNumColors == 0)
{
if (wBitCount != 24)
dwNumColors = 1L << wBitCount ;
else
dwNumColors = 0 ;
}
dwColorTableSize = dwNumColors * sizeof (RGBQUAD) ;
}
return lpDib + GetDibInfoHeaderSize (lpDib) + dwColorTableSize ;
}
// Read a DIB from a file into memory
BYTE huge * ReadDib (char * szFileName)
{
BITMAPFILEHEADER bmfh ;
BYTE huge * lpDib ;
DWORD dwDibSize, dwOffset, dwHeaderSize ;
int hFile ;
WORD wDibRead ;
if (-1 == (hFile = _lopen (szFileName, OF_READ | OF_SHARE_DENY_WRITE)))
return NULL ;
if (_lread (hFile, (LPSTR) &bmfh, sizeof (BITMAPFILEHEADER)) !=
sizeof (BITMAPFILEHEADER))
{
_lclose (hFile) ;
return NULL ;
}
if (bmfh.bfType != * (WORD *) "BM")
{
_lclose (hFile) ;
return NULL ;
}
dwDibSize = bmfh.bfSize - sizeof (BITMAPFILEHEADER) ;
lpDib = (BYTE huge * ) GlobalAllocPtr (GMEM_MOVEABLE, dwDibSize) ;
if (lpDib == NULL)
{
_lclose (hFile) ;
return NULL ;
}
dwOffset = 0 ;
while (dwDibSize > 0)
{
wDibRead = (WORD) min (32768ul, dwDibSize) ;
if (wDibRead != _lread (hFile, (LPSTR) (lpDib + dwOffset), wDibRead))
{
_lclose (hFile) ;
return NULL ;
}
dwDibSize -= wDibRead ;
dwOffset += wDibRead ;
}
_lclose (hFile) ;
dwHeaderSize = GetDibInfoHeaderSize (lpDib) ;
if (dwHeaderSize < 12 || (dwHeaderSize > 12 && dwHeaderSize < 16))
return NULL ;
return lpDib ;
}
long FAR PASCAL _export MainWndProc(HWND hWnd,UINT message,UINT wParam,LONG lParam)
{
PAINTSTRUCT ps;
HDC hdc;
RECT rect;
unsigned char r,g,b,x;
FILE *fi;
int i;
static BYTE huge *lpDib;
static BYTE huge *lpDibBits;
static int cxDib, cyDib;
static LPLOGPALETTE LogPal;
static HPALETTE hLogPal;
switch(message)
{
case WM_CREATE:
fi=fopen("somefile.bmp","r");
if(fi==NULL)
return 0;
LogPal=(LPLOGPALETTE)farmalloc(sizeof(LOGPALETTE)+sizeof(PALETTEENTRY)*256);
LogPal->palVersion=0x300;
LogPal->palNumEntries=256;
fseek(fi,54L,0);
for(i=0;i<256;i++)
{
fscanf(fi,"%c%c%c%c",&b,&g,&r,&x);
LogPal->palPalEntry[i].peRed=r;
LogPal->palPalEntry[i].peGreen=g;
LogPal->palPalEntry[i].peBlue=b;
LogPal->palPalEntry[i].peFlags=x;
}
fclose(fi);
hLogPal=CreatePalette(LogPal);
return 0;
case WM_PAINT:
hdc=BeginPaint(hWnd,&ps);
GetClientRect(hWnd,&rect);
SelectPalette(hdc,hLogPal,0);
RealizePalette(hdc);
SetStretchBltMode(hdc,COLORONCOLOR);
lpDib=ReadDib(bmp_fname);
lpDibBits=GetDibBitsAddr(lpDib);
cxDib=GetDibWidth(lpDib);
cyDib=GetDibHeight(lpDib);
StretchDIBits(hdc,0,0,rect.right,rect.bottom,0,0,cxDib,cyDib,(LPSTR)lpDibBits,
(LPBITMAPINFO)lpDib,DIB_RGB_COLORS,SRCCOPY);
EndPaint(hWnd,&ps);
break;
case WM_DESTROY:
farfree(LogPal);
DeleteObject(hLogPal);
PostQuitMessage(0);
break;
default:
return (DefWindowProc(hWnd,message,wParam,lParam));
}
return (DefWindowProc(hWnd,message,wParam,lParam));
}