GFX.C
资源名称:MSDN_VC98.zip [点击查看]
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:15k
源码类别:
Windows编程
开发平台:
Visual C++
- /*==========================================================================
- *
- * Copyright (C) 1995-1997 Microsoft Corporation. All Rights Reserved.
- *
- * File: gfx.c
- * Content: DirectDraw related code.
- *
- *
- ***************************************************************************/
- #include "gfx.h"
- #include "input.h"
- #include "ddutil.h"
- /*
- * Externals
- */
- extern BOOL gbUseEmulation; // user DDHEL or DDHAL ?
- extern BOOL gbFullscreen; // window or fullscreen mode ?
- extern HWND ghWndMain; // main window
- extern DWORD gdwKeys;
- extern int gnProgramState; // current state of program (rest, splash, active, etc.)
- extern RECT grcWindow; // client window rectangle
- extern BOOL gbFullscreen; // fullscreen or window mode ?
- extern HINSTANCE ghinst; // application instance handle
- extern TCHAR gtszClassName[]; // Duel's class name
- /*
- * Globals
- */
- LPDIRECTDRAWSURFACE glpFrontBuffer; // primary surface
- LPDIRECTDRAWSURFACE glpBackBuffer; // back buffer for animation
- LPDIRECTDRAWSURFACE glpSplash; // splash screen
- LPDIRECTDRAWSURFACE glpShip0; // ship bitmaps
- LPDIRECTDRAWSURFACE glpShip1;
- LPDIRECTDRAWSURFACE glpShip2;
- LPDIRECTDRAWSURFACE glpShip3;
- LPDIRECTDRAWSURFACE glpNum; // Numbers bitmap
- LPDIRECTDRAW glpDD; // DirectDraw interface
- LPDIRECTDRAWPALETTE glpArtPalette=NULL; // Game screen palette
- LPDIRECTDRAWPALETTE glpSplashPalette=NULL; // Splash screen palette
- LPDIRECTDRAWCLIPPER glpClipper=NULL; // Clipper for front buffer
- DWORD gdwFillColor;
- int gnGameBPP; // primary surface bit depth
- #ifdef DEBUG
- BOOL gbHELBlt = FALSE;
- #endif
- BOOL InitGraphics( void )
- {
- DDCAPS ddcaps;
- HRESULT ddrval;
- DDSURFACEDESC ddsd;
- DDSCAPS ddscaps;
- TCHAR tszTitle[MAX_WINDOWTITLE];
- LoadString(ghinst, IDS_DUEL_TITLE, tszTitle, MAX_WINDOWTITLE);
- // Create a window
- ghWndMain = CreateWindowEx(
- WS_EX_APPWINDOW, // WS_EX_TOPMOST,
- gtszClassName,
- tszTitle,
- // don't show the window yet
- WS_POPUP | // non-app window POPUP
- WS_SYSMENU, // so we get an icon in the tray
- 0,
- 0,
- GetSystemMetrics(SM_CXSCREEN),
- GetSystemMetrics(SM_CYSCREEN),
- NULL,
- NULL,
- ghinst,
- NULL );
- if( !ghWndMain )
- {
- return FALSE;
- }
- UpdateWindow( ghWndMain );
- SetFocus( ghWndMain );
- // ddraw stuff begins here
- if( gbUseEmulation )
- ddrval = DirectDrawCreate( (LPVOID) DDCREATE_EMULATIONONLY, &glpDD, NULL );
- else
- ddrval = DirectDrawCreate( NULL, &glpDD, NULL );
- if( ddrval != DD_OK )
- return ShowError(IDS_DDRAW_ERROR_DDC);
- // set access mode based on fullscreen/window
- if (gbFullscreen)
- {
- ddrval = glpDD->lpVtbl->SetCooperativeLevel( glpDD, ghWndMain,
- DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN );
- }
- else
- {
- ddrval = glpDD->lpVtbl->SetCooperativeLevel( glpDD, ghWndMain,
- DDSCL_NORMAL);
- }
- if( ddrval != DD_OK )
- return ShowError(IDS_DDRAW_ERROR_SCL);
- if (gbFullscreen)
- {
- // set the mode to 640 by 480 by 8
- ddrval = glpDD->lpVtbl->SetDisplayMode( glpDD, 640, 480, 8 );
- if( ddrval != DD_OK )
- return ShowError(IDS_DDRAW_ERROR_SDM);
- }
- else
- {
- RECT rcWork;
- RECT rc;
- HDC hdc;
- DWORD dwStyle;
- //
- // when in rome (I mean when in windows) we should use the
- // current mode
- //
- hdc = GetDC(NULL);
- gnGameBPP = GetDeviceCaps(hdc, PLANES) * GetDeviceCaps(hdc, BITSPIXEL);
- ReleaseDC(NULL, hdc);
- //
- // if we are still a WS_POPUP window we should convert to a
- // normal app window so we look like a windows app.
- //
- dwStyle = GetWindowStyle(ghWndMain);
- dwStyle &= ~WS_POPUP;
- dwStyle |= WS_OVERLAPPED | WS_CAPTION | WS_THICKFRAME | WS_MINIMIZEBOX;
- SetWindowLong(ghWndMain, GWL_STYLE, dwStyle);
- // set window size
- SetRect(&rc, 0, 0, MAX_DEFWIN_X, MAX_DEFWIN_Y);
- AdjustWindowRectEx(&rc,
- GetWindowStyle(ghWndMain),
- GetMenu(ghWndMain) != NULL,
- GetWindowExStyle(ghWndMain));
- SetWindowPos(ghWndMain, NULL, 0, 0, rc.right-rc.left, rc.bottom-rc.top,
- SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);
- SetWindowPos(ghWndMain, HWND_NOTOPMOST, 0, 0, 0, 0,
- SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
- //
- // make sure our window does not hang outside of the work area
- // this will make people who have the tray on the top or left
- // happy.
- //
- SystemParametersInfo(SPI_GETWORKAREA, 0, &rcWork, 0);
- GetWindowRect(ghWndMain, &rc);
- if (rc.left < rcWork.left) rc.left = rcWork.left;
- if (rc.top < rcWork.top) rc.top = rcWork.top;
- SetWindowPos(ghWndMain, NULL, rc.left, rc.top, 0, 0,
- SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
- }
- // check the color key hardware capabilities
- ddcaps.dwSize = sizeof( ddcaps );
- memset( &ddsd, 0, sizeof( ddsd ) );
- ddsd.dwSize = sizeof( ddsd );
- if (gbFullscreen)
- {
- // Create surfaces
- ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
- ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE |
- DDSCAPS_FLIP |
- DDSCAPS_COMPLEX;
- ddsd.dwBackBufferCount = 1;
- ddrval = glpDD->lpVtbl->CreateSurface( glpDD, &ddsd, &glpFrontBuffer, NULL );
- if( ddrval != DD_OK )
- return ShowError(IDS_DDRAW_ERROR_CSFB);
- // get a pointer to the back buffer
- ddscaps.dwCaps = DDSCAPS_BACKBUFFER;
- ddrval = glpFrontBuffer->lpVtbl->GetAttachedSurface(
- glpFrontBuffer,
- &ddscaps,
- &glpBackBuffer );
- if( ddrval != DD_OK )
- return ShowError(IDS_DDRAW_ERROR_GAS);
- }
- else
- {
- // window case, create the primary surface
- // and create a backbuffer in offscreen memory
- ddsd.dwFlags = DDSD_CAPS;
- ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
- ddrval = glpDD->lpVtbl->CreateSurface( glpDD, &ddsd, &glpFrontBuffer, NULL );
- if( ddrval != DD_OK )
- return ShowError(IDS_DDRAW_ERROR_CSFB);
- ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
- ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
- ddsd.dwWidth = MAX_DEFWIN_X;
- ddsd.dwHeight = MAX_DEFWIN_Y;
- ddrval = glpDD->lpVtbl->CreateSurface( glpDD, &ddsd, &glpBackBuffer, NULL );
- if( ddrval != DD_OK )
- return ShowError(IDS_DDRAW_ERROR_CSBB);
- ddrval = glpDD->lpVtbl->CreateClipper(glpDD, 0, &glpClipper, NULL);
- if( ddrval != DD_OK )
- return ShowError(IDS_DDRAW_ERROR_CC);
- ddrval = glpClipper->lpVtbl->SetHWnd(glpClipper, 0, ghWndMain);
- if( ddrval != DD_OK )
- return ShowError(IDS_DDRAW_ERROR_SH);
- ddrval = glpFrontBuffer->lpVtbl->SetClipper(glpFrontBuffer, glpClipper);
- if( ddrval != DD_OK )
- return ShowError(IDS_DDRAW_ERROR_SC);
- }
- ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
- ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
- #ifdef DEBUG
- if( gbHELBlt )
- ddsd.ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY;
- #endif
- ddsd.dwWidth = 320;
- ddsd.dwHeight = 128;
- ddrval = glpDD->lpVtbl->CreateSurface( glpDD, &ddsd, &glpShip0, NULL );
- if( ddrval != DD_OK )
- return ShowError(IDS_DDRAW_ERROR_CSS0);
- ddsd.dwWidth = 320;
- ddsd.dwHeight = 128;
- ddrval = glpDD->lpVtbl->CreateSurface( glpDD, &ddsd, &glpShip1, NULL );
- if( ddrval != DD_OK )
- return ShowError(IDS_DDRAW_ERROR_CSS1);
- ddsd.dwWidth = 320;
- ddsd.dwHeight = 128;
- ddrval = glpDD->lpVtbl->CreateSurface( glpDD, &ddsd, &glpShip2, NULL );
- if( ddrval != DD_OK )
- return ShowError(IDS_DDRAW_ERROR_CSS2);
- ddsd.dwWidth = 320;
- ddsd.dwHeight = 128;
- ddrval = glpDD->lpVtbl->CreateSurface( glpDD, &ddsd, &glpShip3, NULL );
- if( ddrval != DD_OK )
- return ShowError(IDS_DDRAW_ERROR_CSS3);
- ddsd.dwHeight = 16;
- ddrval = glpDD->lpVtbl->CreateSurface( glpDD, &ddsd, &glpNum, NULL );
- if( ddrval != DD_OK )
- return ShowError(IDS_DDRAW_ERROR_CSN);
- if( !RestoreSurfaces() )
- return ShowError(IDS_DDRAW_ERROR_RS);
- gdwKeys = 0;
- ShowWindow(ghWndMain, SW_SHOW);
- return TRUE;
- }
- void CleanupGraphics(void)
- {
- if( glpShip0 != NULL )
- glpShip0->lpVtbl->Release( glpShip0 );
- if( glpShip1 != NULL )
- glpShip1->lpVtbl->Release( glpShip1 );
- if( glpShip2 != NULL )
- glpShip2->lpVtbl->Release( glpShip2 );
- if( glpShip3 != NULL )
- glpShip3->lpVtbl->Release( glpShip3 );
- if( glpNum != NULL )
- glpNum->lpVtbl->Release( glpNum );
- if (!gbFullscreen && glpClipper)
- glpClipper->lpVtbl->Release( glpClipper );
- if( glpFrontBuffer != NULL )
- glpFrontBuffer->lpVtbl->Release( glpFrontBuffer );
- if( glpArtPalette != NULL )
- glpArtPalette->lpVtbl->Release( glpArtPalette );
- if( glpSplashPalette != NULL )
- glpSplashPalette->lpVtbl->Release( glpSplashPalette );
- if( !gbFullscreen && (glpBackBuffer != NULL ))
- glpBackBuffer->lpVtbl->Release( glpBackBuffer );
- if( glpDD != NULL )
- glpDD->lpVtbl->Release( glpDD );
- }
- void bltSplash( LPRECT rc)
- {
- HRESULT ddrval;
- HBITMAP hbm;
- if( ( glpFrontBuffer == NULL ) ||
- ( glpSplashPalette == NULL ) ||
- ( glpBackBuffer == NULL ) )
- {
- return;
- }
- // set the palette before loading the splash screen
- glpFrontBuffer->lpVtbl->SetPalette( glpFrontBuffer, glpSplashPalette );
- hbm = (HBITMAP)LoadImage( GetModuleHandle( NULL ), TEXT("SPLASH"), IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION );
- if ( NULL == hbm )
- return;
- // if the surface is lost, DDCopyBitmap will fail and the surface will
- // be restored below.
- ddrval = DDCopyBitmap( glpBackBuffer, hbm, 0, 0, 0, 0 );
- DeleteObject( hbm );
- while( 1 )
- {
- if( NULL == rc)
- {
- ddrval = glpFrontBuffer->lpVtbl->Blt( glpFrontBuffer,
- &grcWindow, glpBackBuffer, NULL, DDBLT_WAIT, NULL);
- }
- else
- {
- ddrval = glpFrontBuffer->lpVtbl->Blt( glpFrontBuffer,
- &grcWindow, glpBackBuffer, rc, DDBLT_WAIT, NULL);
- }
- if( ddrval == DD_OK )
- return;
- if( ddrval == DDERR_SURFACELOST )
- if( !RestoreSurfaces() )
- return;
- if( ddrval != DDERR_WASSTILLDRAWING )
- return;
- }
- }
- void bltScore( char *num, int x, int y )
- {
- char *c;
- RECT src;
- int i;
- for(c=num; *c != ' '; c++)
- {
- i = *c - '0';
- src.left = i*16;
- src.top = 0;
- src.right = src.left + 16;
- src.bottom = src.top + 16;
- bltObject( x, y, glpNum, &src, DDBLTFAST_SRCCOLORKEY );
- x += 16;
- }
- }
- void bltObject( int x, int y, LPDIRECTDRAWSURFACE surf, LPRECT src, DWORD flags )
- {
- HRESULT ddrval;
- while( 1 )
- {
- ddrval = glpBackBuffer->lpVtbl->BltFast( glpBackBuffer, x, y, surf, src, flags );
- if( ddrval == DD_OK )
- return;
- if( ddrval == DDERR_SURFACELOST )
- if( !RestoreSurfaces() )
- return;
- if( ddrval != DDERR_WASSTILLDRAWING )
- return;
- }
- }
- void EraseScreen( void )
- {
- DDBLTFX ddbltfx;
- HRESULT ddrval;
- // Erase the background
- ddbltfx.dwSize = sizeof( ddbltfx );
- ddbltfx.dwFillColor = gdwFillColor;
- while( 1 )
- {
- ddrval = glpBackBuffer->lpVtbl->Blt( glpBackBuffer, NULL, NULL,
- NULL, DDBLT_COLORFILL, &ddbltfx );
- if( ddrval == DD_OK )
- {
- break;
- }
- if( ddrval == DDERR_SURFACELOST )
- {
- if( !RestoreSurfaces() )
- return;
- }
- if( ddrval != DDERR_WASSTILLDRAWING )
- {
- return;
- }
- }
- }
- void FlipScreen( void )
- {
- HRESULT ddrval;
- // Flip the surfaces
- if (gbFullscreen)
- {
- while( 1 )
- {
- ddrval = glpFrontBuffer->lpVtbl->Flip( glpFrontBuffer, NULL, 0 );
- if( ddrval == DD_OK )
- {
- break;
- }
- if( ddrval == DDERR_SURFACELOST )
- {
- if( !RestoreSurfaces() )
- {
- return;
- }
- }
- if( ddrval != DDERR_WASSTILLDRAWING )
- {
- break;
- }
- }
- }
- else
- {
- ddrval = IDirectDrawSurface_Blt(
- glpFrontBuffer, // dest surface
- &grcWindow, // dest rect
- glpBackBuffer, // src surface
- NULL, // src rect (all of it)
- DDBLT_WAIT,
- NULL);
- }
- }
- BOOL RestoreSurfaces( void )
- {
- HRESULT ddrval;
- HBITMAP hbm;
- ddrval = glpFrontBuffer->lpVtbl->Restore(glpFrontBuffer);
- if( ddrval != DD_OK )
- return FALSE;
- ddrval = glpBackBuffer->lpVtbl->Restore(glpBackBuffer);
- if( ddrval != DD_OK )
- return FALSE;
- ddrval = glpShip0->lpVtbl->Restore(glpShip0);
- if( ddrval != DD_OK )
- return FALSE;
- ddrval = glpShip1->lpVtbl->Restore(glpShip1);
- if( ddrval != DD_OK )
- return FALSE;
- ddrval = glpShip2->lpVtbl->Restore(glpShip2);
- if( ddrval != DD_OK )
- return FALSE;
- ddrval = glpShip3->lpVtbl->Restore(glpShip3);
- if( ddrval != DD_OK )
- return FALSE;
- ddrval = glpNum->lpVtbl->Restore(glpNum);
- if( ddrval != DD_OK )
- return FALSE;
- // Create and set the palette for the splash bitmap
- glpSplashPalette = DDLoadPalette( glpDD, TEXT("SPLASH") );
- if( NULL == glpSplashPalette )
- return FALSE;
- // Create and set the palette for the art bitmap
- glpArtPalette = DDLoadPalette( glpDD, TEXT("Duel8") );
- if( NULL == glpArtPalette )
- return FALSE;
- // set the palette before loading the art
- glpFrontBuffer->lpVtbl->SetPalette( glpFrontBuffer, glpArtPalette );
- hbm = (HBITMAP)LoadImage(GetModuleHandle(NULL), TEXT("Duel8"), IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION );
- if( NULL == hbm )
- return FALSE;
- ddrval = DDCopyBitmap( glpShip0, hbm, 0, 0, 320, 128 );
- if( ddrval != DD_OK )
- {
- DeleteObject( hbm );
- return FALSE;
- }
- ddrval = DDCopyBitmap( glpShip1, hbm, 0, 128, 320, 128 );
- if( ddrval != DD_OK )
- {
- DeleteObject( hbm );
- return FALSE;
- }
- ddrval = DDCopyBitmap( glpShip2, hbm, 0, 256, 320, 128 );
- if( ddrval != DD_OK )
- {
- DeleteObject( hbm );
- return FALSE;
- }
- ddrval = DDCopyBitmap( glpShip3, hbm, 0, 384, 320, 128 );
- if( ddrval != DD_OK )
- {
- DeleteObject( hbm );
- return FALSE;
- }
- ddrval = DDCopyBitmap( glpNum, hbm, 0, 512, 320, 16 );
- if( ddrval != DD_OK )
- {
- DeleteObject( hbm );
- return FALSE;
- }
- DeleteObject( hbm );
- // set colorfill colors and color gdwKeys according to bitmap contents
- gdwFillColor = DDColorMatch( glpShip0, CLR_INVALID );
- DDSetColorKey( glpShip0, CLR_INVALID );
- DDSetColorKey( glpShip1, CLR_INVALID );
- DDSetColorKey( glpShip2, CLR_INVALID );
- DDSetColorKey( glpShip3, CLR_INVALID );
- DDSetColorKey( glpNum, CLR_INVALID );
- return TRUE;
- }
- void SetGamePalette(void)
- {
- if (glpFrontBuffer)
- glpFrontBuffer->lpVtbl->SetPalette( glpFrontBuffer, glpArtPalette );
- }
- void FlipToGDI(void)
- {
- if (glpDD)
- glpDD->lpVtbl->FlipToGDISurface( glpDD );
- }