/* ** 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 . */ #include #include #include 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)); }