home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / tolkit45.zip / os2tk45 / samples / mm / beehive / beehive.c < prev    next >
Text File  |  1999-05-11  |  26KB  |  822 lines

  1. /***************************************************************************
  2. *
  3. *  File name       : BEEHIVE.C
  4. *
  5. * Description      : This program demonstrates the use of the sprite compiler
  6. *                    and the advantages of compiled sprites over normal
  7. *                    sprite alorithms.
  8. *
  9. * Entry Points     :
  10. *                    Initialize()
  11. *                    SetupDive()
  12. *                    SetupFullScreen()
  13. *                    ReadFile()
  14. *                    Main()
  15. *                    MyWindowProc()
  16. *
  17. * DIVE API's       :
  18. *                    DiveBlitImage
  19. *                    DiveAllocImageBuffer
  20. *                    DiveOpen
  21. *                    DiveFreeImageBuffer
  22. *                    DiveClose
  23. *                    DiveSetupBlitter
  24. *
  25. * Copyright        : COPYRIGHT IBM CORPORATION, 1991, 1992, 1993, 1994, 1995
  26. *
  27. *        DISCLAIMER OF WARRANTIES.  The following [enclosed] code is
  28. *        sample code created by IBM Corporation. This sample code is not
  29. *        part of any standard or IBM product and is provided to you solely
  30. *        for  the purpose of assisting you in the development of your
  31. *        applications.  The code is provided "AS IS", without
  32. *        warranty of any kind.  IBM shall not be liable for any damages
  33. *        arising out of your use of the sample code, even if they have been
  34. *        advised of the possibility of such damages.
  35. *
  36. ****************************************************************************/
  37.  
  38.  
  39.  
  40. #define INCL_DOS
  41. #define INCL_GPI
  42. #define INCL_WIN
  43. #define INCL_DOSSEMAPHORES
  44.  
  45. #include <os2.h>
  46. #include <stdio.h>
  47. #include <string.h>
  48. #include <stdlib.h>
  49. #define  _MEERROR_H_
  50. #include <mmioos2.h>
  51. #include <dive.h>
  52. #include <fourcc.h>
  53.  
  54. #include "beehive.h"
  55.  
  56.  
  57.  
  58. // Global definitions
  59. //
  60. HAB       hab;                         // PM anchor block handle
  61. HDIVE     hDive;
  62. HWND      hwndFrame;                   // Frame window handle
  63. HWND      hwndClient;                  // Client window handle
  64. HPAL      hpal;                        // Handle to new palette
  65. HMTX      hmtx;                        // used to serialize buffer access
  66.  
  67. BOOL      fVrnDisabled = TRUE;
  68. BOOL      fEndThread = FALSE;
  69. BOOL      fUseCompiledBlit = TRUE;
  70. ULONG     ulrc;
  71.  
  72. BMPDATA     bmpScene;
  73. BMPDATA     bmpImage1,                 // Bee moving to the right
  74.             bmpImage1b,                // Bee moving to the right with wing
  75.             bmpImage2,                 // Bee moving to the left
  76.             bmpImage2b,                // Bee moving to the left with wing
  77.             bmpBackGround;             // Back Ground
  78.  
  79. SPRITEDATA  FirstSprite;
  80.  
  81. DIVE_CAPS DiveCaps = {0};
  82.  
  83. BOOL      fFSBase = TRUE;               // FS DIVE support in base OS
  84.  
  85.  
  86. //**************************************************************************
  87. // Name           : SetupFullScreen
  88. //
  89. // Description    : This procedure provides for full screen dive support
  90. //                  by loading the GAMESRVR dll and retrieving the address
  91. //                  of the init procedure.
  92. //
  93. // Returns        : 1 = Fail
  94. //                  0 = Successful
  95. //
  96. //**************************************************************************
  97.  
  98. ULONG SetupFullScreen( VOID )
  99. {
  100.     PFN       pfnInitGameFrameProc;     // GameSrvr
  101.     UCHAR     szErrorBuf[256];          // String used for error msgs
  102.     HMODULE   hmodGameSrvr;             // Module handle for GAMESRVR
  103.  
  104.     ULONG     aulVersion[2];            // OS/2 version number
  105.     ULONG     pvmi;
  106.     ULONG     ul;
  107.  
  108.  
  109.  
  110.     DosQuerySysInfo( QSV_VERSION_MAJOR, QSV_VERSION_MINOR, &aulVersion, 8 );
  111.  
  112.     if (aulVersion[0] == 20 && aulVersion[1] <= 30 )
  113.     {
  114.        fFSBase = FALSE;
  115.  
  116.        if ( 0 == DosLoadModule( szErrorBuf, 256, "GAMESRVR", &hmodGameSrvr ) )
  117.        {
  118.            if ( 0 == DosQueryProcAddr( hmodGameSrvr, 1, 0, &pfnInitGameFrameProc ) )
  119.            {
  120.                ( pfnInitGameFrameProc )( hwndFrame, 0 );
  121.            }
  122.        }
  123.        else
  124.        {
  125.            WinMessageBox( HWND_DESKTOP, HWND_DESKTOP,
  126.                    (PSZ)"usage: BEEHIVE failed to load GAMESRVR.DLL.",
  127.                    (PSZ)"Error!", 0, MB_OK | MB_MOVEABLE );
  128.  
  129.             return( 1 );
  130.        }
  131.     }
  132.     else
  133.     {
  134.        fFSBase = TRUE;
  135.        DosLoadModule( szErrorBuf, 256, "PMMERGE", &hmodGameSrvr );
  136.        if ( 0 == DosQueryProcAddr( hmodGameSrvr, 6099, 0, &pfnInitGameFrameProc ) )
  137.        {
  138.            ( pfnInitGameFrameProc )( hwndFrame, 0 );
  139.        }
  140.        else
  141.        {
  142.            WinMessageBox( HWND_DESKTOP, HWND_DESKTOP,
  143.                    (PSZ)"usage: BEEHIVE failed to access FS functions.",
  144.                    (PSZ)"Error!", 0, MB_OK | MB_MOVEABLE );
  145.             return( 1 );
  146.        }
  147.     }
  148.  
  149.   WinSendMsg( hwndFrame, WM_GetVideoModeTable, (MPARAM)&pvmi, (MPARAM)&ul );
  150.  
  151.    return( 0 );
  152. }
  153.  
  154.  
  155.  
  156. //***************************************************************************
  157. //     Name:      SetupDive
  158. //
  159. //    Description:
  160. //
  161. //       This routine will check that the system can support DIVE. One of
  162. //    the requirements is that the display must be setup for at least 256
  163. //    colors. If successful, this routine will open one dive instance. If
  164. //    unsuccessful, a dialog box will be displayed and the routine will
  165. //    return a non zero value.
  166. //
  167. //    Parameters:    NONE
  168. //
  169. //    Returns:       0 = successful
  170. //                   1 = failed
  171. //
  172. //***************************************************************************
  173.  
  174. ULONG SetupDive ( VOID )
  175. {
  176. //   DIVE_CAPS DiveCaps = {0};
  177.    FOURCC    fccFormats[100] = {0};        // Color format code
  178.  
  179.    // Get the screen capabilities, and if the system support only 16 colors
  180.    // the sample should be terminated.
  181.    //
  182.    DiveCaps.pFormatData = fccFormats;
  183.    DiveCaps.ulFormatLength = 120;
  184.    DiveCaps.ulStructLen = sizeof(DIVE_CAPS);
  185.  
  186.    DiveQueryCaps ( &DiveCaps, DIVE_BUFFER_SCREEN );
  187.  
  188.    if ( DiveCaps.ulDepth < 8 )
  189.    {
  190.       WinMessageBox( HWND_DESKTOP, HWND_DESKTOP,
  191.           (PSZ)"usage: The sample program can not run on this system environment.",
  192.           (PSZ)"PARALAX.EXE - DIVE Sample", 0, MB_OK | MB_INFORMATION );
  193.       return ( 1 );
  194.    }
  195.  
  196.    // Get an instance of DIVE APIs.
  197.    //
  198.    if ( DiveOpen ( &hDive, FALSE, 0 ) )
  199.    {
  200.       WinMessageBox( HWND_DESKTOP, HWND_DESKTOP,
  201.                (PSZ)"usage: Unable to open a DIVE instance.",
  202.                (PSZ)"PARALAX.EXE - Game Sample", 0, MB_OK | MB_INFORMATION );
  203.       return ( 1 );
  204.    }
  205.  
  206.    return( 0 );
  207.  
  208. }
  209.  
  210. //***************************************************************************
  211. //
  212. // Description   : The main "off screen" image buffer is allocated here and
  213. //                 all of the required images are read from local pcx files.
  214. //                 Also, the first sprite in the animation is initialized.
  215. //
  216. // Parameters    : None
  217. //
  218. // Return        : 0 = Successful
  219. //                 1 = Failed
  220. //
  221. //***************************************************************************
  222.  
  223. ULONG Initialize( VOID )
  224. {
  225.    // Create a dive instance
  226.    //
  227.    ulrc = SetupDive();
  228.    if( ulrc )
  229.       return ulrc;
  230.  
  231.    ulrc = ReadFile( "bee1.pcx", &bmpImage1 );     // bee moving right
  232.    ulrc += ReadFile( "bee1b.pcx", &bmpImage1b );   // bee moving right with wing
  233.    ulrc += ReadFile( "bee2.pcx", &bmpImage2 );     // bee moving left
  234.    ulrc += ReadFile( "bee2b.pcx", &bmpImage2b );   // bee moving left with wing
  235.    ulrc += ReadFile( "honey.pcx", &bmpBackGround );
  236.    if( ulrc )
  237.       return ulrc;
  238.  
  239.    // Associate dos buffer with dive.
  240.    //
  241.    bmpScene.ulWidth = bmpBackGround.ulWidth;
  242.    bmpScene.ulHeight = bmpBackGround.ulHeight;
  243.  
  244.    // Allocate memory for scene buffer
  245.    //
  246.    ulrc = DosAllocMem ( (PPVOID)&bmpScene.pbBuffer,
  247.                         bmpScene.ulWidth * bmpScene.ulHeight,
  248.                         MY_ALLOC_FLAGS );
  249.    if( ulrc ) return( ulrc );
  250.  
  251.    memset( bmpScene.pbBuffer, 0, bmpScene.ulWidth * bmpScene.ulHeight );
  252.  
  253.    bmpScene.ulImage = 0;
  254.    ulrc = DiveAllocImageBuffer ( hDive,
  255.                           &bmpScene.ulImage,
  256.                           FOURCC_LUT8,
  257.                           bmpScene.ulWidth,
  258.                           bmpScene.ulHeight,
  259.                           0,
  260.                           bmpScene.pbBuffer );
  261.    if( ulrc ) return ulrc;
  262.  
  263.    // Generate a blitter for images
  264.    //
  265.    ulrc += GenBlitSprite( (PPVOID)&bmpImage1.pfnBlit,   // pointer to blitter
  266.                   bmpImage1.pbBuffer,           // Pointer to image data
  267.                   bmpImage1.ulWidth,            // Width of image
  268.                   bmpImage1.ulHeight,           // Height of image
  269.                   bmpScene.ulWidth,             // Width of scene buffer
  270.                   0 );                          // Transparent color
  271.  
  272.    ulrc += GenBlitSprite( (PPVOID)&bmpImage1b.pfnBlit,   // pointer to blitter
  273.                   bmpImage1b.pbBuffer,           // Pointer to image data
  274.                   bmpImage1b.ulWidth,            // Width of image
  275.                   bmpImage1b.ulHeight,           // Height of image
  276.                   bmpScene.ulWidth,             // Width of scene buffer
  277.                   0 );                          // Transparent color
  278.  
  279.    ulrc += GenBlitSprite( (PPVOID)&bmpImage2.pfnBlit,   // pointer to blitter
  280.                   bmpImage2.pbBuffer,           // Pointer to image data
  281.                   bmpImage2.ulWidth,            // Width of image
  282.                   bmpImage2.ulHeight,           // Height of image
  283.                   bmpScene.ulWidth,             // Width of scene buffer
  284.                   0 );                          // Transparent color
  285.  
  286.    ulrc += GenBlitSprite( (PPVOID)&bmpImage2b.pfnBlit,   // pointer to blitter
  287.                   bmpImage2b.pbBuffer,           // Pointer to image data
  288.                   bmpImage2b.ulWidth,            // Width of image
  289.                   bmpImage2b.ulHeight,           // Height of image
  290.                   bmpScene.ulWidth,             // Width of scene buffer
  291.                   0 );                          // Transparent color
  292.  
  293.    if( ulrc ) return ulrc;
  294.  
  295.    // Initialize sprite control structure
  296.    //
  297.    FirstSprite.pbmp = &bmpImage1;         // Set first frame of sprite
  298.    FirstSprite.ulPositionX = 0;           // Start sprite at upper left
  299.    FirstSprite.ulPositionY = 0;
  300.    FirstSprite.lDeltaX    = 4;            // Default velocity
  301.    FirstSprite.lDeltaY    = 2;
  302.    FirstSprite.pNextSprite = NULL;
  303.  
  304.    // Create a mutex semaphore for serializing access to video buffers.
  305.    //
  306.    DosCreateMutexSem( (PSZ)NULL, &hmtx, 0UL, FALSE );
  307.  
  308.    return( 0 );
  309.  
  310. }
  311.  
  312.  
  313.  
  314. //***************************************************************************
  315. //
  316. // Name          : MyWindowProc
  317. //
  318. // Description   : Window procedure.
  319. //
  320. // Concepts      :
  321. //
  322. // Parameters    : Message parameter 1
  323. //                 Message parameter 2
  324. //
  325. // Return        : calling WinDefWindowProc
  326. //
  327. //***************************************************************************
  328.  
  329. MRESULT EXPENTRY MyWindowProc ( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 )
  330. {
  331.    HRGN     hrgn;                   // Region handle
  332.    RGNRECT  rgnCtl;                 // Processing control structure
  333.    RECTL    rclBound;               // Bounding rectangle for blitting
  334.    POINTL   pointl;                 // Lower left corner of window
  335.    SWP      swp;                    // Standard window position
  336.    RECTL    rcls[50];               // Visible rectangles
  337.    ULONG    ulNumRcls;
  338.  
  339.    USHORT   fsKeyFlags;             // Virtual key message flags.
  340.    PSPRITEDATA  pSprite,            // Sprite data structure
  341.                 pNewSprite;
  342.  
  343.    SETUP_BLITTER SetupBlitter;      // structure for DiveSetupBlitter
  344.  
  345.    static HDC  hdc;                 // Device context for client window
  346.    static HPS  hps;                 // Presentation space handle
  347.    static BOOL fSwitching = FALSE;  // TRUE when switchine to/from full screen
  348.    static BOOL fFullScreen = FALSE; // TRUE when in full screen
  349.  
  350.    PQMSG     pqmsg;
  351.  
  352.    switch( msg )
  353.    {
  354.    case WM_CREATE:
  355.  
  356.       // Create a presentation space
  357.       //
  358.       hdc = WinOpenWindowDC( hwnd );
  359.       hps = WinGetPS ( hwnd );
  360.       break;
  361.  
  362.    case WM_NotifyVideoModeChange:
  363.  
  364.       // If mp1 == 0 then GAMESRVR is about to switch to full screen mode
  365.       // and we need to turn off blitting. If mp1 is non zero then GAMSRVR
  366.       // has just finished a transition and we have to check what mode we
  367.       // are now in. The current mode is indicated by mp2 where 0 or 1 is
  368.       // desktop mode and anything else is full screen mode. Currently,
  369.       // full screen mode only supports mode 13. This will be extended
  370.       // in the future.
  371.       //
  372.       if( (ULONG)mp1 == 0 )
  373.       {
  374.          fSwitching = TRUE;
  375.          fVrnDisabled = TRUE;
  376.  
  377.          printf( "beginning switch screen mode \n ");
  378.  
  379.          // Grab the mutex semaphore to stop blitting
  380.          //
  381.          DosRequestMutexSem( hmtx, SEM_INDEFINITE_WAIT );
  382.  
  383.          printf( "recieved mutex sem \n" );
  384.       }
  385.       else
  386.       {
  387.          // Determine the mode we are now in
  388.          //
  389.          if( ( (ULONG)mp2 == 0 ) || ( (ULONG)mp2 == 1 ) )
  390.          {
  391.             fFullScreen = FALSE;
  392.          printf( "done switching to desktop mode\n" );
  393.          }
  394.  
  395.          else
  396.          {
  397.             fFullScreen = TRUE;
  398.          printf( "done switching to full screen \n" );
  399.          }
  400.  
  401.          // Indicate that we are done switching modes
  402.          //
  403.          fSwitching = FALSE;
  404.  
  405.          // Release the mutex semaphore to enable blitting
  406.          //
  407.          DosReleaseMutexSem( hmtx );
  408.  
  409.          printf( "mutex sem released\n" );
  410.  
  411.          // Post a message to setup dive
  412.          //
  413.          WinPostMsg( hwndFrame, WM_VRNENABLED, 0L, 0L );
  414.       }
  415.       break;
  416.  
  417.    case WM_COMMAND:
  418.  
  419.       switch ( SHORT1FROMMP ( mp1 ) )
  420.       {
  421.       case ID_EXIT:
  422.  
  423.          // Make sure that we are in desk top mode
  424.          //
  425.          WinSendMsg( hwndFrame, WM_SetVideoMode, (MPARAM)WS_DesktopDive, 0 );
  426.  
  427.          // Post to quit the dispatch message loop.
  428.          //
  429.          WinPostMsg ( hwnd, WM_QUIT, 0L, 0L );
  430.          break;
  431.  
  432.       case ID_NEWTEXT:
  433.  
  434.          // Write new text string to the title bar
  435.          //
  436.          WinSetWindowText ( hwndFrame, (PSZ)mp2 );
  437.          break;
  438.  
  439.       case ID_FULLSCRN:
  440.  
  441.          // Indicate that we are switching to full screen mode
  442.          // and disable blitting.
  443.          //
  444.          fVrnDisabled = TRUE;
  445.          fSwitching = TRUE;
  446.  
  447.          // Post the message to switch to full screen mode.
  448.          //
  449.          WinPostMsg( hwndFrame,
  450.                      WM_SetVideoMode,
  451.                      (MPARAM)WS_FullScreenDive,
  452.                      0 );
  453.          break;
  454.  
  455.       case ID_NORMAL:
  456.          // The user has requested that we switch to normal blit
  457.          // mode. Setting this flag will cause the animation module
  458.          // to use a normal blit routine instead of the compiled
  459.          // blit routines.
  460.          //
  461.          fUseCompiledBlit = FALSE;
  462.          break;
  463.  
  464.       case ID_COMPILED:
  465.          // The user has requested that we use the compiled blit routines
  466.          // Setting this flag will cause the animation module to use the
  467.          // compiled blit routines.
  468.          //
  469.          fUseCompiledBlit = TRUE;
  470.          break;
  471.  
  472.  
  473.       default:
  474.  
  475.          // Let PM handle this message.
  476.          //
  477.          return WinDefWindowProc ( hwnd, msg, mp1, mp2 );
  478.       }
  479.       break;
  480.  
  481.  
  482.    case WM_VRNDISABLED:
  483.  
  484.       DiveSetupBlitter ( hDive, 0 );
  485.       fVrnDisabled = TRUE;
  486.       break;
  487.  
  488.    case WM_VRNENABLED:
  489.  
  490.       // Break if we are in the process of switching modes.
  491.       //
  492.       if( fSwitching ) break;
  493.  
  494.       // If we are in full screen mode then the blitter parameters are
  495.       // set to accomodate mode 13. Other wise we need the blitter
  496.       // parameters to match the window properties.
  497.       //
  498.       if( fFullScreen )
  499.       {
  500.          swp.cx = 320;              // Set width for mode 13.
  501.          swp.cy = 200;              // Set height for mode 13.
  502.          pointl.x = 0;              // Set window corner to origin
  503.          pointl.y = 0;
  504.          ulNumRcls = 1;             // Only one rectangle in full screen
  505.          rcls[0].xLeft = 0;
  506.          rcls[0].xRight = 320;
  507.          rcls[0].yBottom = 0;
  508.          rcls[0].yTop = 200;
  509.       }
  510.       else
  511.       {
  512.          // Find the window position and size, relative to parent.
  513.          //
  514.          WinQueryWindowPos ( hwndClient, &swp );
  515.  
  516.          // Convert the point to offset from desktop lower left.
  517.          //
  518.          pointl.x = swp.x;
  519.          pointl.y = swp.y;
  520.  
  521.          WinMapWindowPoints ( hwndFrame, HWND_DESKTOP,
  522.                               &pointl, 1 );
  523.  
  524.          hrgn = GpiCreateRegion ( hps, 0L, NULL );
  525.          if ( hrgn )
  526.          {
  527.             // NOTE: If mp1 is zero, then this was just a move message.
  528.             // Illustrate the visible region on a WM_VRNENABLE.
  529.             //
  530.             WinQueryVisibleRegion ( hwnd, hrgn );
  531.             rgnCtl.ircStart     = 0;
  532.             rgnCtl.crc          = 50;
  533.             rgnCtl.ulDirection  = 1;
  534.  
  535.             // Get the all visible rectangles
  536.             //
  537.             if( !GpiQueryRegionRects( hps, hrgn, NULL, &rgnCtl, rcls ))
  538.             {
  539.                DiveSetupBlitter ( hDive, 0 );
  540.                GpiDestroyRegion ( hps, hrgn );
  541.                break;
  542.             }
  543.  
  544.             ulNumRcls = rgnCtl.crcReturned;
  545.             GpiDestroyRegion( hps, hrgn );
  546.  
  547.             // Release presentation space
  548.             //
  549.             WinReleasePS( hps );
  550.  
  551.          } // End if
  552.  
  553.       } // End else
  554.  
  555.       SetupBlitter.ulStructLen = sizeof ( SETUP_BLITTER );
  556.       SetupBlitter.fccSrcColorFormat = FOURCC_LUT8;
  557.       SetupBlitter.ulSrcWidth = bmpScene.ulWidth;
  558.       SetupBlitter.ulSrcHeight = bmpScene.ulHeight;
  559.       SetupBlitter.ulSrcPosX = 0;
  560.       SetupBlitter.ulSrcPosY = 0;
  561.       SetupBlitter.fInvert = FALSE;
  562.       SetupBlitter.ulDitherType = 1;
  563.  
  564.       SetupBlitter.fccDstColorFormat = FOURCC_SCRN;
  565.       SetupBlitter.ulDstWidth = swp.cx;
  566.       SetupBlitter.ulDstHeight = swp.cy;
  567.       SetupBlitter.lDstPosX = 0;
  568.       SetupBlitter.lDstPosY = 0;
  569.       SetupBlitter.lScreenPosX = pointl.x;
  570.       SetupBlitter.lScreenPosY = pointl.y;
  571.       SetupBlitter.ulNumDstRects = ulNumRcls;
  572.       SetupBlitter.pVisDstRects = rcls;
  573.       DiveSetupBlitter ( hDive, &SetupBlitter );
  574.  
  575.       // Enable blitting
  576.       //
  577.       fVrnDisabled = FALSE;
  578.       break;
  579.  
  580.    case WM_CLOSE:
  581.  
  582.       // Post to quit the dispatch message loop.
  583.       //
  584.       WinPostMsg ( hwnd, WM_QUIT, 0L, 0L );
  585.       break;
  586.  
  587.    case WM_CHAR:
  588.       // If the user presses the 'h' or 'H' key, then start a timer that
  589.       // causes sprites to be generated. When the user releases the key
  590.       // then stop the timer.
  591.  
  592.       // Character input: first two byte of message is the character code.
  593.       //
  594.       fsKeyFlags = (USHORT) SHORT1FROMMP ( mp1 );
  595.  
  596.       // If the key is released then stop the timer
  597.       //
  598.       if( fsKeyFlags & KC_KEYUP )
  599.       {
  600.          WinStopTimer( hab, hwnd, ID_TIMER );
  601.          break;
  602.       }
  603.  
  604.       // Throw away key repeate messages
  605.       //
  606.       if( fsKeyFlags & KC_PREVDOWN ) break;
  607.  
  608.       switch ( SHORT1FROMMP ( mp2 ) )
  609.       {
  610.       case 'h':
  611.       case 'H':
  612.          // User has just pressed the right key so start
  613.          // a 100 ms timer.
  614.          //
  615.          WinStartTimer( hab, hwnd, ID_TIMER, 100 );
  616.          break;
  617.       case 'f':
  618.       case 'F':
  619.            if ( fFullScreen )
  620.            {
  621.                WinSendMsg( hwndFrame, WM_SetVideoMode, (MPARAM)WS_DesktopDive, 0 );
  622.                fFullScreen = FALSE;
  623.            }
  624.            else
  625.            {
  626.                // Indicate that we are switching to full screen mode
  627.                // and disable blitting.
  628.                fVrnDisabled = TRUE;
  629.                fSwitching = TRUE;
  630.                WinSendMsg( hwndFrame, WM_SetVideoMode, (MPARAM)WS_FullScreenDive, 0 );
  631.                fFullScreen = TRUE;
  632.            }
  633.          break;
  634.       } // end switch
  635.  
  636.    case WM_TIMER:
  637.       // This timer message will cause a sprite to be generated.
  638.       //
  639.       if( SHORT1FROMMP( mp1 ) == ID_TIMER )
  640.       {
  641.  
  642.          // Create another sprite and add it to the linked list
  643.          //
  644.          pSprite = &FirstSprite;
  645.  
  646.          // Travers the list until we reach the last sprite
  647.          //
  648.          while( pSprite->pNextSprite != NULL )
  649.             pSprite = pSprite->pNextSprite;
  650.  
  651.          // Allocate space for a new sprite.
  652.          //
  653.          ulrc = DosAllocMem ( (PPVOID)&pNewSprite,
  654.                               sizeof( SPRITEDATA ),
  655.                               MY_ALLOC_FLAGS );
  656.          if( ulrc ) break;
  657.  
  658.          pNewSprite->pbmp = &bmpImage1;         // Set first frame of sprite
  659.  
  660.          pNewSprite->ulPositionX = 0;           // Set sprite position
  661.          pNewSprite->ulPositionY = 0;
  662.  
  663.          pNewSprite->lDeltaX = ( 6 * rand() ) / RAND_MAX + 1;
  664.          pNewSprite->lDeltaY = ( 3 * rand() ) / RAND_MAX + 1;
  665.  
  666.          pNewSprite->pNextSprite = NULL;
  667.  
  668.          // Add the new sprite to the linked list.
  669.          //
  670.          pSprite->pNextSprite = pNewSprite;
  671.  
  672.       }  // end if
  673.  
  674.       break;
  675.  
  676.    }  // end switch
  677.  
  678.    return WinDefWindowProc ( hwnd, msg, mp1, mp2 );
  679. }
  680.  
  681.  
  682.  
  683. //**************************************************************************
  684. //
  685. // Name           : main
  686. //
  687. // Description    : After initializing, a second thread is created that
  688. //                  is responsible for continuously updating the output
  689. //                  window for the next frame of the animation.
  690. //
  691. // Parameters     : None
  692. //
  693. //**************************************************************************
  694.  
  695.  
  696.  
  697.  
  698. ULONG main ( VOID )
  699.    {
  700.    PSZ      pszMyWindow = "MyWindow";     // Window class name
  701.    PSZ      pszTitleText = "PARALAX";     // Title bar text
  702.  
  703.    TID      tidBlitThread;
  704.    HMQ      hmq;                 // Message queue handle
  705.    QMSG     qmsg;                // Message from message queue
  706.    ULONG    flCreate;            // Window creation control flags
  707.    ULONG    i;                   // Index for the files to open
  708.    LONG     lCx, lCy;            // System values for screen extents
  709.  
  710.    PSPRITEDATA pSpriteData,
  711.                pNextSprite;
  712.  
  713.    extern APIENTRY Animation( void );
  714.  
  715.    /* Initialize the presentation manager, and create a message queue.
  716.    */
  717.    hab = WinInitialize ( 0 );
  718.    hmq = WinCreateMsgQueue ( hab, 0 );
  719.  
  720.    ulrc = Initialize();
  721.    if( !ulrc )
  722.    {
  723.  
  724.       // Register a window class, and create a standard window.
  725.       //
  726.       WinRegisterClass ( hab, pszMyWindow, MyWindowProc, 0, 0 );
  727.  
  728.       flCreate = FCF_STANDARD & ~FCF_SHELLPOSITION & ~FCF_ACCELTABLE;
  729.  
  730.       hwndFrame = WinCreateStdWindow ( HWND_DESKTOP,
  731.                                        0,
  732.                                        &flCreate,
  733.                                        pszMyWindow,
  734.                                        pszTitleText,
  735.                                        WS_SYNCPAINT | WS_VISIBLE,
  736.                                        NULLHANDLE,
  737.                                        ID_MAINWND,
  738.                                        &hwndClient );
  739.  
  740.       // Setup full screen dive
  741.       //
  742.       SetupFullScreen();
  743.  
  744.       // Center the window on the desktop
  745.       //
  746.       lCx = WinQuerySysValue( HWND_DESKTOP, SV_CXSCREEN );
  747.       lCy = WinQuerySysValue( HWND_DESKTOP, SV_CYSCREEN );
  748.  
  749.       WinSetWindowPos( hwndFrame,
  750.                      NULLHANDLE,
  751.                      ( lCx - 640 )/2,
  752.                      ( lCy - 480 )/2,
  753.                      640,
  754.                      480,
  755.                      SWP_MOVE | SWP_SIZE | SWP_SHOW | SWP_ACTIVATE );
  756.  
  757.       //WinSetActiveWindow( HWND_DESKTOP, hwndFrame );
  758.  
  759.       // Turn on visible region notification.
  760.       //
  761.       WinSetVisibleRegionNotify ( hwndClient, TRUE );
  762.  
  763.       // Send an invlaidation message to the client.
  764.       //
  765.       WinPostMsg ( hwndFrame, WM_VRNENABLED, 0L, 0L );
  766.  
  767.       // Create animation thread
  768.       //
  769.       DosCreateThread ( &tidBlitThread,
  770.                         (PFNTHREAD) Animation,
  771.                         0L,
  772.                         0L,
  773.                         8192L);
  774.  
  775.       // While there are still messages, dispatch them.
  776.       //
  777.       while ( WinGetMsg ( hab, &qmsg, 0, 0, 0 ) )
  778.          WinDispatchMsg ( hab, &qmsg );
  779.    }
  780.  
  781.    fEndThread = TRUE;
  782.    DosWaitThread ( &tidBlitThread, DCWW_WAIT );
  783.  
  784.    // Turn off visible region notificationm tidy up, and terminate.
  785.    //
  786.    WinSetVisibleRegionNotify ( hwndClient, FALSE );
  787.  
  788.    // Release allocated buffers
  789.    //
  790.    pSpriteData = FirstSprite.pNextSprite;
  791.  
  792.    while( pSpriteData != NULL )                 // While there are sprites..
  793.    {
  794.       pNextSprite = pSpriteData->pNextSprite;   // Save pointer to next sprite
  795.       DosFreeMem( pSpriteData );                // Free sprite structure
  796.       pSpriteData = pNextSprite;                // Get pointer to next sprite
  797.    }
  798.  
  799.    // Free Image buffers
  800.    //
  801.    DiveFreeImageBuffer( hDive, bmpScene.ulImage );
  802.    DosFreeMem( bmpScene.pbBuffer );
  803.    DosFreeMem( bmpBackGround.pbBuffer );
  804.    DosFreeMem( bmpImage1.pbBuffer );
  805.    DosFreeMem( bmpImage1b.pbBuffer );
  806.    DosFreeMem( bmpImage2.pbBuffer );
  807.    DosFreeMem( bmpImage2b.pbBuffer );
  808.  
  809.    // Free generated sprite code
  810.    //
  811.    DosFreeMem( ( PVOID )bmpImage1.pfnBlit );
  812.    DosFreeMem( ( PVOID )bmpImage1b.pfnBlit );
  813.    DosFreeMem( ( PVOID )bmpImage2.pfnBlit );
  814.    DosFreeMem( ( PVOID )bmpImage2b.pfnBlit );
  815.  
  816.    WinDestroyWindow ( hwndFrame );
  817.    WinDestroyMsgQueue ( hmq );
  818.    WinTerminate ( hab );
  819.  
  820.    return ( 0 );
  821.    }
  822.