home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / graphics / directx / palette / palette.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1997-07-15  |  10.0 KB  |  478 lines

  1. /*==========================================================================
  2.  *
  3.  *  Copyright (C) 1995-1997 Microsoft Corporation. All Rights Reserved.
  4.  *
  5.  *  File:    palette.cpp
  6.  *  Content:    Does some basic palette manipulation
  7.  *
  8.  ***************************************************************************/
  9. #define WIN32_LEAN_AND_MEAN
  10. #include <windows.h>
  11. #include <windowsx.h>
  12. #include <ddraw.h>
  13. #include "resource.h"
  14. #include "lbprintf.h"
  15.  
  16. static char    szClass[32]="DDTest1Class";
  17. static char    szCaption[32]="DirectDraw Palette Test";
  18.  
  19. /*
  20.  * DirectDraw objects we will use
  21.  */
  22. #define MAX_PALETTES    4
  23. LPDIRECTDRAW        lpDD;
  24. LPDIRECTDRAWSURFACE    lpDDPSurf;
  25. LPDIRECTDRAWPALETTE    lpDDPal[MAX_PALETTES];
  26. LPDIRECTDRAWPALETTE    lpDDPalCurr;
  27.  
  28. HWND            hWndMain;
  29.  
  30. BOOL            bIsExclusive = TRUE;
  31. BOOL            bActive;
  32.  
  33.  
  34. /*
  35.  * doAttach
  36.  *
  37.  * attach palette to the primary surface
  38.  */
  39. static void doAttach( int index )
  40. {
  41.     HRESULT    ddrval;
  42.  
  43.     ddrval = lpDDPSurf->SetPalette( lpDDPal[index] );
  44.     if( ddrval == DDERR_SURFACELOST )
  45.     {
  46.         lpDDPSurf->Restore();
  47.         ddrval = lpDDPSurf->SetPalette( lpDDPal[index] );
  48.     }
  49.     if (!FAILED(ddrval))
  50.     {
  51.        LBPrintfDDRC( ddrval, "doAttach1: SetPalette" );
  52.        lpDDPalCurr = lpDDPal[index];
  53.     }
  54.     else
  55.     {
  56.     LBPrintf( "Could not attach palette" );
  57.     lpDDPalCurr = NULL;
  58.     }
  59.  
  60. } /* doAttach */
  61.  
  62. /*
  63.  * doDetach
  64.  *
  65.  * detach the current palette from the primary surface
  66.  */
  67. static void doDetach( void )
  68. {
  69.     HRESULT    ddrval;
  70.  
  71.     ddrval = lpDDPSurf->SetPalette( NULL );
  72.     if( ddrval == DDERR_SURFACELOST )
  73.     {
  74.         lpDDPSurf->Restore();
  75.         ddrval = lpDDPSurf->SetPalette( NULL );
  76.     }
  77.     LBPrintfDDRC( ddrval, "doDetach: SetPalette" );
  78.     lpDDPalCurr = NULL;
  79.  
  80. } /* doDetach */
  81.  
  82. /*
  83.  * doCycle
  84.  *
  85.  * cycle the current palette's red entries by 10
  86.  */
  87. static void doCycle( void )
  88. {
  89.     if( lpDDPalCurr != NULL )
  90.     {
  91.     #define ENTRIES 10
  92.     #define BASE 0
  93.     PALETTEENTRY    pe[ENTRIES];
  94.     HRESULT        ddrval;
  95.     int        i;
  96.  
  97.     /*
  98.      * display the original entries
  99.      */
  100.     ddrval = lpDDPalCurr->GetEntries( 0, BASE, ENTRIES, pe );
  101.     if( ddrval == DDERR_SURFACELOST )
  102.     {
  103.             lpDDPSurf->Restore();
  104.         ddrval = lpDDPalCurr->GetEntries( 0, BASE, ENTRIES, pe );
  105.     }
  106.     LBPrintfDDRC( ddrval, "GetEntries" );
  107.     LBPrintf( "Old Entries" );
  108.     for( i=0;i<ENTRIES;i++ )
  109.     {
  110.         LBPrintf( "    pe[%d] (r,g,b) = (%d,%d,%d)", i, pe[i].peRed,
  111.             pe[i].peGreen, pe[i].peBlue );
  112.     }
  113.  
  114.     /*
  115.      * cycle the red values
  116.      */
  117.     for( i=0;i<ENTRIES;i++ )
  118.     {
  119.         pe[i].peRed = (BYTE) (((int)pe[i].peRed + 50) % 256);
  120.     }
  121.     ddrval = lpDDPalCurr->SetEntries( 0, BASE, ENTRIES, pe );
  122.     if( ddrval == DDERR_SURFACELOST )
  123.     {
  124.             lpDDPSurf->Restore();
  125.         ddrval = lpDDPalCurr->SetEntries( 0, BASE, ENTRIES, pe );
  126.     }
  127.     LBPrintfDDRC( ddrval, "SetEntries" );
  128.  
  129.     /*
  130.      * display the new values
  131.      */
  132.     ddrval = lpDDPalCurr->GetEntries( 0, BASE, ENTRIES, pe );
  133.     if( ddrval == DDERR_SURFACELOST )
  134.     {
  135.             lpDDPSurf->Restore();
  136.         ddrval = lpDDPalCurr->GetEntries( 0, BASE, ENTRIES, pe );
  137.     }
  138.     LBPrintfDDRC( ddrval, "GetEntries" );
  139.     LBPrintf( "New Entries" );
  140.     for( i=0;i<ENTRIES;i++ )
  141.     {
  142.         LBPrintf( "    pe[%d] (r,g,b) = (%d,%d,%d)", i, pe[i].peRed,
  143.             pe[i].peGreen, pe[i].peBlue );
  144.     }
  145.     }
  146.     else
  147.     {
  148.     LBPrintf( "No palette attached" );
  149.     }
  150.  
  151. } /* doCycle */
  152.  
  153. /*
  154.  * resetExclusiveAndPalettes
  155.  *
  156.  * Sets exclusive mode to the desired value, and the rebuilds
  157.  * the palettes.
  158.  *
  159.  * Palettes in exclusive mode bypass GDI and go directly to the display
  160.  * driver, so the performance is much higher.
  161.  */
  162. static BOOL resetExclusiveAndPalettes( BOOL excl )
  163. {
  164.     LPPALETTEENTRY    ppe;
  165.     int            i;
  166.     HRESULT        ddrval;
  167.  
  168.     /*
  169.      * create palette entries
  170.      */
  171.     ppe = (LPPALETTEENTRY) LocalAlloc( LPTR, sizeof( PALETTEENTRY ) * 256 );
  172.     if( ppe == NULL )
  173.     {
  174.     return FALSE;
  175.     }
  176.  
  177.     /*
  178.      * release existing palettes
  179.      */
  180.     for( i=0;i<MAX_PALETTES;i++ )
  181.     {
  182.     if( lpDDPal[i] != NULL )
  183.     {
  184.         ddrval = lpDDPal[i]->Release();
  185.         LBPrintfDDRC( ddrval, "Release" );
  186.         lpDDPal[i] = NULL;
  187.     }
  188.     }
  189.  
  190.     /*
  191.      * No current palette any more.
  192.      */
  193.     lpDDPalCurr = NULL;
  194.  
  195.     if( excl )
  196.     {
  197.     ddrval = lpDD->SetCooperativeLevel( hWndMain, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN );
  198.     }
  199.     else
  200.     {
  201.     ddrval = lpDD->SetCooperativeLevel( hWndMain, DDSCL_NORMAL );
  202.     }
  203.         
  204.     LBPrintfDDRC( ddrval, "SetCooperativeLevel" );
  205.  
  206.     /*
  207.      * set up 4 palettes
  208.      */
  209.     ppe[0].peRed = 0;
  210.     ppe[0].peGreen = 0;
  211.     ppe[0].peBlue = 0;
  212.     ppe[255].peRed = 255;
  213.     ppe[255].peGreen = 255;
  214.     ppe[255].peBlue = 255;
  215.  
  216.     for( i=1;i<255;i++ )
  217.     {
  218.     ppe[i].peRed = 0;
  219.     ppe[i].peGreen = 0;
  220.     ppe[i].peBlue = 0;
  221.     }
  222.     ddrval = lpDD->CreatePalette( DDPCAPS_8BIT, ppe, &lpDDPal[0], NULL );
  223.     LBPrintfDDRC( ddrval, "CreatePalette" );
  224.  
  225.     for( i=1;i<255;i++ )
  226.     {
  227.     ppe[i].peRed = 0;
  228.     ppe[i].peGreen = 255;
  229.     ppe[i].peBlue = 255;
  230.     }
  231.     ddrval = lpDD->CreatePalette( DDPCAPS_8BIT, ppe, &lpDDPal[1], NULL );
  232.     LBPrintfDDRC( ddrval, "CreatePalette" );
  233.  
  234.     for( i=1;i<255;i++ )
  235.     {
  236.     ppe[i].peRed = 255;
  237.     ppe[i].peGreen = 255;
  238.     ppe[i].peBlue = 0;
  239.     }
  240.     ddrval = lpDD->CreatePalette( DDPCAPS_8BIT, ppe, &lpDDPal[2], NULL );
  241.     LBPrintfDDRC( ddrval, "CreatePalette" );
  242.  
  243.     for( i=1;i<255;i++ )
  244.     {
  245.     ppe[i].peRed = 255;
  246.     ppe[i].peGreen = 0;
  247.     ppe[i].peBlue = 255;
  248.     }
  249.     ddrval = lpDD->CreatePalette( DDPCAPS_8BIT, ppe, &lpDDPal[3], NULL );
  250.     LBPrintfDDRC( ddrval, "CreatePalette" );
  251.     LocalFree( ppe );
  252.  
  253.     for( i=0;i<MAX_PALETTES;i++ )
  254.     {
  255.     LBPrintf( "lpDDPal %d = %08lx", i+1, lpDDPal[i] );
  256.     }
  257.     return TRUE;
  258.  
  259. } /* resetExclusiveAndPalettes */
  260.  
  261. /*
  262.  * WindowProc
  263.  *
  264.  * Messages for our window are handled here
  265.  */
  266. LRESULT CALLBACK WindowProc( HWND hWnd, unsigned uMsg, WPARAM wParam, LPARAM lParam )
  267. {
  268.  
  269.     switch( uMsg )
  270.     {
  271.     case WM_COMMAND:
  272.     switch( LOWORD( wParam ) )
  273.     {
  274.     case IDM_EXCLUSIVE:
  275.         bIsExclusive = !bIsExclusive;
  276.         resetExclusiveAndPalettes( bIsExclusive );
  277.         break;
  278.     case IDM_ATTACH1:
  279.     case IDM_ATTACH2:
  280.     case IDM_ATTACH3:
  281.     case IDM_ATTACH4:
  282.         doAttach( LOWORD( wParam ) - IDM_ATTACH1 );
  283.         break;
  284.     case IDM_DETACH:
  285.         doDetach();
  286.         break;
  287.     case IDM_CYCLE:
  288.         doCycle();
  289.         break;
  290.     case IDM_CLEAR:
  291.         LBClear();
  292.         break;
  293.     case IDM_EXIT:
  294.         DestroyWindow( hWnd );
  295.         break;
  296.     }
  297.     break;
  298.  
  299.     case WM_PAINT:
  300.     {
  301.     PAINTSTRUCT    ps;
  302.  
  303.     BeginPaint( hWnd, &ps );
  304.     EndPaint( hWnd, &ps );
  305.     break;
  306.     }
  307.  
  308.     case WM_INITMENU:
  309.     CheckMenuItem( (HMENU) wParam, IDM_EXCLUSIVE, MF_BYCOMMAND |
  310.             (bIsExclusive ? MF_CHECKED:MF_UNCHECKED) );
  311.     break;
  312.  
  313.     case WM_SIZE:
  314.     /*
  315.      * resize our message listbox
  316.      */
  317.     LBSize( LOWORD( lParam ), HIWORD( lParam ) );
  318.     break;
  319.  
  320.     case WM_DESTROY:
  321.     /*
  322.      * free all DirectDraw objects
  323.      */
  324.     if( lpDD != NULL )
  325.     {
  326.         int i;
  327.  
  328.         for( i=0;i<MAX_PALETTES;i++ )
  329.         {
  330.         if( lpDDPal[i] != NULL )
  331.         {
  332.             lpDDPal[i]->Release();
  333.             lpDDPal[i] = NULL;
  334.         }
  335.         }
  336.  
  337.         if( lpDDPSurf != NULL )
  338.         {
  339.         lpDDPSurf->Release();
  340.         lpDDPSurf = NULL;
  341.         }
  342.         lpDD->Release();
  343.         lpDD = NULL;
  344.     }
  345.     PostQuitMessage( 0 );
  346.     break;
  347.  
  348.     default:
  349.     return DefWindowProc( hWnd, uMsg, wParam, lParam );
  350.     }
  351.     return 0L;
  352.  
  353. } /* WindowProc */
  354.  
  355. /*
  356.  * doInit - do work required for every instance of the application:
  357.  *          create the window, initialize data
  358.  */
  359. static BOOL doInit( HINSTANCE hInstance, int nCmdShow )
  360. {
  361.     WNDCLASS        wc;
  362.     HRESULT        ddrval;
  363.     DDSURFACEDESC    ddsd;
  364.  
  365.     /*
  366.      * set up and register window class
  367.      */
  368.     wc.style = CS_HREDRAW | CS_VREDRAW;
  369.     wc.lpfnWndProc = (WNDPROC) WindowProc;
  370.     wc.cbClsExtra = 0;
  371.     wc.cbWndExtra = sizeof( DWORD );
  372.     wc.hInstance = hInstance;
  373.     wc.hIcon = LoadIcon( hInstance, IDI_APPLICATION );
  374.     wc.hCursor = LoadCursor( NULL, IDC_ARROW );
  375.     wc.hbrBackground = (HBRUSH)GetStockObject( WHITE_BRUSH );
  376.     wc.lpszMenuName = MAKEINTRESOURCE( IDR_MENU );
  377.     wc.lpszClassName = szClass;
  378.     if( !RegisterClass( &wc ) )
  379.     {
  380.     return FALSE;
  381.     }
  382.     
  383.     /*
  384.      * create a window
  385.      */
  386.     hWndMain = CreateWindow(
  387.     szClass,        // class
  388.     szCaption,        // caption
  389.     WS_OVERLAPPEDWINDOW,    // style 
  390.     CW_USEDEFAULT,        // x pos
  391.     CW_USEDEFAULT,        // y pos
  392.     CW_USEDEFAULT,        // width
  393.     CW_USEDEFAULT,        // height
  394.     NULL,            // parent window
  395.     NULL,            // menu 
  396.     hInstance,        // instance
  397.     NULL            // parms
  398.     );
  399.             
  400.     if( !hWndMain )
  401.     {
  402.     return FALSE;
  403.     }
  404.  
  405.     LBCreate( hWndMain, 100 );
  406.  
  407.     ShowWindow( hWndMain, nCmdShow );
  408.     UpdateWindow( hWndMain );
  409.  
  410.     /*
  411.      * create the main DirectDraw object
  412.      */
  413.     ddrval = DirectDrawCreate( NULL, &lpDD, NULL );
  414.     LBPrintfDDRC( ddrval, "DirectDrawCreate" );
  415.     if( ddrval != DD_OK )
  416.     {
  417.     DestroyWindow( hWndMain );
  418.     return FALSE;
  419.     }
  420.  
  421.     ddrval = lpDD->SetCooperativeLevel( hWndMain, DDSCL_NORMAL );
  422.  
  423.     /*
  424.      * create the primary surface
  425.      */
  426.     ddsd.dwSize = sizeof( ddsd );
  427.     ddsd.dwFlags = DDSD_CAPS;
  428.     ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
  429.     ddrval = lpDD->CreateSurface( &ddsd, &lpDDPSurf, NULL );
  430.     LBPrintfDDRC( ddrval, "CreateSurface" );
  431.     if( ddrval != DD_OK )
  432.     {
  433.     lpDD->Release();
  434.     DestroyWindow( hWndMain );
  435.     return FALSE;
  436.     }
  437.  
  438.     /*
  439.      * set up palettes
  440.      */
  441.     if( !resetExclusiveAndPalettes( bIsExclusive ) )
  442.     {
  443.     lpDDPSurf->Release();
  444.     lpDD->Release();
  445.     DestroyWindow( hWndMain );
  446.     return FALSE;
  447.     }
  448.     
  449.     return TRUE;
  450.             
  451. } /* doInit */
  452.  
  453. /*
  454.  * WinMain - initialization, message loop
  455.  */
  456. int PASCAL WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
  457.             LPSTR lpCmdLine, int nCmdShow)
  458. {
  459.     MSG        msg;
  460.  
  461.     hPrevInstance = hPrevInstance;
  462.     lpCmdLine = lpCmdLine;
  463.  
  464.     if( !doInit( hInstance, nCmdShow ) )
  465.     {
  466.     return FALSE;
  467.     }
  468.  
  469.     while( GetMessage( &msg, NULL, NULL, NULL ) )
  470.     {
  471.     TranslateMessage( &msg );
  472.     DispatchMessage( &msg );
  473.     }
  474.  
  475.     return( msg.wParam );
  476.  
  477. } /* WinMain */
  478.