DONUT.CPP
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:9k
源码类别:

Windows编程

开发平台:

Visual C++

  1. /*==========================================================================
  2.  *
  3.  *  Copyright (C) 1995-1997 Microsoft Corporation. All Rights Reserved.
  4.  *
  5.  *  File:       donut.cpp
  6.  *
  7.  ***************************************************************************/
  8. #define NAME "Donut"
  9. #define TITLE "Donut"
  10. #define WIN32_LEAN_AND_MEAN
  11. #include <windows.h>
  12. #include <windowsx.h>
  13. #include <ddraw.h>
  14. #include "resource.h"
  15. #include "ddutil.h"
  16. char szBitmap[] = "DONUT";
  17. int             gPos = 0;
  18. BOOL            gExclusive = FALSE;
  19. int             gMode = 0;
  20. HWND            hwnd;
  21. LPDIRECTDRAW            lpDD;           // DirectDraw object
  22. LPDIRECTDRAWSURFACE     lpDDSPrimary;   // DirectDraw primary surface
  23. LPDIRECTDRAWSURFACE     lpDDSOne;       // Offscreen surface 1
  24. LPDIRECTDRAWSURFACE     lpDDSTwo;       // Offscreen surface 2
  25. LPDIRECTDRAWPALETTE     lpDDPal;        // DirectDraw palette
  26. BOOL                    bActive;        // is application active?
  27. /*
  28.  * restoreAll
  29.  *
  30.  * restore all lost objects
  31.  */
  32. HRESULT restoreAll( void )
  33. {
  34.     HRESULT     ddrval;
  35.     ddrval = lpDDSPrimary->Restore();
  36.     if( ddrval == DD_OK )
  37.     {
  38. ddrval = lpDDSOne->Restore();
  39. if( ddrval == DD_OK )
  40. {
  41.     ddrval = lpDDSTwo->Restore();
  42.     if( ddrval == DD_OK )
  43.     {
  44. DDReLoadBitmap(lpDDSOne, szBitmap);
  45.     }
  46. }
  47.     }
  48.     return ddrval;
  49. } /* restoreAll */
  50. /*
  51.  * updateFrame
  52.  * 
  53.  * Decide what needs to be blitted next, wait for flip to complete,
  54.  * then flip the buffers.
  55.  */
  56. void updateFrame( void )
  57. {
  58.     static DWORD        lastTickCount = 0;
  59.     static int          currentFrame = 0;
  60.     static BOOL         haveBackground = FALSE;
  61.     DWORD               thisTickCount;
  62.     RECT                rcRect;
  63.     DWORD               delay = 17;
  64.     HRESULT             ddrval;
  65.     int                 pos;
  66.     thisTickCount = GetTickCount();
  67.     if((thisTickCount - lastTickCount) <= delay)
  68.     {
  69. return;
  70.     }
  71.     switch( gPos )
  72.     {
  73. case 0: pos = 0; break;
  74. case 1: pos = 64; break;
  75. case 2: pos = 128; break;
  76.     }
  77.     rcRect.left = 0;
  78.     rcRect.top = 0;
  79.     rcRect.right = 64;
  80.     rcRect.bottom = 64;
  81.     // restore a previously saved patch
  82.     while( haveBackground )
  83.     {
  84. ddrval = lpDDSPrimary->BltFast( pos, 0, lpDDSTwo, &rcRect, FALSE );
  85. if( ddrval == DD_OK )
  86. {
  87.     haveBackground = TRUE;
  88.     break;
  89. }
  90. if( ddrval == DDERR_SURFACELOST )
  91. {
  92.     ddrval = restoreAll();
  93.     if( ddrval != DD_OK )
  94.     {
  95. return;
  96.     }
  97. }
  98. if( ddrval != DDERR_WASSTILLDRAWING )
  99. {
  100.     return;
  101. }
  102.     }
  103.     rcRect.left = pos;
  104.     rcRect.right = pos+64;
  105.     // Save the current primary surface that we are about to overwrite
  106.     while( 1 )
  107.     {
  108. haveBackground = FALSE;
  109. ddrval = lpDDSTwo->BltFast( 0, 0, lpDDSPrimary,
  110.     &rcRect, DDBLTFAST_NOCOLORKEY);
  111. if( ddrval == DD_OK )
  112. {
  113.     haveBackground = TRUE;
  114.     break;
  115. }
  116. if( ddrval == DDERR_SURFACELOST )
  117. {
  118.     ddrval = restoreAll();
  119.     if( ddrval != DD_OK )
  120.     {
  121. return;
  122.     }
  123. }
  124. if( ddrval != DDERR_WASSTILLDRAWING )
  125. {
  126.     return;
  127. }
  128.     }
  129.     
  130.     thisTickCount = GetTickCount();
  131.     if((thisTickCount - lastTickCount) > delay)
  132.     {
  133. // Move to next frame;
  134. lastTickCount = thisTickCount;
  135. currentFrame++;
  136. if(currentFrame > 59)
  137. {
  138.     currentFrame = 0;
  139. }
  140.     }
  141.     // Blit the stuff for the next frame
  142.     rcRect.left   = currentFrame%10*64;
  143.     rcRect.top    = currentFrame/10*64;
  144.     rcRect.right  = currentFrame%10*64 + 64;
  145.     rcRect.bottom = currentFrame/10*64 + 64;
  146.     while( 1 )
  147.     {
  148. ddrval = lpDDSPrimary->BltFast( pos, 0, lpDDSOne,
  149.     &rcRect, DDBLTFAST_SRCCOLORKEY);
  150. if( ddrval == DD_OK )
  151. {
  152.     break;
  153. }
  154. if( ddrval == DDERR_SURFACELOST )
  155. {
  156.     ddrval = restoreAll();
  157.     if( ddrval != DD_OK )
  158.     {
  159. return;
  160.     }
  161. }
  162. if( ddrval != DDERR_WASSTILLDRAWING )
  163. {
  164.     return;
  165. }
  166.     }
  167.     if(ddrval != DD_OK)
  168.     {
  169. return;
  170.     }
  171. } /* updateFrame */
  172. /*
  173.  * finiObjects
  174.  *
  175.  * finished with all objects we use; release them
  176.  */
  177. static void finiObjects( void )
  178. {
  179.     if( lpDD != NULL )
  180.     {
  181. if( lpDDSPrimary != NULL )
  182. {
  183.     lpDDSPrimary->Release();
  184.     lpDDSPrimary = NULL;
  185. }
  186. if( lpDDSOne != NULL )
  187. {
  188.     lpDDSOne->Release();
  189.     lpDDSOne = NULL;
  190. }
  191. if( lpDDPal != NULL )
  192. {
  193.     lpDDPal->Release();
  194.     lpDDPal = NULL;
  195. }
  196. lpDD->Release();
  197. lpDD = NULL;
  198.     }
  199.     // Clean up the screen on exit
  200.     RedrawWindow( NULL, NULL, NULL, RDW_INVALIDATE | RDW_ERASE |
  201.      RDW_ALLCHILDREN );
  202. } /* finiObjects */
  203. long FAR PASCAL WindowProc( HWND hWnd, UINT message, 
  204.     WPARAM wParam, LPARAM lParam )
  205. {
  206.     hwnd = hWnd;
  207.     switch( message )
  208.     {
  209.     case WM_ACTIVATEAPP:
  210. bActive = wParam;
  211. break;
  212.     case WM_SETCURSOR:
  213. SetCursor(NULL);
  214. return TRUE;
  215.     case WM_PALETTECHANGED:
  216. if ((HWND)wParam == hWnd)
  217.     break;
  218. // fall through to WM_QUERYNEWPALETTE
  219.     case WM_QUERYNEWPALETTE:
  220. // install our palette here
  221. if (lpDDPal)
  222. {
  223.     lpDDSPrimary->SetPalette(lpDDPal);
  224. }
  225. DDReLoadBitmap(lpDDSOne, szBitmap);
  226. break;
  227.     case WM_CREATE:
  228. break;
  229.     case WM_KEYDOWN:
  230. switch( wParam )
  231. {
  232. case VK_ESCAPE:
  233. case VK_F12:
  234.     PostMessage(hWnd,WM_CLOSE,0,0);
  235.     break;
  236. }
  237. break;
  238.     case WM_DESTROY:
  239. finiObjects();
  240. PostQuitMessage( 0 );
  241. break;
  242.     }
  243.     return DefWindowProc(hWnd, message, wParam, lParam);
  244. } /* WindowProc */
  245. /*
  246.  * This function is called if the initialization function fails
  247.  */
  248. BOOL initFail( HWND hwnd )
  249. {
  250.     finiObjects();
  251.     MessageBox( hwnd, "DirectDraw Init FAILED", TITLE, MB_OK );
  252.     DestroyWindow( hwnd );
  253.     return FALSE;
  254. } /* initFail */
  255. /*
  256.  * doInit - do work required for every instance of the application:
  257.  *                create the window, initialize data
  258.  */
  259. static BOOL doInit( HINSTANCE hInstance, int nCmdShow )
  260. {
  261.     HWND                hwnd;
  262.     WNDCLASS            wc;
  263.     DDSURFACEDESC       ddsd;
  264.     HRESULT             ddrval;
  265.     /*
  266.      * set up and register window class
  267.      */
  268.     wc.style = CS_HREDRAW | CS_VREDRAW;
  269.     wc.lpfnWndProc = WindowProc;
  270.     wc.cbClsExtra = 0;
  271.     wc.cbWndExtra = 0;
  272.     wc.hInstance = hInstance;
  273.     wc.hIcon = LoadIcon( hInstance, IDI_APPLICATION );
  274.     wc.hCursor = LoadCursor( NULL, IDC_ARROW );
  275.     wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
  276.     wc.lpszMenuName = NAME;
  277.     wc.lpszClassName = NAME;
  278.     RegisterClass( &wc );
  279.     
  280.     /*
  281.      * create a window
  282.      */
  283.     hwnd = CreateWindowEx(
  284. 0,
  285. NAME,
  286. TITLE,
  287. WS_POPUP,
  288. 0,
  289. 0,
  290. 1,
  291. 1,
  292. NULL,
  293. NULL,
  294. hInstance,
  295. NULL );
  296.     if( !hwnd )
  297.     {
  298. return FALSE;
  299.     }
  300.     ShowWindow( hwnd, nCmdShow );
  301.     UpdateWindow( hwnd );
  302.     /*
  303.      * create the main DirectDraw object
  304.      */
  305.     ddrval = DirectDrawCreate( NULL, &lpDD, NULL );
  306.     if( ddrval != DD_OK )
  307.     {
  308. return initFail(hwnd);
  309.     }
  310.     // Get exclusive mode if requested
  311.     if(gExclusive)
  312.     {
  313. ddrval = lpDD->SetCooperativeLevel( hwnd, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN );
  314.     }
  315.     else
  316.     {
  317. ddrval = lpDD->SetCooperativeLevel( hwnd, DDSCL_NORMAL );
  318.     }
  319.     if( ddrval != DD_OK )
  320.     {
  321. return initFail(hwnd);
  322.     }
  323.     // Set the video mode to 640x480x8
  324.     switch( gMode )
  325.     {
  326. case 1:  ddrval = lpDD->SetDisplayMode( 640, 480, 8); break;
  327. case 2:  ddrval = lpDD->SetDisplayMode( 800, 600, 8); break;
  328. case 3:  ddrval = lpDD->SetDisplayMode( 1024, 768, 8); break;
  329. case 4:  ddrval = lpDD->SetDisplayMode( 1280, 1024, 8); break;
  330.     }
  331.     if( ddrval != DD_OK )
  332.     {
  333. return initFail(hwnd);
  334.     }
  335.     // Create the primary surface
  336.     ddsd.dwSize = sizeof( ddsd );
  337.     ddsd.dwFlags = DDSD_CAPS;
  338.     ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
  339.     ddrval = lpDD->CreateSurface( &ddsd, &lpDDSPrimary, NULL );
  340.     if( ddrval != DD_OK )
  341.     {
  342. return initFail(hwnd);
  343.     }
  344.     lpDDPal = DDLoadPalette(lpDD, szBitmap);
  345.     if (lpDDPal)
  346.     {
  347. lpDDSPrimary->SetPalette(lpDDPal);
  348.     }
  349.     lpDDSOne = DDLoadBitmap(lpDD, szBitmap, 0, 0);
  350.     if( lpDDSOne == NULL )
  351.     {
  352. return initFail(hwnd);
  353.     }
  354.     // set color key to black
  355.     DDSetColorKey(lpDDSOne, RGB(0,0,0));
  356.     ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
  357.     ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
  358.     ddsd.dwHeight = 64;
  359.     ddsd.dwWidth = 64;
  360.     ddrval = lpDD->CreateSurface( &ddsd, &lpDDSTwo, NULL );
  361.     if( ddrval != DD_OK )
  362.     {
  363. return initFail(hwnd);
  364.     }
  365.     return TRUE;
  366. } /* doInit */
  367. /*
  368.  * WinMain - initialization, message loop
  369.  */
  370. int PASCAL WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
  371. LPSTR lpCmdLine, int nCmdShow)
  372. {
  373.     MSG         msg;
  374.     LPSTR       c;
  375.     for(c=lpCmdLine; *c != ''; c++)
  376.     {
  377. switch( *c )
  378. {
  379.     case '0': gPos = 0; break;
  380.     case '1': gPos = 1; break;
  381.     case '2': gPos = 2; break;
  382.     case 'X': gExclusive = TRUE; break;
  383.     case 'A': gExclusive = TRUE; gMode = 1; break;
  384.     case 'B': gExclusive = TRUE; gMode = 2; break;
  385.     case 'C': gExclusive = TRUE; gMode = 3; break;
  386.     case 'D': gExclusive = TRUE; gMode = 4; break;
  387. }
  388.     }
  389.     
  390.     if( !doInit( hInstance, nCmdShow ) )
  391.     {
  392. return FALSE;
  393.     }
  394.     while( 1 )
  395.     {
  396. if( PeekMessage( &msg, NULL, 0, 0, PM_NOREMOVE ) )
  397. {
  398.     if( !GetMessage( &msg, NULL, 0, 0 ) )
  399. return msg.wParam;
  400.     TranslateMessage(&msg); 
  401.     DispatchMessage(&msg);
  402. }
  403. else if( !gExclusive || bActive )
  404. {
  405.     updateFrame();
  406. }
  407. else
  408. {
  409.     WaitMessage();
  410. }
  411.     }
  412. } /* WinMain */