home *** CD-ROM | disk | FTP | other *** search
- /***********************************************************************
- File: BitMap.c
- Date: 5-23-92
-
-
- Abstract:
-
- This file contains functions pertaining to drawing a bitmap on the screen.
-
- Contents:
-
- FadePic() -- Slowly fade a picture on the screen to the background
- DrawClippedPic() -- Draw a picture, clipped to a specified rectangle
- NewFullPic() -- Create a record of type FullPicType
- DeleteFullPic() -- Delete a record of type FullPicType
- AddPic() -- Load a new picture bitmap set
- DelPic() -- Remove a picture bitmap set from memory.
-
-
- Revision History:
-
-
- ************************************************************************/
- #include "winmaze.h"
- #include "mazproto.h"
-
- #define MASKROP(fore,back) (DWORD)(((back << 8)&0xFF000000) | fore)
- #define MASKROP2(black,white) (DWORD)(((black << 8)&0xFF000000) | white) & 0xFFFF0000
-
-
-
-
- //
- // PicSpec goes:
- // Base BM filename, iPicNum for the picture, offsets for each facing:
- // {width, depth, left offset, top offset}
- //
- PicSpecType PicSpec[] = {
- {"FISH", PIC_FISH,
- {
- {35,41,30,42},
- {62,35,15,49},
- {21,31,36,51},
- {62,31,21,53}
- }},
- {"ROBO", PIC_ROBOT,
- {
- {40,107,19,43},
- {50,107,13,43},
- {43,106,23,44},
- {48,107,30,43}
- }},
- {"SMIL", PIC_SMILEY,
- {
- {62,62,17,40},
- {68,62,17,40},
- {62,62,17,40},
- {70,62,9,40}
- }},
- {"REAP", PIC_REAPER,
- {
- {90,114,5,26},
- {85,114,8,26},
- {90,114,5,26},
- {85,114,8,26}
- }}
- };
-
- int iNumPicSpecs = sizeof(PicSpec) / sizeof(PicSpecType);
-
-
-
-
-
- /*=====================================================================
- Function: FadePic()
-
- Inputs: Picture #, facing, and clipping rectangle to fade.
-
- Outputs:none
-
- Abstract:
- Fade will fade out a given bitmap by XORing its bitmap with a 50% grey tone.
- ======================================================================*/
-
- void FadePic(
- int iPicNum,
- BYTE bFacing,
- HDC hDC,
- LPRECT lprFrom,
- LPRECT lprDRect
- )
- {
- FullPicType FAR *fptTrav;
- BOOL bFound;
- HDC hFadeDC,hMaskDC,hbmFadeDC;
- HBITMAP hbmFade;
- int DestWidth,DestHeight,SrcWidth,SrcHeight;
- int iRelDirIndex,i,j;
-
-
- fptTrav = &fptPic;
- bFound = FALSE;
-
- iRelDirIndex=2;
- while(bFacing != ptSelf.Pos.Facing) {
- iRelDirIndex = (iRelDirIndex+1)%4;
- bFacing = LEFT_TO_ABS(bFacing);
- }
-
- while(fptTrav->next != NULL) {
- fptTrav = fptTrav->next;
- if (fptTrav->iPicNum == iPicNum) {
- bFound = TRUE;
- break;
- }
- }
-
- if (bFound) {
- hMaskDC = CreateCompatibleDC(hDC);
- hFadeDC = CreateCompatibleDC(hDC);
- hbmFadeDC = CreateCompatibleDC(hFadeDC);
- SrcWidth = lprFrom->right-lprFrom->left+1;
- SrcHeight = lprFrom->bottom-lprFrom->top+1;
- DestWidth = lprDRect->right-lprDRect->left+1;
- DestHeight = lprDRect->bottom-lprDRect->top+1;
- hbmFade = CreateCompatibleBitmap(hFadeDC,DestWidth,DestHeight);
- SelectObject(hbmFadeDC,hbmFade);
- SelectObject(hFadeDC,hFadeBM[0]);
- SelectObject(hMaskDC,fptTrav->M[iRelDirIndex].hBitmap);
-
- //
- // Copy the Fade pattern into the Fade Bitmap
- //
- for(i=0;i<DestWidth;i+=PIC_X) {
- for(j=0;j<DestHeight;j+=PIC_Y) {
- BitBlt(hbmFadeDC,i,j,
- ((i+PIC_X)<=DestWidth) ? PIC_X : DestWidth,
- ((j+PIC_Y)<=DestHeight) ? PIC_Y : DestHeight,
- hFadeDC,0,0,
- SRCCOPY);
- }
- }
-
- //
- // StretchBlt the mask onto the fade
- //
- StretchBlt(hbmFadeDC,0,0,DestWidth,DestHeight,
- hMaskDC,0,0,SrcWidth,SrcHeight,
- NOTSRCERASE);
-
- //
- // BitBlt the result onto the screen.
- //
- BitBlt(hDC,lprDRect->left,lprDRect->top,DestWidth,DestHeight,
- hbmFadeDC,0,0,
- SRCPAINT);
-
- DeleteDC(hFadeDC);
- DeleteDC(hMaskDC);
- DeleteDC(hbmFadeDC);
- DeleteObject(hbmFade);
- DeleteObject(hFadeBM[0]);
- hFadeBM[0] = LoadBitmap(hInst,(LPCTSTR)((0)?"FADE2":"FADE1"));
-
- }
-
- return;
-
- }
-
-
-
-
- /*=====================================================================
- Function: DrawClippedPic()
-
- Inputs: Picture #, Relative facing, clip/dest rectangles,
-
- Outputs:none
-
- Abstract:
- DrawClippedPic will draw the portions of picture # iPicNum visible through
- the clipping window. Player bitmaps smaller than a full panel in size
- Will need to be scaled.
- ======================================================================*/
-
- void DrawClippedPic(
- int iPicNum,
- BYTE bFacingIndex,
- HDC hDC,
- LPRECT lprDRect,
- LPRECT lprClip,
- LPRECT lprFrom,
- int iRelx,
- int iRely
- )
-
- {
- RECT rSrc;
- FullPicType FAR *fptTrav;
- BOOL bFound;
- HDC hPicDC,hMaskDC;
- int DestWidth,DestHeight;
- POINT pBlt[3];
- //
- // the floats are offset ratio's, ie percentage of the total
- // width/depth to add to each side of the source rect.
- //
- float sWidth,sDepth,dWidth,dDepth;
- float fRelScaling;
-
- if (lprClip->right < lprClip->left+2) {
- return;
- }
-
- fptTrav = &fptPic;
- bFound = FALSE;
-
- //
- // Check to see if the Picture we're supposed to draw has been loaded.
- //
- AddPic(iPicNum);
-
- while(fptTrav->next != NULL) {
- fptTrav = fptTrav->next;
- if (fptTrav->iPicNum == iPicNum) {
- bFound = TRUE;
- break;
- }
- }
-
- if (bFound) {
-
- //
- // bFound will now indicates whether the picture has been pre-stretched
- //
-
- bFound = (PreStretch[iPicNum][iRely].P[bFacingIndex].hBitmap != (HANDLE) NULL);
- bFound = bFound && (PreStretch[iPicNum][iRely].M[bFacingIndex].hBitmap != (HANDLE) NULL);
-
- //
- // We'll need the source dimensions whether it's prestretched or not.
- //
- if (bFound) {
- sWidth = (float) PreStretch[iPicNum][iRely].P[bFacingIndex].xSize;
- sDepth = (float) PreStretch[iPicNum][iRely].P[bFacingIndex].ySize;
- }
- else {
- sWidth = (float) fptTrav->P[bFacingIndex].xSize;
- sDepth = (float) fptTrav->P[bFacingIndex].ySize;
- }
-
- //
- // Assume that we want the ENTIRE source bitmap.
- //
- rSrc.left = 0;
- rSrc.top = 0;
- rSrc.right = (INT) sWidth-1;
- rSrc.bottom = (INT) sDepth-1;
-
- //
- // fRelScaling*an offset gives # of pixels of REAL offset.
- //
- fRelScaling = ((float) (lprDRect->bottom - lprDRect->top))/(float)PIC_Y;
-
- if (bFound) {
- lprDRect->left += PreStretch[iPicNum][iRely].P[bFacingIndex].xOrg;
- lprDRect->top += PreStretch[iPicNum][iRely].P[bFacingIndex].yOrg;
- lprDRect->right = lprDRect->left + (int) sWidth;
- lprDRect->bottom = lprDRect->top + (int) sDepth;
- }
- else {
- lprDRect->left += (int) (fRelScaling*fptTrav->P[bFacingIndex].xOrg);
- lprDRect->top += (int) (fRelScaling*fptTrav->P[bFacingIndex].yOrg);
- lprDRect->right = lprDRect->left + (int) (fRelScaling*sWidth);
- lprDRect->bottom = lprDRect->top + (int) (fRelScaling*sDepth);
- }
-
- dWidth = (float) lprDRect->right - lprDRect->left;
- dDepth = (float) lprDRect->bottom - lprDRect->top;
-
- //
- // Rather than doing a clipped bitblt, we just modify the source
- // rectangle to be the parts which are visible.
- //
- if (lprDRect->left < lprClip->left) {
- rSrc.left += (LONG) (sWidth*((float) (lprClip->left - lprDRect->left))/dWidth);
- lprDRect->left = lprClip->left;
- }
- if (lprDRect->top < lprClip->top) {
- rSrc.top += (LONG) (sDepth*((float) lprClip->top - lprDRect->top)/dDepth);
- lprDRect->top = lprClip->top;
- }
- if (lprDRect->right > lprClip->right) {
- rSrc.right += (LONG) (sWidth*((float) lprClip->right - lprDRect->right)/dWidth);
- lprDRect->right = lprClip->right;
- }
- if (lprDRect->bottom > lprClip->bottom) {
- rSrc.bottom += (LONG) (sDepth*((float) lprClip->bottom - lprDRect->bottom)/dDepth);
- lprDRect->bottom = lprClip->bottom;
- }
- //
- // Set the Dest variables to the TRUE physical dest width/depth
- //
- DestWidth = lprDRect->right - lprDRect->left;
- DestHeight = lprDRect->bottom - lprDRect->top+1;
-
- if ((DestWidth < 1)||(DestHeight < 1)) {
- return;
- }
-
- hPicDC = CreateCompatibleDC(hDC);
- hMaskDC = CreateCompatibleDC(hPicDC);
-
- if (bFound) {
- //
- // If the bitmaps are pre-stretched...
- //
-
- SelectObject(hPicDC,PreStretch[iPicNum][iRely].P[bFacingIndex].hBitmap);
- SelectObject(hMaskDC,PreStretch[iPicNum][iRely].M[bFacingIndex].hBitmap);
-
- BitBlt(hDC,lprDRect->left,lprDRect->top,DestWidth,DestHeight,
- hMaskDC,rSrc.left,rSrc.top,
- SRCAND);
- BitBlt(hDC,lprDRect->left,lprDRect->top,DestWidth,DestHeight,
- hPicDC,rSrc.left,rSrc.top,
- SRCPAINT);
- }
- else {
- //
- // If the bitmaps are NOT pre-stretched.
- //
- SelectObject(hPicDC,fptTrav->P[bFacingIndex].hBitmap);
- SelectObject(hMaskDC,fptTrav->M[bFacingIndex].hBitmap);
- //
- // stretch the mask onto the screen
- //
- pBlt[0].x = lprDRect->left;
- pBlt[0].y = lprDRect->top;
- pBlt[1].x = lprDRect->right;
- pBlt[1].y = lprDRect->top;
- pBlt[2].x = lprDRect->left;
- pBlt[2].y = lprDRect->bottom;
-
- StretchBlt(hDC,lprDRect->left,lprDRect->top,DestWidth,DestHeight,
- hMaskDC,rSrc.left,rSrc.top,rSrc.right-rSrc.left+1,rSrc.bottom-rSrc.top+1,
- SRCAND);
- //
- // then the picture as well
- //
- StretchBlt(hDC,lprDRect->left,lprDRect->top,DestWidth,DestHeight,
- hPicDC,rSrc.left,rSrc.top,rSrc.right-rSrc.left+1,rSrc.bottom-rSrc.top+1,
- SRCPAINT);
- }
-
- DeleteDC(hPicDC);
- DeleteDC(hMaskDC);
- }
- else {
- MessageBox(NULL,"Unknown Picture Draw Requested","DrawClippedPic",
- MB_ICONEXCLAMATION|MB_APPLMODAL);
- }
-
- *lprFrom = rSrc;
-
- return;
- }
-
-
-
-
- /*=====================================================================
- Function: NewFullPic()
-
- Inputs: Picture # to load, pointer to next
-
- Outputs:Returns a pointer to an initialized FullPicType data structure
-
- Abstract:
- ======================================================================*/
-
- FullPicType FAR *NewFullPic(
- int iPicNum,
- FullPicType FAR *next
- )
- {
- FullPicType FAR *fptTemp;
- int i;
- HANDLE hMem;
-
- hMem = GlobalAlloc(GHND,sizeof(FullPicType));
- fptTemp = (FullPicType FAR *) GlobalLock(hMem);
- if (fptTemp == NULL) {
- MessageBox((HANDLE)NULL,"Out of memory: unable to create NewFullPic.","NewFullPic",
- MB_ICONEXCLAMATION|MB_APPLMODAL);
- }
- else {
- for(i=0;i<4;i++) {
- fptTemp->P[i].hBitmap = (HANDLE) NULL;
- fptTemp->P[i].xSize = PicSpec[iPicNum].PicPos[i].xSize;
- fptTemp->P[i].ySize = PicSpec[iPicNum].PicPos[i].ySize;
- fptTemp->P[i].xOrg = PicSpec[iPicNum].PicPos[i].xOrg;
- fptTemp->P[i].yOrg = PicSpec[iPicNum].PicPos[i].yOrg;
- fptTemp->M[i].hBitmap = (HANDLE) NULL;
- fptTemp->M[i].xSize = PicSpec[iPicNum].PicPos[i].xSize;
- fptTemp->M[i].ySize = PicSpec[iPicNum].PicPos[i].ySize;
- fptTemp->M[i].xOrg = PicSpec[iPicNum].PicPos[i].xOrg;
- fptTemp->M[i].yOrg = PicSpec[iPicNum].PicPos[i].yOrg;
- }
- fptTemp->iPicNum = iPicNum;
- fptTemp->next = next;
- }
-
- return(fptTemp);
-
- }
-
-
-
- /*=====================================================================
- Function: DeleteFullPic()
-
- Inputs: pointer to FullPicType to free
-
- Outputs:Returns pointer to ->next element of deleted pic.
-
- Abstract:
- ======================================================================*/
-
- FullPicType FAR *DeleteFullPic(
- FullPicType FAR *fptTrav
- )
- {
- int i;
- FullPicType FAR *fptTemp;
- HANDLE hMem;
-
- if (fptTrav == NULL) {
- fptTemp = fptTrav;
- }
- else {
- fptTemp = fptTrav->next;
-
- for (i=0;i<4;i++) {
- if (fptTrav->P[i].hBitmap != (HANDLE) NULL) {
- DeleteObject(fptTrav->P[i].hBitmap);
- }
- if (fptTrav->M[i].hBitmap != (HANDLE) NULL) {
- DeleteObject(fptTrav->M[i].hBitmap);
- }
- }
-
- hMem = (HGLOBAL) GlobalHandle(SELECTOROF(fptTrav));
- GlobalUnlock(hMem);
- GlobalFree(hMem);
- }
-
- return(fptTemp);
- }
-
-
-
-
- /*=====================================================================
- Function: AddPic()
-
- Inputs: Picture # to load
-
- Outputs:Returns success/failure.
-
- Abstract:
- AddPic will take care of loading in a given picture's bitmap, if it isn't
- already in the fptPic list. If the specified type of picture can't be found,
- FALSE is returned. Note that when we load a picture, we also make sure
- that it is restricted to the confines of its mask by turning everything
- outside the mask BLACK. This is necessary for drawing as well.
- ======================================================================*/
-
- BOOL AddPic(
- int iPicNum
- )
- {
- char cDirs[4] = {'F','L','B','R'};
- FullPicType FAR *fptTrav;
- BOOL bFound;
- int i,j;
- char cBitmapName[32];
- HDC hDC,hPicDC,hMaskDC;
-
- fptTrav = &fptPic;
- bFound = FALSE;
-
- //
- // Look to see if the picture's already been loaded into memory. If
- // it has, we won't have to load it.
- //
- while (fptTrav->next != NULL) {
- fptTrav = fptTrav->next;
-
- if (fptTrav->iPicNum == iPicNum) {
- bFound = TRUE;
- break;
- }
- }
-
- //
- // If we didn't find the bitmap, we really DO need to load it.
- //
- if (!bFound) {
-
- //
- // We can only load the requested picture if it's in our list of
- // known pics. Check to make sure it is.
- //
- for(i=0;i<iNumPicSpecs;i++) {
- if (PicSpec[i].iPicNum == iPicNum) {
- bFound = TRUE;
- break;
- }
- }
-
- if (bFound) {
- hDC = GetDC(hWndMaze);
- hPicDC = CreateCompatibleDC(hDC);
- hMaskDC = CreateCompatibleDC(hPicDC);
- ReleaseDC(hWndMaze,hDC);
-
- fptTrav->next = NewFullPic(iPicNum,fptTrav->next);
- fptTrav = fptTrav->next;
- strcpy(cBitmapName,PicSpec[i].cBase);
- cBitmapName[5]='\0';
-
- //
- // Load in the bitmaps
- //
- for(j=0;j<4;j++) {
- cBitmapName[4]=cDirs[j];
- if (fptTrav->P[j].hBitmap != NULL) {
- DeleteObject(fptTrav->P[j].hBitmap);
- }
- fptTrav->P[j].hBitmap = LoadBitmap(hInst,(LPCTSTR)cBitmapName);
- if (fptTrav->P[j].hBitmap == (HANDLE) NULL) {
- MessageBox((HANDLE) NULL,"Unable to load bitmap","AddPic",
- MB_ICONEXCLAMATION|MB_APPLMODAL);
- bFound = FALSE;
- }
- //
- // Copy stats for the Bitmap's size/origin into the struct
- //
- fptTrav->P[j].xSize = PicSpec[i].PicPos[j].xSize;
- fptTrav->P[j].ySize = PicSpec[i].PicPos[j].ySize;
- fptTrav->P[j].xOrg = PicSpec[i].PicPos[j].xOrg;
- fptTrav->P[j].yOrg = PicSpec[i].PicPos[j].yOrg;
- }
-
- cBitmapName[5]='M';
- cBitmapName[6]='\0';
-
- //
- // Load in the masks for the bitmaps
- //
- for(j=0;j<4;j++) {
- cBitmapName[4]=cDirs[j];
- if (fptTrav->M[j].hBitmap != NULL) {
- DeleteObject(fptTrav->M[j].hBitmap);
- }
- fptTrav->M[j].hBitmap = LoadBitmap(hInst,(LPCTSTR)cBitmapName);
- if (fptTrav->M[j].hBitmap == (HANDLE) NULL) {
- MessageBox((HANDLE) NULL,"Unable to load bitmap mask","AddPic",
- MB_ICONEXCLAMATION|MB_APPLMODAL);
- bFound = FALSE;
- }
- //
- // Copy stats for the Mask's size/origin into the struct
- //
- fptTrav->M[j].xSize = PicSpec[i].PicPos[j].xSize;
- fptTrav->M[j].ySize = PicSpec[i].PicPos[j].ySize;
- fptTrav->M[j].xOrg = PicSpec[i].PicPos[j].xOrg;
- fptTrav->M[j].yOrg = PicSpec[i].PicPos[j].yOrg;
- }
- /***********BUGBUG
- //
- // Invert the background of the bitmaps from white to black
- //
- for(j=0;j<4;j++) {
- SelectObject(hPicDC,fptTrav->P[j].hBitmap);
- SelectObject(hMaskDC,fptTrav->M[j].hBitmap);
- BitBlt(hPicDC,0,0,
- PicSpec[iPicNum].PicPos[i].xSize,
- PicSpec[iPicNum].PicPos[i].ySize,
- hMaskDC,0,0,SRCINVERT);
- }
- *************/
-
- DeleteDC(hPicDC);
- DeleteDC(hMaskDC);
- }
- }
-
- return(bFound);
- }
-
-
-
-
- /*=====================================================================
- Function: DelPic()
-
- Inputs: Picture # to Delete from pic list
-
- Outputs:Returns success/failure.
-
- Abstract:
- DelPic will remove a picture, assuming that it is not being used by anyone
- in ptDrones and ptPlayers, and it isn't of type PIC_DEFAULT.
- ======================================================================*/
-
- BOOL DelPic(
- int iPicNum
- )
- {
- FullPicType FAR *fptTrav;
- BOOL bFound,bStillUsed;
- PlayerType FAR *ptTrav;
-
-
- if (iPicNum == PIC_DEFAULT) {
- return(TRUE);
- }
-
- fptTrav = &fptPic;
- bFound = FALSE;
-
- while (fptTrav->next != NULL) {
- if (fptTrav->next->iPicNum == iPicNum) {
- bFound = TRUE;
- bStillUsed = FALSE;
-
- ptTrav = &ptPlayers;
- while (ptTrav->next != NULL) {
- ptTrav = ptTrav->next;
- if (ptTrav->iPicNum == iPicNum) {
- bStillUsed = TRUE;
- break;
- }
- }
-
- ptTrav = &ptDrones;
- while (ptTrav->next != NULL) {
- ptTrav = ptTrav->next;
- if (ptTrav->iPicNum == iPicNum) {
- bStillUsed = TRUE;
- break;
- }
- }
-
- if (!bStillUsed) {
- fptTrav->next = DeleteFullPic(fptTrav->next);
- }
-
- break;
- }
-
- fptTrav = fptTrav->next;
- }
-
- return(bFound);
- }
-