home *** CD-ROM | disk | FTP | other *** search
/ NEXT Generation 27 / NEXT27.iso / pc / demos / emperor / dx3.exe / SDK / SAMPLES / DDEX5 / DDEX5.CPP < prev    next >
C/C++ Source or Header  |  1996-08-28  |  11KB  |  466 lines

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