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

Windows编程

开发平台:

Visual C++

  1. /*==========================================================================
  2.  *
  3.  *  Copyright (C) 1995-1997 Microsoft Corporation. All Rights Reserved.
  4.  *
  5.  *  File: ddex5.cpp
  6.  *  Content: Direct Draw example program 5. Adds functionality to
  7.  * example program 4.  Uses GetEntries() to read a palette,
  8.  * modifies the entries, and then uses SetEntries() to update
  9.  * the palette.  This program requires 1.2 Meg of video ram.
  10.  *
  11.  ***************************************************************************/
  12. #define NAME "DDExample5"
  13. #define TITLE "Direct Draw Example 5"
  14. #define WIN32_LEAN_AND_MEAN
  15. #include <windows.h>
  16. #include <windowsx.h>
  17. #include <ddraw.h>
  18. #include "resource.h"
  19. #include "ddutil.h"
  20. char szBitmap[] = "ALL";
  21. LPDIRECTDRAW lpDD; // DirectDraw object
  22. LPDIRECTDRAWSURFACE lpDDSPrimary; // DirectDraw primary surface
  23. LPDIRECTDRAWSURFACE lpDDSBack; // DirectDraw back surface
  24. LPDIRECTDRAWSURFACE lpDDSOne; // Offscreen surface 1
  25. LPDIRECTDRAWPALETTE lpDDPal; // The primary surface palette
  26. BOOL bActive; // is application active?
  27. BYTE torusColors[256]; // Marks the colors used in the torus
  28. /*
  29.  * restoreAll
  30.  *
  31.  * restore all lost objects
  32.  */
  33. HRESULT restoreAll( void )
  34. {
  35.     HRESULT ddrval;
  36.     DDSURFACEDESC ddsd;
  37.     ddrval = lpDDSPrimary->Restore();
  38.     if( ddrval == DD_OK )
  39.     {
  40. ddrval = lpDDSOne->Restore();
  41. if( ddrval == DD_OK )
  42.         {
  43.             DDReLoadBitmap(lpDDSOne, szBitmap);
  44. }
  45.     }
  46.     //Loose the old palette
  47.     lpDDPal->Release();
  48.     // create and set the palette (restart cycling from the same place)
  49.     lpDDPal = DDLoadPalette(lpDD, szBitmap);
  50.     if (lpDDPal)
  51.         lpDDSPrimary->SetPalette(lpDDPal);
  52.     //
  53.     // Mark the colors used in the torus frames
  54.     //
  55.     int i,x,y;
  56.     // First, set all colors as unused
  57.     for(i=0; i<256; i++)
  58.     {
  59.         torusColors[i] = 0;
  60.     }
  61.     // lock the surface and scan the lower part (the torus area)
  62.     // and remember all the index's we find.
  63.     ddsd.dwSize = sizeof(ddsd);
  64.     while (lpDDSOne->Lock(NULL, &ddsd, 0, NULL) == DDERR_WASSTILLDRAWING)
  65.         ;
  66.     // Now search through the torus frames and mark used colors
  67.     for( y=480; y<480+384; y++ )
  68.     {
  69.         for( x=0; x<640; x++ )
  70.         {
  71.             torusColors[((BYTE *)ddsd.lpSurface)[y*ddsd.lPitch+x]] = 1;
  72.         }
  73.     }
  74.     lpDDSOne->Unlock(NULL);
  75.     return ddrval;
  76. } /* restoreAll */
  77. /*
  78.  * updateFrame
  79.  * 
  80.  * Decide what needs to be blitted next, wait for flip to complete,
  81.  * then flip the buffers.
  82.  */
  83. void updateFrame( void )
  84. {
  85.     static DWORD lastTickCount[4] = {0,0,0,0};
  86.     static int currentFrame[3] = {0,0,0};
  87.     DWORD thisTickCount;
  88.     RECT rcRect;
  89.     DWORD delay[4] = {50, 78, 13, 93};
  90.     int i;
  91.     int xpos[3] = {288, 190, 416};
  92.     int ypos[3] = {128, 300, 256};
  93.     PALETTEENTRY pe[256];
  94.     HRESULT ddrval;
  95.     // Decide which frame will be blitted next
  96.     thisTickCount = GetTickCount();
  97.     for(i=0; i<3; i++)
  98.     {
  99. if((thisTickCount - lastTickCount[i]) > delay[i])
  100. {
  101.     // Move to next frame;
  102.     lastTickCount[i] = thisTickCount;
  103.     currentFrame[i]++;
  104.     if(currentFrame[i] > 59)
  105. currentFrame[i] = 0;
  106. }
  107.     }
  108.     // Blit the stuff for the next frame
  109.     rcRect.left = 0;
  110.     rcRect.top = 0;
  111.     rcRect.right = 640;
  112.     rcRect.bottom = 480;
  113.     while( 1 )
  114.     {
  115.         ddrval = lpDDSBack->BltFast( 0, 0, lpDDSOne,
  116.             &rcRect, DDBLTFAST_NOCOLORKEY );
  117. if( ddrval == DD_OK )
  118. {
  119.     break;
  120. }
  121. if( ddrval == DDERR_SURFACELOST )
  122. {
  123.     ddrval = restoreAll();
  124.     if( ddrval != DD_OK )
  125.     {
  126. return;
  127.     }
  128. }
  129. if( ddrval != DDERR_WASSTILLDRAWING )
  130. {
  131.     return;
  132. }
  133.     }
  134.     if(ddrval != DD_OK)
  135.     {
  136.     return;
  137.     }
  138.     for(i=0; i<3; i++)
  139.     {
  140.         rcRect.left   = currentFrame[i]%10*64;
  141.         rcRect.top    = currentFrame[i]/10*64 + 480;
  142.         rcRect.right  = currentFrame[i]%10*64 + 64;
  143.         rcRect.bottom = currentFrame[i]/10*64 + 64 + 480;
  144. while( 1 )
  145. {
  146.     ddrval = lpDDSBack->BltFast( xpos[i], ypos[i], lpDDSOne,
  147.                                  &rcRect, DDBLTFAST_SRCCOLORKEY );
  148.     if( ddrval == DD_OK )
  149.     {
  150. break;
  151.     }
  152.     if( ddrval == DDERR_SURFACELOST )
  153.     {
  154. ddrval = restoreAll();
  155. if( ddrval != DD_OK )
  156. {
  157.     return;
  158. }
  159.     }
  160.     if( ddrval != DDERR_WASSTILLDRAWING )
  161.     {
  162. return;
  163.     }
  164. }
  165.     }
  166.     if( (thisTickCount - lastTickCount[3]) > delay[3] )
  167.     {
  168. // Change the palette
  169. if(lpDDPal->GetEntries( 0, 0, 256, pe ) != DD_OK)
  170. {
  171.     return;
  172. }
  173. for(i=1; i<256; i++)
  174. {
  175.     if(!torusColors[i])
  176.     {
  177. continue;
  178.     }
  179.     pe[i].peRed = (pe[i].peRed+2) % 256;
  180.     pe[i].peGreen = (pe[i].peGreen+1) % 256;
  181.     pe[i].peBlue = (pe[i].peBlue+3) % 256;
  182. }
  183. if(lpDDPal->SetEntries( 0, 0, 256, pe) != DD_OK)
  184. {
  185.     return;
  186. }
  187.     
  188. lastTickCount[3] = thisTickCount;
  189.     }
  190.     
  191.     // Flip the surfaces
  192.     while( 1 )
  193.     {
  194. ddrval = lpDDSPrimary->Flip( NULL, 0 );
  195. if( ddrval == DD_OK )
  196. {
  197.     break;
  198. }
  199. if( ddrval == DDERR_SURFACELOST )
  200. {
  201.     ddrval = restoreAll();
  202.     if( ddrval != DD_OK )
  203.     {
  204. break;
  205.     }
  206. }
  207. if( ddrval != DDERR_WASSTILLDRAWING )
  208. {
  209.     break;
  210. }
  211.     }
  212. } /* updateFrame */
  213. /*
  214.  * finiObjects
  215.  *
  216.  * finished with all objects we use; release them
  217.  */
  218. static void finiObjects( void )
  219. {
  220.     if( lpDD != NULL )
  221.     {
  222. if( lpDDSPrimary != NULL )
  223. {
  224.     lpDDSPrimary->Release();
  225.     lpDDSPrimary = NULL;
  226. }
  227. if( lpDDSOne != NULL )
  228. {
  229.     lpDDSOne->Release();
  230.     lpDDSOne = NULL;
  231. }
  232. if( lpDDPal != NULL )
  233. {
  234.     lpDDPal->Release();
  235.     lpDDPal = NULL;
  236. }
  237. lpDD->Release();
  238. lpDD = NULL;
  239.     }
  240. } /* finiObjects */
  241. long FAR PASCAL WindowProc( HWND hWnd, UINT message, 
  242.     WPARAM wParam, LPARAM lParam )
  243. {
  244.     switch( message )
  245.     {
  246.     case WM_ACTIVATEAPP:
  247.      bActive = wParam;
  248. break;
  249.     case WM_SETCURSOR:
  250.         SetCursor(NULL);
  251.         return TRUE;
  252.     case WM_CREATE:
  253. break;
  254.     case WM_KEYDOWN:
  255. switch( wParam )
  256. {
  257. case VK_ESCAPE:
  258.         case VK_F12:
  259.             PostMessage(hWnd, WM_CLOSE, 0, 0);
  260.     break;
  261. }
  262. break;
  263.     case WM_DESTROY:
  264.      finiObjects();
  265. PostQuitMessage( 0 );
  266. break;
  267.     }
  268.     return DefWindowProc(hWnd, message, wParam, lParam);
  269. } /* WindowProc */
  270. /*
  271.  * This function is called if the initialization function fails
  272.  */
  273. BOOL initFail( HWND hwnd )
  274. {
  275.     finiObjects();
  276.     MessageBox( hwnd, "DirectDraw Init FAILED", TITLE, MB_OK );
  277.     DestroyWindow( hwnd );
  278.     return FALSE;
  279. } /* initFail */
  280. /*
  281.  * doInit - do work required for every instance of the application:
  282.  *   create the window, initialize data
  283.  */
  284. static BOOL doInit( HINSTANCE hInstance, int nCmdShow )
  285. {
  286.     HWND hwnd;
  287.     WNDCLASS wc;
  288.     DDSURFACEDESC ddsd;
  289.     DDSCAPS ddscaps;
  290.     HRESULT ddrval;
  291.     /*
  292.      * set up and register window class
  293.      */
  294.     wc.style = CS_HREDRAW | CS_VREDRAW;
  295.     wc.lpfnWndProc = WindowProc;
  296.     wc.cbClsExtra = 0;
  297.     wc.cbWndExtra = 0;
  298.     wc.hInstance = hInstance;
  299.     wc.hIcon = LoadIcon( hInstance, IDI_APPLICATION );
  300.     wc.hCursor = LoadCursor( NULL, IDC_ARROW );
  301.     wc.hbrBackground = GetStockBrush(BLACK_BRUSH);
  302.     wc.lpszMenuName = NAME;
  303.     wc.lpszClassName = NAME;
  304.     RegisterClass( &wc );
  305.     /*
  306.      * create a window
  307.      */
  308.     hwnd = CreateWindowEx(
  309.         0,
  310. NAME,
  311. TITLE,
  312. WS_POPUP,
  313. 0,
  314. 0,
  315.         GetSystemMetrics(SM_CXSCREEN),
  316.         GetSystemMetrics(SM_CYSCREEN),
  317. NULL,
  318. NULL,
  319. hInstance,
  320.         NULL );
  321.     if( !hwnd )
  322.     {
  323. return FALSE;
  324.     }
  325.     ShowWindow( hwnd, nCmdShow );
  326.     UpdateWindow( hwnd );
  327.     SetFocus( hwnd );
  328.     /*
  329.      * create the main DirectDraw object
  330.      */
  331.     ddrval = DirectDrawCreate( NULL, &lpDD, NULL );
  332.     if( ddrval != DD_OK )
  333.     {
  334. return initFail(hwnd);
  335.     }
  336.     // Get exclusive mode
  337.     ddrval = lpDD->SetCooperativeLevel( hwnd, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN );
  338.     if( ddrval != DD_OK )
  339.     {
  340. return initFail(hwnd);
  341.     }
  342.     // Set the video mode to 640x480x8
  343.     ddrval = lpDD->SetDisplayMode( 640, 480, 8);
  344.     if(ddrval != DD_OK)
  345.     {
  346. return initFail(hwnd);
  347.     }
  348.     // Create the primary surface with 1 back buffer
  349.     ddsd.dwSize = sizeof( ddsd );
  350.     ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
  351.     ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE |
  352.   DDSCAPS_FLIP |
  353.   DDSCAPS_COMPLEX;
  354.     ddsd.dwBackBufferCount = 1;
  355.     ddrval = lpDD->CreateSurface( &ddsd, &lpDDSPrimary, NULL );
  356.     if( ddrval != DD_OK )
  357.     {
  358. return initFail(hwnd);
  359.     }
  360.     ddscaps.dwCaps = DDSCAPS_BACKBUFFER;
  361.     ddrval = lpDDSPrimary->GetAttachedSurface(&ddscaps, &lpDDSBack);
  362.     if( ddrval != DD_OK )
  363.     {
  364. return initFail(hwnd);
  365.     }
  366.     // create and set the palette
  367.     lpDDPal = DDLoadPalette(lpDD, szBitmap);
  368.     if (lpDDPal)
  369.         lpDDSPrimary->SetPalette(lpDDPal);
  370.     // Create the offscreen surface, by loading our bitmap.
  371.     lpDDSOne = DDLoadBitmap(lpDD, szBitmap, 0, 0);
  372.     if( lpDDSOne == NULL )
  373.     {
  374. return initFail(hwnd);
  375.     }
  376.     // set the color key to black
  377.     DDSetColorKey(lpDDSOne, RGB(0,0,0));
  378.     //
  379.     // Mark the colors used in the torus frames
  380.     //
  381.     int i,x,y;
  382.     // First, set all colors as unused
  383.     for(i=0; i<256; i++)
  384.     {
  385.         torusColors[i] = 0;
  386.     }
  387.     // lock the surface and scan the lower part (the torus area)
  388.     // and remember all the index's we find.
  389.     ddsd.dwSize = sizeof(ddsd);
  390.     while (lpDDSOne->Lock(NULL, &ddsd, 0, NULL) == DDERR_WASSTILLDRAWING)
  391.         ;
  392.     // Now search through the torus frames and mark used colors
  393.     for( y=480; y<480+384; y++ )
  394.     {
  395.         for( x=0; x<640; x++ )
  396.         {
  397.             torusColors[((BYTE *)ddsd.lpSurface)[y*ddsd.lPitch+x]] = 1;
  398.         }
  399.     }
  400.     lpDDSOne->Unlock(NULL);
  401.     return TRUE;
  402. } /* doInit */
  403. /*
  404.  * WinMain - initialization, message loop
  405.  */
  406. int PASCAL WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
  407. LPSTR lpCmdLine, int nCmdShow)
  408. {
  409.     MSG msg;
  410.     lpCmdLine = lpCmdLine;
  411.     hPrevInstance = hPrevInstance;
  412.     if( !doInit( hInstance, nCmdShow ) )
  413.     {
  414. return FALSE;
  415.     }
  416.     while( 1 )
  417.     {
  418. if( PeekMessage( &msg, NULL, 0, 0, PM_NOREMOVE ) )
  419. {
  420.     if( !GetMessage( &msg, NULL, 0, 0 ) )
  421.     {
  422. return msg.wParam;
  423.     }
  424.     TranslateMessage(&msg); 
  425.     DispatchMessage(&msg);
  426. }
  427. else if( bActive )
  428. {
  429.     updateFrame();
  430.         }
  431.         else
  432.         {
  433.             // make sure we go to sleep if we have nothing else to do
  434.             WaitMessage();
  435.         }
  436.     }
  437. } /* WinMain */