GFX.C
资源名称:MSDN_VC98.zip [点击查看]
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:15k
源码类别:
Windows编程
开发平台:
Visual C++
- /*==========================================================================
- *
- * Copyright (C) 1995-1997 Microsoft Corporation. All Rights Reserved.
- * Copyright (C) 1994-1995 ATI Technologies Inc. All Rights Reserved.
- *
- * File: gfx.c
- * Content: graphics API
- *
- ***************************************************************************/
- #include "foxbear.h"
- GFX_BITMAP *lpVRAM;
- static BOOL fForceRestore = FALSE;
- /*
- * gfxBlt
- */
- BOOL gfxBlt(RECT *dst, GFX_HBM bm, POINT *src)
- {
- GFX_BITMAP* pbm = (GFX_BITMAP*)bm;
- HRESULT ddrval;
- DWORD bltflags;
- RECT rc;
- int x,y,dx,dy;
- if( GameSize.cy == C_SCREEN_H )
- {
- y = dst->top;
- dy = dst->bottom - dst->top;
- rc.top = src->y;
- rc.bottom = rc.top + dy;
- }
- else
- {
- y = MapY(dst->top);
- dy = MapY(dst->bottom) - y;
- rc.top = MapDY(src->y);
- rc.bottom = rc.top + dy;
- }
- if( GameSize.cx == C_SCREEN_W )
- {
- x = dst->left;
- dx = dst->right - dst->left;
- rc.left = src->x;
- rc.right = rc.left + dx;
- }
- else
- {
- x = MapX(dst->left);
- dx = MapX(dst->right) - x;
- rc.left = MapDX(src->x);
- rc.right = rc.left + dx;
- }
- if( dx == 0 || dy == 0 )
- {
- return TRUE;
- }
- if (pbm->lpSurface)
- {
- if( pbm->bTrans )
- bltflags = bTransDest ? DDBLTFAST_DESTCOLORKEY : DDBLTFAST_SRCCOLORKEY;
- else
- bltflags = bTransDest ? DDBLTFAST_DESTCOLORKEY : DDBLTFAST_NOCOLORKEY;
- ddrval = IDirectDrawSurface_BltFast(
- lpBackBuffer, x, y,
- pbm->lpSurface, &rc, bltflags | DDBLTFAST_WAIT);
- if (ddrval != DD_OK)
- {
- Msg("BltFast failed err=%d", ddrval);
- }
- }
- else
- {
- DDBLTFX ddbltfx;
- rc.left = x;
- rc.top = y;
- rc.right = rc.left + dx;
- rc.bottom = rc.top + dy;
- ddbltfx.dwSize = sizeof( ddbltfx );
- ddbltfx.dwFillColor = pbm->dwColor;
- ddrval = IDirectDrawSurface_Blt(
- lpBackBuffer, // dest surface
- &rc, // dest rect
- NULL, // src surface
- NULL, // src rect
- DDBLT_COLORFILL | DDBLT_WAIT,
- &ddbltfx);
- }
- return TRUE;
- } /* gfxBlt */
- /*
- * gfxCreateSolidColorBitmap
- */
- GFX_HBM gfxCreateSolidColorBitmap(COLORREF rgb)
- {
- GFX_BITMAP *pvram;
- pvram = MemAlloc( sizeof( *pvram ) );
- if( pvram == NULL )
- {
- return NULL;
- }
- pvram->dwColor = DDColorMatch(lpBackBuffer, rgb);
- pvram->lpSurface = NULL;
- pvram->lpbi = NULL;
- pvram->bTrans = FALSE;
- pvram->link = lpVRAM;
- lpVRAM = pvram;
- return (GFX_HBM) pvram;
- } /* gfxCreateSolidColorBitmap */
- /*
- * gfxCreateBitmap
- */
- GFX_HBM gfxCreateVramBitmap(BITMAPINFOHEADER UNALIGNED *lpbi,BOOL bTrans)
- {
- GFX_BITMAP *pvram;
- pvram = MemAlloc( sizeof( *pvram ) );
- if( pvram == NULL )
- {
- return NULL;
- }
- pvram->lpSurface = DDCreateSurface(MapRX(lpbi->biWidth),
- MapRY(lpbi->biHeight), FALSE, TRUE);
- pvram->lpbi = lpbi;
- pvram->dwColor = 0;
- pvram->bTrans = bTrans;
- if( pvram->lpSurface == NULL )
- {
- return NULL;
- }
- pvram->link = lpVRAM;
- lpVRAM = pvram;
- gfxRestore((GFX_HBM) pvram);
- return (GFX_HBM) pvram;
- } /* gfxCreateVramBitmap */
- /*
- * gfxDestroyBitmap
- */
- BOOL gfxDestroyBitmap ( GFX_HBM hbm )
- {
- GFX_BITMAP *p = (GFX_BITMAP *)hbm;
- if (hbm == NULL || hbm == GFX_TRUE)
- {
- return FALSE;
- }
- if (p->lpSurface)
- {
- IDirectDrawSurface_Release(p->lpSurface);
- p->lpSurface = NULL;
- }
- if (p->lpbi)
- {
- p->lpbi = NULL;
- }
- MemFree((VOID *)p);
- return TRUE;
- } /* gfxDestroyBitmap */
- /*
- * gfxStretchBackBuffer()
- */
- BOOL gfxStretchBackbuffer()
- {
- if (lpStretchBuffer)
- {
- IDirectDrawSurface_Blt(
- lpStretchBuffer, // dest surface
- NULL, // dest rect (all of it)
- lpBackBuffer, // src surface
- &GameRect, // src rect
- DDBLT_WAIT,
- NULL);
- IDirectDrawSurface_Blt(
- lpBackBuffer, // dest surface
- NULL, // dest rect (all of it)
- lpStretchBuffer, // src surface
- NULL, // src rect
- DDBLT_WAIT,
- NULL);
- }
- else
- {
- IDirectDrawSurface_Blt(
- lpBackBuffer, // dest surface
- NULL, // dest rect (all of it)
- lpBackBuffer, // src surface
- &GameRect, // src rect
- DDBLT_WAIT,
- NULL);
- }
- return TRUE;
- } /* gfxStretchBackbuffer */
- /*
- * gfxFlip
- */
- BOOL gfxFlip( void )
- {
- HRESULT ddrval;
- ddrval = IDirectDrawSurface_Flip( lpFrontBuffer, NULL, DDFLIP_WAIT );
- if( ddrval != DD_OK )
- {
- Msg( "Flip FAILED, rc=%08lx", ddrval );
- return FALSE;
- }
- return TRUE;
- } /* gfxFlip */
- /*
- * gfxUpdateWindow
- */
- BOOL gfxUpdateWindow()
- {
- HRESULT ddrval;
- ddrval = IDirectDrawSurface_Blt(
- lpFrontBuffer, // dest surface
- &rcWindow, // dest rect
- lpBackBuffer, // src surface
- NULL, // src rect (all of it)
- DDBLT_WAIT,
- NULL);
- return ddrval == DD_OK;
- } /* gfxUpdateWindow */
- /*
- * gfxSwapBuffers
- *
- * this is called when the game loop has rendered a frame into
- * the backbuffer, its goal is to display something for the user to see.
- *
- * there are four cases...
- *
- * Fullscreen:
- * we just call IDirectDrawSurface::Flip(lpFrontBuffer)
- * being careful to handle return code right.
- *
- * Fullscreen (stretched):
- * the game loop has rendered a frame 1/2 the display
- * size, we do a Blt to stretch the frame to the backbuffer
- * the we just call IDirectDrawSurface::Flip(lpFrontBuffer)
- *
- * Window mode (foreground palette):
- * in this case we call IDirectDrawSurface::Blt to copy
- * the back buffer to the window.
- *
- * Window mode (background palette):
- * in this case we are in a window, but we dont own the
- * palette. all our art was loaded to a specific palette
- * IDirectDrawSurface::Blt does not do color translation
- * we have a few options in this case...
- *
- * reload or remap the art to the the current palette
- * (we can do this easily with a GetDC, StetchDIBits)
- * FoxBear has *alot* of art, so this would be too slow.
- *
- * use GDI to draw the backbuffer, GDI will handle
- * the color conversion so things will look correct.
- *
- * pause the game (this is what we do so this function
- * will never be called)
- *
- */
- BOOL gfxSwapBuffers( void )
- {
- if( bFullscreen )
- {
- if( bStretch )
- {
- gfxStretchBackbuffer();
- }
- if (nBufferCount > 1)
- return gfxFlip();
- else
- return TRUE;
- }
- else
- {
- return gfxUpdateWindow();
- }
- } /* gfxSwapBuffers */
- /*
- * gfxBegin
- */
- GFX_HBM gfxBegin( void )
- {
- if( !DDEnable() )
- {
- return NULL;
- }
- if( !DDCreateFlippingSurface() )
- {
- DDDisable(TRUE);
- return NULL;
- }
- Splash();
- return GFX_TRUE;
- } /* gfxBegin */
- /*
- * gfxEnd
- */
- BOOL gfxEnd ( GFX_HBM hbm )
- {
- GFX_BITMAP *curr;
- GFX_BITMAP *next;
- for( curr = lpVRAM; curr; curr=next )
- {
- next = curr->link;
- gfxDestroyBitmap ((GFX_HBM)curr);
- }
- lpVRAM = NULL;
- return DDDisable(FALSE);
- return TRUE;
- } /* gfxEnd */
- /*
- * gfxRestore
- *
- * restore the art when one or more surfaces are lost
- */
- BOOL gfxRestore(GFX_HBM bm)
- {
- GFX_BITMAP *pbm = (GFX_BITMAP*)bm;
- HRESULT ddrval;
- HDC hdc;
- LPVOID lpBits;
- RGBQUAD *prgb;
- int i,w,h;
- RECT rc;
- struct {
- BITMAPINFOHEADER bi;
- RGBQUAD ct[256];
- } dib;
- IDirectDrawSurface *pdds = pbm->lpSurface;
- BITMAPINFOHEADER UNALIGNED *pbi = pbm->lpbi;
- if (pdds == NULL)
- return TRUE;
- if (IDirectDrawSurface_Restore(pdds) != DD_OK)
- return FALSE;
- if (pbi == NULL)
- return TRUE;
- //
- // in 8bbp mode if we get switched away from while loading
- // (and palette mapping) our art, the colors will not be correct
- // because some app may have changed the system palette.
- //
- // if we are in stress mode, just keep going. It is more important
- // to make progress than to get the colors right.
- //
- if (!bFullscreen &&
- GameBPP == 8 &&
- GetForegroundWindow() != hWndMain &&
- !bStress )
- {
- Msg("gfxRestore: **** foreground window changed while loading art!");
- fForceRestore = TRUE;
- PauseGame();
- return FALSE;
- }
- dib.bi = *pbi;
- prgb = (RGBQUAD *)((LPBYTE)pbi + pbi->biSize);
- lpBits = (LPBYTE)(prgb + pbi->biClrUsed);
- if( pbi->biClrUsed == 0 && pbi->biBitCount <= 8 )
- {
- lpBits = (LPBYTE)(prgb + (1<<pbi->biBitCount));
- }
- w = MapRX(pbi->biWidth);
- h = MapRY(pbi->biHeight);
- /*
- * hack to make sure fox off-white doesn't become
- * pure white (which is transparent)
- */
- for( i=0; i<256; i++ )
- {
- dib.ct[i] = prgb[i];
- if( dib.ct[i].rgbRed == 0xff &&
- dib.ct[i].rgbGreen == 0xff &&
- dib.ct[i].rgbBlue == 224 )
- {
- dib.ct[i].rgbBlue = 0x80;
- }
- else
- if( dib.ct[i].rgbRed == 251 &&
- dib.ct[i].rgbGreen == 243 &&
- dib.ct[i].rgbBlue == 234 )
- {
- dib.ct[i].rgbBlue = 0x80;
- }
- }
- /*
- * if we are in 8bit mode we know the palette is 332 we can
- * do the mapping our self.
- *
- * NOTE we can only do this in fullscreen mode
- * in windowed mode, we have to share the palette with
- * the window manager and we dont get all of the colors
- * in the order we assume.
- *
- */
- if (bFullscreen && GameBPP == pbi->biBitCount && GameBPP == 8 )
- {
- BYTE xlat332[256];
- DDSURFACEDESC ddsd;
- int x,y,dib_pitch;
- BYTE *src, *dst;
- BOOL stretch;
- IDirectDrawSurface *pdds1;
- HDC hdc1;
- stretch = w != pbi->biWidth || h != pbi->biHeight;
- for( i=0;i<256;i++ )
- {
- xlat332[i] =
- ((dib.ct[i].rgbRed >> 0) & 0xE0 ) |
- ((dib.ct[i].rgbGreen >> 3) & 0x1C ) |
- ((dib.ct[i].rgbBlue >> 6) & 0x03 );
- }
- /*
- * if we are stretching copy into the back buffer
- * then use GDI to stretch later.
- */
- if( stretch )
- {
- pdds1 = lpBackBuffer;
- }
- else
- {
- pdds1 = pdds;
- }
- ddsd.dwSize = sizeof(ddsd);
- ddrval = IDirectDrawSurface_Lock(
- pdds1, NULL, &ddsd, DDLOCK_WAIT, NULL);
- if( ddrval == DD_OK )
- {
- dib_pitch = (pbi->biWidth+3)&~3;
- src = (BYTE *)lpBits + dib_pitch * (pbi->biHeight-1);
- dst = (BYTE *)ddsd.lpSurface;
- for( y=0; y<(int)pbi->biHeight; y++ )
- {
- for( x=0; x<(int)pbi->biWidth; x++ )
- {
- dst[x] = xlat332[src[x]];
- }
- dst += ddsd.lPitch;
- src -= dib_pitch;
- }
- IDirectDrawSurface_Unlock(pdds1, NULL);
- }
- else
- {
- Msg("Lock failed err=%d", ddrval);
- return FALSE;
- }
- if( stretch )
- {
- if( IDirectDrawSurface_GetDC(pdds,&hdc) == DD_OK )
- {
- if( IDirectDrawSurface_GetDC(pdds1,&hdc1) == DD_OK )
- {
- SetStretchBltMode(hdc, COLORONCOLOR);
- StretchBlt(hdc, 0, 0, w, h,
- hdc1, 0, 0, pbi->biWidth, pbi->biHeight, SRCCOPY);
- IDirectDrawSurface_ReleaseDC(pdds1,hdc1);
- }
- IDirectDrawSurface_ReleaseDC(pdds,hdc);
- }
- }
- }
- else if( IDirectDrawSurface_GetDC(pdds,&hdc) == DD_OK )
- {
- SetStretchBltMode(hdc, COLORONCOLOR);
- StretchDIBits(hdc, 0, 0, w, h,
- 0, 0, pbi->biWidth, pbi->biHeight,
- lpBits, (BITMAPINFO *)&dib.bi, DIB_RGB_COLORS, SRCCOPY);
- IDirectDrawSurface_ReleaseDC(pdds,hdc);
- }
- /*
- * show the art while loading...
- */
- rc.left = rcWindow.left,
- rc.top = rcWindow.top + 20;
- rc.right = rc.left + w;
- rc.bottom = rc.top + h;
- IDirectDrawSurface_Blt(lpFrontBuffer, &rc, pdds, NULL, DDBLT_WAIT, NULL);
- return TRUE;
- } /* gfxRestore */
- /*
- * gfxRestoreAll
- *
- * restore the art when one or more surfaces are lost
- */
- BOOL gfxRestoreAll()
- {
- GFX_BITMAP *curr;
- HWND hwndF = GetForegroundWindow();
- Splash();
- for( curr = lpVRAM; curr != NULL; curr = curr->link)
- {
- if (curr->lpSurface &&
- (fForceRestore || IDirectDrawSurface_IsLost(curr->lpSurface) == DDERR_SURFACELOST))
- {
- if( !gfxRestore(curr) )
- {
- Msg( "gfxRestoreAll: ************ Restore FAILED!" );
- return FALSE;
- }
- }
- }
- DDClear();
- fForceRestore = FALSE;
- return TRUE;
- } /* gfxRestoreAll */
- /*
- * gfxFillBack
- */
- void gfxFillBack( DWORD dwColor )
- {
- DDBLTFX ddbltfx;
- ddbltfx.dwSize = sizeof( ddbltfx );
- ddbltfx.dwFillColor = dwColor;
- IDirectDrawSurface_Blt(
- lpBackBuffer, // dest surface
- NULL, // dest rect
- NULL, // src surface
- NULL, // src rect
- DDBLT_COLORFILL | DDBLT_WAIT,
- &ddbltfx);
- } /* gfxFillBack */