windows-nt/Source/XPSP1/NT/shell/osshell/games/sol/back.c

543 lines
12 KiB
C
Raw Normal View History

2020-09-26 03:20:57 -05:00
#include "sol.h"
VSZASSERT
/* flags for _lseek */
#define SEEK_CUR 1
#define SEEK_END 2
#define SEEK_SET 0
#define cbBand 8192
BGND bgnd;
BOOL _FValidBm(BMP *pbm)
{
return((pbm->biBitCount == 1 || pbm->biBitCount == 4)
&& pbm->biPlanes == 1 && pbm->biSize == sizeof(BMP));
}
BOOL FInitBgnd(TCHAR *szFile)
{
INT fh;
BOOL fResult;
LONG lcbBm;
LONG dwBmSize;
fResult = fFalse;
bgnd.fUseBitmap = fFalse;
if((fh = OpenFile(szFile, &bgnd.of, OF_CANCEL|OF_READ)) == -1)
return fFalse;
if(!FReadDibBitmapInfo(fh, &bgnd.bm))
goto ReturnClose;
bgnd.dwOfsBits = M_llseek( fh, 0L, SEEK_CUR);
if(!_FValidBm(&bgnd.bm))
goto ReturnClose;
/* BUG: check if bitmap is ok */
bgnd.cbLine = (((INT) bgnd.bm.biWidth * bgnd.bm.biBitCount+31)/32)*4;
lcbBm = (LONG) bgnd.cbLine * DyBmp(bgnd.bm);
bgnd.ibndMac = (INT) ((lcbBm+cbBand-1) / cbBand);
if((bgnd.rghbnd = PAlloc(bgnd.ibndMac*sizeof(HANDLE))) == NULL)
goto ReturnClose;
bgnd.dyBand = (INT) ((LONG) DyBmp(bgnd.bm) * cbBand / lcbBm);
bgnd.fUseBitmap = fTrue;
SetBgndOrg();
fResult = fTrue;
ReturnClose:
M_lclose(fh);
return fResult;
}
BOOL FDestroyBgnd()
{
INT ibnd;
HANDLE *phbnd;
if(bgnd.fUseBitmap)
{
for(ibnd = 0; ibnd < bgnd.ibndMac; ibnd++)
{
if(*(phbnd = &bgnd.rghbnd[ibnd]) != NULL)
{
GlobalFree(*phbnd);
*phbnd = NULL;
}
}
FreeP(bgnd.rghbnd);
}
return fTrue;
}
BOOL FGetBgndFile(TCHAR *sz)
{
if(bgnd.fUseBitmap)
PszCopy(bgnd.of.szPathName, sz);
else
sz[0] = TEXT('\000');
return fTrue;
}
BOOL _FLoadBand(INT ibnd, Y y)
{
HANDLE hbnd;
BYTE[ ]*FAR[ ]**lpb;
INT ipln;
INT fh;
LONG lcbpln;
HANDLE *phbnd;
DY dy;
phbnd = &bgnd.rghbnd[ibnd];
if(*phbnd != NULL)
GlobalFree(*phbnd);
hbnd = GlobalAlloc(GMEM_MOVEABLE|GMEM_DISCARDABLE, (LONG) cbBand);
lpb = GlobalLock(hbnd);
if(lpb == NULL)
return fFalse;
fh = OpenFile("", &bgnd.of, OF_REOPEN|OF_READ );
lcbpln = 0L;
dy = WMin(bgnd.dyBand, DyBmp(bgnd.bm)-y);
for(ipln = 0; ipln < CplnBmp(bgnd.bm); ipln++)
{
M_llseek( fh, (LONG)OfsBits(bgnd)+ipln*lcbpln+(y)*CbLine(bgnd), 0);
M_lread( fh, (LPSTR) lpb+ipln*CbLine(bgnd)*bgnd.dyBand, dy * CbLine(bgnd));
}
GlobalUnlock(hbnd);
*phbnd = hbnd;
M_lclose(fh);
return fTrue;
}
Y _YDrawBand(HDC hdcMem, HBITMAP hbm, X xLeft, Y yTop, X xRight, Y yBot)
{
HBITMAP hbmSav;
HANDLE hbnd;
BYTE[ ]*FAR[ ]**lpb;
Y y;
INT ibnd;
/* round yTop to nearest band */
y = ((yTop-bgnd.ptOrg.y)/bgnd.dyBand)*bgnd.dyBand;
ibnd = y/bgnd.dyBand;
if(ibnd < 0)
return bgnd.ptOrg.y;
if(ibnd >= bgnd.ibndMac)
return yBot+1;
ibnd = bgnd.ibndMac-ibnd-1;
Assert(ibnd >= 0);
Assert(ibnd < bgnd.ibndMac);
while((hbnd = bgnd.rghbnd[ibnd]) == NULL ||
(lpb = (BYTE[ ]*FAR[ ]**) GlobalLock(hbnd)) == NULL)
{
if(!_FLoadBand(ibnd, y))
/* KLUDGE:, should back out gracefully */
return yBot;
}
Assert(lpb != NULL);
SetDIBitsToDevice(hdcCur, xLeft-xOrgCur, yTop-yOrgCur,
WMin(xRight-xLeft, DyBmp(bgnd.bm)-xLeft+bgnd.ptOrg.x),
WMin(WMin(bgnd.dyBand, yBot-yTop), DyBmp(bgnd.bm)-yTop+bgnd.ptOrg.y),
0, 0,
y-bgnd.ptOrg.y,
bgnd.dyBand,
// xLeft-bgnd.ptOrg.x, yTop-y-bgnd.ptOrg.y,
// 0,
// WMin(WMin(bgnd.dyBand, yBot-yTop), DyBmp(bgnd.bm)-yTop+bgnd.ptOrg.y),
lpb,
(BITMAPINFO FAR *)&bgnd.bm,
DIB_RGB_COLORS);
GlobalUnlock(hbnd);
return y+bgnd.dyBand+bgnd.ptOrg.y;
}
VOID DrawBgnd(X xLeft, Y yTop, X xRight, Y yBot)
{
INT dy;
Y y;
HDC hdcMem;
HBITMAP hbm;
HBRUSH hbr;
if(bgnd.fUseBitmap)
{
for(y = yTop; y <= yBot; )
{
y = _YDrawBand(hdcMem, hbm, xLeft, y, xRight, yBot);
}
ExcludeClipRect(hdcCur, bgnd.ptOrg.x-xOrgCur, bgnd.ptOrg.y-yOrgCur, bgnd.ptOrg.x+DxBmp(bgnd.bm)-xOrgCur, bgnd.ptOrg.y+DyBmp(bgnd.bm)-yOrgCur);
}
MSetBrushOrg(hdcCur, xOrgCur, yOrgCur);
MUnrealizeObject( hbrTable );
hbr = SelectObject(hdcCur, hbrTable);
Assert(xRight >= xLeft);
Assert(yBot >= yTop);
PatBlt(hdcCur, xLeft-xOrgCur, yTop-yOrgCur, xRight-xLeft, yBot-yTop, PATCOPY);
SelectObject(hdcCur, hbr);
if(bgnd.fUseBitmap)
SelectClipRgn(hdcCur, NULL);
}
VOID SetBgndOrg()
{
bgnd.ptOrg.x = (rcClient.xRight - DxBmp(bgnd.bm))/2;
bgnd.ptOrg.y = (rcClient.yBot - DyBmp(bgnd.bm))/2;
}
/*
* ReadDibBitmapInfo()
*
* Will read a file in DIB format and return a global HANDLE to it's
* BITMAPINFO. This function will work with both "old" and "new"
* bitmap formats, but will allways return a "new" BITMAPINFO
*
*/
BOOL FReadDibBitmapInfo(INT fh, BITMAPINFO *pbi)
{
DWORD off;
HANDLE hbi = NULL;
INT size;
INT i;
WORD nNumColors;
RGBQUAD FAR *pRgb;
BITMAPINFOHEADER bi;
BITMAPCOREHEADER bc;
LPBITMAPINFOHEADER lpbi;
BITMAPFILEHEADER bf;
if (fh == -1)
return NULL;
off = M_llseek( fh, 0L, SEEK_CUR);
if (sizeof(bf) != M_lread( fh, (LPSTR)&bf, sizeof(bf)) )
return fFalse;
/*
* do we have a RC HEADER?
*/
if (!ISDIB(bf.bfType))
{
bf.bfOffBits = 0L;
M_llseek( fh, off, SEEK_SET );
}
if (sizeof(bi) != M_lread( fh, (LPSTR)&bi, sizeof(bi)) )
return fFalse;
nNumColors = DibNumColors(&bi);
/*
* what type of bitmap info is this?
*/
switch (size = (INT)bi.biSize)
{
case sizeof(BITMAPINFOHEADER):
break;
case sizeof(BITMAPCOREHEADER):
bc = *(BITMAPCOREHEADER*)&bi;
bi.biSize = sizeof(BITMAPINFOHEADER);
bi.biWidth = (DWORD)bc.bcWidth;
bi.biHeight = (DWORD)bc.bcHeight;
bi.biPlanes = (WORD)bc.bcPlanes;
bi.biBitCount = (WORD)bc.bcBitCount;
bi.biStyle = 0;
bi.biSizeImage = 0;
bi.biXPelsPerMeter = 0;
bi.biYPelsPerMeter = 0;
bi.biClrUsed = nNumColors;
bi.biClrImportant = nNumColors;
M_llseek(fh, (LONG)sizeof(BITMAPCOREHEADER)-sizeof(BITMAPINFOHEADER), SEEK_CUR);
break;
default:
return fFalse; /* not a DIB */
}
/*
* fill in some default values!
*/
if (bi.biSizeImage == 0)
{
bi.biSizeImage = WIDTHBYTES((DWORD)bi.biWidth * bi.biBitCount)
* bi.biHeight;
}
if (bi.biXPelsPerMeter == 0)
{
bi.biXPelsPerMeter = 0; // ??????????????
}
if (bi.biYPelsPerMeter == 0)
{
bi.biYPelsPerMeter = 0; // ??????????????
}
if (bi.biClrUsed == 0)
{
bi.biClrUsed = DibNumColors(&bi);
}
lpbi = (VOID FAR *)pbi;
*lpbi = bi;
pRgb = (RGBQUAD FAR *)((LPSTR)lpbi + bi.biSize);
if (nNumColors)
{
if (size == sizeof(BITMAPCOREHEADER))
{
/*
* convert a old color table (3 byte entries) to a new
* color table (4 byte entries)
*/
M_lread( fh, (LPSTR)pRgb, nNumColors * sizeof(RGBTRIPLE) );
for (i=nNumColors-1; i>=0; i--)
{
RGBQUAD rgb;
rgb.rgbRed = ((RGBTRIPLE FAR *)pRgb)[i].rgbtRed;
rgb.rgbBlue = ((RGBTRIPLE FAR *)pRgb)[i].rgbtBlue;
rgb.rgbGreen = ((RGBTRIPLE FAR *)pRgb)[i].rgbtGreen;
rgb.rgbReserved = (BYTE)0;
pRgb[i] = rgb; // BUG, this is wrong!!!!
}
}
else
{
M_lread(fh, (LPSTR)pRgb, nNumColors * sizeof(RGBQUAD));
}
}
if (bf.bfOffBits != 0L)
M_llseek( fh, off + bf.bfOffBits, SEEK_SET );
return fTrue;
}
/* How Many colors does this DIB have?
* this will work on both PM and Windows bitmap info structures.
*/
WORD DibNumColors(VOID FAR * pv)
{
INT bits;
/*
* with the new format headers, the size of the palette is in biClrUsed
* else is dependent on bits per pixel
*/
if (((LPBITMAPINFOHEADER)pv)->biSize != sizeof(BITMAPCOREHEADER))
{
if (((LPBITMAPINFOHEADER)pv)->biClrUsed != 0)
return (WORD)((LPBITMAPINFOHEADER)pv)->biClrUsed;
bits = ((LPBITMAPINFOHEADER)pv)->biBitCount;
}
else
{
bits = ((LPBITMAPCOREHEADER)pv)->bcBitCount;
}
switch (bits)
{
case 1:
return 2;
case 4:
return 16;
case 8:
Assert(fFalse); // NYI
return 256;
default:
return 0;
}
}
#ifdef LATER
HDC HdcCreateImage(HDC hdcApp, INT idbMask, INT idbImage, LONG rgb, DX *pdx, DY *pdy)
{
HDC hdcMem, hdcMem1;
HBITMAP hbmT, hbmTT, hbmMask;
HBRUSH hbr;
BITMAP bm;
hdcMem = CreateCompatibleDC(hdcApp);
hbmMask = LoadBitmap(hinstApp, MAKEINTRESOURCE(idbMask));
GetObject(hbmMask, sizeof(BITMAP), (LPSTR) &bm);
/* enlarge the size of hdc */
hbmT = SelectObject(hdcMem, CreateCompatibleBitmap(hdcApp, bm.bmWidth, bm.bmHeight));
hbr = SelectObject(hdcMem, hbrTable);
PatBlt(hdcMem, 0, 0, bm.bmWidth, bm.bmHeight, PATCOPY);
SelectObject(hdcMem, hbr);
hdcMem1 = CreateCompatibleDC(hdcApp);
hbmTT = SelectObject(hdcMem1, hbmMask);
BitBlt(hdcMem, 0, 0, bm.bmWidth, bm.bmHeight, hdcMem1, 0, 0, SRCAND);
/* load image and delete hbmMask */
DeleteObject(SelectObject(hdcMem1, LoadBitmap(hinstApp, MAKEINTRESOURCE(idbImage))));
/* load brush to color image */
hbr = SelectObject(hdcMem, CreateSolidBrush(rgb));
#define ropDPSao 0x00EA02E9 /* (Source & Pattern) | Dest */
BitBlt(hdcMem, 0, 0, bm.bmWidth, bm.bmHeight, hdcMem1, 0, 0, ropDPSao);
DeleteObject(SelectObject(hdcMem, hbr));
DeleteObject(SelectObject(hdcMem1, hbmTT));
DeleteDC(hdcMem1);
*pdx = bm.bmWidth;
*pdy = bm.bmHeight;
return hdcMem;
}
Marquee(RC *prc)
{
HDC hdc;
HDC hdcObj;
X x;
Y y;
DX dxObj;
DY dyObj;
DX dx;
DY dy;
INT dobjX, dobjY; /* # of objects per dir */
INT iobj;
INT iSlice, iSlice1;
hdc = GetDC(hwndApp);
hdcObj = HdcCreateImage(hdc, idbBlackBear, idbWhiteBear, RGB(255, 0, 0), &dxObj, &dyObj);
dobjX = (prc->xRight-prc->xLeft)/dxObj;
dobjY = (prc->yBot-prc->yTop)/dyObj;
dx = dxObj*2;
dy = 0;
y = prc->yTop-dyObj;
x = prc->xLeft-dxObj+iSlice%dxObj;
for(iobj = 0; iobj < 2*dobjX+2*dobjY; iobj++)
{
BitBlt(hdc, x, y, dxObj, dyObj, hdcObj, 0, 0, SRCCOPY);
if(dy == 0)
{
if(x > prc->xRight+dxObj)
{
dy = dyObj*2;
dx = 0;
}
else if(x < prc->xLeft-dxObj)
{
dy = -dyObj*2;
dx = 0;
}
}
else if(dx == 0)
{
if(y > prc->yBot+dyObj)
{
dx = -dxObj*2;
dy = 0;
}
}
x+=dx;
y+=dy;
}
for(iSlice = 0; iSlice < 5; iSlice++)
{
for(iSlice1 = 0; iSlice1 < dxObj; iSlice1++)
{
BitBlt(hdc, prc->xLeft-dxObj+iSlice1+1, prc->yTop-dyObj, prc->xRight-prc->xLeft+dxObj, dyObj,
hdc, prc->xLeft-dxObj+iSlice1, prc->yTop-dyObj, SRCCOPY);
BitBlt(hdc, prc->xRight+dxObj, prc->yTop-dyObj+iSlice1+1, dxObj, prc->yBot-prc->yTop+dyObj,
hdc, prc->xRight+dxObj, prc->yTop-dyObj+iSlice1, SRCCOPY);
}
}
DeleteDC(hdcObj);
ReleaseDC(hwndApp, hdc);
return fTrue;
}
Animation()
{
INT iX, iY, ihdc;
DX dx;
DY dy;
HDC hdc;
HDC rghdc[3];
RC rc;
rc.xLeft = 100; rc.xRight = 300;
rc.yTop = 100; rc.yBot = 200;
Marquee(&rc);
return fTrue;
}
#endif /* LATER */