home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / warptlk3.zip / TOOLKIT / SAMPLES / MM / DIVE / SHOW.C < prev    next >
C/C++ Source or Header  |  1995-10-02  |  50KB  |  1,338 lines

  1.  /**************************************************************************
  2.  *
  3.  * File Name        : SHOW.C
  4.  *
  5.  * Description      : This program provides the sample code of using DIVE APIs.
  6.  *
  7.  *                    Direct Interface Video Extension is developed for
  8.  *                    the entertainment, education, and games software
  9.  *                    to give the high-speed perforemance.
  10.  *
  11.  *
  12.  *
  13.  * Concepts         :
  14.  *
  15.  * Entry Points     : DirectMoveMem()
  16.  *                    ReadFile()
  17.  *                    Main()
  18.  *                    MyWindowProc()
  19.  *
  20.  * DIVE API's       :
  21.  *                    DiveSetSourcePalette
  22.  *                    DiveBlitImage
  23.  *                    DiveAllocImageBuffer
  24.  *                    DiveBeginImageBufferAccess
  25.  *                    DiveEndImageBufferAccess
  26.  *                    DiveOpen
  27.  *                    DiveSetDestinationPalette
  28.  *                    DiveFreeImageBuffer
  29.  *                    DiveClose
  30.  *                    DiveSetupBlitter
  31.  *
  32.  * Copyright        : COPYRIGHT IBM CORPORATION, 1991, 1992, 1993
  33.  *
  34.  *        DISCLAIMER OF WARRANTIES.  The following [enclosed] code is
  35.  *        sample code created by IBM Corporation. This sample code is not
  36.  *        part of any standard or IBM product and is provided to you solely
  37.  *        for  the purpose of assisting you in the development of your
  38.  *        applications.  The code is provided "AS IS", without
  39.  *        warranty of any kind.  IBM shall not be liable for any damages
  40.  *        arising out of your use of the sample code, even if they have been
  41.  *        advised of the possibility of such damages.
  42.  *
  43.  ****************************************************************************/
  44.  
  45. #define INCL_DOS
  46. #define INCL_GPI
  47. #define INCL_WIN
  48. #include <os2.h>
  49. #include <stdio.h>
  50. #include <stdlib.h>
  51. #define  _MEERROR_H_
  52. #include <mmioos2.h>                   /* It is from MMPM toolkit           */
  53. #include <dive.h>
  54. #include <fourcc.h>
  55. #include "show.h"
  56.  
  57.  
  58. /* Function prototypes
  59. */
  60. MRESULT EXPENTRY MyWindowProc ( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 );
  61. MRESULT EXPENTRY MyDlgProc ( HWND hwndDlg, ULONG msg, MPARAM mp1, MPARAM mp2 );
  62.  
  63. /* Global definitions
  64. */
  65. HAB       hab;                          /* PM anchor block handle            */
  66. ULONG     ulImage[MAX_FILE];            /* Image buffers from DIVE           */
  67. PVOID     pbImage[MAX_FILE];            /* Pointer to DIVE image buffer      */
  68. PVOID     pbSrcImage[MAX_FILE];         /* Pointer to Dos image buffer       */
  69. PBYTE     pPalette[MAX_FILE];           /* Pointer to bitmap palette area    */
  70. PSZ       pszMyWindow = "MyWindow";     /* Window class name                 */
  71. PSZ       pszTitleText = "DIVE SAMPLE"; /* Title bar text                    */
  72. ULONG     ulToEnd = 0;                  /* Controls the display thread       */
  73. DIVE_CAPS DiveCaps = {0};
  74. FOURCC    fccFormats[100] = {0};        /* Color format code                 */
  75. ULONG     ulFramesToTime=8;             /* Interval of frames to get time    */
  76. ULONG     ulNumFrames=0;                /* Frame counter                     */
  77.  
  78. /*  Default bitmap file name definitions
  79. **       These files are used only when EXE is called without parameter.
  80. */
  81. PSZ  pszDefFile[]   = { {"TPG20000.BMP"},
  82.                         {"TPG20001.BMP"},
  83.                         {"TPG20002.BMP"},
  84.                         {"TPG20003.BMP"},
  85.                         {"TPG20004.BMP"},
  86.                         {"TPG20005.BMP"},
  87.                         {"TPG20006.BMP"},
  88.                         {"TPG20007.BMP"},
  89.                         {"TPG20008.BMP"},
  90.                         {"TPG20009.BMP"},
  91.                         {"TPG20010.BMP"},
  92.                         {"TPG20011.BMP"},
  93.                         {"TPG20012.BMP"},
  94.                         {"TPG20013.BMP"},
  95.                         {"TPG20014.BMP"},
  96.                         {"TPG20015.BMP"} };
  97.  
  98. /*
  99. **  It is the definition how many time draw one bitmap continuously to
  100. **  look the picture better.
  101. */
  102. ULONG ulDrawCnt[] =   { 1,                       /* For TPG20000.BMP  */
  103.                         1,                       /* For TPG20001.BMP  */
  104.                         1,                       /* For TPG20002.BMP  */
  105.                         1,                       /* For TPG20003.BMP  */
  106.                         1,                       /* For TPG20004.BMP  */
  107.                         1,                       /* For TPG20005.BMP  */
  108.                         1,                       /* For TPG20006.BMP  */
  109.                         1,                       /* For TPG20007.BMP  */
  110.                         1,                       /* For TPG20008.BMP  */
  111.                         1,                       /* For TPG20009.BMP  */
  112.                         1,                       /* For TPG20010.BMP  */
  113.                         1,                       /* For TPG20011.BMP  */
  114.                         1,                       /* For TPG20012.BMP  */
  115.                         1,                       /* For TPG20013.BMP  */
  116.                         1,                       /* For TPG20014.BMP  */
  117.                         1 };                     /* For TPG20015.BMP  */
  118.  
  119. /****************************************************************************
  120.  *
  121.  * Name          : DirectMoveMem
  122.  *
  123.  * Description   : It is calling DIVE bitblt function periodically.
  124.  *                 And also it calculates how many frames per a second
  125.  *                 is able to be blit to the screen.
  126.  *
  127.  * Concepts      :
  128.  *
  129.  * Parameters    : Pointer to window data
  130.  *
  131.  * Return        : VOID
  132.  *
  133.  ****************************************************************************/
  134.  
  135. VOID APIENTRY DirectMoveMem ( ULONG parm1 )
  136.    {
  137.    ULONG    ulTime0, ulTime1;     /* output buffer for DosQierySysInfo      */
  138.    ULONG    ulIndexImage = 0;     /* Index of bitmap data                   */
  139.    CHAR     achFrameRate[48];     /* string buffer for WinSetWindowText     */
  140.    ULONG    ulFirstTime=0;        /* very first time flag for DiveSetSour.. */
  141.  
  142.    PWINDATA pwinData;             /* pointer to window data                 */
  143.    ULONG    ulCount = 0;          /* Counter for each bitmap                */
  144.    PBYTE    pDestAddress;         /* destination VRAM adrress               */
  145.    PBYTE    pSrcAddress;          /* source btimap data address             */
  146.  
  147.    BOOL     fFirstLineInRect;     /* Indicates start of drawing sequence    */
  148.    RECTL    rcl;                  /* Current rectangle to draw              */
  149.    ULONG    ulMoreLine;           /* Number of lines left to draw           */
  150.    ULONG    ulRemLinesInBank;     /* Number of lines left in bank           */
  151.    ULONG    ulBankNumber;         /* Bank number returned from DIVE         */
  152.    ULONG    ulCopyLengthBytes;    /* Length of scan line for current window */
  153.    ULONG    i;
  154.  
  155.    pwinData =(PWINDATA)parm1;
  156.  
  157.    while ( !ulToEnd )
  158.       {
  159.  
  160.       /* Check if it's time to start the blit-time counter.
  161.       */
  162.       if ( !ulNumFrames++ )
  163.          DosQuerySysInfo ( QSV_MS_COUNT, QSV_MS_COUNT, &ulTime0, 4L );
  164.  
  165.       /* Check if need to change the source palette.
  166.       **
  167.       ** In this sample case, this API should be called only once at
  168.       ** very first.  After this, it will not be called, because there is
  169.       ** assumption that all bitmap data have the sample palette.
  170.       */
  171.       if (( pwinData->fChgSrcPalette ) || (( !ulFirstTime ) &&
  172.             ( pwinData->ulnumColor  == 256 )) )
  173.          {
  174.          DiveSetSourcePalette ( pwinData->hDive, 0,
  175.                                   pwinData->ulnumColor,
  176.                                   pPalette[ulIndexImage] );
  177.          ulFirstTime = 0xFFFF;
  178.          }
  179.  
  180.       /* Check to see if images are in process of being converted
  181.       ** If not, then continue updating display
  182.       */
  183.       if ( ! pwinData->fDataInProcess )
  184.          {
  185.          /* Check if direct or blit mode
  186.          */
  187.          if (pwinData->fDirect)
  188.             {
  189.             /* Write image to frame buffer directly
  190.             */
  191.             if (!pwinData->fVrnDisabled)
  192.                {
  193.                /* Copy bitmap data for each rectangle
  194.                */
  195.                for (i = 0; i < pwinData->ulNumRcls; i++)
  196.                   {
  197.                   pSrcAddress = (PBYTE)pbImage[ulIndexImage];
  198.                   memcpy (&rcl, &pwinData->rcls[i], sizeof(RECTL) );
  199.  
  200.                   /* Size of scan line bounded by this rectangle
  201.                   */
  202.                   ulCopyLengthBytes = ( rcl.xRight - rcl.xLeft ) *
  203.                                       pwinData->ulColorSizeBytes;
  204.  
  205.                   /* Number of lines contained in this rectangle
  206.                   */
  207.                   ulMoreLine = rcl.yTop - rcl.yBottom;
  208.  
  209.                   /* Start position in source bitmap
  210.                   */
  211.                   pSrcAddress += ( pwinData->swp.cy - rcl.yTop )
  212.                                   * pwinData->ulLineSizeBytes +
  213.                                  ( rcl.xLeft * pwinData->ulColorSizeBytes );
  214.  
  215.                   /* Map rectangle to desktop coordinates
  216.                   */
  217.                   rcl.yTop    += pwinData->cyWindowPos;
  218.                   rcl.yBottom += pwinData->cyWindowPos;
  219.                   rcl.xRight  += pwinData->cxWindowPos;
  220.                   rcl.xLeft   += pwinData->cxWindowPos;
  221.  
  222.                  /* NOTICE !!! */
  223.                  /**** TEMPORARY ADJUSTMENT  start ****************************
  224.                   * If this adjustment is not here, DiveCalcFrameBufferAddress
  225.                   * returns 1 dot higher position.
  226.                   * Need to contact the devloper.
  227.                   *************************************************************/
  228.                   rcl.yTop --;
  229.                   rcl.yBottom --;
  230.                  /* end temporary adjustment */
  231.  
  232.                   fFirstLineInRect = TRUE;
  233.  
  234.                   while ( ulMoreLine )
  235.                      {
  236.                      if ( fFirstLineInRect )
  237.                         {
  238.                         /* Get VRAM start location
  239.                         */
  240.                         DiveCalcFrameBufferAddress ( pwinData->hDive,
  241.                                                        &rcl,
  242.                                                        &pDestAddress,
  243.                                                        &ulBankNumber,
  244.                                                        &ulRemLinesInBank );
  245.  
  246.                         if ( DiveAcquireFrameBuffer ( pwinData->hDive,
  247.                                                         &rcl ))
  248.                            break;
  249.  
  250.                         DiveSwitchBank ( pwinData->hDive, ulBankNumber );
  251.                         fFirstLineInRect = FALSE;
  252.                         }
  253.                      /* Copy one Line to display
  254.                      */
  255.                      memcpy ( pDestAddress, pSrcAddress, ulCopyLengthBytes );
  256.  
  257.                      /* Update source address
  258.                      */
  259.                      pSrcAddress += pwinData->ulLineSizeBytes;
  260.  
  261.                      ulMoreLine--;
  262.                      ulRemLinesInBank--;
  263.                      rcl.yTop--;
  264.  
  265.                      /* Check if time to switch banks.
  266.                      */
  267.                      if ( !ulRemLinesInBank )
  268.                         {
  269.                         DiveCalcFrameBufferAddress ( pwinData->hDive,
  270.                                                        &rcl,
  271.                                                        &pDestAddress,
  272.                                                        &ulBankNumber,
  273.                                                        &ulRemLinesInBank );
  274.  
  275.                         DiveSwitchBank ( pwinData->hDive, ulBankNumber );
  276.                         }
  277.                      else
  278.                         {
  279.                         /* update destination address.
  280.                         */
  281.                         pDestAddress += DiveCaps.ulScanLineBytes;
  282.                         }
  283.  
  284.                      } /* end while: go to next scan line */
  285.  
  286.                   DiveDeacquireFrameBuffer ( pwinData->hDive );
  287.                   } /* end for: go to next rectangle */
  288.                }/* end if */
  289.             }
  290.          else
  291.             {
  292.             /* Blit the image using DiveBlit
  293.             */
  294.             DiveBlitImage ( pwinData->hDive,
  295.                             ulImage[ulIndexImage],
  296.                             DIVE_BUFFER_SCREEN );
  297.          } /* endif */
  298.  
  299.          /* Updated the index for the bitmap data to be drawn next.
  300.          */
  301.          ulCount ++;
  302.          if ( ulCount >=  ulDrawCnt[ulIndexImage] )
  303.             {
  304.             ulIndexImage ++;
  305.             ulCount = 0;
  306.             }
  307.          if ( ulIndexImage >= pwinData->ulMaxFiles )
  308.             ulIndexImage = 0;
  309.  
  310.          /* Check to see if we have enough frames for a fairly accurate read.
  311.          */
  312.          if ( ulNumFrames>=ulFramesToTime )
  313.             {
  314.             DosQuerySysInfo ( QSV_MS_COUNT, QSV_MS_COUNT, &ulTime1, 4L );
  315.             ulTime1 -= ulTime0;
  316.             if ( ulTime1 )
  317.                sprintf ( achFrameRate, "%d: %d: %5.2f frames per second.",
  318.                            pwinData->hDive, ulFramesToTime,
  319.                            (float)ulFramesToTime * 1000.0 / (float)ulTime1 );
  320.             else
  321.                sprintf ( achFrameRate, "%d: %d: Lots of frames per second.",
  322.                            pwinData->hDive, ulFramesToTime );
  323.             WinPostMsg ( pwinData->hwndFrame, WM_COMMAND,
  324.                            (PVOID)ID_NEWTEXT, achFrameRate );
  325.             ulNumFrames = 0;
  326.  
  327.             /* Adjust number of frames to time based on last set.
  328.             */
  329.             if ( ulTime1 < 250 )
  330.                ulFramesToTime <<= 1;
  331.             if ( ulTime1 > 3000 )
  332.                ulFramesToTime >>= 1;
  333.             }
  334.  
  335.          /* Let other threads and processes have some time.
  336.          */
  337.          }
  338.       DosSleep ( 0 );
  339.       }
  340.  
  341.    return;
  342.    }
  343.  
  344. /****************************************************************************
  345.  *
  346.  * Name          : ReadFile
  347.  *
  348.  * Description   : It opens the file, and reads bitmap header and bitmap
  349.  *                 palette, and reads image data to the buffer allocated
  350.  *                 by DIVE APIs.
  351.  *
  352.  * Concepts      :
  353.  *
  354.  * Parameters    : Index for the file to open
  355.  *                 Pointer to the file name to open
  356.  *                 Pointer to window data
  357.  *
  358.  * Return        : 0 - succeed
  359.  *                 1 - fail
  360.  *
  361.  ****************************************************************************/
  362.  
  363.  
  364. unsigned long ReadFile ( ULONG iFile, unsigned char *pszFile,
  365.                                                        PWINDATA pwinData )
  366.    {
  367.    HFILE hFile;                 /* file handke                              */
  368.    ULONG ulNumBytes;            /* output for number of bytes actually read */
  369.    ULONG ulFileLength;          /* file length                              */
  370.    PBYTE pbBuffer;              /* pointer to the image/ temp. palette data */
  371.    ULONG ulScanLineBytes;       /* output for number of bytes a scan line   */
  372.    ULONG ulScanLines;           /* output for height of the buffer          */
  373.    PBITMAPFILEHEADER2 pImgHdr;  /* pointer to bitmapheader                  */
  374.    ULONG i, j;
  375.    PBYTE pbTmpDst;              /* temporaly destination pointer            */
  376.  
  377.    /* Attempt to open up the passed filename.
  378.    */
  379.    if ( DosOpen ( pszFile, &hFile, &ulNumBytes, 0L, FILE_NORMAL,
  380.                     OPEN_ACTION_OPEN_IF_EXISTS | OPEN_ACTION_FAIL_IF_NEW,
  381.                     OPEN_ACCESS_READONLY | OPEN_SHARE_DENYREADWRITE |
  382.                     OPEN_FLAGS_SEQUENTIAL | OPEN_FLAGS_NO_CACHE, 0L ) )
  383.       return ( 1 );
  384.  
  385.    /* Get the legnth of the file.
  386.    */
  387.    DosSetFilePtr ( hFile, 0L, FILE_END, &ulFileLength );
  388.    DosSetFilePtr ( hFile, 0L, FILE_BEGIN, &ulNumBytes );
  389.  
  390.    /* Allocate memory for bitmap file header
  391.    */
  392.    if ( DosAllocMem ( (PPVOID)&pImgHdr, sizeof(BITMAPFILEHEADER2),
  393.                         (ULONG) PAG_COMMIT | PAG_READ | PAG_WRITE) )
  394.       {
  395.       DosClose ( hFile );
  396.       return ( 1 );
  397.       }
  398.  
  399.    /* Read from the beginning of the header to cbFix in BITMAPINFOHEADER
  400.    ** to know the length of the header.
  401.    */
  402.    if ( DosRead ( hFile, pImgHdr,
  403.                     sizeof(BITMAPFILEHEADER2) - sizeof(BITMAPINFOHEADER2) +
  404.                     sizeof(ULONG),
  405.                     &ulNumBytes ))
  406.       {
  407.       DosFreeMem ( (PVOID)pImgHdr );
  408.       DosClose ( hFile );
  409.       return ( 1 );
  410.       }
  411.  
  412.    /* Read the rest of the header.
  413.    */
  414.    if ( DosRead ( hFile, (PBYTE)pImgHdr + ulNumBytes,
  415.                     pImgHdr->bmp2.cbFix - sizeof(ULONG),
  416.                     &ulNumBytes ))
  417.       {
  418.       DosFreeMem ( (PVOID)pImgHdr );
  419.       DosClose ( hFile );
  420.       return ( 1 );
  421.       }
  422.  
  423.     pwinData->ulnumColor = 1;
  424.  
  425.    /* Check the bitmap header format --  new or old one.
  426.    */
  427.    if ( pImgHdr->bmp2.cbFix != sizeof(BITMAPINFOHEADER) )
  428.       {
  429.       /*  Bitmap has new format (BITMAPFILEHEADER2)
  430.       */
  431.  
  432.       /* Check bitmap header to see if it can support.
  433.       */
  434.  
  435.       /* Set how many color bitmap data is supporting
  436.       */
  437.       pwinData->ulnumColor <<= pImgHdr->bmp2.cBitCount;
  438.  
  439.       /* Set bitmap width and height in pels.
  440.       */
  441.       pwinData->ulWidth  = pImgHdr->bmp2.cx;
  442.       pwinData->ulHeight = pImgHdr->bmp2.cy;
  443.  
  444.       /* Calculate source line size.  It should be double word boundary.
  445.       */
  446.       pwinData->ulSrcLineSizeBytes = ((( pImgHdr->bmp2.cx *
  447.                               ( pImgHdr->bmp2.cBitCount >> 3 )) + 3 ) / 4 ) * 4;
  448.  
  449.       /* Set bitmap coclor format.
  450.       */
  451.       switch ( pImgHdr->bmp2.cBitCount )
  452.          {
  453.          case 8:
  454.             pwinData->fccColorFormat = FOURCC_LUT8;
  455.             /* Alloate buffer for palette data in bitmap file.
  456.             */
  457.             if ( DosAllocMem ( (PPVOID) &(pPalette[iFile]),
  458.                                  pwinData->ulnumColor * sizeof(ULONG),
  459.                                  (ULONG) PAG_COMMIT | PAG_READ | PAG_WRITE) )
  460.                {
  461.                DosFreeMem ( (PVOID)pImgHdr );
  462.                DosClose ( hFile );
  463.                return ( 1 );
  464.                }
  465.  
  466.             /* Read palette data.
  467.             */
  468.             if ( DosRead ( hFile, pPalette[iFile],
  469.                              pwinData->ulnumColor * sizeof(ULONG),
  470.                              &ulNumBytes ))
  471.                {
  472.                DosFreeMem ( (PVOID)pImgHdr );
  473.                DosFreeMem ( (PVOID)(pPalette[iFile]) );
  474.                DosClose ( hFile );
  475.                return ( 1 );
  476.                }
  477.             break;
  478.          case 16:
  479.             pwinData->fccColorFormat = FOURCC_R565;
  480.             break;
  481.          case 24:
  482.             pwinData->fccColorFormat = FOURCC_BGR3;
  483.             break;
  484.          default:
  485.             DosFreeMem ( (PVOID)pImgHdr );
  486.             DosClose ( hFile );
  487.             return ( 1 );
  488.          } /* endswitch */
  489.  
  490.       }
  491.    else
  492.       {
  493.       /*  Bitmap has old format (BITMAPFILEHEADER)
  494.       */
  495.  
  496.        /* Set how many color bitmap data is supporting
  497.       */
  498.       pwinData->ulnumColor <<= ((PBITMAPFILEHEADER)pImgHdr)->bmp.cBitCount;
  499.  
  500.       /* Set bitmap width and height in pels.
  501.       */
  502.       pwinData->ulWidth  = ((PBITMAPFILEHEADER)pImgHdr)->bmp.cx;
  503.       pwinData->ulHeight = ((PBITMAPFILEHEADER)pImgHdr)->bmp.cy;
  504.  
  505.       /* Calculate source line size.  It should be double word boundary.
  506.       */
  507.       pwinData->ulSrcLineSizeBytes = ((( ((PBITMAPFILEHEADER)pImgHdr)->bmp.cx *
  508.            ( ((PBITMAPFILEHEADER)pImgHdr)->bmp.cBitCount >> 3 )) + 3 ) / 4 ) * 4;
  509.  
  510.       /* Set bitmap coclor format.
  511.       */
  512.       switch ( ((PBITMAPFILEHEADER)pImgHdr)->bmp.cBitCount )
  513.          {
  514.          case 8:
  515.             pwinData->fccColorFormat = FOURCC_LUT8;
  516.             /* Alloate buffer for temporally palette data in bitmap file
  517.             */
  518.             if ( DosAllocMem ( (PPVOID) &pbBuffer,
  519.                                  pwinData->ulnumColor * sizeof(RGB),
  520.                                  (ULONG) PAG_COMMIT | PAG_READ | PAG_WRITE) )
  521.                {
  522.                DosFreeMem ( (PVOID)pImgHdr );
  523.                DosClose ( hFile );
  524.                return ( 1 );
  525.                }
  526.             if ( DosAllocMem ( (PPVOID) &(pPalette[iFile]),
  527.                                  pwinData->ulnumColor * sizeof(ULONG),
  528.                                  (ULONG) PAG_COMMIT | PAG_READ | PAG_WRITE) )
  529.                {
  530.                DosFreeMem ( (PVOID)pImgHdr );
  531.                DosFreeMem( (PVOID)pbBuffer );
  532.                DosClose ( hFile );
  533.                return ( 1 );
  534.                }
  535.  
  536.             /* Read palette data
  537.             */
  538.             if ( DosRead ( hFile, pbBuffer,
  539.                              pwinData->ulnumColor * sizeof(RGB),
  540.                              &ulNumBytes ))
  541.                {
  542.                DosFreeMem ( (PVOID)pImgHdr );
  543.                DosFreeMem( (PVOID)pbBuffer );
  544.                DosFreeMem( (PVOID)pPalette[iFile] );
  545.                DosClose ( hFile );
  546.                return ( 1 );
  547.                }
  548.  
  549.             /* Make each color from 3 bytes to 4 bytes.
  550.             */
  551.             pbTmpDst = pPalette[iFile];
  552.             for ( i = 0; i < pwinData->ulnumColor; i++ )
  553.                {
  554.                *pbTmpDst ++= *pbBuffer++;
  555.                *pbTmpDst ++= *pbBuffer++;
  556.                *pbTmpDst ++= *pbBuffer++;
  557.                *pbTmpDst ++= 0;
  558.                } /* endfor */
  559.  
  560.             DosFreeMem( (PVOID)pbBuffer );
  561.             break;
  562.          case 16:
  563.             pwinData->fccColorFormat = FOURCC_R565;
  564.             break;
  565.          case 24:
  566.             pwinData->fccColorFormat = FOURCC_BGR3;
  567.             break;
  568.          default:
  569.             {
  570.             DosFreeMem ( (PVOID)pImgHdr );
  571.             DosClose ( hFile );
  572.             return ( 1 );
  573.             }
  574.          } /* endswitch */
  575.  
  576.  
  577.       }
  578.  
  579.  
  580.    /* Allocate a buffer for image data
  581.    */
  582.  
  583.    if ( DosAllocMem ( (PPVOID)&pbSrcImage[iFile], pwinData->ulSrcLineSizeBytes *
  584.                       pwinData->ulHeight, (ULONG) PAG_COMMIT | PAG_READ |
  585.                       PAG_WRITE) )
  586.       {
  587.       if ( pwinData->fccColorFormat == FOURCC_LUT8 )
  588.          DosFreeMem( (PVOID)pPalette[iFile] );
  589.       DosClose ( hFile );
  590.       return( 1 );
  591.       }
  592.  
  593.    /* Read image data
  594.    */
  595.    if ( DosRead ( hFile, pbSrcImage[iFile],
  596.                     pwinData->ulSrcLineSizeBytes * pwinData->ulHeight,
  597.                     &ulNumBytes ))
  598.       {
  599.       DosFreeMem ( pbSrcImage[iFile] );
  600.       if ( pwinData->fccColorFormat == FOURCC_LUT8 )
  601.          DosFreeMem( (PVOID)pPalette[iFile] );
  602.       DosClose ( hFile );
  603.       return( 1 );
  604.       }
  605.  
  606.    /* Close the file and release the access to the image buffer
  607.    */
  608.    DosFreeMem( (PVOID)pImgHdr );
  609.    DosClose ( hFile );
  610.    return ( 0 );
  611.    }
  612.  
  613.  
  614.  
  615. /****************************************************************************
  616.  *
  617.  * Name          : Main
  618.  *
  619.  * Description   : This is main routine of this sample program.
  620.  *
  621.  * Concepts      :
  622.  *
  623.  * Parameters    : At command prompt, when the user start this EXE without
  624.  *                 any parameters, like
  625.  *                    SHOW
  626.  *                 it shows 16 default bitmaps which has a sequence.
  627.  *                 When the user specifies the names of bitmap file, like
  628.  *                    SHOW XXXXXX.BMP YYYYYY.BMP
  629.  *                 it shows the bitmaps specified at command line in turn.
  630.  *
  631.  * Return        : 1 - fail
  632.  *                 0 - suceed
  633.  *
  634.  ****************************************************************************/
  635.  
  636. main ( int argc, char *argv[] )
  637.    {
  638.    TID       tidBlitThread;        /* Thread ID for DirectMemMove          */
  639.    HMQ       hmq;                  /* Message queue handle                 */
  640.    QMSG      qmsg;                 /* Message from message queue           */
  641.    ULONG     flCreate;             /* Window creation control flags        */
  642.    ULONG     i;                    /* Index for the files to open          */
  643.    PWINDATA  pwinData;             /* Pointer to window data               */
  644.    PLONG     pPal;                 /* Pointer to system physical palette   */
  645.  
  646.  
  647.    /* Initialize the presentation manager, and create a message queue.
  648.    */
  649.    hab = WinInitialize ( 0 );
  650.    hmq = WinCreateMsgQueue ( hab, 0 );
  651.  
  652.    /* Allocate a buffer for the window data
  653.    */
  654.    pwinData = (PWINDATA) malloc (sizeof(WINDATA));
  655.  
  656.    /* Get the screen capabilities, and if the system support only 16 colors
  657.    ** the sample should be terminated.
  658.    */
  659.    DiveCaps.pFormatData = fccFormats;
  660.    DiveCaps.ulFormatLength = 120;
  661.    DiveCaps.ulStructLen = sizeof(DIVE_CAPS);
  662.  
  663.    if ( DiveQueryCaps ( &DiveCaps, DIVE_BUFFER_SCREEN ))
  664.       {
  665.       WinMessageBox( HWND_DESKTOP, HWND_DESKTOP,
  666.           (PSZ)"usage: The sample program can not run on this system environment.",
  667.           (PSZ)"SHOW.EXE - DIVE Sample", 0, MB_OK | MB_INFORMATION );
  668.       free ( pwinData );
  669.       WinDestroyMsgQueue ( hmq );
  670.       WinTerminate ( hab );
  671.       return ( 1 );
  672.       }
  673.  
  674.    if ( DiveCaps.ulDepth < 8 )
  675.       {
  676.       WinMessageBox( HWND_DESKTOP, HWND_DESKTOP,
  677.           (PSZ)"usage: The sample program can not run on this system environment.",
  678.           (PSZ)"SHOW.EXE - DIVE Sample", 0, MB_OK | MB_INFORMATION );
  679.       free ( pwinData );
  680.       WinDestroyMsgQueue ( hmq );
  681.       WinTerminate ( hab );
  682.       return ( 1 );
  683.       }
  684.  
  685.    /* Calculate number of bytes per pell
  686.    */
  687.    pwinData->ulColorSizeBytes = DiveCaps.ulScanLineBytes/
  688.                                 DiveCaps.ulHorizontalResolution;
  689.  
  690.    /* Get an instance of DIVE APIs.
  691.    */
  692.    if ( DiveOpen ( &(pwinData->hDive), FALSE, 0 ) )
  693.       {
  694.  
  695.       WinMessageBox( HWND_DESKTOP, HWND_DESKTOP,
  696.                        (PSZ)"usage: The sample program can not run on this system environment.",
  697.                        (PSZ)"SHOW.EXE - DIVE Sample", 0, MB_OK | MB_INFORMATION );
  698.       free ( pwinData );
  699.       WinDestroyMsgQueue ( hmq );
  700.       WinTerminate ( hab );
  701.       return ( 1 );
  702.       }
  703.  
  704.  
  705.    /* Read bitmap files
  706.    */
  707.    if ( argc == 1 )                               /* Default case           */
  708.       {                                           /* Read DROI00XX.BMP file */
  709.       for ( i = 0, pwinData->ulMaxFiles = 0; i < MAX_FILE; i ++ )
  710.          {
  711.          if ( ReadFile ( i, pszDefFile[i], pwinData ))
  712.             {
  713.             WinMessageBox( HWND_DESKTOP, HWND_DESKTOP,
  714.                              (PSZ)"usage: SHOW failed to open bitmaps.",
  715.                              (PSZ)"Error!", 0, MB_OK | MB_MOVEABLE );
  716.             free ( pwinData );
  717.             WinDestroyMsgQueue ( hmq );
  718.             WinTerminate ( hab );
  719.             return ( 1 );
  720.             }
  721.          else
  722.             pwinData->ulMaxFiles ++;
  723.          }
  724.       }
  725.    else                 /* The case which the user specify bitmap file names */
  726.       {
  727.       if (( argc > 1 ) && ( argc <= MAX_FILE + 1))
  728.          {
  729.          for ( i = 1; i < (ULONG)(argc); i++ )
  730.              {
  731.              if ( ReadFile ( i-1, (unsigned char *)argv[i], pwinData ))
  732.                 {
  733.                 WinMessageBox( HWND_DESKTOP, HWND_DESKTOP,
  734.                                  (PSZ)"usage: SHOW failed to open bitmaps.",
  735.                                  (PSZ)"Error!", 0, MB_OK | MB_MOVEABLE );
  736.                 free ( pwinData );
  737.                 WinDestroyMsgQueue ( hmq );
  738.                 WinTerminate ( hab );
  739.                 return ( 1 );
  740.                 }
  741.              }
  742.           pwinData->ulMaxFiles = argc-1;
  743.          }
  744.       else
  745.          {
  746.          WinMessageBox( HWND_DESKTOP, HWND_DESKTOP,
  747.             (PSZ)"usage: SHOW failed to open bitmaps.",
  748.             (PSZ)"Error!", 0, MB_OK | MB_MOVEABLE );
  749.          free ( pwinData );
  750.          WinDestroyMsgQueue ( hmq );
  751.          WinTerminate ( hab );
  752.          return ( 1 );
  753.          }
  754.       }
  755.  
  756.    /* Register a window class, and create a standard window.
  757.    */
  758.    WinRegisterClass ( hab, pszMyWindow, MyWindowProc, 0, sizeof(ULONG) );
  759.    flCreate = FCF_TASKLIST | FCF_SYSMENU  | FCF_TITLEBAR | FCF_ICON |
  760.                   FCF_SIZEBORDER | FCF_MINMAX | FCF_MENU | FCF_SHELLPOSITION;
  761.    pwinData->hwndFrame = WinCreateStdWindow ( HWND_DESKTOP,
  762.                                               WS_VISIBLE, &flCreate,
  763.                                               pszMyWindow,
  764.                                               pszTitleText,
  765.                                               WS_SYNCPAINT | WS_VISIBLE,
  766.                                               0, ID_MAINWND,
  767.                                               &(pwinData->hwndClient));
  768.  
  769.    WinSetWindowULong (pwinData->hwndClient, 0, (ULONG)pwinData);
  770.  
  771.  
  772.    pwinData->cxWidthBorder = (LONG) WinQuerySysValue(HWND_DESKTOP, SV_CXSIZEBORDER);
  773.    pwinData->cyWidthBorder = (LONG) WinQuerySysValue(HWND_DESKTOP, SV_CYSIZEBORDER);
  774.    pwinData->cyTitleBar    = (LONG) WinQuerySysValue(HWND_DESKTOP, SV_CYTITLEBAR);
  775.    pwinData->cyMenu        = (LONG) WinQuerySysValue(HWND_DESKTOP, SV_CYMENU);
  776.  
  777.    pwinData->cxWidthWindow  = pwinData->ulWidth + pwinData->cxWidthBorder * 2;
  778.    pwinData->cyHeightWindow = pwinData->ulHeight + (pwinData->cyWidthBorder * 2 +
  779.                                        pwinData->cyTitleBar + pwinData->cyMenu );
  780.  
  781.    pwinData->cxWindowPos   = ( (LONG)WinQuerySysValue(HWND_DESKTOP, SV_CXSCREEN)
  782.                        - pwinData->cxWidthWindow ) / 2;
  783.    pwinData->cyWindowPos   = ( (LONG)WinQuerySysValue(HWND_DESKTOP, SV_CYSCREEN)
  784.                        - pwinData->cyHeightWindow ) / 2;
  785.  
  786.  
  787.    /* Set the window position and size.
  788.    */
  789.    WinSetWindowPos (pwinData->hwndFrame,
  790.                       HWND_TOP,
  791.                       pwinData->cxWindowPos, pwinData->cyWindowPos,
  792.                       pwinData->cxWidthWindow, pwinData->cyHeightWindow,
  793.                       SWP_SIZE | SWP_MOVE | SWP_SHOW | SWP_ACTIVATE);
  794.  
  795.  
  796.    /* Turn on visible region notification.
  797.    */
  798.    WinSetVisibleRegionNotify ( pwinData->hwndClient, TRUE );
  799.  
  800.    /* set the flag for the first time simulation of palette of bitmap data
  801.    */
  802.    pwinData->fChgSrcPalette = FALSE;
  803.    pwinData->fStartBlit = FALSE;
  804.    pwinData->fDataInProcess = FALSE;
  805.    pwinData->fDirect = FALSE;
  806.  
  807.    /* Send an invlaidation message to the client.
  808.    */
  809.    WinPostMsg ( pwinData->hwndFrame, WM_VRNENABLED, 0L, 0L );
  810.  
  811.    /* Start up the blitting thread.
  812.    */
  813.    if ( DosCreateThread ( &(pwinData->tidBlitThread),
  814.                             (PFNTHREAD) DirectMoveMem,
  815.                             (ULONG)pwinData, 0L, 8192L))
  816.       {
  817.       WinSetVisibleRegionNotify ( pwinData->hwndClient, FALSE );
  818.  
  819.       for ( i = 0; i < pwinData->ulMaxFiles; i++ )
  820.           DiveFreeImageBuffer ( pwinData->hDive, ulImage[i] );
  821.  
  822.       DiveClose ( pwinData->hDive );
  823.       WinDestroyWindow ( pwinData->hwndFrame );
  824.       free ( pwinData);
  825.       WinDestroyMsgQueue ( hmq );
  826.       WinTerminate ( hab );
  827.       return ( 1 );
  828.       }
  829.  
  830.    /* Set the proiroty of the blitting thread
  831.    */
  832.    DosSetPriority ( PRTYS_THREAD, PRTYC_IDLETIME,
  833.                       0, pwinData->tidBlitThread );
  834.  
  835.    /* While there are still messages, dispatch them.
  836.    */
  837.    while ( WinGetMsg ( hab, &qmsg, 0, 0, 0 ) )
  838.       WinDispatchMsg ( hab, &qmsg );
  839.  
  840.    /* Set the variable to end the running thread, and wait for it to end.
  841.    */
  842.    ulToEnd = 1;
  843.    DosWaitThread ( &(pwinData->tidBlitThread), DCWW_WAIT );
  844.  
  845.    /* Turn off visible region notificationm tidy up, and terminate.
  846.    */
  847.    WinSetVisibleRegionNotify ( pwinData->hwndClient, FALSE );
  848.  
  849.    /* Free the buffers allocated by DIVE and close DIVE
  850.    */
  851.    for  ( i = 0; i < pwinData->ulMaxFiles; i++ )
  852.        DiveFreeImageBuffer ( pwinData->hDive, ulImage[i] );
  853.    DiveClose ( pwinData->hDive );
  854.  
  855.    if ( pwinData->fccColorFormat == FOURCC_LUT8 )
  856.       {
  857.       for  ( i = 0; i < pwinData->ulMaxFiles; i++ )
  858.           DosFreeMem ( pPalette[i] );
  859.       }
  860.  
  861.    /* Process for termination
  862.    */
  863.    WinDestroyWindow ( pwinData->hwndFrame );
  864.    free ( pwinData );
  865.    WinDestroyMsgQueue ( hmq );
  866.    WinTerminate ( hab );
  867.    return ( 0 );
  868.    }
  869.  
  870. /****************************************************************************
  871.  *
  872.  * Name          : MyWindowProc
  873.  *
  874.  * Description   : It is the window procedure of this program.
  875.  *
  876.  * Concepts      :
  877.  *
  878.  * Parameters    : Message parameter 1
  879.  *                 Message parameter 2
  880.  *
  881.  * Return        : calling WinDefWindowProc
  882.  *
  883.  ****************************************************************************/
  884.  
  885. MRESULT EXPENTRY MyWindowProc ( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 )
  886.    {
  887.    POINTL    pointl;                /* Point to offset from Desktop         */
  888.    HRGN      hrgn;                  /* Region handle                        */
  889.    HPS       hps;                   /* Presentation Space handle            */
  890.    RECTL     rcl;                   /* Current widow rectangle              */
  891.    ULONG     ulTmpImage;            /* For tmp image number                 */
  892.    RGNRECT   rgnCtl;                /* Processing control structure         */
  893.    PWINDATA  pwinData;              /* Pointer to window data               */
  894.    SETUP_BLITTER SetupBlitter;      /* structure for DiveSetupBlitter       */
  895.    ULONG     ulScanLineBytes;       /* Size of scan line for current window */
  896.    ULONG     ulScanLines;           /* Number of scan lines in window       */
  897.    ULONG     ulRemainder;           /* Used to check direct mode support    */
  898.    ULONG     i, rc;
  899.  
  900.    /* Get the pointer to window data
  901.    */
  902.    if ( pwinData = (PWINDATA)WinQueryWindowULong (hwnd, 0))
  903.       {
  904.       switch( msg )
  905.          {
  906.          case WM_COMMAND:
  907.             switch ( SHORT1FROMMP ( mp1 ) )
  908.                {
  909.                case ID_SNAP:
  910.                   {
  911.                   /* Use the initial width and height of the window such that
  912.                   ** the actual video area equals the source width and height.
  913.                   */
  914.  
  915.                   /* Set the new size of the window, but don't move it.
  916.                   */
  917.                   WinSetWindowPos ( pwinData->hwndFrame, HWND_TOP,
  918.                                       100, 100,
  919.                                       pwinData->cxWidthWindow,
  920.                                       pwinData->cyHeightWindow,
  921.                                       SWP_SIZE | SWP_ACTIVATE | SWP_SHOW );
  922.                   }
  923.                   break;
  924.  
  925.                case ID_QUERY:
  926.  
  927.                   /* Display screen capablilities in the dialog box
  928.                   */
  929.                   WinDlgBox ( HWND_DESKTOP, pwinData->hwndClient,
  930.                                MyDlgProc, (HMODULE)0,
  931.                                ID_DIALOG, (PVOID)pwinData );
  932.  
  933.                   break;
  934.  
  935.                case ID_EXIT:
  936.                   /* Post to quit the dispatch message loop.
  937.                   */
  938.                   WinPostMsg ( hwnd, WM_QUIT, 0L, 0L );
  939.                   break;
  940.  
  941.                case ID_NEWTEXT:
  942.                   /* Write new text string to the title bar
  943.                   */
  944.                   WinSetWindowText ( pwinData->hwndFrame, (PSZ)mp2 );
  945.                   break;
  946.  
  947.                case ID_DIRECT:
  948.                   /* Check to make sure that this system can support
  949.                    * direct mode.
  950.                    *
  951.                    * Note: if the screen aperture size is not an even
  952.                    *       multiple of the scan line size, then the
  953.                    *       system will have bank breaks within the
  954.                    *       scan line. This would make the direct mode
  955.                    *       blit alorithm too complicated for this
  956.                    *       sample. Therefore, if this condition exists
  957.                    *       the sample will not go into direct mode
  958.                    */
  959.  
  960.                   ulRemainder = DiveCaps.ulApertureSize %
  961.                                 DiveCaps.ulScanLineBytes;
  962.  
  963.                   if( !DiveCaps.fScreenDirect ||
  964.                       ( DiveCaps.fBankSwitched && ulRemainder ) )
  965.                   {
  966.                      WinMessageBox( HWND_DESKTOP, HWND_DESKTOP,
  967.                      (PSZ)"usage: Direct mode not supported in this environment.",
  968.                      (PSZ)"Error!", 0, MB_OK | MB_MOVEABLE );
  969.  
  970.                      break;
  971.                   }
  972.  
  973.                   pwinData->fDataInProcess = TRUE;
  974.  
  975.                   /* Set flag for direct frame buffer access
  976.                   */
  977.                   pwinData->fDirect = TRUE;
  978.  
  979.                   /* Post invalidation message.
  980.                   */
  981.                   WinPostMsg ( hwnd, WM_VRNENABLED, 0L, 0L );
  982.                   break;
  983.  
  984.                case ID_USEDIVE:
  985.                   pwinData->fDataInProcess = TRUE;
  986.  
  987.                   /* Set flag for dive blit mode
  988.                   */
  989.                   pwinData->fDirect = FALSE;
  990.  
  991.                   /* Post invalidation message.
  992.                   */
  993.                   WinPostMsg ( hwnd, WM_VRNENABLED, 0L, 0L );
  994.                   break;
  995.  
  996.                default:
  997.                   /* Let PM handle this message.
  998.                   */
  999.                   return WinDefWindowProc ( hwnd, msg, mp1, mp2 );
  1000.                }
  1001.             break;
  1002.  
  1003.          case WM_VRNDISABLED:
  1004.  
  1005.             pwinData->fDataInProcess = TRUE;
  1006.             DiveSetupBlitter ( pwinData->hDive, 0 );
  1007.             pwinData->fVrnDisabled = TRUE;
  1008.             break;
  1009.  
  1010.          case WM_VRNENABLED:
  1011.             pwinData->fDataInProcess = TRUE;
  1012.             hps = WinGetPS ( hwnd );
  1013.             if ( !hps )
  1014.                break;
  1015.             hrgn = GpiCreateRegion ( hps, 0L, NULL );
  1016.             if ( hrgn )
  1017.                {
  1018.                /* NOTE: If mp1 is zero, then this was just a move message.
  1019.                ** Illustrate the visible region on a WM_VRNENABLE.
  1020.                */
  1021.                WinQueryVisibleRegion ( hwnd, hrgn );
  1022.                rgnCtl.ircStart     = 0;
  1023.                rgnCtl.crc          = 50;
  1024.                rgnCtl.ulDirection  = 1;
  1025.  
  1026.                /* Get the all ORed rectangles
  1027.                */
  1028.                if ( GpiQueryRegionRects ( hps, hrgn, NULL,
  1029.                                           &rgnCtl, pwinData->rcls) )
  1030.                   {
  1031.                   pwinData->ulNumRcls = rgnCtl.crcReturned;
  1032.  
  1033.                   /* Now find the window position and size, relative to parent.
  1034.                   */
  1035.                   WinQueryWindowPos ( pwinData->hwndClient, &pwinData->swp );
  1036.  
  1037.                   rcl.xLeft   = 0;
  1038.                   rcl.yBottom = 0;
  1039.  
  1040.                   /* Convert the point to offset from desktop lower left.
  1041.                   */
  1042.                   pointl.x = pwinData->swp.x;
  1043.                   pointl.y = pwinData->swp.y;
  1044.  
  1045.                   WinMapWindowPoints ( pwinData->hwndFrame,
  1046.                                        HWND_DESKTOP, &pointl, 1 );
  1047.  
  1048.                   pwinData->cxWindowPos = pointl.x;
  1049.                   pwinData->cyWindowPos = pointl.y;
  1050.  
  1051.  
  1052.                   /* If the sample is in direct mode check to make sure
  1053.                   ** that the window is not too large. For direct mode the
  1054.                   ** window size is limited to 640x480. This is done to
  1055.                   ** avoide excesive swapping.
  1056.                   */
  1057.  
  1058.                   if ( pwinData->fDirect )
  1059.                      {
  1060.                      if ( pwinData->swp.cx > 640 )
  1061.                         {
  1062.                         WinSetWindowPos ( pwinData->hwndFrame, 0, 0, 0,
  1063.                                           640, pwinData->swp.cy, SWP_SIZE );
  1064.                         return ( FALSE );
  1065.                         }
  1066.  
  1067.                      if ( pwinData->swp.cy > 480 )
  1068.                         {
  1069.                         WinSetWindowPos ( pwinData->hwndFrame, 0, 0, 0,
  1070.                                           pwinData->swp.cx, 480, SWP_SIZE );
  1071.                         return ( FALSE );
  1072.                         }
  1073.                      }
  1074.  
  1075.  
  1076.  
  1077.                   /* Calculate size of scan line bounded by visible window
  1078.                   ** and round up to 4 pell increments.
  1079.                   */
  1080.                   i = pwinData->swp.cx * pwinData->ulColorSizeBytes;
  1081.                   pwinData->ulLineSizeBytes = i/4*4;
  1082.                   if (i - pwinData->ulLineSizeBytes)
  1083.                      pwinData->ulLineSizeBytes += 4;
  1084.  
  1085.                   }
  1086.                else
  1087.                   {
  1088.                   DiveSetupBlitter ( pwinData->hDive, 0 );
  1089.                   GpiDestroyRegion ( hps, hrgn );
  1090.                   break;
  1091.                   }
  1092.  
  1093.                GpiDestroyRegion( hps, hrgn );
  1094.                }
  1095.             WinReleasePS( hps );
  1096.  
  1097.  
  1098.             /* Tell DIVE about the new settings.
  1099.             */
  1100.             SetupBlitter.ulStructLen = sizeof ( SETUP_BLITTER );
  1101.             SetupBlitter.fccSrcColorFormat = pwinData->fccColorFormat;
  1102.             SetupBlitter.ulSrcWidth = pwinData->ulWidth;
  1103.             SetupBlitter.ulSrcHeight = pwinData->ulHeight;
  1104.             SetupBlitter.ulSrcPosX = 0;
  1105.             SetupBlitter.ulSrcPosY = 0;
  1106.             SetupBlitter.ulDitherType = 1;
  1107.             SetupBlitter.fInvert = TRUE;
  1108.  
  1109.             SetupBlitter.lDstPosX = 0;
  1110.             SetupBlitter.lDstPosY = 0;
  1111.             SetupBlitter.fccDstColorFormat = FOURCC_SCRN;
  1112.             SetupBlitter.lScreenPosX = 0;
  1113.             SetupBlitter.lScreenPosY = 0;
  1114.             SetupBlitter.ulNumDstRects = 1;
  1115.  
  1116.             /* If direct mode then stretch blit to video buffers
  1117.             */
  1118.             if ( pwinData->fDirect )
  1119.                {
  1120.                rcl.xRight  = pwinData->swp.cx;
  1121.                rcl.yTop    = pwinData->swp.cy;
  1122.                SetupBlitter.ulDstWidth = pwinData->swp.cx;
  1123.                SetupBlitter.ulDstHeight = pwinData->swp.cy;
  1124.                SetupBlitter.pVisDstRects = &rcl;
  1125.                }
  1126.             /* If blit mode then blit to video buffers without stretching
  1127.             */
  1128.             else
  1129.                {
  1130.                rcl.xRight = pwinData->ulWidth;
  1131.                rcl.yTop   = pwinData->ulHeight;
  1132.                SetupBlitter.ulDstWidth = pwinData->ulWidth;
  1133.                SetupBlitter.ulDstHeight = pwinData->ulHeight;
  1134.                SetupBlitter.pVisDstRects = &rcl;
  1135.                }
  1136.  
  1137.             DiveSetupBlitter ( pwinData->hDive, &SetupBlitter );
  1138.  
  1139.             for (i = 0; i < pwinData->ulMaxFiles ; i++ )
  1140.                {
  1141.                DiveFreeImageBuffer ( pwinData->hDive, ulImage[i] );
  1142.  
  1143.  
  1144.                /* Register source image buffer with DIVE
  1145.                */
  1146.                ulTmpImage = 0;
  1147.                if ( rc = DiveAllocImageBuffer (pwinData->hDive,
  1148.                                           &ulTmpImage,
  1149.                                           pwinData->fccColorFormat,
  1150.                                           pwinData->ulWidth,
  1151.                                           pwinData->ulHeight,
  1152.                                           pwinData->ulSrcLineSizeBytes,
  1153.                                           (PBYTE)pbSrcImage[i] ) )
  1154.                   break;
  1155.  
  1156.                /* Allocate DIVE image buffer
  1157.                */
  1158.                if ( rc = DiveAllocImageBuffer (pwinData->hDive,
  1159.                                           &(ulImage[i]),
  1160.                                           FOURCC_SCRN,
  1161.                                           rcl.xRight,
  1162.                                           rcl.yTop,
  1163.                                           0, 0) )
  1164.                   break;
  1165.  
  1166.                if ( DiveBeginImageBufferAccess ( pwinData->hDive,
  1167.                                                  ulImage[i],
  1168.                                                  (PPBYTE)&pbImage[i],
  1169.                                                  &ulScanLineBytes,
  1170.                                                  &ulScanLines ))
  1171.                   {
  1172.                   DiveFreeImageBuffer ( pwinData->hDive, ulTmpImage );
  1173.                   DiveFreeImageBuffer ( pwinData->hDive, ulImage[i] );
  1174.                   break;
  1175.                   }
  1176.                /* Blit source image to DIVE buffer
  1177.                */
  1178.                DiveBlitImage ( pwinData->hDive, ulTmpImage, ulImage[i] );
  1179.  
  1180.                DiveEndImageBufferAccess ( pwinData->hDive, ulImage[i] );
  1181.                DiveFreeImageBuffer ( pwinData->hDive, ulTmpImage );
  1182.                }
  1183.  
  1184.             /* Now setup blitter to blit to the screen
  1185.             ** Note: This code has no affect when in direct mode
  1186.             */
  1187.             SetupBlitter.fccSrcColorFormat = FOURCC_SCRN;
  1188.             SetupBlitter.lScreenPosX = pointl.x;
  1189.             SetupBlitter.lScreenPosY = pointl.y;
  1190.             SetupBlitter.fInvert = FALSE;
  1191.             SetupBlitter.ulDstWidth = pwinData->swp.cx;
  1192.             SetupBlitter.ulDstHeight = pwinData->swp.cy;
  1193.             SetupBlitter.ulNumDstRects = pwinData->ulNumRcls;
  1194.             SetupBlitter.pVisDstRects = pwinData->rcls;
  1195.  
  1196.             DiveSetupBlitter ( pwinData->hDive, &SetupBlitter );
  1197.  
  1198.             ulFramesToTime=4;
  1199.             ulNumFrames=1;
  1200.             pwinData->fDataInProcess = FALSE;
  1201.             pwinData->fVrnDisabled = FALSE;
  1202.  
  1203.             break;
  1204.  
  1205.  
  1206.          case WM_REALIZEPALETTE:
  1207.             /* This tells DIVE that the physical palette may have changed.
  1208.             */
  1209.             DiveSetDestinationPalette ( pwinData->hDive, 0, 0, 0 );
  1210.  
  1211.             break;
  1212.  
  1213.          case WM_CLOSE:
  1214.             /* Post to quit the dispatch message loop.
  1215.             */
  1216.             WinPostMsg ( hwnd, WM_QUIT, 0L, 0L );
  1217.             break;
  1218.  
  1219.          default:
  1220.             /* Let PM handle this message.
  1221.             */
  1222.             return WinDefWindowProc ( hwnd, msg, mp1, mp2 );
  1223.          }
  1224.       }
  1225.    else
  1226.       /* Let PM handle this message.
  1227.       */
  1228.       return WinDefWindowProc ( hwnd, msg, mp1, mp2 );
  1229.  
  1230.    return ( FALSE );
  1231.    }
  1232.  
  1233. /****************************************************************************
  1234.  *
  1235.  * Name          : MyDlgProc
  1236.  *
  1237.  * Description   : It is the dialog procedure of this program.
  1238.  *
  1239.  * Concepts      :
  1240.  *
  1241.  * Parameters    : Message parameter 1
  1242.  *                 Message parameter 2
  1243.  *
  1244.  * Return        : calling WinDefDlgProc
  1245.  *
  1246.  ****************************************************************************/
  1247.  
  1248. MRESULT EXPENTRY MyDlgProc ( HWND hwndDlg, ULONG msg, MPARAM mp1, MPARAM mp2 )
  1249.    {
  1250.    CHAR      string[10];
  1251.    CHAR      *pString;
  1252.  
  1253.    switch( msg )
  1254.       {
  1255.       case WM_INITDLG:
  1256.  
  1257.          WinSetFocus ( HWND_DESKTOP, hwndDlg );
  1258.  
  1259.          if ( !DiveCaps.fScreenDirect )
  1260.             WinSetDlgItemText ( hwndDlg, ID_EF_11, "NO" );
  1261.          else
  1262.             WinSetDlgItemText ( hwndDlg, ID_EF_11, "YES" );
  1263.  
  1264.          if ( !DiveCaps.fBankSwitched )
  1265.             WinSetDlgItemText ( hwndDlg, ID_EF_12, "NO" );
  1266.          else
  1267.             WinSetDlgItemText ( hwndDlg, ID_EF_12, "YES" );
  1268.  
  1269.          pString = _ultoa ( DiveCaps.ulDepth, string, 10 );
  1270.          WinSetDlgItemText ( hwndDlg, ID_EF_13, pString );
  1271.  
  1272.          pString = _ultoa ( DiveCaps.ulHorizontalResolution,
  1273.                              string, 10 );
  1274.          WinSetDlgItemText ( hwndDlg, ID_EF_14, pString );
  1275.  
  1276.          pString = _ultoa ( DiveCaps.ulVerticalResolution, string, 10 );
  1277.          WinSetDlgItemText ( hwndDlg, ID_EF_15, pString );
  1278.  
  1279.          pString = _ultoa ( DiveCaps.ulScanLineBytes, string, 10 );
  1280.          WinSetDlgItemText ( hwndDlg, ID_EF_16, pString );
  1281.  
  1282.          switch (DiveCaps.fccColorEncoding)
  1283.             {
  1284.             case FOURCC_LUT8:
  1285.                WinSetDlgItemText ( hwndDlg, ID_EF_17, "256" );
  1286.                break;
  1287.             case FOURCC_R565:
  1288.                WinSetDlgItemText ( hwndDlg, ID_EF_17, "64K" );
  1289.                break;
  1290.             case FOURCC_R555:
  1291.                WinSetDlgItemText ( hwndDlg, ID_EF_17, "32K" );
  1292.                break;
  1293.             case FOURCC_R664:
  1294.                WinSetDlgItemText ( hwndDlg, ID_EF_17, "64K" );
  1295.                break;
  1296.             case FOURCC_RGB3:
  1297.                WinSetDlgItemText ( hwndDlg, ID_EF_17, "16M" );
  1298.                break;
  1299.             case FOURCC_BGR3:
  1300.                WinSetDlgItemText ( hwndDlg, ID_EF_17, "16M" );
  1301.                break;
  1302.             case FOURCC_RGB4:
  1303.                WinSetDlgItemText ( hwndDlg, ID_EF_17, "16M" );
  1304.                break;
  1305.             case FOURCC_BGR4:
  1306.                WinSetDlgItemText ( hwndDlg, ID_EF_17, "16M" );
  1307.                break;
  1308.             default:
  1309.                WinSetDlgItemText ( hwndDlg, ID_EF_17, "???" );
  1310.             } /* endswitch */
  1311.  
  1312.          pString = _ultoa ( DiveCaps.ulApertureSize, string, 10 );
  1313.          WinSetDlgItemText ( hwndDlg, ID_EF_18, pString );
  1314.  
  1315.          pString = _ultoa ( DiveCaps.ulInputFormats, string, 10 );
  1316.          WinSetDlgItemText ( hwndDlg, ID_EF_19, pString );
  1317.  
  1318.          pString = _ultoa ( DiveCaps.ulOutputFormats, string, 10 );
  1319.          WinSetDlgItemText ( hwndDlg, ID_EF_20, pString );
  1320.  
  1321.          break;
  1322.  
  1323.       case WM_COMMAND:
  1324.          switch ( SHORT1FROMMP ( mp1 ) )
  1325.             {
  1326.             case DID_OK:
  1327.  
  1328.                WinDismissDlg ( hwndDlg, TRUE );
  1329.                break;
  1330.             }
  1331.  
  1332.       default:
  1333.          return ( WinDefDlgProc (hwndDlg, msg, mp1, mp2) );
  1334.  
  1335.       }
  1336.    }
  1337.  
  1338.