home *** CD-ROM | disk | FTP | other *** search
- // Window Animation DLL for NPS WPS Enhancer
- // Copyright (C) 1995, N.P.S.
- // 100 or more columns are necessary to read this file properly
-
- #define INCL_PM
- #include <os2.h>
- #include <memory.h>
- #include <string.h>
- #include <stdlib.h>
- #include "npswpswa.h"
-
- // to export
-
- extern "C" BOOL EXPENTRY SpinFrame(AnimationData *padat);
- extern "C" BOOL EXPENTRY VortexFrames(AnimationData *padat);
- extern "C" BOOL EXPENTRY ScatterGatherFrames(AnimationData *padat);
- extern "C" BOOL EXPENTRY SpikeFrames(AnimationData *padat);
- extern "C" BOOL EXPENTRY FireworksFrames(AnimationData *padat);
-
- const FIXED Fixed1 = 1 << 16;
- static POINTL PointZero = { 0, 0 };
- static MATRIXLF Matrix1 = { Fixed1, 0, 0, 0, Fixed1, 0, 0, 0, 1 };
-
- void drawBox(HPS hps, POINTL &pointCenter, POINTL &pointRelRightTop);
- void drawPolygon(HPS hps, POINTL *paPoints, LONG cPoints);
-
- LONG fixedMul(LONG lMultiplicand, FIXED fMultiplier);
- FIXED fixedDiv(LONG lNumerator, LONG lDenominator);
- POINTL operator*(const POINTL &point, const MATRIXLF &matrix);
- MATRIXLF operator*(const MATRIXLF &matrix1, const MATRIXLF &matrix2);
- MATRIXLF mix(const MATRIXLF &matrix1, const MATRIXLF &matrix2, FIXED fMix);
- POINTL mix(const POINTL &point1, const POINTL &point2, FIXED fMix);
-
- inline POINTL operator+(POINTL &point1, POINTL &point2)
- { POINTL pointResult;
- pointResult.x = point1.x + point2.x;
- pointResult.y = point1.y + point2.y;
- return pointResult;
- }
-
- inline POINTL operator-(POINTL &point1, POINTL &point2)
- { POINTL pointResult;
- pointResult.x = point1.x - point2.x;
- pointResult.y = point1.y - point2.y;
- return pointResult;
- }
-
- inline MATRIXLF& operator*=(MATRIXLF &matrix1, const MATRIXLF &matrix2)
- { return matrix1 = matrix1 * matrix2;
- }
-
- BOOL EXPENTRY SpinFrame(AnimationData *padat)
- { if (padat->animCallType == AnimationDraw
- || padat->animCallType == AnimationErase)
- { POINTL aPtRectangle[4];
- aPtRectangle[1].x = aPtRectangle[0].x = padat->ptRelRightTop.x;
- aPtRectangle[1].y = -(aPtRectangle[0].y = padat->ptRelRightTop.y);
-
- MATRIXLF matrix;
- FIXED afxScale[2];
- afxScale[0] = afxScale[1] = fixedDiv(padat->lStep, padat->cTotalSteps);
- GpiScale(padat->hps, &matrix, TRANSFORM_REPLACE, afxScale, &PointZero);
- GpiRotate(padat->hps, &matrix, TRANSFORM_ADD,
- fixedDiv(padat->lParameter * (padat->lStep - padat->cTotalSteps),
- padat->cTotalSteps),
- &PointZero);
- aPtRectangle[0] = aPtRectangle[0] * matrix;
- aPtRectangle[1] = aPtRectangle[1] * matrix;
-
- aPtRectangle[2] = padat->ptCenter + aPtRectangle[0];
- aPtRectangle[3] = padat->ptCenter + aPtRectangle[1];
- aPtRectangle[0] = padat->ptCenter - aPtRectangle[0];
- aPtRectangle[1] = padat->ptCenter - aPtRectangle[1];
-
- drawPolygon(padat->hps, aPtRectangle, 4);
- }
-
- return TRUE;
- }
-
- BOOL EXPENTRY VortexFrames(AnimationData *padat)
- { switch (padat->animCallType)
- { case AnimationInitialize:
- GpiRotate(padat->hps, (MATRIXLF *)padat->achBuffer, TRANSFORM_REPLACE,
- 72 * Fixed1, &padat->ptCenter);
- break;
- case AnimationDraw:
- case AnimationErase:
- { POINTL ptBoxRel;
- ptBoxRel.x = padat->ptRelRightTop.x * padat->lStep / padat->cTotalSteps;
- ptBoxRel.y = padat->ptRelRightTop.y * padat->lStep / padat->cTotalSteps;
-
- MATRIXLF matrix;
- FIXED afxScale[2];
- afxScale[0] = afxScale[1] = fixedDiv((padat->cTotalSteps - padat->lStep) * 4,
- padat->cTotalSteps * 3);
- GpiTranslate(padat->hps, &matrix, TRANSFORM_REPLACE, &padat->ptRelRightTop);
- GpiScale(padat->hps, &matrix, TRANSFORM_ADD, afxScale, &padat->ptCenter);
- GpiRotate(padat->hps, &matrix, TRANSFORM_ADD,
- fixedDiv(padat->lParameter * padat->lStep, padat->cTotalSteps),
- &padat->ptCenter);
-
- POINTL ptBoxCenter = padat->ptCenter * matrix;
-
- for (int iLoop = 0; iLoop < 5; iLoop++)
- { drawBox(padat->hps, ptBoxCenter, ptBoxRel);
- ptBoxCenter = ptBoxCenter * *(MATRIXLF *)padat->achBuffer;
- }
-
- break;
- }
- }
-
- return TRUE;
- }
-
- BOOL EXPENTRY ScatterGatherFrames(AnimationData *padat)
- { if (padat->animCallType == AnimationDraw
- || padat->animCallType == AnimationErase)
- { LONG lDivisor = padat->lParameter;
- POINTL ptBoxRel;
-
- ptBoxRel.x = padat->ptRelRightTop.x * padat->lStep / (padat->cTotalSteps * lDivisor);
- ptBoxRel.y = padat->ptRelRightTop.y * padat->lStep / (padat->cTotalSteps * lDivisor);
-
- MATRIXLF matrix;
- FIXED afxScale[2];
- afxScale[0] = afxScale[1] = fixedDiv(padat->cTotalSteps * 3 - padat->lStep * 2,
- padat->cTotalSteps);
- GpiScale(padat->hps, &matrix, TRANSFORM_REPLACE, afxScale, &PointZero);
- GpiTranslate(padat->hps, &matrix, TRANSFORM_ADD, &padat->ptCenter);
-
- for (int iRow = 0; iRow < lDivisor; iRow++)
- { for (int iColumn = 0; iColumn < padat->lParameter; iColumn++)
- { POINTL ptTileCenter;
- ptTileCenter.x = (iRow * 2 - lDivisor + 1) * padat->ptRelRightTop.x / lDivisor;
- ptTileCenter.y = (iColumn * 2 - lDivisor + 1) * padat->ptRelRightTop.y / lDivisor;
- ptTileCenter = ptTileCenter * matrix;
-
- drawBox(padat->hps, ptTileCenter, ptBoxRel);
- }
- }
- }
-
- return TRUE;
- }
-
- BOOL EXPENTRY SpikeFrames(AnimationData *padat)
- { struct SpikeData
- { POINTL aPtTriangleEnd[16][3], aPtEndCenter[16], aPtTriangleCenter[16];
- MATRIXLF aMatrixCircle[16];
- };
-
- switch (padat->animCallType)
- { case AnimationInitialize:
- { LONG xLeft = padat->rectWindow.xLeft,
- xRight = padat->rectWindow.xRight,
- yBottom = padat->rectWindow.yBottom,
- yTop = padat->rectWindow.yTop;
-
- POINTL *paPtTriangle = ((SpikeData *)padat->achBuffer)->aPtTriangleEnd[0],
- *paPtCenter = ((SpikeData *)padat->achBuffer)->aPtEndCenter;
- for (int iIndex = 0; iIndex < 16; iIndex++, paPtTriangle += 3, paPtCenter++)
- { paPtTriangle[0] = padat->ptCenter;
-
- if (iIndex < 4)
- { paPtTriangle[1].y = paPtTriangle[2].y = yTop;
- paPtTriangle[1].x = (xLeft * (4 - iIndex) + xRight * iIndex) / 4;
- paPtTriangle[2].x = (xLeft * (3 - iIndex) + xRight * (iIndex + 1)) / 4;
- }
- else if (iIndex < 8)
- { paPtTriangle[1].x = paPtTriangle[2].x = xRight;
- paPtTriangle[1].y = (yTop * (8 - iIndex) + yBottom * (iIndex - 4)) / 4;
- paPtTriangle[2].y = (yTop * (7 - iIndex) + yBottom * (iIndex - 3)) / 4;
- }
- else if (iIndex < 12)
- { paPtTriangle[1].y = paPtTriangle[2].y = yBottom;
- paPtTriangle[1].x = (xRight * (12 - iIndex) + xLeft * (iIndex - 8)) / 4;
- paPtTriangle[2].x = (xRight * (11 - iIndex) + xLeft * (iIndex - 7)) / 4;
- }
- else
- { paPtTriangle[1].x = paPtTriangle[2].x = xLeft;
- paPtTriangle[1].y = (yBottom * (16 - iIndex) + yTop * (iIndex - 12)) / 4;
- paPtTriangle[2].y = (yBottom * (15 - iIndex) + yTop * (iIndex - 11)) / 4;
- }
-
- paPtCenter->x = (paPtTriangle[0].x + paPtTriangle[1].x + paPtTriangle[2].x) / 3;
- paPtCenter->y = (paPtTriangle[0].y + paPtTriangle[1].y + paPtTriangle[2].y) / 3;
- }
-
- paPtCenter = ((SpikeData *)padat->achBuffer)->aPtTriangleCenter;
- POINTL ptTriangleCenter;
- ptTriangleCenter.x = padat->ptCenter.x;
- ptTriangleCenter.y =
- padat->ptCenter.y + (padat->ptRelRightTop.x + padat->ptRelRightTop.y) * 4 / 5;
-
- for (iIndex = 0; iIndex < 16; iIndex++)
- { MATRIXLF matrix;
- GpiRotate(padat->hps, &matrix, TRANSFORM_REPLACE,
- (33 * Fixed1) + (-22 * Fixed1) * iIndex, &padat->ptCenter);
- paPtCenter[iIndex] = ptTriangleCenter * matrix;
-
- POINTL ptTemp =
- paPtCenter[iIndex] - ((SpikeData *)padat->achBuffer)->aPtEndCenter[iIndex];
- GpiTranslate(padat->hps, &((SpikeData *)padat->achBuffer)->aMatrixCircle[iIndex],
- TRANSFORM_REPLACE, &ptTemp);
- }
-
- break;
- }
- case AnimationDraw:
- case AnimationErase:
- { POINTL aPtTriangle[3];
- FIXED fixedFactor;
-
- MATRIXLF matrix;
- FIXED afxScale[2];
- afxScale[0] = afxScale[1] = fixedDiv(padat->lStep, padat->cTotalSteps);
-
- if (padat->lStep < padat->cTotalSteps / 2)
- { fixedFactor = (Fixed1 - fixedDiv(padat->lStep * 2, padat->cTotalSteps))
- * padat->lParameter;
-
- for (int iIndex = 0; iIndex < 16; iIndex++)
- { GpiScale(padat->hps, &matrix, TRANSFORM_REPLACE, afxScale,
- &((SpikeData *)padat->achBuffer)->aPtEndCenter[iIndex]);
- GpiRotate(padat->hps, &matrix, TRANSFORM_ADD, fixedFactor,
- &((SpikeData *)padat->achBuffer)->aPtEndCenter[iIndex]);
- matrix = matrix * ((SpikeData *)padat->achBuffer)->aMatrixCircle[iIndex];
-
- for (int iAngle = 0; iAngle < 3; iAngle++)
- { aPtTriangle[iAngle] =
- ((SpikeData *)padat->achBuffer)->aPtTriangleEnd[iIndex][iAngle] * matrix;
- }
-
- drawPolygon(padat->hps, aPtTriangle, 3);
- }
- }
- else
- { fixedFactor = fixedDiv(padat->lStep * 2 - padat->cTotalSteps, padat->cTotalSteps);
-
- for (int iIndex = 0; iIndex < 16; iIndex++)
- { GpiScale(padat->hps, &matrix, TRANSFORM_REPLACE, afxScale,
- &((SpikeData *)padat->achBuffer)->aPtEndCenter[iIndex]);
- matrix *= mix(Matrix1, ((SpikeData *)padat->achBuffer)->aMatrixCircle[iIndex],
- fixedFactor);
-
- for (int iAngle = 0; iAngle < 3; iAngle++)
- { aPtTriangle[iAngle] =
- ((SpikeData *)padat->achBuffer)->aPtTriangleEnd[iIndex][iAngle] * matrix;
- }
-
- drawPolygon(padat->hps, aPtTriangle, 3);
- }
- }
-
- break;
- }
- }
-
- return TRUE;
- }
-
- BOOL EXPENTRY FireworksFrames(AnimationData *padat)
- { const int NUMBER_OF_RECTS = 10;
-
- struct FireworksData
- { POINTL aPtCenter[NUMBER_OF_RECTS];
- };
-
- switch (padat->animCallType)
- { case AnimationInitialize:
- { POINTL *paPtCenter = ((FireworksData *)padat->achBuffer)->aPtCenter;
- POINTL ptRectCenter;
- ptRectCenter.x = padat->ptCenter.x;
- ptRectCenter.y =
- padat->ptCenter.y + (padat->ptRelRightTop.x + padat->ptRelRightTop.y) * 5 / 3;
-
- for (int iIndex = 0; iIndex < NUMBER_OF_RECTS; iIndex++)
- { MATRIXLF matrix;
- GpiRotate(padat->hps, &matrix, TRANSFORM_REPLACE,
- iIndex * (360 * Fixed1 / NUMBER_OF_RECTS), &padat->ptCenter);
- paPtCenter[iIndex] = ptRectCenter * matrix;
- }
-
- break;
- }
- case AnimationDraw:
- case AnimationErase:
- { POINTL ptTemp;
- FIXED fixedFactor = fixedDiv(padat->lStep, padat->cTotalSteps);
-
- MATRIXLF matrix;
- FIXED afxScale[2];
- afxScale[0] = afxScale[1] = fixedFactor;
-
- POINTL aPtRect[4], aPtTemp[4];
- aPtRect[0].x = aPtRect[3].x = -padat->ptRelRightTop.x;
- aPtRect[1].x = aPtRect[2].x = padat->ptRelRightTop.x;
- aPtRect[0].y = aPtRect[1].y = padat->ptRelRightTop.y;
- aPtRect[2].y = aPtRect[3].y = -padat->ptRelRightTop.y;
-
- for (int iIndex = 0; iIndex < NUMBER_OF_RECTS; iIndex++)
- { GpiScale(padat->hps, &matrix, TRANSFORM_REPLACE, afxScale, &PointZero);
- GpiRotate(padat->hps, &matrix, TRANSFORM_ADD,
- (Fixed1 - fixedFactor) * padat->lParameter, &PointZero);
- POINTL ptTemp;
- ptTemp = mix(padat->ptCenter, ((FireworksData *)padat->achBuffer)->aPtCenter[iIndex],
- fixedFactor);
- GpiTranslate(padat->hps, &matrix, TRANSFORM_ADD, &ptTemp);
-
- for (int iAngle = 0; iAngle < 4; iAngle++)
- { aPtTemp[iAngle] = aPtRect[iAngle] * matrix;
- }
-
- drawPolygon(padat->hps, aPtTemp, 4);
- }
-
- break;
- }
- }
-
- return TRUE;
- }
-
- // drawing functions
-
- void drawBox(HPS hps, POINTL &ptCenter, POINTL &ptRelRightTop)
- { if (ptRelRightTop.x == 0 && ptRelRightTop.y == 0) return;
-
- POINTL ptTemp = ptCenter - ptRelRightTop;
- GpiMove(hps, &ptTemp);
- ptTemp = ptCenter + ptRelRightTop;
- GpiBox(hps, DRO_OUTLINE, &ptTemp, 0, 0);
- }
-
- void drawPolygon(HPS hps, POINTL *paPoints, LONG cPoints)
- { if (cPoints == 0) return;
-
- if (paPoints[cPoints - 1].x == paPoints[0].x
- && paPoints[cPoints - 1].y == paPoints[0].y)
- { return;
- }
-
- for (int iIndex = 1; iIndex < cPoints; iIndex++)
- { if (paPoints[iIndex].x == paPoints[iIndex - 1].x
- && paPoints[iIndex].y == paPoints[iIndex - 1].y)
- { return;
- }
- }
-
- GpiMove(hps, &paPoints[cPoints - 1]);
- GpiPolyLine(hps, cPoints, paPoints);
- }
-
- // helper functions
-
- LONG fixedMul(LONG lMultiplicand, FIXED fxMultiplier)
- { // returns lMultiplicand * fxMultiplier as a LONG
- // also returns a FIXED if lMultiplicand is a FIXED
-
- return lMultiplicand * (fxMultiplier >> 16)
- + (lMultiplicand >> 16) * (fxMultiplier & 0xffff)
- + ((ULONG)((lMultiplicand & 0xffff) * (fxMultiplier & 0xffff)) >> 16);
- }
-
- FIXED fixedDiv(LONG lNumerator, LONG lDenominator)
- { // returns lNumerator / lDenominator as a FIXED
- // also works well for 2 FIXED's
-
- if (lNumerator == 0 || lDenominator == 0) return 0;
-
- LONG lSignBit = (lNumerator ^ lDenominator) >> 31;
- lNumerator = abs(lNumerator);
- lDenominator = abs(lDenominator);
-
- ULONG ulQuotient = (ULONG)lNumerator / (ULONG)lDenominator;
- lNumerator -= ulQuotient * lDenominator;
-
- if (lNumerator == 0) ulQuotient <<= 16;
- else
- { int cShiftRemain = 16;
-
- do
- { ulQuotient <<= 1;
- lNumerator <<= 1;
- cShiftRemain--;
-
- if (lNumerator >= lDenominator)
- { ulQuotient++;
- lNumerator -= lDenominator;
- if (lNumerator == 0)
- { ulQuotient <<= cShiftRemain;
- break;
- }
- }
- } while (cShiftRemain > 0);
- }
-
- return (ulQuotient ^ lSignBit) - lSignBit; /* reverse sign if lSignBit = -1 */
- }
-
- POINTL operator*(const POINTL &point, const MATRIXLF &matrix)
- { // returns POINTL transformed by MATRIXLF
-
- POINTL pointResult;
- pointResult.x = fixedMul(point.x, matrix.fxM11) + fixedMul(point.y, matrix.fxM21) + matrix.lM31;
- pointResult.y = fixedMul(point.x, matrix.fxM12) + fixedMul(point.y, matrix.fxM22) + matrix.lM32;
- return pointResult;
- }
-
- POINTL mix(const POINTL &pointSource1, const POINTL &pointSource2, FIXED fMix)
- { // mix 2 POINTL's according to FIXED
-
- POINTL pointResult;
- pointResult.x = fixedMul(pointSource1.x, fMix) + fixedMul(pointSource2.x, Fixed1 - fMix);
- pointResult.y = fixedMul(pointSource1.y, fMix) + fixedMul(pointSource2.y, Fixed1 - fMix);
- return pointResult;
- }
-
- MATRIXLF operator*(const MATRIXLF &mtx1, const MATRIXLF &mtx2)
- { // returns product of 2 MATRIXLF's
-
- MATRIXLF mtxProduct;
- mtxProduct.fxM11 = fixedMul(mtx1.fxM11, mtx2.fxM11) + fixedMul(mtx1.fxM12, mtx2.fxM21);
- mtxProduct.fxM12 = fixedMul(mtx1.fxM11, mtx2.fxM12) + fixedMul(mtx1.fxM12, mtx2.fxM22);
- mtxProduct.lM13 = 0;
- mtxProduct.fxM21 = fixedMul(mtx1.fxM21, mtx2.fxM11) + fixedMul(mtx1.fxM22, mtx2.fxM21);
- mtxProduct.fxM22 = fixedMul(mtx1.fxM21, mtx2.fxM12) + fixedMul(mtx1.fxM22, mtx2.fxM22);
- mtxProduct.lM23 = 0;
- mtxProduct.lM31 = fixedMul(mtx1.lM31, mtx2.fxM11) + fixedMul(mtx1.lM32, mtx2.fxM21) + mtx2.lM31;
- mtxProduct.lM32 = fixedMul(mtx1.lM31, mtx2.fxM12) + fixedMul(mtx1.lM32, mtx2.fxM22) + mtx2.lM32;
- mtxProduct.lM33 = 1;
- return mtxProduct;
- }
-
- MATRIXLF mix(const MATRIXLF &matrix1, const MATRIXLF &matrix2, FIXED fMix)
- { // mix 2 MATRIXLF's according to FIXED
-
- MATRIXLF matrixResult;
- for (int iIndex = 0; iIndex < 9; iIndex++)
- { ((PLONG)&matrixResult)[iIndex] =
- fixedMul(((PLONG)&matrix1)[iIndex], fMix)
- + fixedMul(((PLONG)&matrix2)[iIndex], Fixed1 - fMix);
- }
-
- return matrixResult;
- }
-