home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: WPS_PM / WPS_PM.zip / npssp181.zip / npswpswa.cpp < prev    next >
C/C++ Source or Header  |  1995-10-08  |  16KB  |  449 lines

  1. // Window Animation DLL for NPS WPS Enhancer
  2. // Copyright (C) 1995, N.P.S.
  3. // 100 or more columns are necessary to read this file properly
  4.  
  5. #define INCL_PM
  6. #include <os2.h>
  7. #include <memory.h>
  8. #include <string.h>
  9. #include <stdlib.h>
  10. #include "npswpswa.h"
  11.  
  12. // to export
  13.  
  14. extern "C" BOOL EXPENTRY SpinFrame(AnimationData *padat);
  15. extern "C" BOOL EXPENTRY VortexFrames(AnimationData *padat);
  16. extern "C" BOOL EXPENTRY ScatterGatherFrames(AnimationData *padat);
  17. extern "C" BOOL EXPENTRY SpikeFrames(AnimationData *padat);
  18. extern "C" BOOL EXPENTRY FireworksFrames(AnimationData *padat);
  19.  
  20. const FIXED Fixed1 = 1 << 16;
  21. static POINTL PointZero = { 0, 0 };
  22. static MATRIXLF Matrix1 = { Fixed1, 0, 0, 0, Fixed1, 0, 0, 0, 1 };
  23.  
  24. void drawBox(HPS hps, POINTL &pointCenter, POINTL &pointRelRightTop);
  25. void drawPolygon(HPS hps, POINTL *paPoints, LONG cPoints);
  26.  
  27. LONG fixedMul(LONG lMultiplicand, FIXED fMultiplier);
  28. FIXED fixedDiv(LONG lNumerator, LONG lDenominator);
  29. POINTL operator*(const POINTL &point, const MATRIXLF &matrix);
  30. MATRIXLF operator*(const MATRIXLF &matrix1, const MATRIXLF &matrix2);
  31. MATRIXLF mix(const MATRIXLF &matrix1, const MATRIXLF &matrix2, FIXED fMix);
  32. POINTL mix(const POINTL &point1, const POINTL &point2, FIXED fMix);
  33.  
  34. inline POINTL operator+(POINTL &point1, POINTL &point2)
  35. {  POINTL pointResult;
  36.    pointResult.x = point1.x + point2.x;
  37.    pointResult.y = point1.y + point2.y;
  38.    return pointResult;
  39. }
  40.  
  41. inline POINTL operator-(POINTL &point1, POINTL &point2)
  42. {  POINTL pointResult;
  43.    pointResult.x = point1.x - point2.x;
  44.    pointResult.y = point1.y - point2.y;
  45.    return pointResult;
  46. }
  47.  
  48. inline MATRIXLF& operator*=(MATRIXLF &matrix1, const MATRIXLF &matrix2)
  49. {  return matrix1 = matrix1 * matrix2;
  50. }
  51.  
  52. BOOL EXPENTRY SpinFrame(AnimationData *padat)
  53. {  if (padat->animCallType == AnimationDraw
  54.        || padat->animCallType == AnimationErase)
  55.    {  POINTL aPtRectangle[4];
  56.       aPtRectangle[1].x = aPtRectangle[0].x = padat->ptRelRightTop.x;
  57.       aPtRectangle[1].y = -(aPtRectangle[0].y = padat->ptRelRightTop.y);
  58.  
  59.       MATRIXLF matrix;
  60.       FIXED afxScale[2];
  61.       afxScale[0] = afxScale[1] = fixedDiv(padat->lStep, padat->cTotalSteps);
  62.       GpiScale(padat->hps, &matrix, TRANSFORM_REPLACE, afxScale, &PointZero);
  63.       GpiRotate(padat->hps, &matrix, TRANSFORM_ADD,
  64.         fixedDiv(padat->lParameter * (padat->lStep - padat->cTotalSteps),
  65.              padat->cTotalSteps),
  66.         &PointZero);
  67.       aPtRectangle[0] = aPtRectangle[0] * matrix;
  68.       aPtRectangle[1] = aPtRectangle[1] * matrix;
  69.  
  70.       aPtRectangle[2] = padat->ptCenter + aPtRectangle[0];
  71.       aPtRectangle[3] = padat->ptCenter + aPtRectangle[1];
  72.       aPtRectangle[0] = padat->ptCenter - aPtRectangle[0];
  73.       aPtRectangle[1] = padat->ptCenter - aPtRectangle[1];
  74.  
  75.       drawPolygon(padat->hps, aPtRectangle, 4);
  76.    }
  77.  
  78.    return TRUE;
  79. }
  80.  
  81. BOOL EXPENTRY VortexFrames(AnimationData *padat)
  82. {  switch (padat->animCallType)
  83.    {  case AnimationInitialize:
  84.      GpiRotate(padat->hps, (MATRIXLF *)padat->achBuffer, TRANSFORM_REPLACE,
  85.            72 * Fixed1, &padat->ptCenter);
  86.      break;
  87.       case AnimationDraw:
  88.       case AnimationErase:
  89.       {  POINTL ptBoxRel;
  90.      ptBoxRel.x = padat->ptRelRightTop.x * padat->lStep / padat->cTotalSteps;
  91.      ptBoxRel.y = padat->ptRelRightTop.y * padat->lStep / padat->cTotalSteps;
  92.  
  93.      MATRIXLF matrix;
  94.      FIXED afxScale[2];
  95.      afxScale[0] = afxScale[1] = fixedDiv((padat->cTotalSteps - padat->lStep) * 4,
  96.                           padat->cTotalSteps * 3);
  97.      GpiTranslate(padat->hps, &matrix, TRANSFORM_REPLACE, &padat->ptRelRightTop);
  98.      GpiScale(padat->hps, &matrix, TRANSFORM_ADD, afxScale, &padat->ptCenter);
  99.      GpiRotate(padat->hps, &matrix, TRANSFORM_ADD,
  100.            fixedDiv(padat->lParameter * padat->lStep, padat->cTotalSteps),
  101.            &padat->ptCenter);
  102.  
  103.      POINTL ptBoxCenter = padat->ptCenter * matrix;
  104.  
  105.      for (int iLoop = 0; iLoop < 5; iLoop++)
  106.      {  drawBox(padat->hps, ptBoxCenter, ptBoxRel);
  107.         ptBoxCenter = ptBoxCenter * *(MATRIXLF *)padat->achBuffer;
  108.      }
  109.  
  110.      break;
  111.       }
  112.    }
  113.  
  114.    return TRUE;
  115. }
  116.  
  117. BOOL EXPENTRY ScatterGatherFrames(AnimationData *padat)
  118. {  if (padat->animCallType == AnimationDraw
  119.        || padat->animCallType == AnimationErase)
  120.    {  LONG lDivisor = padat->lParameter;
  121.       POINTL ptBoxRel;
  122.       
  123.       ptBoxRel.x = padat->ptRelRightTop.x * padat->lStep / (padat->cTotalSteps * lDivisor);
  124.       ptBoxRel.y = padat->ptRelRightTop.y * padat->lStep / (padat->cTotalSteps * lDivisor);
  125.  
  126.       MATRIXLF matrix;
  127.       FIXED afxScale[2];
  128.       afxScale[0] = afxScale[1] = fixedDiv(padat->cTotalSteps * 3 - padat->lStep * 2,
  129.                        padat->cTotalSteps);
  130.       GpiScale(padat->hps, &matrix, TRANSFORM_REPLACE, afxScale, &PointZero);
  131.       GpiTranslate(padat->hps, &matrix, TRANSFORM_ADD, &padat->ptCenter);
  132.  
  133.       for (int iRow = 0; iRow < lDivisor; iRow++)
  134.       {  for (int iColumn = 0; iColumn < padat->lParameter; iColumn++)
  135.      {  POINTL ptTileCenter;
  136.         ptTileCenter.x = (iRow * 2 - lDivisor + 1) * padat->ptRelRightTop.x / lDivisor;
  137.         ptTileCenter.y = (iColumn * 2 - lDivisor + 1) * padat->ptRelRightTop.y / lDivisor;
  138.         ptTileCenter = ptTileCenter * matrix;
  139.  
  140.         drawBox(padat->hps, ptTileCenter, ptBoxRel);
  141.      }
  142.       }
  143.    }
  144.  
  145.    return TRUE;
  146. }
  147.  
  148. BOOL EXPENTRY SpikeFrames(AnimationData *padat)
  149. {  struct SpikeData
  150.    {  POINTL aPtTriangleEnd[16][3], aPtEndCenter[16], aPtTriangleCenter[16];
  151.       MATRIXLF aMatrixCircle[16];
  152.    };
  153.  
  154.    switch (padat->animCallType)
  155.    {  case AnimationInitialize:
  156.       {  LONG xLeft = padat->rectWindow.xLeft,
  157.           xRight = padat->rectWindow.xRight,
  158.           yBottom = padat->rectWindow.yBottom,
  159.           yTop = padat->rectWindow.yTop;
  160.         
  161.      POINTL *paPtTriangle = ((SpikeData *)padat->achBuffer)->aPtTriangleEnd[0],
  162.             *paPtCenter = ((SpikeData *)padat->achBuffer)->aPtEndCenter;
  163.      for (int iIndex = 0; iIndex < 16; iIndex++, paPtTriangle += 3, paPtCenter++)
  164.      {  paPtTriangle[0] = padat->ptCenter;
  165.  
  166.         if (iIndex < 4)
  167.         {  paPtTriangle[1].y = paPtTriangle[2].y = yTop;
  168.            paPtTriangle[1].x = (xLeft * (4 - iIndex) + xRight * iIndex) / 4;
  169.            paPtTriangle[2].x = (xLeft * (3 - iIndex) + xRight * (iIndex + 1)) / 4;
  170.         }
  171.         else if (iIndex < 8)
  172.         {  paPtTriangle[1].x = paPtTriangle[2].x = xRight;
  173.            paPtTriangle[1].y = (yTop * (8 - iIndex) + yBottom * (iIndex - 4)) / 4;
  174.            paPtTriangle[2].y = (yTop * (7 - iIndex) + yBottom * (iIndex - 3)) / 4;
  175.         }
  176.         else if (iIndex < 12)
  177.         {  paPtTriangle[1].y = paPtTriangle[2].y = yBottom;
  178.            paPtTriangle[1].x = (xRight * (12 - iIndex) + xLeft * (iIndex - 8)) / 4;
  179.            paPtTriangle[2].x = (xRight * (11 - iIndex) + xLeft * (iIndex - 7)) / 4;
  180.         }
  181.         else
  182.         {  paPtTriangle[1].x = paPtTriangle[2].x = xLeft;
  183.            paPtTriangle[1].y = (yBottom * (16 - iIndex) + yTop * (iIndex - 12)) / 4;
  184.            paPtTriangle[2].y = (yBottom * (15 - iIndex) + yTop * (iIndex - 11)) / 4;
  185.         }
  186.  
  187.         paPtCenter->x = (paPtTriangle[0].x + paPtTriangle[1].x + paPtTriangle[2].x) / 3;
  188.         paPtCenter->y = (paPtTriangle[0].y + paPtTriangle[1].y + paPtTriangle[2].y) / 3;
  189.      }
  190.  
  191.      paPtCenter = ((SpikeData *)padat->achBuffer)->aPtTriangleCenter;
  192.      POINTL ptTriangleCenter;
  193.      ptTriangleCenter.x = padat->ptCenter.x;
  194.      ptTriangleCenter.y =
  195.         padat->ptCenter.y + (padat->ptRelRightTop.x + padat->ptRelRightTop.y) * 4 / 5;
  196.      
  197.      for (iIndex = 0; iIndex < 16; iIndex++)
  198.      {  MATRIXLF matrix;
  199.         GpiRotate(padat->hps, &matrix, TRANSFORM_REPLACE,
  200.               (33 * Fixed1) + (-22 * Fixed1) * iIndex, &padat->ptCenter);
  201.         paPtCenter[iIndex] = ptTriangleCenter * matrix;
  202.  
  203.         POINTL ptTemp =
  204.            paPtCenter[iIndex] - ((SpikeData *)padat->achBuffer)->aPtEndCenter[iIndex];
  205.         GpiTranslate(padat->hps, &((SpikeData *)padat->achBuffer)->aMatrixCircle[iIndex],
  206.              TRANSFORM_REPLACE, &ptTemp);
  207.      }
  208.  
  209.      break;
  210.       }
  211.       case AnimationDraw:
  212.       case AnimationErase:
  213.       {  POINTL aPtTriangle[3];
  214.      FIXED fixedFactor;
  215.  
  216.      MATRIXLF matrix;
  217.      FIXED afxScale[2];
  218.      afxScale[0] = afxScale[1] = fixedDiv(padat->lStep, padat->cTotalSteps);
  219.  
  220.      if (padat->lStep < padat->cTotalSteps / 2)
  221.      {  fixedFactor = (Fixed1 - fixedDiv(padat->lStep * 2, padat->cTotalSteps))
  222.            * padat->lParameter;
  223.  
  224.         for (int iIndex = 0; iIndex < 16; iIndex++)
  225.         {  GpiScale(padat->hps, &matrix, TRANSFORM_REPLACE, afxScale,
  226.             &((SpikeData *)padat->achBuffer)->aPtEndCenter[iIndex]);
  227.            GpiRotate(padat->hps, &matrix, TRANSFORM_ADD, fixedFactor,
  228.              &((SpikeData *)padat->achBuffer)->aPtEndCenter[iIndex]);
  229.            matrix = matrix * ((SpikeData *)padat->achBuffer)->aMatrixCircle[iIndex];
  230.  
  231.            for (int iAngle = 0; iAngle < 3; iAngle++)
  232.            {  aPtTriangle[iAngle] = 
  233.              ((SpikeData *)padat->achBuffer)->aPtTriangleEnd[iIndex][iAngle] * matrix;
  234.            }
  235.  
  236.            drawPolygon(padat->hps, aPtTriangle, 3);
  237.         }
  238.      }
  239.      else
  240.      {  fixedFactor = fixedDiv(padat->lStep * 2 - padat->cTotalSteps, padat->cTotalSteps);
  241.  
  242.         for (int iIndex = 0; iIndex < 16; iIndex++)
  243.         {  GpiScale(padat->hps, &matrix, TRANSFORM_REPLACE, afxScale,
  244.             &((SpikeData *)padat->achBuffer)->aPtEndCenter[iIndex]);
  245.            matrix *= mix(Matrix1, ((SpikeData *)padat->achBuffer)->aMatrixCircle[iIndex],
  246.                  fixedFactor);
  247.  
  248.            for (int iAngle = 0; iAngle < 3; iAngle++)
  249.            {  aPtTriangle[iAngle] = 
  250.              ((SpikeData *)padat->achBuffer)->aPtTriangleEnd[iIndex][iAngle] * matrix;
  251.            }
  252.  
  253.            drawPolygon(padat->hps, aPtTriangle, 3);
  254.         }
  255.      }
  256.  
  257.      break;
  258.       }
  259.    }
  260.  
  261.    return TRUE;
  262. }
  263.  
  264. BOOL EXPENTRY FireworksFrames(AnimationData *padat)
  265. {  const int NUMBER_OF_RECTS = 10;
  266.  
  267.    struct FireworksData
  268.    {  POINTL aPtCenter[NUMBER_OF_RECTS];
  269.    };
  270.  
  271.    switch (padat->animCallType)
  272.    {  case AnimationInitialize:
  273.       {  POINTL *paPtCenter = ((FireworksData *)padat->achBuffer)->aPtCenter;
  274.      POINTL ptRectCenter;
  275.      ptRectCenter.x = padat->ptCenter.x;
  276.      ptRectCenter.y =
  277.         padat->ptCenter.y + (padat->ptRelRightTop.x + padat->ptRelRightTop.y) * 5 / 3;
  278.      
  279.      for (int iIndex = 0; iIndex < NUMBER_OF_RECTS; iIndex++)
  280.      {  MATRIXLF matrix;
  281.         GpiRotate(padat->hps, &matrix, TRANSFORM_REPLACE,
  282.               iIndex * (360 * Fixed1 / NUMBER_OF_RECTS), &padat->ptCenter);
  283.         paPtCenter[iIndex] = ptRectCenter * matrix;
  284.      }
  285.  
  286.      break;
  287.       }
  288.       case AnimationDraw:
  289.       case AnimationErase:
  290.       {  POINTL ptTemp;
  291.      FIXED fixedFactor = fixedDiv(padat->lStep, padat->cTotalSteps);
  292.  
  293.      MATRIXLF matrix;
  294.      FIXED afxScale[2];
  295.      afxScale[0] = afxScale[1] = fixedFactor;
  296.  
  297.      POINTL aPtRect[4], aPtTemp[4];
  298.      aPtRect[0].x = aPtRect[3].x = -padat->ptRelRightTop.x;
  299.      aPtRect[1].x = aPtRect[2].x = padat->ptRelRightTop.x;
  300.      aPtRect[0].y = aPtRect[1].y = padat->ptRelRightTop.y;
  301.      aPtRect[2].y = aPtRect[3].y = -padat->ptRelRightTop.y;
  302.  
  303.      for (int iIndex = 0; iIndex < NUMBER_OF_RECTS; iIndex++)
  304.      {  GpiScale(padat->hps, &matrix, TRANSFORM_REPLACE, afxScale, &PointZero);
  305.         GpiRotate(padat->hps, &matrix, TRANSFORM_ADD,
  306.               (Fixed1 - fixedFactor) * padat->lParameter, &PointZero);
  307.         POINTL ptTemp;
  308.         ptTemp = mix(padat->ptCenter, ((FireworksData *)padat->achBuffer)->aPtCenter[iIndex],
  309.              fixedFactor);
  310.         GpiTranslate(padat->hps, &matrix, TRANSFORM_ADD, &ptTemp);
  311.       
  312.         for (int iAngle = 0; iAngle < 4; iAngle++)
  313.         {  aPtTemp[iAngle] = aPtRect[iAngle] * matrix;
  314.         }
  315.       
  316.         drawPolygon(padat->hps, aPtTemp, 4);
  317.      }
  318.  
  319.      break;
  320.       }
  321.    }
  322.  
  323.    return TRUE;
  324. }
  325.  
  326. // drawing functions
  327.  
  328. void drawBox(HPS hps, POINTL &ptCenter, POINTL &ptRelRightTop)
  329. {  if (ptRelRightTop.x == 0 && ptRelRightTop.y == 0) return;
  330.  
  331.    POINTL ptTemp = ptCenter - ptRelRightTop;
  332.    GpiMove(hps, &ptTemp);
  333.    ptTemp = ptCenter + ptRelRightTop;
  334.    GpiBox(hps, DRO_OUTLINE, &ptTemp, 0, 0);
  335. }
  336.  
  337. void drawPolygon(HPS hps, POINTL *paPoints, LONG cPoints)
  338. {  if (cPoints == 0) return;
  339.  
  340.    if (paPoints[cPoints - 1].x == paPoints[0].x
  341.        && paPoints[cPoints - 1].y == paPoints[0].y)
  342.    {  return;
  343.    }
  344.  
  345.    for (int iIndex = 1; iIndex < cPoints; iIndex++)
  346.    {  if (paPoints[iIndex].x == paPoints[iIndex - 1].x
  347.       && paPoints[iIndex].y == paPoints[iIndex - 1].y)
  348.       {  return;
  349.       }
  350.    }
  351.  
  352.    GpiMove(hps, &paPoints[cPoints - 1]);
  353.    GpiPolyLine(hps, cPoints, paPoints);
  354. }
  355.  
  356. // helper functions
  357.  
  358. LONG fixedMul(LONG lMultiplicand, FIXED fxMultiplier)
  359. {  // returns lMultiplicand * fxMultiplier as a LONG
  360.    // also returns a FIXED if lMultiplicand is a FIXED
  361.  
  362.    return lMultiplicand * (fxMultiplier >> 16) 
  363.       + (lMultiplicand >> 16) * (fxMultiplier & 0xffff)
  364.      + ((ULONG)((lMultiplicand & 0xffff) * (fxMultiplier & 0xffff)) >> 16);
  365. }
  366.  
  367. FIXED fixedDiv(LONG lNumerator, LONG lDenominator)
  368. {  // returns lNumerator / lDenominator as a FIXED
  369.    // also works well for 2 FIXED's
  370.  
  371.    if (lNumerator == 0 || lDenominator == 0) return 0;
  372.  
  373.    LONG lSignBit = (lNumerator ^ lDenominator) >> 31;
  374.    lNumerator = abs(lNumerator);
  375.    lDenominator = abs(lDenominator);
  376.  
  377.    ULONG ulQuotient = (ULONG)lNumerator / (ULONG)lDenominator;
  378.    lNumerator -= ulQuotient * lDenominator;
  379.  
  380.    if (lNumerator == 0) ulQuotient <<= 16;
  381.    else
  382.    {  int cShiftRemain = 16;
  383.  
  384.       do
  385.       {  ulQuotient <<= 1;
  386.      lNumerator <<= 1;
  387.      cShiftRemain--;
  388.  
  389.      if (lNumerator >= lDenominator)
  390.      {  ulQuotient++;
  391.         lNumerator -= lDenominator;
  392.         if (lNumerator == 0)
  393.         {  ulQuotient <<= cShiftRemain;
  394.            break;
  395.         }
  396.      }
  397.       } while (cShiftRemain > 0);
  398.    }
  399.  
  400.    return (ulQuotient ^ lSignBit) - lSignBit;  /* reverse sign if lSignBit = -1 */
  401. }
  402.  
  403. POINTL operator*(const POINTL &point, const MATRIXLF &matrix)
  404. {  // returns POINTL transformed by MATRIXLF
  405.  
  406.    POINTL pointResult;
  407.    pointResult.x = fixedMul(point.x, matrix.fxM11) + fixedMul(point.y, matrix.fxM21) + matrix.lM31;
  408.    pointResult.y = fixedMul(point.x, matrix.fxM12) + fixedMul(point.y, matrix.fxM22) + matrix.lM32;
  409.    return pointResult;
  410. }   
  411.  
  412. POINTL mix(const POINTL &pointSource1, const POINTL &pointSource2, FIXED fMix)
  413. {  // mix 2 POINTL's according to FIXED
  414.  
  415.    POINTL pointResult;
  416.    pointResult.x = fixedMul(pointSource1.x, fMix) + fixedMul(pointSource2.x, Fixed1 - fMix);
  417.    pointResult.y = fixedMul(pointSource1.y, fMix) + fixedMul(pointSource2.y, Fixed1 - fMix);
  418.    return pointResult;
  419. }
  420.  
  421. MATRIXLF operator*(const MATRIXLF &mtx1, const MATRIXLF &mtx2)
  422. {  // returns product of 2 MATRIXLF's
  423.  
  424.    MATRIXLF mtxProduct;
  425.    mtxProduct.fxM11 = fixedMul(mtx1.fxM11, mtx2.fxM11) + fixedMul(mtx1.fxM12, mtx2.fxM21);
  426.    mtxProduct.fxM12 = fixedMul(mtx1.fxM11, mtx2.fxM12) + fixedMul(mtx1.fxM12, mtx2.fxM22);
  427.    mtxProduct.lM13 = 0;
  428.    mtxProduct.fxM21 = fixedMul(mtx1.fxM21, mtx2.fxM11) + fixedMul(mtx1.fxM22, mtx2.fxM21);
  429.    mtxProduct.fxM22 = fixedMul(mtx1.fxM21, mtx2.fxM12) + fixedMul(mtx1.fxM22, mtx2.fxM22);
  430.    mtxProduct.lM23 = 0;
  431.    mtxProduct.lM31 = fixedMul(mtx1.lM31, mtx2.fxM11) + fixedMul(mtx1.lM32, mtx2.fxM21) + mtx2.lM31;
  432.    mtxProduct.lM32 = fixedMul(mtx1.lM31, mtx2.fxM12) + fixedMul(mtx1.lM32, mtx2.fxM22) + mtx2.lM32;
  433.    mtxProduct.lM33 = 1;
  434.    return mtxProduct;
  435. }
  436.  
  437. MATRIXLF mix(const MATRIXLF &matrix1, const MATRIXLF &matrix2, FIXED fMix)
  438. {  // mix 2 MATRIXLF's according to FIXED
  439.  
  440.    MATRIXLF matrixResult;
  441.    for (int iIndex = 0; iIndex < 9; iIndex++)
  442.    {  ((PLONG)&matrixResult)[iIndex] =
  443.      fixedMul(((PLONG)&matrix1)[iIndex], fMix)
  444.         + fixedMul(((PLONG)&matrix2)[iIndex], Fixed1 - fMix);
  445.    }
  446.  
  447.    return matrixResult;
  448. }
  449.