summaryrefslogtreecommitdiff
path: root/win32/plugins/dfxvideo/winsrc/draw.c
diff options
context:
space:
mode:
Diffstat (limited to 'win32/plugins/dfxvideo/winsrc/draw.c')
-rw-r--r--win32/plugins/dfxvideo/winsrc/draw.c4762
1 files changed, 4762 insertions, 0 deletions
diff --git a/win32/plugins/dfxvideo/winsrc/draw.c b/win32/plugins/dfxvideo/winsrc/draw.c
new file mode 100644
index 00000000..d25104d6
--- /dev/null
+++ b/win32/plugins/dfxvideo/winsrc/draw.c
@@ -0,0 +1,4762 @@
+/***************************************************************************
+ draw.c - description
+ -------------------
+ begin : Sun Oct 28 2001
+ copyright : (C) 2001 by Pete Bernert
+ email : BlackDove@addcom.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. See also the license.txt file for *
+ * additional informations. *
+ * *
+ ***************************************************************************/
+
+#define _IN_DRAW
+
+#include "externals.h"
+#include "gpu.h"
+#include "draw.h"
+#include "prim.h"
+#include "menu.h"
+#include "interp.h"
+
+////////////////////////////////////////////////////////////////////////////////////
+// misc globals
+////////////////////////////////////////////////////////////////////////////////////
+
+int iResX;
+int iResY;
+long lLowerpart;
+BOOL bIsFirstFrame = TRUE;
+BOOL bCheckMask=FALSE;
+unsigned short sSetMask=0;
+unsigned long lSetMask=0;
+int iDesktopCol=16;
+int iShowFPS=0;
+int iWinSize;
+int iUseScanLines=0;
+int iUseNoStretchBlt=0;
+int iFastFwd=0;
+int iDebugMode=0;
+int iFVDisplay=0;
+PSXPoint_t ptCursorPoint[8];
+unsigned short usCursorActive=0;
+
+unsigned int LUT16to32[65536];
+unsigned int RGBtoYUV[65536];
+
+// prototypes
+void hq2x_32( unsigned char * srcPtr, DWORD srcPitch, unsigned char * dstPtr, int width, int height);
+void hq2x( unsigned char * srcPtr, DWORD srcPitch, unsigned char * dstPtr, int width, int height);
+void hq3x_16( unsigned char * srcPtr, DWORD srcPitch, unsigned char * dstPtr, int width, int height);
+void hq3x_32( unsigned char * srcPtr, DWORD srcPitch, unsigned char * dstPtr, int width, int height);
+
+////////////////////////////////////////////////////////////////////////
+// generic 2xSaI helpers
+////////////////////////////////////////////////////////////////////////
+
+void * pSaISmallBuff=NULL;
+void * pSaIBigBuff=NULL;
+
+#define GET_RESULT(A, B, C, D) ((A != C || A != D) - (B != C || B != D))
+
+static __inline int GetResult1(DWORD A, DWORD B, DWORD C, DWORD D, DWORD E)
+{
+ int x = 0;
+ int y = 0;
+ int r = 0;
+ if (A == C) x+=1; else if (B == C) y+=1;
+ if (A == D) x+=1; else if (B == D) y+=1;
+ if (x <= 1) r+=1;
+ if (y <= 1) r-=1;
+ return r;
+}
+
+static __inline int GetResult2(DWORD A, DWORD B, DWORD C, DWORD D, DWORD E)
+{
+ int x = 0;
+ int y = 0;
+ int r = 0;
+ if (A == C) x+=1; else if (B == C) y+=1;
+ if (A == D) x+=1; else if (B == D) y+=1;
+ if (x <= 1) r-=1;
+ if (y <= 1) r+=1;
+ return r;
+}
+
+#define colorMask8 0x00FEFEFE
+#define lowPixelMask8 0x00010101
+#define qcolorMask8 0x00FCFCFC
+#define qlowpixelMask8 0x00030303
+
+#define INTERPOLATE8(A, B) ((((A & colorMask8) >> 1) + ((B & colorMask8) >> 1) + (A & B & lowPixelMask8)))
+#define Q_INTERPOLATE8(A, B, C, D) (((((A & qcolorMask8) >> 2) + ((B & qcolorMask8) >> 2) + ((C & qcolorMask8) >> 2) + ((D & qcolorMask8) >> 2) \
+ + ((((A & qlowpixelMask8) + (B & qlowpixelMask8) + (C & qlowpixelMask8) + (D & qlowpixelMask8)) >> 2) & qlowpixelMask8))))
+
+
+void Super2xSaI_ex8(unsigned char *srcPtr, DWORD srcPitch,
+ unsigned char *dstBitmap, int width, int height)
+{
+ DWORD dstPitch = srcPitch<<1;
+ DWORD srcPitchHalf = srcPitch>>1;
+ int finWidth = srcPitch>>2;
+ DWORD line;
+ DWORD *dP;
+ DWORD *bP;
+ int iXA,iXB,iXC,iYA,iYB,iYC,finish;
+ DWORD color4, color5, color6;
+ DWORD color1, color2, color3;
+ DWORD colorA0, colorA1, colorA2, colorA3,
+ colorB0, colorB1, colorB2, colorB3,
+ colorS1, colorS2;
+ DWORD product1a, product1b,
+ product2a, product2b;
+
+ line = 0;
+
+ {
+ for (; height; height-=1)
+ {
+ bP = (DWORD *)srcPtr;
+ dP = (DWORD *)(dstBitmap + line*dstPitch);
+ for (finish = width; finish; finish -= 1 )
+ {
+//--------------------------------------- B1 B2
+// 4 5 6 S2
+// 1 2 3 S1
+// A1 A2
+ if(finish==finWidth) iXA=0;
+ else iXA=1;
+ if(finish>4) {iXB=1;iXC=2;}
+ else
+ if(finish>3) {iXB=1;iXC=1;}
+ else {iXB=0;iXC=0;}
+ if(line==0) {iYA=0;}
+ else {iYA=finWidth;}
+ if(height>4) {iYB=finWidth;iYC=srcPitchHalf;}
+ else
+ if(height>3) {iYB=finWidth;iYC=finWidth;}
+ else {iYB=0;iYC=0;}
+
+ colorB0 = *(bP- iYA - iXA);
+ colorB1 = *(bP- iYA);
+ colorB2 = *(bP- iYA + iXB);
+ colorB3 = *(bP- iYA + iXC);
+
+ color4 = *(bP - iXA);
+ color5 = *(bP);
+ color6 = *(bP + iXB);
+ colorS2 = *(bP + iXC);
+
+ color1 = *(bP + iYB - iXA);
+ color2 = *(bP + iYB);
+ color3 = *(bP + iYB + iXB);
+ colorS1= *(bP + iYB + iXC);
+
+ colorA0 = *(bP + iYC - iXA);
+ colorA1 = *(bP + iYC);
+ colorA2 = *(bP + iYC + iXB);
+ colorA3 = *(bP + iYC + iXC);
+
+ if (color2 == color6 && color5 != color3)
+ {
+ product2b = product1b = color2;
+ }
+ else
+ if (color5 == color3 && color2 != color6)
+ {
+ product2b = product1b = color5;
+ }
+ else
+ if (color5 == color3 && color2 == color6)
+ {
+ register int r = 0;
+
+ r += GET_RESULT ((color6&0x00ffffff), (color5&0x00ffffff), (color1&0x00ffffff), (colorA1&0x00ffffff));
+ r += GET_RESULT ((color6&0x00ffffff), (color5&0x00ffffff), (color4&0x00ffffff), (colorB1&0x00ffffff));
+ r += GET_RESULT ((color6&0x00ffffff), (color5&0x00ffffff), (colorA2&0x00ffffff), (colorS1&0x00ffffff));
+ r += GET_RESULT ((color6&0x00ffffff), (color5&0x00ffffff), (colorB2&0x00ffffff), (colorS2&0x00ffffff));
+
+ if (r > 0)
+ product2b = product1b = color6;
+ else
+ if (r < 0)
+ product2b = product1b = color5;
+ else
+ {
+ product2b = product1b = INTERPOLATE8(color5, color6);
+ }
+ }
+ else
+ {
+ if (color6 == color3 && color3 == colorA1 && color2 != colorA2 && color3 != colorA0)
+ product2b = Q_INTERPOLATE8 (color3, color3, color3, color2);
+ else
+ if (color5 == color2 && color2 == colorA2 && colorA1 != color3 && color2 != colorA3)
+ product2b = Q_INTERPOLATE8 (color2, color2, color2, color3);
+ else
+ product2b = INTERPOLATE8 (color2, color3);
+
+ if (color6 == color3 && color6 == colorB1 && color5 != colorB2 && color6 != colorB0)
+ product1b = Q_INTERPOLATE8 (color6, color6, color6, color5);
+ else
+ if (color5 == color2 && color5 == colorB2 && colorB1 != color6 && color5 != colorB3)
+ product1b = Q_INTERPOLATE8 (color6, color5, color5, color5);
+ else
+ product1b = INTERPOLATE8 (color5, color6);
+ }
+
+ if (color5 == color3 && color2 != color6 && color4 == color5 && color5 != colorA2)
+ product2a = INTERPOLATE8(color2, color5);
+ else
+ if (color5 == color1 && color6 == color5 && color4 != color2 && color5 != colorA0)
+ product2a = INTERPOLATE8(color2, color5);
+ else
+ product2a = color2;
+
+ if (color2 == color6 && color5 != color3 && color1 == color2 && color2 != colorB2)
+ product1a = INTERPOLATE8(color2, color5);
+ else
+ if (color4 == color2 && color3 == color2 && color1 != color5 && color2 != colorB0)
+ product1a = INTERPOLATE8(color2, color5);
+ else
+ product1a = color5;
+
+ *dP=product1a;
+ *(dP+1)=product1b;
+ *(dP+(srcPitchHalf))=product2a;
+ *(dP+1+(srcPitchHalf))=product2b;
+
+ bP += 1;
+ dP += 2;
+ }//end of for ( finish= width etc..)
+
+ line += 2;
+ srcPtr += srcPitch;
+ }; //endof: for (; height; height--)
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void Std2xSaI_ex8(unsigned char *srcPtr, DWORD srcPitch,
+ unsigned char *dstBitmap, int width, int height)
+{
+ DWORD dstPitch = srcPitch<<1;
+ DWORD srcPitchHalf = srcPitch>>1;
+ int finWidth = srcPitch>>2;
+ DWORD line;
+ DWORD *dP;
+ DWORD *bP;
+ int iXA,iXB,iXC,iYA,iYB,iYC,finish;
+
+ DWORD colorA, colorB;
+ DWORD colorC, colorD,
+ colorE, colorF, colorG, colorH,
+ colorI, colorJ, colorK, colorL,
+ colorM, colorN, colorO, colorP;
+ DWORD product, product1, product2;
+
+ line = 0;
+
+ {
+ for (; height; height-=1)
+ {
+ bP = (DWORD *)srcPtr;
+ dP = (DWORD *)(dstBitmap + line*dstPitch);
+ for (finish = width; finish; finish -= 1 )
+ {
+//---------------------------------------
+// Map of the pixels: I|E F|J
+// G|A B|K
+// H|C D|L
+// M|N O|P
+ if(finish==finWidth) iXA=0;
+ else iXA=1;
+ if(finish>4) {iXB=1;iXC=2;}
+ else
+ if(finish>3) {iXB=1;iXC=1;}
+ else {iXB=0;iXC=0;}
+ if(line==0) {iYA=0;}
+ else {iYA=finWidth;}
+ if(height>4) {iYB=finWidth;iYC=srcPitchHalf;}
+ else
+ if(height>3) {iYB=finWidth;iYC=finWidth;}
+ else {iYB=0;iYC=0;}
+
+ colorI = *(bP- iYA - iXA);
+ colorE = *(bP- iYA);
+ colorF = *(bP- iYA + iXB);
+ colorJ = *(bP- iYA + iXC);
+
+ colorG = *(bP - iXA);
+ colorA = *(bP);
+ colorB = *(bP + iXB);
+ colorK = *(bP + iXC);
+
+ colorH = *(bP + iYB - iXA);
+ colorC = *(bP + iYB);
+ colorD = *(bP + iYB + iXB);
+ colorL = *(bP + iYB + iXC);
+
+ colorM = *(bP + iYC - iXA);
+ colorN = *(bP + iYC);
+ colorO = *(bP + iYC + iXB);
+ colorP = *(bP + iYC + iXC);
+
+
+ if((colorA == colorD) && (colorB != colorC))
+ {
+ if(((colorA == colorE) && (colorB == colorL)) ||
+ ((colorA == colorC) && (colorA == colorF) &&
+ (colorB != colorE) && (colorB == colorJ)))
+ {
+ product = colorA;
+ }
+ else
+ {
+ product = INTERPOLATE8(colorA, colorB);
+ }
+
+ if(((colorA == colorG) && (colorC == colorO)) ||
+ ((colorA == colorB) && (colorA == colorH) &&
+ (colorG != colorC) && (colorC == colorM)))
+ {
+ product1 = colorA;
+ }
+ else
+ {
+ product1 = INTERPOLATE8(colorA, colorC);
+ }
+ product2 = colorA;
+ }
+ else
+ if((colorB == colorC) && (colorA != colorD))
+ {
+ if(((colorB == colorF) && (colorA == colorH)) ||
+ ((colorB == colorE) && (colorB == colorD) &&
+ (colorA != colorF) && (colorA == colorI)))
+ {
+ product = colorB;
+ }
+ else
+ {
+ product = INTERPOLATE8(colorA, colorB);
+ }
+
+ if(((colorC == colorH) && (colorA == colorF)) ||
+ ((colorC == colorG) && (colorC == colorD) &&
+ (colorA != colorH) && (colorA == colorI)))
+ {
+ product1 = colorC;
+ }
+ else
+ {
+ product1=INTERPOLATE8(colorA, colorC);
+ }
+ product2 = colorB;
+ }
+ else
+ if((colorA == colorD) && (colorB == colorC))
+ {
+ if (colorA == colorB)
+ {
+ product = colorA;
+ product1 = colorA;
+ product2 = colorA;
+ }
+ else
+ {
+ register int r = 0;
+ product1 = INTERPOLATE8(colorA, colorC);
+ product = INTERPOLATE8(colorA, colorB);
+
+ r += GetResult1 (colorA&0x00FFFFFF, colorB&0x00FFFFFF, colorG&0x00FFFFFF, colorE&0x00FFFFFF, colorI&0x00FFFFFF);
+ r += GetResult2 (colorB&0x00FFFFFF, colorA&0x00FFFFFF, colorK&0x00FFFFFF, colorF&0x00FFFFFF, colorJ&0x00FFFFFF);
+ r += GetResult2 (colorB&0x00FFFFFF, colorA&0x00FFFFFF, colorH&0x00FFFFFF, colorN&0x00FFFFFF, colorM&0x00FFFFFF);
+ r += GetResult1 (colorA&0x00FFFFFF, colorB&0x00FFFFFF, colorL&0x00FFFFFF, colorO&0x00FFFFFF, colorP&0x00FFFFFF);
+
+ if (r > 0)
+ product2 = colorA;
+ else
+ if (r < 0)
+ product2 = colorB;
+ else
+ {
+ product2 = Q_INTERPOLATE8(colorA, colorB, colorC, colorD);
+ }
+ }
+ }
+ else
+ {
+ product2 = Q_INTERPOLATE8(colorA, colorB, colorC, colorD);
+
+ if ((colorA == colorC) && (colorA == colorF) &&
+ (colorB != colorE) && (colorB == colorJ))
+ {
+ product = colorA;
+ }
+ else
+ if ((colorB == colorE) && (colorB == colorD) && (colorA != colorF) && (colorA == colorI))
+ {
+ product = colorB;
+ }
+ else
+ {
+ product = INTERPOLATE8(colorA, colorB);
+ }
+
+ if ((colorA == colorB) && (colorA == colorH) &&
+ (colorG != colorC) && (colorC == colorM))
+ {
+ product1 = colorA;
+ }
+ else
+ if ((colorC == colorG) && (colorC == colorD) &&
+ (colorA != colorH) && (colorA == colorI))
+ {
+ product1 = colorC;
+ }
+ else
+ {
+ product1 = INTERPOLATE8(colorA, colorC);
+ }
+ }
+
+//////////////////////////
+
+ *dP=colorA;
+ *(dP+1)=product;
+ *(dP+(srcPitchHalf))=product1;
+ *(dP+1+(srcPitchHalf))=product2;
+
+ bP += 1;
+ dP += 2;
+ }//end of for ( finish= width etc..)
+
+ line += 2;
+ srcPtr += srcPitch;
+ }; //endof: for (; height; height--)
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void SuperEagle_ex8(unsigned char *srcPtr, DWORD srcPitch,
+ unsigned char *dstBitmap, int width, int height)
+{
+ DWORD dstPitch = srcPitch<<1;
+ DWORD srcPitchHalf = srcPitch>>1;
+ int finWidth = srcPitch>>2;
+ DWORD line;
+ DWORD *dP;
+ DWORD *bP;
+ int iXA,iXB,iXC,iYA,iYB,iYC,finish;
+ DWORD color4, color5, color6;
+ DWORD color1, color2, color3;
+ DWORD colorA1, colorA2,
+ colorB1, colorB2,
+ colorS1, colorS2;
+ DWORD product1a, product1b,
+ product2a, product2b;
+
+ line = 0;
+
+ {
+ for (; height; height-=1)
+ {
+ bP = (DWORD *)srcPtr;
+ dP = (DWORD *)(dstBitmap + line*dstPitch);
+ for (finish = width; finish; finish -= 1 )
+ {
+ if(finish==finWidth) iXA=0;
+ else iXA=1;
+ if(finish>4) {iXB=1;iXC=2;}
+ else
+ if(finish>3) {iXB=1;iXC=1;}
+ else {iXB=0;iXC=0;}
+ if(line==0) {iYA=0;}
+ else {iYA=finWidth;}
+ if(height>4) {iYB=finWidth;iYC=srcPitchHalf;}
+ else
+ if(height>3) {iYB=finWidth;iYC=finWidth;}
+ else {iYB=0;iYC=0;}
+
+ colorB1 = *(bP- iYA);
+ colorB2 = *(bP- iYA + iXB);
+
+ color4 = *(bP - iXA);
+ color5 = *(bP);
+ color6 = *(bP + iXB);
+ colorS2 = *(bP + iXC);
+
+ color1 = *(bP + iYB - iXA);
+ color2 = *(bP + iYB);
+ color3 = *(bP + iYB + iXB);
+ colorS1= *(bP + iYB + iXC);
+
+ colorA1 = *(bP + iYC);
+ colorA2 = *(bP + iYC + iXB);
+
+ if(color2 == color6 && color5 != color3)
+ {
+ product1b = product2a = color2;
+ if((color1 == color2) ||
+ (color6 == colorB2))
+ {
+ product1a = INTERPOLATE8(color2, color5);
+ product1a = INTERPOLATE8(color2, product1a);
+ }
+ else
+ {
+ product1a = INTERPOLATE8(color5, color6);
+ }
+
+ if((color6 == colorS2) ||
+ (color2 == colorA1))
+ {
+ product2b = INTERPOLATE8(color2, color3);
+ product2b = INTERPOLATE8(color2, product2b);
+ }
+ else
+ {
+ product2b = INTERPOLATE8(color2, color3);
+ }
+ }
+ else
+ if (color5 == color3 && color2 != color6)
+ {
+ product2b = product1a = color5;
+
+ if ((colorB1 == color5) ||
+ (color3 == colorS1))
+ {
+ product1b = INTERPOLATE8(color5, color6);
+ product1b = INTERPOLATE8(color5, product1b);
+ }
+ else
+ {
+ product1b = INTERPOLATE8(color5, color6);
+ }
+
+ if ((color3 == colorA2) ||
+ (color4 == color5))
+ {
+ product2a = INTERPOLATE8(color5, color2);
+ product2a = INTERPOLATE8(color5, product2a);
+ }
+ else
+ {
+ product2a = INTERPOLATE8(color2, color3);
+ }
+ }
+ else
+ if (color5 == color3 && color2 == color6)
+ {
+ register int r = 0;
+
+ r += GET_RESULT ((color6&0x00ffffff), (color5&0x00ffffff), (color1&0x00ffffff), (colorA1&0x00ffffff));
+ r += GET_RESULT ((color6&0x00ffffff), (color5&0x00ffffff), (color4&0x00ffffff), (colorB1&0x00ffffff));
+ r += GET_RESULT ((color6&0x00ffffff), (color5&0x00ffffff), (colorA2&0x00ffffff), (colorS1&0x00ffffff));
+ r += GET_RESULT ((color6&0x00ffffff), (color5&0x00ffffff), (colorB2&0x00ffffff), (colorS2&0x00ffffff));
+
+ if (r > 0)
+ {
+ product1b = product2a = color2;
+ product1a = product2b = INTERPOLATE8(color5, color6);
+ }
+ else
+ if (r < 0)
+ {
+ product2b = product1a = color5;
+ product1b = product2a = INTERPOLATE8(color5, color6);
+ }
+ else
+ {
+ product2b = product1a = color5;
+ product1b = product2a = color2;
+ }
+ }
+ else
+ {
+ product2b = product1a = INTERPOLATE8(color2, color6);
+ product2b = Q_INTERPOLATE8(color3, color3, color3, product2b);
+ product1a = Q_INTERPOLATE8(color5, color5, color5, product1a);
+
+ product2a = product1b = INTERPOLATE8(color5, color3);
+ product2a = Q_INTERPOLATE8(color2, color2, color2, product2a);
+ product1b = Q_INTERPOLATE8(color6, color6, color6, product1b);
+ }
+
+////////////////////////////////
+
+ *dP=product1a;
+ *(dP+1)=product1b;
+ *(dP+(srcPitchHalf))=product2a;
+ *(dP+1+(srcPitchHalf))=product2b;
+
+ bP += 1;
+ dP += 2;
+ }//end of for ( finish= width etc..)
+
+ line += 2;
+ srcPtr += srcPitch;
+ }; //endof: for (; height; height--)
+ }
+}
+
+/////////////////////////
+
+static __inline void scale2x_32_def_whole(unsigned long* dst0, unsigned long* dst1, const unsigned long* src0, const unsigned long* src1, const unsigned long* src2, unsigned count)
+{
+ // first pixel
+ if (src0[0] != src2[0] && src1[0] != src1[1]) {
+ dst0[0] = src1[0] == src0[0] ? src0[0] : src1[0];
+ dst0[1] = src1[1] == src0[0] ? src0[0] : src1[0];
+ dst1[0] = src1[0] == src2[0] ? src2[0] : src1[0];
+ dst1[1] = src1[1] == src2[0] ? src2[0] : src1[0];
+ } else {
+ dst0[0] = src1[0];
+ dst0[1] = src1[0];
+ dst1[0] = src1[0];
+ dst1[1] = src1[0];
+ }
+ ++src0;
+ ++src1;
+ ++src2;
+ dst0 += 2;
+ dst1 += 2;
+
+ // central pixels
+ count -= 2;
+ while (count) {
+ if (src0[0] != src2[0] && src1[-1] != src1[1]) {
+ dst0[0] = src1[-1] == src0[0] ? src0[0] : src1[0];
+ dst0[1] = src1[1] == src0[0] ? src0[0] : src1[0];
+ dst1[0] = src1[-1] == src2[0] ? src2[0] : src1[0];
+ dst1[1] = src1[1] == src2[0] ? src2[0] : src1[0];
+ } else {
+ dst0[0] = src1[0];
+ dst0[1] = src1[0];
+ dst1[0] = src1[0];
+ dst1[1] = src1[0];
+ }
+
+ ++src0;
+ ++src1;
+ ++src2;
+ dst0 += 2;
+ dst1 += 2;
+ --count;
+ }
+
+ // last pixel
+ if (src0[0] != src2[0] && src1[-1] != src1[0]) {
+ dst0[0] = src1[-1] == src0[0] ? src0[0] : src1[0];
+ dst0[1] = src1[0] == src0[0] ? src0[0] : src1[0];
+ dst1[0] = src1[-1] == src2[0] ? src2[0] : src1[0];
+ dst1[1] = src1[0] == src2[0] ? src2[0] : src1[0];
+ } else {
+ dst0[0] = src1[0];
+ dst0[1] = src1[0];
+ dst1[0] = src1[0];
+ dst1[1] = src1[0];
+ }
+}
+
+void Scale2x_ex8(unsigned char *srcPtr, DWORD srcPitch,
+ unsigned char *dstPtr, int width, int height)
+{
+ const int dstPitch = srcPitch<<1;
+
+ int count = height;
+
+ unsigned long *dst0 = (unsigned long *)dstPtr;
+ unsigned long *dst1 = dst0 + (dstPitch >> 2);
+
+ unsigned long *src0 = (unsigned long *)srcPtr;
+ unsigned long *src1 = src0 + (srcPitch >> 2);
+ unsigned long *src2 = src1 + (srcPitch >> 2);
+ scale2x_32_def_whole(dst0, dst1, src0, src0, src1, width);
+
+ count -= 2;
+ while(count) {
+ dst0 += dstPitch >> 1;
+ dst1 += dstPitch >> 1;
+ scale2x_32_def_whole(dst0, dst1, src0, src0, src1, width);
+ src0 = src1;
+ src1 = src2;
+ src2 += srcPitch >> 2;
+ --count;
+ }
+ dst0 += dstPitch >> 1;
+ dst1 += dstPitch >> 1;
+ scale2x_32_def_whole(dst0, dst1, src0, src1, src1, width);
+
+}
+
+////////////////////////////////////////////////////////////////////////
+
+static __inline void scale3x_32_def_whole(unsigned long* dst0, unsigned long* dst1, unsigned long* dst2, const unsigned long* src0, const unsigned long* src1, const unsigned long* src2, unsigned count)
+{
+ //first pixel
+ if (src0[0] != src2[0] && src1[0] != src1[1]) {
+ dst0[0] = src1[0];
+ dst0[1] = (src1[0] == src0[0] && src1[0] != src0[1]) || (src1[1] == src0[0] && src1[0] != src0[0]) ? src0[0] : src1[0];
+ dst0[2] = src1[1] == src0[0] ? src1[1] : src1[0];
+ dst1[0] = (src1[0] == src0[0] && src1[0] != src2[0]) || (src1[0] == src2[0] && src1[0] != src0[0]) ? src1[0] : src1[0];
+ dst1[1] = src1[0];
+ dst1[2] = (src1[1] == src0[0] && src1[0] != src2[1]) || (src1[1] == src2[0] && src1[0] != src0[1]) ? src1[1] : src1[0];
+ dst2[0] = src1[0];
+ dst2[1] = (src1[0] == src2[0] && src1[0] != src2[1]) || (src1[1] == src2[0] && src1[0] != src2[0]) ? src2[0] : src1[0];
+ dst2[2] = src1[1] == src2[0] ? src1[1] : src1[0];
+ } else {
+ dst0[0] = src1[0];
+ dst0[1] = src1[0];
+ dst0[2] = src1[0];
+ dst1[0] = src1[0];
+ dst1[1] = src1[0];
+ dst1[2] = src1[0];
+ dst2[0] = src1[0];
+ dst2[1] = src1[0];
+ dst2[2] = src1[0];
+ }
+ ++src0;
+ ++src1;
+ ++src2;
+ dst0 += 3;
+ dst1 += 3;
+ dst2 += 3;
+
+ //central pixels
+ count -= 2;
+ while (count) {
+ if (src0[0] != src2[0] && src1[-1] != src1[1]) {
+ dst0[0] = src1[-1] == src0[0] ? src1[-1] : src1[0];
+ dst0[1] = (src1[-1] == src0[0] && src1[0] != src0[1]) || (src1[1] == src0[0] && src1[0] != src0[-1]) ? src0[0] : src1[0];
+ dst0[2] = src1[1] == src0[0] ? src1[1] : src1[0];
+ dst1[0] = (src1[-1] == src0[0] && src1[0] != src2[-1]) || (src1[-1] == src2[0] && src1[0] != src0[-1]) ? src1[-1] : src1[0];
+ dst1[1] = src1[0];
+ dst1[2] = (src1[1] == src0[0] && src1[0] != src2[1]) || (src1[1] == src2[0] && src1[0] != src0[1]) ? src1[1] : src1[0];
+ dst2[0] = src1[-1] == src2[0] ? src1[-1] : src1[0];
+ dst2[1] = (src1[-1] == src2[0] && src1[0] != src2[1]) || (src1[1] == src2[0] && src1[0] != src2[-1]) ? src2[0] : src1[0];
+ dst2[2] = src1[1] == src2[0] ? src1[1] : src1[0];
+ } else {
+ dst0[0] = src1[0];
+ dst0[1] = src1[0];
+ dst0[2] = src1[0];
+ dst1[0] = src1[0];
+ dst1[1] = src1[0];
+ dst1[2] = src1[0];
+ dst2[0] = src1[0];
+ dst2[1] = src1[0];
+ dst2[2] = src1[0];
+ }
+
+ ++src0;
+ ++src1;
+ ++src2;
+ dst0 += 3;
+ dst1 += 3;
+ dst2 += 3;
+ --count;
+ }
+
+ // last pixel
+ if (src0[0] != src2[0] && src1[-1] != src1[0]) {
+ dst0[0] = src1[-1] == src0[0] ? src1[-1] : src1[0];
+ dst0[1] = (src1[-1] == src0[0] && src1[0] != src0[0]) || (src1[0] == src0[0] && src1[0] != src0[-1]) ? src0[0] : src1[0];
+ dst0[2] = src1[0];
+ dst1[0] = (src1[-1] == src0[0] && src1[0] != src2[-1]) || (src1[-1] == src2[0] && src1[0] != src0[-1]) ? src1[-1] : src1[0];
+ dst1[1] = src1[0];
+ dst1[2] = (src1[0] == src0[0] && src1[0] != src2[0]) || (src1[0] == src2[0] && src1[0] != src0[0]) ? src1[0] : src1[0];
+ dst2[0] = src1[-1] == src2[0] ? src1[-1] : src1[0];
+ dst2[1] = (src1[-1] == src2[0] && src1[0] != src2[0]) || (src1[0] == src2[0] && src1[0] != src2[-1]) ? src2[0] : src1[0];
+ dst2[2] = src1[0];
+ } else {
+ dst0[0] = src1[0];
+ dst0[1] = src1[0];
+ dst0[2] = src1[0];
+ dst1[0] = src1[0];
+ dst1[1] = src1[0];
+ dst1[2] = src1[0];
+ dst2[0] = src1[0];
+ dst2[1] = src1[0];
+ dst2[2] = src1[0];
+ }
+}
+
+
+void Scale3x_ex8(unsigned char *srcPtr, DWORD srcPitch,
+ unsigned char *dstPtr, int width, int height)
+{
+ int count = height;
+
+ int dstPitch = srcPitch >> 1;
+
+
+ unsigned long *dst0 = (unsigned long *)dstPtr;
+ unsigned long *dst1 = dst0 + dstPitch;
+ unsigned long *dst2 = dst1 + dstPitch;
+
+ unsigned long *src0 = (unsigned long *)srcPtr;
+ unsigned long *src1 = src0 + (srcPitch >> 2);
+ unsigned long *src2 = src1 + (srcPitch >> 2);
+ scale3x_32_def_whole(dst0, dst1, dst2, src0, src0, src2, width);
+
+ count -= 2;
+ while(count) {
+ dst0 += dstPitch * 3;
+ dst1 += dstPitch * 3;
+ dst2 += dstPitch * 3;
+
+ scale3x_32_def_whole(dst0, dst1, dst2, src0, src1, src2, width);
+ src0 = src1;
+ src1 = src2;
+ src2 += srcPitch >> 2;
+ --count;
+ }
+ dst0 += dstPitch * 3;
+ dst1 += dstPitch * 3;
+ dst2 += dstPitch * 3;
+
+ scale3x_32_def_whole(dst0, dst1, dst2, src0, src1, src1, width);
+}
+
+
+////////////////////////////////////////////////////////////////////////
+
+#define colorMask6 0x0000F7DE
+#define lowPixelMask6 0x00000821
+#define qcolorMask6 0x0000E79c
+#define qlowpixelMask6 0x00001863
+
+#define INTERPOLATE6(A, B) ((((A & colorMask6) >> 1) + ((B & colorMask6) >> 1) + (A & B & lowPixelMask6)))
+#define Q_INTERPOLATE6(A, B, C, D) (((((A & qcolorMask6) >> 2) + ((B & qcolorMask6) >> 2) + ((C & qcolorMask6) >> 2) + ((D & qcolorMask6) >> 2) \
+ + ((((A & qlowpixelMask6) + (B & qlowpixelMask6) + (C & qlowpixelMask6) + (D & qlowpixelMask6)) >> 2) & qlowpixelMask6))))
+
+void Super2xSaI_ex6(unsigned char *srcPtr, DWORD srcPitch,
+ unsigned char *dstBitmap, int width, int height)
+{
+ DWORD dstPitch = srcPitch<<1;
+ int finWidth = srcPitch>>1;
+ DWORD line;
+ unsigned short *dP;
+ unsigned short *bP;
+ int iXA,iXB,iXC,iYA,iYB,iYC,finish;
+ DWORD color4, color5, color6;
+ DWORD color1, color2, color3;
+ DWORD colorA0, colorA1, colorA2, colorA3,
+ colorB0, colorB1, colorB2, colorB3,
+ colorS1, colorS2;
+ DWORD product1a, product1b,
+ product2a, product2b;
+
+ line = 0;
+
+ {
+ for (; height; height-=1)
+ {
+ bP = (unsigned short *)srcPtr;
+ dP = (unsigned short *)(dstBitmap + line*dstPitch);
+ for (finish = width; finish; finish -= 1 )
+ {
+//--------------------------------------- B1 B2
+// 4 5 6 S2
+// 1 2 3 S1
+// A1 A2
+ if(finish==finWidth) iXA=0;
+ else iXA=1;
+ if(finish>4) {iXB=1;iXC=2;}
+ else
+ if(finish>3) {iXB=1;iXC=1;}
+ else {iXB=0;iXC=0;}
+ if(line==0) iYA=0;
+ else iYA=finWidth;
+ if(height>4) {iYB=finWidth;iYC=srcPitch;}
+ else
+ if(height>3) {iYB=finWidth;iYC=finWidth;}
+ else {iYB=0;iYC=0;}
+
+
+ colorB0 = *(bP- iYA - iXA);
+ colorB1 = *(bP- iYA);
+ colorB2 = *(bP- iYA + iXB);
+ colorB3 = *(bP- iYA + iXC);
+
+ color4 = *(bP - iXA);
+ color5 = *(bP);
+ color6 = *(bP + iXB);
+ colorS2 = *(bP + iXC);
+
+ color1 = *(bP + iYB - iXA);
+ color2 = *(bP + iYB);
+ color3 = *(bP + iYB + iXB);
+ colorS1= *(bP + iYB + iXC);
+
+ colorA0 = *(bP + iYC - iXA);
+ colorA1 = *(bP + iYC);
+ colorA2 = *(bP + iYC + iXB);
+ colorA3 = *(bP + iYC + iXC);
+
+//--------------------------------------
+ if (color2 == color6 && color5 != color3)
+ {
+ product2b = product1b = color2;
+ }
+ else
+ if (color5 == color3 && color2 != color6)
+ {
+ product2b = product1b = color5;
+ }
+ else
+ if (color5 == color3 && color2 == color6)
+ {
+ register int r = 0;
+
+ r += GET_RESULT ((color6), (color5), (color1), (colorA1));
+ r += GET_RESULT ((color6), (color5), (color4), (colorB1));
+ r += GET_RESULT ((color6), (color5), (colorA2), (colorS1));
+ r += GET_RESULT ((color6), (color5), (colorB2), (colorS2));
+
+ if (r > 0)
+ product2b = product1b = color6;
+ else
+ if (r < 0)
+ product2b = product1b = color5;
+ else
+ {
+ product2b = product1b = INTERPOLATE6 (color5, color6);
+ }
+ }
+ else
+ {
+ if (color6 == color3 && color3 == colorA1 && color2 != colorA2 && color3 != colorA0)
+ product2b = Q_INTERPOLATE6 (color3, color3, color3, color2);
+ else
+ if (color5 == color2 && color2 == colorA2 && colorA1 != color3 && color2 != colorA3)
+ product2b = Q_INTERPOLATE6 (color2, color2, color2, color3);
+ else
+ product2b = INTERPOLATE6 (color2, color3);
+
+ if (color6 == color3 && color6 == colorB1 && color5 != colorB2 && color6 != colorB0)
+ product1b = Q_INTERPOLATE6 (color6, color6, color6, color5);
+ else
+ if (color5 == color2 && color5 == colorB2 && colorB1 != color6 && color5 != colorB3)
+ product1b = Q_INTERPOLATE6 (color6, color5, color5, color5);
+ else
+ product1b = INTERPOLATE6 (color5, color6);
+ }
+
+ if (color5 == color3 && color2 != color6 && color4 == color5 && color5 != colorA2)
+ product2a = INTERPOLATE6 (color2, color5);
+ else
+ if (color5 == color1 && color6 == color5 && color4 != color2 && color5 != colorA0)
+ product2a = INTERPOLATE6(color2, color5);
+ else
+ product2a = color2;
+
+ if (color2 == color6 && color5 != color3 && color1 == color2 && color2 != colorB2)
+ product1a = INTERPOLATE6(color2, color5);
+ else
+ if (color4 == color2 && color3 == color2 && color1 != color5 && color2 != colorB0)
+ product1a = INTERPOLATE6(color2, color5);
+ else
+ product1a = color5;
+
+ *dP=(unsigned short)product1a;
+ *(dP+1)=(unsigned short)product1b;
+ *(dP+(srcPitch))=(unsigned short)product2a;
+ *(dP+1+(srcPitch))=(unsigned short)product2b;
+
+ bP += 1;
+ dP += 2;
+ }//end of for ( finish= width etc..)
+
+ line += 2;
+ srcPtr += srcPitch;
+ }; //endof: for (; height; height--)
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void Std2xSaI_ex6(unsigned char *srcPtr, DWORD srcPitch,
+ unsigned char *dstBitmap, int width, int height)
+{
+ DWORD dstPitch = srcPitch<<1;
+ int finWidth = srcPitch>>1;
+ DWORD line;
+ unsigned short *dP;
+ unsigned short *bP;
+ int iXA,iXB,iXC,iYA,iYB,iYC,finish;
+
+ DWORD colorA, colorB;
+ DWORD colorC, colorD,
+ colorE, colorF, colorG, colorH,
+ colorI, colorJ, colorK, colorL,
+ colorM, colorN, colorO, colorP;
+ DWORD product, product1, product2;
+
+ line = 0;
+
+ {
+ for (; height; height-=1)
+ {
+ bP = (unsigned short *)srcPtr;
+ dP = (unsigned short *)(dstBitmap + line*dstPitch);
+ for (finish = width; finish; finish -= 1 )
+ {
+//---------------------------------------
+// Map of the pixels: I|E F|J
+// G|A B|K
+// H|C D|L
+// M|N O|P
+ if(finish==finWidth) iXA=0;
+ else iXA=1;
+ if(finish>4) {iXB=1;iXC=2;}
+ else
+ if(finish>3) {iXB=1;iXC=1;}
+ else {iXB=0;iXC=0;}
+ if(line==0) iYA=0;
+ else iYA=finWidth;
+ if(height>4) {iYB=finWidth;iYC=srcPitch;}
+ else
+ if(height>3) {iYB=finWidth;iYC=finWidth;}
+ else {iYB=0;iYC=0;}
+
+ colorI = *(bP- iYA - iXA);
+ colorE = *(bP- iYA);
+ colorF = *(bP- iYA + iXB);
+ colorJ = *(bP- iYA + iXC);
+
+ colorG = *(bP - iXA);
+ colorA = *(bP);
+ colorB = *(bP + iXB);
+ colorK = *(bP + iXC);
+
+ colorH = *(bP + iYB - iXA);
+ colorC = *(bP + iYB);
+ colorD = *(bP + iYB + iXB);
+ colorL = *(bP + iYB + iXC);
+
+ colorM = *(bP + iYC - iXA);
+ colorN = *(bP + iYC);
+ colorO = *(bP + iYC + iXB);
+ colorP = *(bP + iYC + iXC);
+
+ if((colorA == colorD) && (colorB != colorC))
+ {
+ if(((colorA == colorE) && (colorB == colorL)) ||
+ ((colorA == colorC) && (colorA == colorF) &&
+ (colorB != colorE) && (colorB == colorJ)))
+ {
+ product = colorA;
+ }
+ else
+ {
+ product = INTERPOLATE6(colorA, colorB);
+ }
+
+ if(((colorA == colorG) && (colorC == colorO)) ||
+ ((colorA == colorB) && (colorA == colorH) &&
+ (colorG != colorC) && (colorC == colorM)))
+ {
+ product1 = colorA;
+ }
+ else
+ {
+ product1 = INTERPOLATE6(colorA, colorC);
+ }
+ product2 = colorA;
+ }
+ else
+ if((colorB == colorC) && (colorA != colorD))
+ {
+ if(((colorB == colorF) && (colorA == colorH)) ||
+ ((colorB == colorE) && (colorB == colorD) &&
+ (colorA != colorF) && (colorA == colorI)))
+ {
+ product = colorB;
+ }
+ else
+ {
+ product = INTERPOLATE6(colorA, colorB);
+ }
+
+ if(((colorC == colorH) && (colorA == colorF)) ||
+ ((colorC == colorG) && (colorC == colorD) &&
+ (colorA != colorH) && (colorA == colorI)))
+ {
+ product1 = colorC;
+ }
+ else
+ {
+ product1=INTERPOLATE6(colorA, colorC);
+ }
+ product2 = colorB;
+ }
+ else
+ if((colorA == colorD) && (colorB == colorC))
+ {
+ if (colorA == colorB)
+ {
+ product = colorA;
+ product1 = colorA;
+ product2 = colorA;
+ }
+ else
+ {
+ register int r = 0;
+ product1 = INTERPOLATE6(colorA, colorC);
+ product = INTERPOLATE6(colorA, colorB);
+
+ r += GetResult1 (colorA, colorB, colorG, colorE, colorI);
+ r += GetResult2 (colorB, colorA, colorK, colorF, colorJ);
+ r += GetResult2 (colorB, colorA, colorH, colorN, colorM);
+ r += GetResult1 (colorA, colorB, colorL, colorO, colorP);
+
+ if (r > 0)
+ product2 = colorA;
+ else
+ if (r < 0)
+ product2 = colorB;
+ else
+ {
+ product2 = Q_INTERPOLATE6(colorA, colorB, colorC, colorD);
+ }
+ }
+ }
+ else
+ {
+ product2 = Q_INTERPOLATE6(colorA, colorB, colorC, colorD);
+
+ if ((colorA == colorC) && (colorA == colorF) &&
+ (colorB != colorE) && (colorB == colorJ))
+ {
+ product = colorA;
+ }
+ else
+ if ((colorB == colorE) && (colorB == colorD) && (colorA != colorF) && (colorA == colorI))
+ {
+ product = colorB;
+ }
+ else
+ {
+ product = INTERPOLATE6(colorA, colorB);
+ }
+
+ if ((colorA == colorB) && (colorA == colorH) &&
+ (colorG != colorC) && (colorC == colorM))
+ {
+ product1 = colorA;
+ }
+ else
+ if ((colorC == colorG) && (colorC == colorD) &&
+ (colorA != colorH) && (colorA == colorI))
+ {
+ product1 = colorC;
+ }
+ else
+ {
+ product1 = INTERPOLATE6(colorA, colorC);
+ }
+ }
+
+ *dP=(unsigned short)colorA;
+ *(dP+1)=(unsigned short)product;
+ *(dP+(srcPitch))=(unsigned short)product1;
+ *(dP+1+(srcPitch))=(unsigned short)product2;
+
+ bP += 1;
+ dP += 2;
+ }//end of for ( finish= width etc..)
+
+ line += 2;
+ srcPtr += srcPitch;
+ }; //endof: for (; height; height--)
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void SuperEagle_ex6(unsigned char *srcPtr, DWORD srcPitch,
+ unsigned char *dstBitmap, int width, int height)
+{
+ DWORD dstPitch = srcPitch<<1;
+ int finWidth = srcPitch>>1;
+ DWORD line;
+ unsigned short *dP;
+ unsigned short *bP;
+ int iXA,iXB,iXC,iYA,iYB,iYC,finish;
+ DWORD color4, color5, color6;
+ DWORD color1, color2, color3;
+ DWORD colorA1, colorA2,
+ colorB1, colorB2,
+ colorS1, colorS2;
+ DWORD product1a, product1b,
+ product2a, product2b;
+
+ line = 0;
+
+ {
+ for (; height; height-=1)
+ {
+ bP = (unsigned short *)srcPtr;
+ dP = (unsigned short *)(dstBitmap + line*dstPitch);
+ for (finish = width; finish; finish -= 1 )
+ {
+ if(finish==finWidth) iXA=0;
+ else iXA=1;
+ if(finish>4) {iXB=1;iXC=2;}
+ else
+ if(finish>3) {iXB=1;iXC=1;}
+ else {iXB=0;iXC=0;}
+ if(line==0) iYA=0;
+ else iYA=finWidth;
+ if(height>4) {iYB=finWidth;iYC=srcPitch;}
+ else
+ if(height>3) {iYB=finWidth;iYC=finWidth;}
+ else {iYB=0;iYC=0;}
+
+ colorB1 = *(bP- iYA);
+ colorB2 = *(bP- iYA + iXB);
+
+ color4 = *(bP - iXA);
+ color5 = *(bP);
+ color6 = *(bP + iXB);
+ colorS2 = *(bP + iXC);
+
+ color1 = *(bP + iYB - iXA);
+ color2 = *(bP + iYB);
+ color3 = *(bP + iYB + iXB);
+ colorS1= *(bP + iYB + iXC);
+
+ colorA1 = *(bP + iYC);
+ colorA2 = *(bP + iYC + iXB);
+
+ if(color2 == color6 && color5 != color3)
+ {
+ product1b = product2a = color2;
+ if((color1 == color2) ||
+ (color6 == colorB2))
+ {
+ product1a = INTERPOLATE6(color2, color5);
+ product1a = INTERPOLATE6(color2, product1a);
+ }
+ else
+ {
+ product1a = INTERPOLATE6(color5, color6);
+ }
+
+ if((color6 == colorS2) ||
+ (color2 == colorA1))
+ {
+ product2b = INTERPOLATE6(color2, color3);
+ product2b = INTERPOLATE6(color2, product2b);
+ }
+ else
+ {
+ product2b = INTERPOLATE6(color2, color3);
+ }
+ }
+ else
+ if (color5 == color3 && color2 != color6)
+ {
+ product2b = product1a = color5;
+
+ if ((colorB1 == color5) ||
+ (color3 == colorS1))
+ {
+ product1b = INTERPOLATE6(color5, color6);
+ product1b = INTERPOLATE6(color5, product1b);
+ }
+ else
+ {
+ product1b = INTERPOLATE6(color5, color6);
+ }
+
+ if ((color3 == colorA2) ||
+ (color4 == color5))
+ {
+ product2a = INTERPOLATE6(color5, color2);
+ product2a = INTERPOLATE6(color5, product2a);
+ }
+ else
+ {
+ product2a = INTERPOLATE6(color2, color3);
+ }
+ }
+ else
+ if (color5 == color3 && color2 == color6)
+ {
+ register int r = 0;
+
+ r += GET_RESULT ((color6), (color5), (color1), (colorA1));
+ r += GET_RESULT ((color6), (color5), (color4), (colorB1));
+ r += GET_RESULT ((color6), (color5), (colorA2), (colorS1));
+ r += GET_RESULT ((color6), (color5), (colorB2), (colorS2));
+
+ if (r > 0)
+ {
+ product1b = product2a = color2;
+ product1a = product2b = INTERPOLATE6(color5, color6);
+ }
+ else
+ if (r < 0)
+ {
+ product2b = product1a = color5;
+ product1b = product2a = INTERPOLATE6(color5, color6);
+ }
+ else
+ {
+ product2b = product1a = color5;
+ product1b = product2a = color2;
+ }
+ }
+ else
+ {
+ product2b = product1a = INTERPOLATE6(color2, color6);
+ product2b = Q_INTERPOLATE6(color3, color3, color3, product2b);
+ product1a = Q_INTERPOLATE6(color5, color5, color5, product1a);
+
+ product2a = product1b = INTERPOLATE6(color5, color3);
+ product2a = Q_INTERPOLATE6(color2, color2, color2, product2a);
+ product1b = Q_INTERPOLATE6(color6, color6, color6, product1b);
+ }
+
+ *dP=(unsigned short)product1a;
+ *(dP+1)=(unsigned short)product1b;
+ *(dP+(srcPitch))=(unsigned short)product2a;
+ *(dP+1+(srcPitch))=(unsigned short)product2b;
+
+ bP += 1;
+ dP += 2;
+ }//end of for ( finish= width etc..)
+
+ line += 2;
+ srcPtr += srcPitch;
+ }; //endof: for (; height; height--)
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+#ifndef MAX
+#define MAX(a,b) (((a) > (b)) ? (a) : (b))
+#define MIN(a,b) (((a) < (b)) ? (a) : (b))
+#endif
+
+void Scale2x_ex6_5(unsigned char *srcPtr, DWORD srcPitch,
+ unsigned char *dstBitmap, int width, int height)
+{
+ int looph, loopw;
+
+ unsigned char * srcpix = srcPtr;
+ unsigned char * dstpix = dstBitmap;
+
+ const int srcpitch = srcPitch;
+ const int dstpitch = srcPitch<<1;
+
+ unsigned short E0, E1, E2, E3, B, D, E, F, H;
+ for(looph = 0; looph < height; ++looph)
+ {
+ for(loopw = 0; loopw < width; ++ loopw)
+ {
+ B = *(unsigned short*)(srcpix + (MAX(0,looph-1)*srcpitch) + (2*loopw));
+ D = *(unsigned short*)(srcpix + (looph*srcpitch) + (2*MAX(0,loopw-1)));
+ E = *(unsigned short*)(srcpix + (looph*srcpitch) + (2*loopw));
+ F = *(unsigned short*)(srcpix + (looph*srcpitch) + (2*MIN(width-1,loopw+1)));
+ H = *(unsigned short*)(srcpix + (MIN(height-1,looph+1)*srcpitch) + (2*loopw));
+
+ if (B != H && D != F) {
+ E0 = D == B ? D : E;
+ E1 = B == F ? F : E;
+ E2 = D == H ? D : E;
+ E3 = H == F ? F : E;
+ } else {
+ E0 = E;
+ E1 = E;
+ E2 = E;
+ E3 = E;
+ }
+
+
+ *(unsigned short*)(dstpix + looph*2*dstpitch + loopw*2*2) = E0;
+ *(unsigned short*)(dstpix + looph*2*dstpitch + (loopw*2+1)*2) = E1;
+ *(unsigned short*)(dstpix + (looph*2+1)*dstpitch + loopw*2*2) = E2;
+ *(unsigned short*)(dstpix + (looph*2+1)*dstpitch + (loopw*2+1)*2) = E3;
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+static __inline void scale3x_16_def_whole(unsigned short* dst0, unsigned short *dst1, unsigned short *dst2, const unsigned short *src0, const unsigned short *src1, const unsigned short *src2, unsigned count)
+{
+ //assert(count >= 2);
+
+ /* first pixel */
+ if (src0[0] != src2[0] && src1[0] != src1[1]) {
+ dst0[0] = src1[0];
+ dst0[1] = (src1[0] == src0[0] && src1[0] != src0[1]) || (src1[1] == src0[0] && src1[0] != src0[0]) ? src0[0] : src1[0];
+ dst0[2] = src1[1] == src0[0] ? src1[1] : src1[0];
+ dst1[0] = (src1[0] == src0[0] && src1[0] != src2[0]) || (src1[0] == src2[0] && src1[0] != src0[0]) ? src1[0] : src1[0];
+ dst1[1] = src1[0];
+ dst1[2] = (src1[1] == src0[0] && src1[0] != src2[1]) || (src1[1] == src2[0] && src1[0] != src0[1]) ? src1[1] : src1[0];
+ dst2[0] = src1[0];
+ dst2[1] = (src1[0] == src2[0] && src1[0] != src2[1]) || (src1[1] == src2[0] && src1[0] != src2[0]) ? src2[0] : src1[0];
+ dst2[2] = src1[1] == src2[0] ? src1[1] : src1[0];
+ } else {
+ dst0[0] = src1[0];
+ dst0[1] = src1[0];
+ dst0[2] = src1[0];
+ dst1[0] = src1[0];
+ dst1[1] = src1[0];
+ dst1[2] = src1[0];
+ dst2[0] = src1[0];
+ dst2[1] = src1[0];
+ dst2[2] = src1[0];
+ }
+ ++src0;
+ ++src1;
+ ++src2;
+ dst0 += 3;
+ dst1 += 3;
+ dst2 += 3;
+
+ /* central pixels */
+ count -= 2;
+ while (count) {
+ if (src0[0] != src2[0] && src1[-1] != src1[1]) {
+ dst0[0] = src1[-1] == src0[0] ? src1[-1] : src1[0];
+ dst0[1] = (src1[-1] == src0[0] && src1[0] != src0[1]) || (src1[1] == src0[0] && src1[0] != src0[-1]) ? src0[0] : src1[0];
+ dst0[2] = src1[1] == src0[0] ? src1[1] : src1[0];
+ dst1[0] = (src1[-1] == src0[0] && src1[0] != src2[-1]) || (src1[-1] == src2[0] && src1[0] != src0[-1]) ? src1[-1] : src1[0];
+ dst1[1] = src1[0];
+ dst1[2] = (src1[1] == src0[0] && src1[0] != src2[1]) || (src1[1] == src2[0] && src1[0] != src0[1]) ? src1[1] : src1[0];
+ dst2[0] = src1[-1] == src2[0] ? src1[-1] : src1[0];
+ dst2[1] = (src1[-1] == src2[0] && src1[0] != src2[1]) || (src1[1] == src2[0] && src1[0] != src2[-1]) ? src2[0] : src1[0];
+ dst2[2] = src1[1] == src2[0] ? src1[1] : src1[0];
+ } else {
+ dst0[0] = src1[0];
+ dst0[1] = src1[0];
+ dst0[2] = src1[0];
+ dst1[0] = src1[0];
+ dst1[1] = src1[0];
+ dst1[2] = src1[0];
+ dst2[0] = src1[0];
+ dst2[1] = src1[0];
+ dst2[2] = src1[0];
+ }
+
+ ++src0;
+ ++src1;
+ ++src2;
+ dst0 += 3;
+ dst1 += 3;
+ dst2 += 3;
+ --count;
+ }
+
+ /* last pixel */
+ if (src0[0] != src2[0] && src1[-1] != src1[0]) {
+ dst0[0] = src1[-1] == src0[0] ? src1[-1] : src1[0];
+ dst0[1] = (src1[-1] == src0[0] && src1[0] != src0[0]) || (src1[0] == src0[0] && src1[0] != src0[-1]) ? src0[0] : src1[0];
+ dst0[2] = src1[0];
+ dst1[0] = (src1[-1] == src0[0] && src1[0] != src2[-1]) || (src1[-1] == src2[0] && src1[0] != src0[-1]) ? src1[-1] : src1[0];
+ dst1[1] = src1[0];
+ dst1[2] = (src1[0] == src0[0] && src1[0] != src2[0]) || (src1[0] == src2[0] && src1[0] != src0[0]) ? src1[0] : src1[0];
+ dst2[0] = src1[-1] == src2[0] ? src1[-1] : src1[0];
+ dst2[1] = (src1[-1] == src2[0] && src1[0] != src2[0]) || (src1[0] == src2[0] && src1[0] != src2[-1]) ? src2[0] : src1[0];
+ dst2[2] = src1[0];
+ } else {
+ dst0[0] = src1[0];
+ dst0[1] = src1[0];
+ dst0[2] = src1[0];
+ dst1[0] = src1[0];
+ dst1[1] = src1[0];
+ dst1[2] = src1[0];
+ dst2[0] = src1[0];
+ dst2[1] = src1[0];
+ dst2[2] = src1[0];
+ }
+}
+
+
+
+void Scale3x_ex6_5(unsigned char *srcPtr, DWORD srcPitch,
+ unsigned char *dstPtr, int width, int height)
+{
+ int count = height;
+ int dstPitch = srcPitch;
+
+ unsigned short *dst0 = (unsigned short *)dstPtr;
+ unsigned short *dst1 = dst0 + dstPitch;
+ unsigned short *dst2 = dst1 + dstPitch;
+
+ unsigned short *src0 = (unsigned short *)srcPtr;
+ unsigned short *src1 = src0 + (srcPitch >> 1);
+ unsigned short *src2 = src1 + (srcPitch >> 1);
+ scale3x_16_def_whole(dst0, dst1, dst2, src0, src1, src2, count);
+
+ count -= 2;
+ while(count) {
+
+ dst0 += dstPitch * 3;
+ dst1 += dstPitch * 3;
+ dst2 += dstPitch * 3;
+
+ scale3x_16_def_whole(dst0, dst1, dst2, src0, src1, src2, width);
+ src0 = src1;
+ src1 = src2;
+ src2 += srcPitch >> 1;
+ --count;
+ }
+ dst0 += dstPitch * 3;
+ dst1 += dstPitch * 3;
+ dst2 += dstPitch * 3;
+
+ scale3x_16_def_whole(dst0, dst1, dst2, src0, src1, src1, width);
+}
+
+////////////////////////////////////////////////////////////////////////
+
+/*
+#define colorMask5 0x0000F7DE
+#define lowPixelMask5 0x00000821
+#define qcolorMask5 0x0000E79c
+#define qlowpixelMask5 0x00001863
+*/
+
+#define colorMask5 0x00007BDE
+#define lowPixelMask5 0x00000421
+#define qcolorMask5 0x0000739c
+#define qlowpixelMask5 0x00000C63
+
+#define INTERPOLATE5(A, B) ((((A & colorMask5) >> 1) + ((B & colorMask5) >> 1) + (A & B & lowPixelMask5)))
+#define Q_INTERPOLATE5(A, B, C, D) (((((A & qcolorMask5) >> 2) + ((B & qcolorMask5) >> 2) + ((C & qcolorMask5) >> 2) + ((D & qcolorMask5) >> 2) \
+ + ((((A & qlowpixelMask5) + (B & qlowpixelMask5) + (C & qlowpixelMask5) + (D & qlowpixelMask5)) >> 2) & qlowpixelMask5))))
+
+void Super2xSaI_ex5(unsigned char *srcPtr, DWORD srcPitch,
+ unsigned char *dstBitmap, int width, int height)
+{
+ DWORD dstPitch = srcPitch<<1;
+ int finWidth = srcPitch>>1;
+ DWORD line;
+ unsigned short *dP;
+ unsigned short *bP;
+ int iXA,iXB,iXC,iYA,iYB,iYC,finish;
+ DWORD color4, color5, color6;
+ DWORD color1, color2, color3;
+ DWORD colorA0, colorA1, colorA2, colorA3,
+ colorB0, colorB1, colorB2, colorB3,
+ colorS1, colorS2;
+ DWORD product1a, product1b,
+ product2a, product2b;
+
+ line = 0;
+
+ {
+ for (; height; height-=1)
+ {
+ bP = (unsigned short *)srcPtr;
+ dP = (unsigned short *)(dstBitmap + line*dstPitch);
+ for (finish = width; finish; finish -= 1 )
+ {
+//--------------------------------------- B1 B2
+// 4 5 6 S2
+// 1 2 3 S1
+// A1 A2
+ if(finish==finWidth) iXA=0;
+ else iXA=1;
+ if(finish>4) {iXB=1;iXC=2;}
+ else
+ if(finish>3) {iXB=1;iXC=1;}
+ else {iXB=0;iXC=0;}
+ if(line==0) iYA=0;
+ else iYA=finWidth;
+ if(height>4) {iYB=finWidth;iYC=srcPitch;}
+ else
+ if(height>3) {iYB=finWidth;iYC=finWidth;}
+ else {iYB=0;iYC=0;}
+
+
+ colorB0 = *(bP- iYA - iXA);
+ colorB1 = *(bP- iYA);
+ colorB2 = *(bP- iYA + iXB);
+ colorB3 = *(bP- iYA + iXC);
+
+ color4 = *(bP - iXA);
+ color5 = *(bP);
+ color6 = *(bP + iXB);
+ colorS2 = *(bP + iXC);
+
+ color1 = *(bP + iYB - iXA);
+ color2 = *(bP + iYB);
+ color3 = *(bP + iYB + iXB);
+ colorS1= *(bP + iYB + iXC);
+
+ colorA0 = *(bP + iYC - iXA);
+ colorA1 = *(bP + iYC);
+ colorA2 = *(bP + iYC + iXB);
+ colorA3 = *(bP + iYC + iXC);
+
+//--------------------------------------
+ if (color2 == color6 && color5 != color3)
+ {
+ product2b = product1b = color2;
+ }
+ else
+ if (color5 == color3 && color2 != color6)
+ {
+ product2b = product1b = color5;
+ }
+ else
+ if (color5 == color3 && color2 == color6)
+ {
+ register int r = 0;
+
+ r += GET_RESULT ((color6), (color5), (color1), (colorA1));
+ r += GET_RESULT ((color6), (color5), (color4), (colorB1));
+ r += GET_RESULT ((color6), (color5), (colorA2), (colorS1));
+ r += GET_RESULT ((color6), (color5), (colorB2), (colorS2));
+
+ if (r > 0)
+ product2b = product1b = color6;
+ else
+ if (r < 0)
+ product2b = product1b = color5;
+ else
+ {
+ product2b = product1b = INTERPOLATE5 (color5, color6);
+ }
+ }
+ else
+ {
+ if (color6 == color3 && color3 == colorA1 && color2 != colorA2 && color3 != colorA0)
+ product2b = Q_INTERPOLATE5 (color3, color3, color3, color2);
+ else
+ if (color5 == color2 && color2 == colorA2 && colorA1 != color3 && color2 != colorA3)
+ product2b = Q_INTERPOLATE5 (color2, color2, color2, color3);
+ else
+ product2b = INTERPOLATE5 (color2, color3);
+
+ if (color6 == color3 && color6 == colorB1 && color5 != colorB2 && color6 != colorB0)
+ product1b = Q_INTERPOLATE5 (color6, color6, color6, color5);
+ else
+ if (color5 == color2 && color5 == colorB2 && colorB1 != color6 && color5 != colorB3)
+ product1b = Q_INTERPOLATE5 (color6, color5, color5, color5);
+ else
+ product1b = INTERPOLATE5 (color5, color6);
+ }
+
+ if (color5 == color3 && color2 != color6 && color4 == color5 && color5 != colorA2)
+ product2a = INTERPOLATE5 (color2, color5);
+ else
+ if (color5 == color1 && color6 == color5 && color4 != color2 && color5 != colorA0)
+ product2a = INTERPOLATE5(color2, color5);
+ else
+ product2a = color2;
+
+ if (color2 == color6 && color5 != color3 && color1 == color2 && color2 != colorB2)
+ product1a = INTERPOLATE5(color2, color5);
+ else
+ if (color4 == color2 && color3 == color2 && color1 != color5 && color2 != colorB0)
+ product1a = INTERPOLATE5(color2, color5);
+ else
+ product1a = color5;
+
+ *dP=(unsigned short)product1a;
+ *(dP+1)=(unsigned short)product1b;
+ *(dP+(srcPitch))=(unsigned short)product2a;
+ *(dP+1+(srcPitch))=(unsigned short)product2b;
+
+ bP += 1;
+ dP += 2;
+ }//end of for ( finish= width etc..)
+
+ line += 2;
+ srcPtr += srcPitch;
+ }; //endof: for (; height; height--)
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void Std2xSaI_ex5(unsigned char *srcPtr, DWORD srcPitch,
+ unsigned char *dstBitmap, int width, int height)
+{
+ DWORD dstPitch = srcPitch<<1;
+ int finWidth = srcPitch>>1;
+ DWORD line;
+ unsigned short *dP;
+ unsigned short *bP;
+ int iXA,iXB,iXC,iYA,iYB,iYC,finish;
+ DWORD colorA, colorB;
+ DWORD colorC, colorD,
+ colorE, colorF, colorG, colorH,
+ colorI, colorJ, colorK, colorL,
+ colorM, colorN, colorO, colorP;
+ DWORD product, product1, product2;
+
+ line = 0;
+
+ {
+ for (; height; height-=1)
+ {
+ bP = (unsigned short *)srcPtr;
+ dP = (unsigned short *)(dstBitmap + line*dstPitch);
+ for (finish = width; finish; finish -= 1 )
+ {
+//---------------------------------------
+// Map of the pixels: I|E F|J
+// G|A B|K
+// H|C D|L
+// M|N O|P
+ if(finish==finWidth) iXA=0;
+ else iXA=1;
+ if(finish>4) {iXB=1;iXC=2;}
+ else
+ if(finish>3) {iXB=1;iXC=1;}
+ else {iXB=0;iXC=0;}
+ if(line==0) iYA=0;
+ else iYA=finWidth;
+ if(height>4) {iYB=finWidth;iYC=srcPitch;}
+ else
+ if(height>3) {iYB=finWidth;iYC=finWidth;}
+ else {iYB=0;iYC=0;}
+
+ colorI = *(bP- iYA - iXA);
+ colorE = *(bP- iYA);
+ colorF = *(bP- iYA + iXB);
+ colorJ = *(bP- iYA + iXC);
+
+ colorG = *(bP - iXA);
+ colorA = *(bP);
+ colorB = *(bP + iXB);
+ colorK = *(bP + iXC);
+
+ colorH = *(bP + iYB - iXA);
+ colorC = *(bP + iYB);
+ colorD = *(bP + iYB + iXB);
+ colorL = *(bP + iYB + iXC);
+
+ colorM = *(bP + iYC - iXA);
+ colorN = *(bP + iYC);
+ colorO = *(bP + iYC + iXB);
+ colorP = *(bP + iYC + iXC);
+
+ if((colorA == colorD) && (colorB != colorC))
+ {
+ if(((colorA == colorE) && (colorB == colorL)) ||
+ ((colorA == colorC) && (colorA == colorF) &&
+ (colorB != colorE) && (colorB == colorJ)))
+ {
+ product = colorA;
+ }
+ else
+ {
+ product = INTERPOLATE5(colorA, colorB);
+ }
+
+ if(((colorA == colorG) && (colorC == colorO)) ||
+ ((colorA == colorB) && (colorA == colorH) &&
+ (colorG != colorC) && (colorC == colorM)))
+ {
+ product1 = colorA;
+ }
+ else
+ {
+ product1 = INTERPOLATE5(colorA, colorC);
+ }
+ product2 = colorA;
+ }
+ else
+ if((colorB == colorC) && (colorA != colorD))
+ {
+ if(((colorB == colorF) && (colorA == colorH)) ||
+ ((colorB == colorE) && (colorB == colorD) &&
+ (colorA != colorF) && (colorA == colorI)))
+ {
+ product = colorB;
+ }
+ else
+ {
+ product = INTERPOLATE5(colorA, colorB);
+ }
+
+ if(((colorC == colorH) && (colorA == colorF)) ||
+ ((colorC == colorG) && (colorC == colorD) &&
+ (colorA != colorH) && (colorA == colorI)))
+ {
+ product1 = colorC;
+ }
+ else
+ {
+ product1=INTERPOLATE5(colorA, colorC);
+ }
+ product2 = colorB;
+ }
+ else
+ if((colorA == colorD) && (colorB == colorC))
+ {
+ if (colorA == colorB)
+ {
+ product = colorA;
+ product1 = colorA;
+ product2 = colorA;
+ }
+ else
+ {
+ register int r = 0;
+ product1 = INTERPOLATE5(colorA, colorC);
+ product = INTERPOLATE5(colorA, colorB);
+
+ r += GetResult1 (colorA, colorB, colorG, colorE, colorI);
+ r += GetResult2 (colorB, colorA, colorK, colorF, colorJ);
+ r += GetResult2 (colorB, colorA, colorH, colorN, colorM);
+ r += GetResult1 (colorA, colorB, colorL, colorO, colorP);
+
+ if (r > 0)
+ product2 = colorA;
+ else
+ if (r < 0)
+ product2 = colorB;
+ else
+ {
+ product2 = Q_INTERPOLATE5(colorA, colorB, colorC, colorD);
+ }
+ }
+ }
+ else
+ {
+ product2 = Q_INTERPOLATE5(colorA, colorB, colorC, colorD);
+
+ if ((colorA == colorC) && (colorA == colorF) &&
+ (colorB != colorE) && (colorB == colorJ))
+ {
+ product = colorA;
+ }
+ else
+ if ((colorB == colorE) && (colorB == colorD) && (colorA != colorF) && (colorA == colorI))
+ {
+ product = colorB;
+ }
+ else
+ {
+ product = INTERPOLATE5(colorA, colorB);
+ }
+
+ if ((colorA == colorB) && (colorA == colorH) &&
+ (colorG != colorC) && (colorC == colorM))
+ {
+ product1 = colorA;
+ }
+ else
+ if ((colorC == colorG) && (colorC == colorD) &&
+ (colorA != colorH) && (colorA == colorI))
+ {
+ product1 = colorC;
+ }
+ else
+ {
+ product1 = INTERPOLATE5(colorA, colorC);
+ }
+ }
+
+ *dP=(unsigned short)colorA;
+ *(dP+1)=(unsigned short)product;
+ *(dP+(srcPitch))=(unsigned short)product1;
+ *(dP+1+(srcPitch))=(unsigned short)product2;
+
+ bP += 1;
+ dP += 2;
+ }//end of for ( finish= width etc..)
+
+ line += 2;
+ srcPtr += srcPitch;
+ }; //endof: for (; height; height--)
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void SuperEagle_ex5(unsigned char *srcPtr, DWORD srcPitch,
+ unsigned char *dstBitmap, int width, int height)
+{
+ DWORD dstPitch = srcPitch<<1;
+ int finWidth = srcPitch>>1;
+ DWORD line;
+ unsigned short *dP;
+ unsigned short *bP;
+ int iXA,iXB,iXC,iYA,iYB,iYC,finish;
+ DWORD color4, color5, color6;
+ DWORD color1, color2, color3;
+ DWORD colorA1, colorA2,
+ colorB1, colorB2,
+ colorS1, colorS2;
+ DWORD product1a, product1b,
+ product2a, product2b;
+
+ line = 0;
+
+ {
+ for (; height; height-=1)
+ {
+ bP = (unsigned short *)srcPtr;
+ dP = (unsigned short *)(dstBitmap + line*dstPitch);
+ for (finish = width; finish; finish -= 1 )
+ {
+ if(finish==finWidth) iXA=0;
+ else iXA=1;
+ if(finish>4) {iXB=1;iXC=2;}
+ else
+ if(finish>3) {iXB=1;iXC=1;}
+ else {iXB=0;iXC=0;}
+ if(line==0) iYA=0;
+ else iYA=finWidth;
+ if(height>4) {iYB=finWidth;iYC=srcPitch;}
+ else
+ if(height>3) {iYB=finWidth;iYC=finWidth;}
+ else {iYB=0;iYC=0;}
+
+ colorB1 = *(bP- iYA);
+ colorB2 = *(bP- iYA + iXB);
+
+ color4 = *(bP - iXA);
+ color5 = *(bP);
+ color6 = *(bP + iXB);
+ colorS2 = *(bP + iXC);
+
+ color1 = *(bP + iYB - iXA);
+ color2 = *(bP + iYB);
+ color3 = *(bP + iYB + iXB);
+ colorS1= *(bP + iYB + iXC);
+
+ colorA1 = *(bP + iYC);
+ colorA2 = *(bP + iYC + iXB);
+
+ if(color2 == color6 && color5 != color3)
+ {
+ product1b = product2a = color2;
+ if((color1 == color2) ||
+ (color6 == colorB2))
+ {
+ product1a = INTERPOLATE5(color2, color5);
+ product1a = INTERPOLATE5(color2, product1a);
+ }
+ else
+ {
+ product1a = INTERPOLATE5(color5, color6);
+ }
+
+ if((color6 == colorS2) ||
+ (color2 == colorA1))
+ {
+ product2b = INTERPOLATE5(color2, color3);
+ product2b = INTERPOLATE5(color2, product2b);
+ }
+ else
+ {
+ product2b = INTERPOLATE5(color2, color3);
+ }
+ }
+ else
+ if (color5 == color3 && color2 != color6)
+ {
+ product2b = product1a = color5;
+
+ if ((colorB1 == color5) ||
+ (color3 == colorS1))
+ {
+ product1b = INTERPOLATE5(color5, color6);
+ product1b = INTERPOLATE5(color5, product1b);
+ }
+ else
+ {
+ product1b = INTERPOLATE5(color5, color6);
+ }
+
+ if ((color3 == colorA2) ||
+ (color4 == color5))
+ {
+ product2a = INTERPOLATE5(color5, color2);
+ product2a = INTERPOLATE5(color5, product2a);
+ }
+ else
+ {
+ product2a = INTERPOLATE5(color2, color3);
+ }
+ }
+ else
+ if (color5 == color3 && color2 == color6)
+ {
+ register int r = 0;
+
+ r += GET_RESULT ((color6), (color5), (color1), (colorA1));
+ r += GET_RESULT ((color6), (color5), (color4), (colorB1));
+ r += GET_RESULT ((color6), (color5), (colorA2), (colorS1));
+ r += GET_RESULT ((color6), (color5), (colorB2), (colorS2));
+
+ if (r > 0)
+ {
+ product1b = product2a = color2;
+ product1a = product2b = INTERPOLATE5(color5, color6);
+ }
+ else
+ if (r < 0)
+ {
+ product2b = product1a = color5;
+ product1b = product2a = INTERPOLATE5(color5, color6);
+ }
+ else
+ {
+ product2b = product1a = color5;
+ product1b = product2a = color2;
+ }
+ }
+ else
+ {
+ product2b = product1a = INTERPOLATE5(color2, color6);
+ product2b = Q_INTERPOLATE5(color3, color3, color3, product2b);
+ product1a = Q_INTERPOLATE5(color5, color5, color5, product1a);
+
+ product2a = product1b = INTERPOLATE5(color5, color3);
+ product2a = Q_INTERPOLATE5(color2, color2, color2, product2a);
+ product1b = Q_INTERPOLATE5(color6, color6, color6, product1b);
+ }
+
+ *dP=(unsigned short)product1a;
+ *(dP+1)=(unsigned short)product1b;
+ *(dP+(srcPitch))=(unsigned short)product2a;
+ *(dP+1+(srcPitch))=(unsigned short)product2b;
+
+ bP += 1;
+ dP += 2;
+ }//end of for ( finish= width etc..)
+
+ line += 2;
+ srcPtr += srcPitch;
+ }; //endof: for (; height; height--)
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+// own swap buffer func (window/fullscreen)
+////////////////////////////////////////////////////////////////////////
+
+sDX DX;
+static DDSURFACEDESC ddsd;
+GUID guiDev;
+BOOL bDeviceOK;
+HWND hWGPU;
+int iSysMemory=0;
+int iFPSEInterface=0;
+int iRefreshRate;
+BOOL bVsync=FALSE;
+BOOL bVsync_Key=FALSE;
+
+void (*BlitScreen) (unsigned char *,long,long);
+void (*pExtraBltFunc) (void);
+void (*p2XSaIFunc) (unsigned char *,DWORD,unsigned char *,int,int);
+
+////////////////////////////////////////////////////////////////////////
+
+static __inline void WaitVBlank(void)
+{
+ if(bVsync_Key)
+ {
+ IDirectDraw2_WaitForVerticalBlank(DX.DD,DDWAITVB_BLOCKBEGIN,0);
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void BlitScreen32(unsigned char * surf,long x,long y) // BLIT IN 32bit COLOR MODE
+{
+ unsigned char * pD;unsigned long lu;unsigned short s;
+ unsigned int startxy;
+ short row,column;
+ short dx=(short)PreviousPSXDisplay.Range.x1;
+ short dy=(short)PreviousPSXDisplay.DisplayMode.y;
+
+ if(iDebugMode && iFVDisplay)
+ {
+ dx=1024;
+ dy=iGPUHeight;
+ x=0;y=0;
+
+ for(column=0;column<dy;column++)
+ {
+ startxy=((1024)*(column+y))+x;
+ for(row=0;row<dx;row++)
+ {
+ s=psxVuw[startxy++];
+ *((unsigned long *)((surf)+(column*ddsd.lPitch)+row*4))=
+ ((((s<<19)&0xf80000)|((s<<6)&0xf800)|((s>>7)&0xf8))&0xffffff)|0xff000000;
+ }
+ }
+ return;
+ }
+
+
+ if(PreviousPSXDisplay.Range.y0) // centering needed?
+ {
+ surf+=PreviousPSXDisplay.Range.y0*ddsd.lPitch;
+ dy-=PreviousPSXDisplay.Range.y0;
+ }
+
+ surf+=PreviousPSXDisplay.Range.x0<<2;
+
+ if(PSXDisplay.RGB24)
+ {
+ if(iFPSEInterface)
+ {
+ for(column=0;column<dy;column++)
+ {
+ startxy=((1024)*(column+y))+x;
+ pD=(unsigned char *)&psxVuw[startxy];
+
+ for(row=0;row<dx;row++)
+ {
+ lu=*((unsigned long *)pD);
+ *((unsigned long *)((surf)+(column*ddsd.lPitch)+row*4))=
+ 0xff000000|(BLUE(lu)<<16)|(GREEN(lu)<<8)|(RED(lu));
+ pD+=3;
+ }
+ }
+ }
+ else
+ {
+ for(column=0;column<dy;column++)
+ {
+ startxy=((1024)*(column+y))+x;
+ pD=(unsigned char *)&psxVuw[startxy];
+
+ for(row=0;row<dx;row++)
+ {
+ lu=*((unsigned long *)pD);
+ *((unsigned long *)((surf)+(column*ddsd.lPitch)+row*4))=
+ 0xff000000|(RED(lu)<<16)|(GREEN(lu)<<8)|(BLUE(lu));
+ pD+=3;
+ }
+ }
+ }
+ }
+ else
+ {
+ for(column=0;column<dy;column++)
+ {
+ startxy=((1024)*(column+y))+x;
+ for(row=0;row<dx;row++)
+ {
+ s=psxVuw[startxy++];
+ *((unsigned long *)((surf)+(column*ddsd.lPitch)+row*4))=
+ ((((s<<19)&0xf80000)|((s<<6)&0xf800)|((s>>7)&0xf8))&0xffffff)|0xff000000;
+ }
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void BlitScreen32_2xSaI(unsigned char * surf,long x,long y) // BLIT IN 32bit COLOR MODE
+{
+ unsigned char * pD;unsigned long lu;unsigned short s;
+ unsigned int startxy,off1,off2;
+ short row,column;
+ short dx=(short)PreviousPSXDisplay.Range.x1;
+ short dy=(short)PreviousPSXDisplay.DisplayMode.y;
+ unsigned char * pS=(unsigned char *)pSaISmallBuff;
+ unsigned long * pS1, * pS2;
+
+ if(PreviousPSXDisplay.DisplayMode.x>512)
+ {BlitScreen32(surf,x,y);return;}
+
+ if(PreviousPSXDisplay.Range.y0) // centering needed?
+ {
+ pS+=PreviousPSXDisplay.Range.y0*2048;
+ dy-=PreviousPSXDisplay.Range.y0;
+ }
+
+ pS+=PreviousPSXDisplay.Range.x0<<2;
+
+ if(PSXDisplay.RGB24)
+ {
+ if(iFPSEInterface)
+ {
+ for(column=0;column<dy;column++)
+ {
+ startxy=((1024)*(column+y))+x;
+ pD=(unsigned char *)&psxVuw[startxy];
+
+ for(row=0;row<dx;row++)
+ {
+ lu=*((unsigned long *)pD);
+ *((unsigned long *)((pS)+(column*2048)+row*4))=
+ 0xff000000|(BLUE(lu)<<16)|(GREEN(lu)<<8)|(RED(lu));
+ pD+=3;
+ }
+ }
+ }
+ else
+ {
+ for(column=0;column<dy;column++)
+ {
+ startxy=((1024)*(column+y))+x;
+ pD=(unsigned char *)&psxVuw[startxy];
+
+ for(row=0;row<dx;row++)
+ {
+ lu=*((unsigned long *)pD);
+ *((unsigned long *)((pS)+(column*2048)+row*4))=
+ 0xff000000|(RED(lu)<<16)|(GREEN(lu)<<8)|(BLUE(lu));
+ pD+=3;
+ }
+ }
+ }
+ }
+ else
+ {
+ for(column=0;column<dy;column++)
+ {
+ startxy=((1024)*(column+y))+x;
+ for(row=0;row<dx;row++)
+ {
+ s=psxVuw[startxy++];
+ *((unsigned long *)((pS)+(column*2048)+row*4))=
+ ((((s<<19)&0xf80000)|((s<<6)&0xf800)|((s>>7)&0xf8))&0xffffff)|0xff000000;
+ }
+ }
+ }
+
+ // ok, here we have filled pSaISmallBuff with PreviousPSXDisplay.DisplayMode.x * PreviousPSXDisplay.DisplayMode.y (*4) data
+ // now do a 2xSai blit to pSaIBigBuff
+
+ p2XSaIFunc((unsigned char *)pSaISmallBuff, 2048,
+ (unsigned char *)pSaIBigBuff,
+ PreviousPSXDisplay.DisplayMode.x,
+ PreviousPSXDisplay.DisplayMode.y);
+
+ // ok, here we have pSaIBigBuff filled with the 2xSai image...
+ // now transfer it to the surface
+
+ dx=(short)PreviousPSXDisplay.DisplayMode.x<<1;
+ dy=(short)PreviousPSXDisplay.DisplayMode.y<<1;
+ off1=(ddsd.lPitch>>2)-dx;
+ off2=1024-dx;
+
+ pS1=(unsigned long *)surf;
+ pS2=(unsigned long *)pSaIBigBuff;
+
+ for(column=0;column<dy;column++)
+ {
+ for(row=0;row<dx;row++)
+ {
+ *(pS1++)=*(pS2++);
+ }
+ pS1+=off1;
+ pS2+=off2;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////
+void BlitScreen32_3xSaI(unsigned char * surf,long x,long y) // BLIT IN 32bit COLOR MODE
+{
+ unsigned char * pD;unsigned long lu;unsigned short s;
+ unsigned int startxy,off1,off2;
+ short row,column;
+ short dx=(short)PreviousPSXDisplay.Range.x1;
+ short dy=(short)PreviousPSXDisplay.DisplayMode.y;
+ unsigned char * pS=(unsigned char *)pSaISmallBuff;
+ unsigned long * pS1, * pS2;
+
+ if(PreviousPSXDisplay.DisplayMode.x>512)
+ {BlitScreen32(surf,x,y);return;}
+
+ if(PreviousPSXDisplay.Range.y0) // centering needed?
+ {
+ pS+=PreviousPSXDisplay.Range.y0*2048;
+ dy-=PreviousPSXDisplay.Range.y0;
+ }
+
+ pS+=PreviousPSXDisplay.Range.x0<<2;
+
+ if(PSXDisplay.RGB24)
+ {
+ if(iFPSEInterface)
+ {
+ for(column=0;column<dy;column++)
+ {
+ startxy=((1024)*(column+y))+x;
+ pD=(unsigned char *)&psxVuw[startxy];
+
+ for(row=0;row<dx;row++)
+ {
+ lu=*((unsigned long *)pD);
+ *((unsigned long *)((pS)+(column*2048)+row*4))=
+ 0xff000000|(BLUE(lu)<<16)|(GREEN(lu)<<8)|(RED(lu));
+ pD+=3;
+ }
+ }
+ }
+ else
+ {
+ for(column=0;column<dy;column++)
+ {
+ startxy=((1024)*(column+y))+x;
+ pD=(unsigned char *)&psxVuw[startxy];
+
+ for(row=0;row<dx;row++)
+ {
+ lu=*((unsigned long *)pD);
+ *((unsigned long *)((pS)+(column*2048)+row*4))=
+ 0xff000000|(RED(lu)<<16)|(GREEN(lu)<<8)|(BLUE(lu));
+ pD+=3;
+ }
+ }
+ }
+ }
+ else
+ {
+ for(column=0;column<dy;column++)
+ {
+ startxy=((1024)*(column+y))+x;
+ for(row=0;row<dx;row++)
+ {
+ s=psxVuw[startxy++];
+ *((unsigned long *)((pS)+(column*2048)+row*4))=
+ ((((s<<19)&0xf80000)|((s<<6)&0xf800)|((s>>7)&0xf8))&0xffffff)|0xff000000;
+ }
+ }
+ }
+
+ // ok, here we have filled pSaISmallBuff with PreviousPSXDisplay.DisplayMode.x * PreviousPSXDisplay.DisplayMode.y (*4) data
+ // now do a 2xSai blit to pSaIBigBuff
+
+ p2XSaIFunc((unsigned char *)pSaISmallBuff, 2048,
+ (unsigned char *)pSaIBigBuff,
+ PreviousPSXDisplay.DisplayMode.x,
+ PreviousPSXDisplay.DisplayMode.y);
+
+ // ok, here we have pSaIBigBuff filled with the 2xSai image...
+ // now transfer it to the surface
+ //CHANGED << 1 to * 3
+
+ dx=(short)PreviousPSXDisplay.DisplayMode.x * 3;
+ dy=(short)PreviousPSXDisplay.DisplayMode.y * 3;
+
+ off1=(ddsd.lPitch>>2)-dx;
+ off2=1024-dx;
+
+ pS1=(unsigned long *)surf;
+ pS2=(unsigned long *)pSaIBigBuff;
+
+ for(column=0;column<dy;column++)
+ {
+ for(row=0;row<dx;row++)
+ {
+ *(pS1++)=*(pS2++);
+ }
+ pS1+=off1;
+ pS2+=off2;
+ }
+}
+//////////////////////////////////////////////////////////////////////
+void BlitScreen16(unsigned char * surf,long x,long y) // BLIT IN 16bit COLOR MODE
+{
+ unsigned long lu;
+ unsigned short row,column;
+ unsigned short dx=(unsigned short)PreviousPSXDisplay.Range.x1;
+ unsigned short dy=(unsigned short)PreviousPSXDisplay.DisplayMode.y;
+
+ if(iDebugMode && iFVDisplay)
+ {
+ unsigned short LineOffset,SurfOffset;
+ unsigned long * SRCPtr;
+ unsigned long * DSTPtr;
+
+ dx=1024;
+ dy=iGPUHeight;
+ x=0;y=0;
+
+ SRCPtr = (unsigned long *)(psxVuw);
+ DSTPtr = ((unsigned long *)surf);
+
+ dx>>=1;
+
+ LineOffset = 512 - dx;
+ SurfOffset = (ddsd.lPitch>>2) - dx;
+
+ for(column=0;column<dy;column++)
+ {
+ for(row=0;row<dx;row++)
+ {
+ lu=*SRCPtr++;
+
+ *DSTPtr++=
+ ((lu<<11)&0xf800f800)|((lu<<1)&0x7c007c0)|((lu>>10)&0x1f001f);
+ }
+ SRCPtr += LineOffset;
+ DSTPtr += SurfOffset;
+ }
+ return;
+ }
+
+ if(PreviousPSXDisplay.Range.y0) // centering needed?
+ {
+ surf+=PreviousPSXDisplay.Range.y0*ddsd.lPitch;
+ dy-=PreviousPSXDisplay.Range.y0;
+ }
+
+ if(PSXDisplay.RGB24)
+ {
+ unsigned char * pD;unsigned int startxy;
+
+ surf+=PreviousPSXDisplay.Range.x0<<1;
+
+ if(iFPSEInterface)
+ {
+ for(column=0;column<dy;column++)
+ {
+ startxy=((1024)*(column+y))+x;
+
+ pD=(unsigned char *)&psxVuw[startxy];
+
+ for(row=0;row<dx;row++)
+ {
+ lu=*((unsigned long *)pD);
+ *((unsigned short *)((surf)+(column*ddsd.lPitch)+(row<<1)))=
+ (unsigned short)(((BLUE(lu)<<8)&0xf800)|((GREEN(lu)<<3)&0x7e0)|(RED(lu)>>3));
+ pD+=3;
+ }
+ }
+ }
+ else
+ {
+ for(column=0;column<dy;column++)
+ {
+ startxy=((1024)*(column+y))+x;
+
+ pD=(unsigned char *)&psxVuw[startxy];
+
+ for(row=0;row<dx;row++)
+ {
+ lu=*((unsigned long *)pD);
+ *((unsigned short *)((surf)+(column*ddsd.lPitch)+(row<<1)))=
+ (unsigned short)(((RED(lu)<<8)&0xf800)|((GREEN(lu)<<3)&0x7e0)|(BLUE(lu)>>3));
+ pD+=3;
+ }
+ }
+ }
+ }
+ else
+ {
+ unsigned short LineOffset,SurfOffset;
+ unsigned long * SRCPtr = (unsigned long *)(psxVuw +
+ (y<<10) + x);
+ unsigned long * DSTPtr =
+ ((unsigned long *)surf)+(PreviousPSXDisplay.Range.x0>>1);
+
+ dx>>=1;
+
+ LineOffset = 512 - dx;
+ SurfOffset = (ddsd.lPitch>>2) - dx;
+
+ for(column=0;column<dy;column++)
+ {
+ for(row=0;row<dx;row++)
+ {
+ lu=*SRCPtr++;
+
+ *DSTPtr++=
+ ((lu<<11)&0xf800f800)|((lu<<1)&0x7c007c0)|((lu>>10)&0x1f001f);
+ }
+ SRCPtr += LineOffset;
+ DSTPtr += SurfOffset;
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void BlitScreen16_2xSaI(unsigned char * surf,long x,long y) // BLIT IN 16bit COLOR MODE
+{
+ unsigned long lu;
+ unsigned short row,column,off1,off2;
+ unsigned short dx=(unsigned short)PreviousPSXDisplay.Range.x1;
+ unsigned short dy=(unsigned short)PreviousPSXDisplay.DisplayMode.y;
+ unsigned char * pS=(unsigned char *)pSaISmallBuff;
+ unsigned long * pS1, * pS2;
+
+ if(PreviousPSXDisplay.DisplayMode.x>512)
+ {BlitScreen16(surf,x,y);return;}
+
+ if(PreviousPSXDisplay.Range.y0) // centering needed?
+ {
+ pS+=PreviousPSXDisplay.Range.y0*1024;
+ dy-=PreviousPSXDisplay.Range.y0;
+ }
+
+ if(PSXDisplay.RGB24)
+ {
+ unsigned char * pD;unsigned int startxy;
+
+ pS+=PreviousPSXDisplay.Range.x0<<1;
+
+ if(iFPSEInterface)
+ {
+ for(column=0;column<dy;column++)
+ {
+ startxy=((1024)*(column+y))+x;
+
+ pD=(unsigned char *)&psxVuw[startxy];
+
+ for(row=0;row<dx;row++)
+ {
+ lu=*((unsigned long *)pD);
+ *((unsigned short *)((pS)+(column*1024)+(row<<1)))=
+ (unsigned short)(((BLUE(lu)<<8)&0xf800)|((GREEN(lu)<<3)&0x7e0)|(RED(lu)>>3));
+ pD+=3;
+ }
+ }
+ }
+ else
+ {
+ for(column=0;column<dy;column++)
+ {
+ startxy=((1024)*(column+y))+x;
+
+ pD=(unsigned char *)&psxVuw[startxy];
+
+ for(row=0;row<dx;row++)
+ {
+ lu=*((unsigned long *)pD);
+ *((unsigned short *)((pS)+(column*1024)+(row<<1)))=
+ (unsigned short)(((RED(lu)<<8)&0xf800)|((GREEN(lu)<<3)&0x7e0)|(BLUE(lu)>>3));
+ pD+=3;
+ }
+ }
+ }
+ }
+ else
+ {
+ unsigned short LineOffset,SurfOffset;
+ unsigned long * SRCPtr = (unsigned long *)(psxVuw +
+ (y<<10) + x);
+ unsigned long * DSTPtr =
+ ((unsigned long *)pS)+(PreviousPSXDisplay.Range.x0>>1);
+
+ dx>>=1;
+
+ LineOffset = 512 - dx;
+ SurfOffset = 256 - dx;
+
+ for(column=0;column<dy;column++)
+ {
+ for(row=0;row<dx;row++)
+ {
+ lu=*SRCPtr++;
+
+ *DSTPtr++=
+ ((lu<<11)&0xf800f800)|((lu<<1)&0x7c007c0)|((lu>>10)&0x1f001f);
+ }
+ SRCPtr += LineOffset;
+ DSTPtr += SurfOffset;
+ }
+ }
+
+ // ok, here we have filled pSaISmallBuff with PreviousPSXDisplay.DisplayMode.x * PreviousPSXDisplay.DisplayMode.y (*4) data
+ // now do a 2xSai blit to pSaIBigBuff
+
+ p2XSaIFunc((unsigned char *)pSaISmallBuff, 1024,
+ (unsigned char *)pSaIBigBuff,
+ PreviousPSXDisplay.DisplayMode.x,
+ PreviousPSXDisplay.DisplayMode.y);
+
+ // ok, here we have pSaIBigBuff filled with the 2xSai image...
+ // now transfer it to the surface
+
+ dx=(short)PreviousPSXDisplay.DisplayMode.x;
+ dy=(short)PreviousPSXDisplay.DisplayMode.y<<1;
+ off1=(ddsd.lPitch>>2)-dx;
+ off2=512-dx;
+
+ pS1=(unsigned long *)surf;
+ pS2=(unsigned long *)pSaIBigBuff;
+
+ for(column=0;column<dy;column++)
+ {
+ for(row=0;row<dx;row++)
+ {
+ *(pS1++)=*(pS2++);
+ }
+ pS1+=off1;
+ pS2+=off2;
+ }
+}
+
+void BlitScreen16_3xSaI(unsigned char * surf,long x,long y) // BLIT IN 16bit COLOR MODE
+{
+ unsigned long lu;
+ unsigned short row,column,off1,off2;
+ unsigned short dx=(unsigned short)PreviousPSXDisplay.Range.x1;
+ unsigned short dy=(unsigned short)PreviousPSXDisplay.DisplayMode.y;
+ unsigned char * pS=(unsigned char *)pSaISmallBuff;
+ unsigned long * pS1, * pS2;
+
+ if(PreviousPSXDisplay.DisplayMode.x>512)
+ {BlitScreen16(surf,x,y);return;}
+
+ if(PreviousPSXDisplay.Range.y0) // centering needed?
+ {
+ pS+=PreviousPSXDisplay.Range.y0*1024;
+ dy-=PreviousPSXDisplay.Range.y0;
+ }
+
+ if(PSXDisplay.RGB24)
+ {
+ unsigned char * pD;unsigned int startxy;
+
+ pS+=PreviousPSXDisplay.Range.x0<<1;
+
+ if(iFPSEInterface)
+ {
+ for(column=0;column<dy;column++)
+ {
+ startxy=((1024)*(column+y))+x;
+
+ pD=(unsigned char *)&psxVuw[startxy];
+
+ for(row=0;row<dx;row++)
+ {
+ lu=*((unsigned long *)pD);
+ *((unsigned short *)((pS)+(column*1024)+(row<<1)))=
+ (unsigned short)(((BLUE(lu)<<8)&0xf800)|((GREEN(lu)<<3)&0x7e0)|(RED(lu)>>3));
+ pD+=3;
+ }
+ }
+ }
+ else
+ {
+ for(column=0;column<dy;column++)
+ {
+ startxy=((1024)*(column+y))+x;
+
+ pD=(unsigned char *)&psxVuw[startxy];
+
+ for(row=0;row<dx;row++)
+ {
+ lu=*((unsigned long *)pD);
+ *((unsigned short *)((pS)+(column*1024)+(row<<1)))=
+ (unsigned short)(((RED(lu)<<8)&0xf800)|((GREEN(lu)<<3)&0x7e0)|(BLUE(lu)>>3));
+ pD+=3;
+ }
+ }
+ }
+ }
+ else
+ {
+ unsigned short LineOffset,SurfOffset;
+ unsigned long * SRCPtr = (unsigned long *)(psxVuw +
+ (y<<10) + x);
+ unsigned long * DSTPtr =
+ ((unsigned long *)pS)+(PreviousPSXDisplay.Range.x0>>1);
+
+ dx>>=1;
+
+ LineOffset = 512 - dx;
+ SurfOffset = 256 - dx;
+
+ for(column=0;column<dy;column++)
+ {
+ for(row=0;row<dx;row++)
+ {
+ lu=*SRCPtr++;
+
+ *DSTPtr++=
+ ((lu<<11)&0xf800f800)|((lu<<1)&0x7c007c0)|((lu>>10)&0x1f001f);
+ }
+ SRCPtr += LineOffset;
+ DSTPtr += SurfOffset;
+ }
+ }
+
+ // ok, here we have filled pSaISmallBuff with PreviousPSXDisplay.DisplayMode.x * PreviousPSXDisplay.DisplayMode.y (*4) data
+ // now do a 2xSai blit to pSaIBigBuff
+
+ p2XSaIFunc((unsigned char *)pSaISmallBuff, 1024,
+ (unsigned char *)pSaIBigBuff,
+ PreviousPSXDisplay.DisplayMode.x,
+ PreviousPSXDisplay.DisplayMode.y);
+
+ // ok, here we have pSaIBigBuff filled with the 2xSai image...
+ // now transfer it to the surface
+
+ dx=(short)(PreviousPSXDisplay.DisplayMode.x * 1.5);
+ dy=(short)PreviousPSXDisplay.DisplayMode.y*3;
+ off1=(ddsd.lPitch>>2)-dx;
+ off2=512-dx;
+
+ pS1=(unsigned long *)surf;
+ pS2=(unsigned long *)pSaIBigBuff;
+
+ for(column=0;column<dy;column++)
+ {
+ for(row=0;row<dx;row++)
+ {
+ *(pS1++)=*(pS2++);
+ }
+ pS1+=off1;
+ pS2+=off2;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void BlitScreen15(unsigned char * surf,long x,long y) // BLIT IN 16bit COLOR MODE
+{
+ unsigned long lu;
+ unsigned short row,column;
+ unsigned short dx=(unsigned short)PreviousPSXDisplay.Range.x1;
+ unsigned short dy=(unsigned short)PreviousPSXDisplay.DisplayMode.y;
+
+ if(PreviousPSXDisplay.Range.y0) // centering needed?
+ {
+ surf+=PreviousPSXDisplay.Range.y0*ddsd.lPitch;
+ dy-=PreviousPSXDisplay.Range.y0;
+ }
+
+ if(PSXDisplay.RGB24)
+ {
+ unsigned char * pD;unsigned int startxy;
+
+ surf+=PreviousPSXDisplay.Range.x0<<1;
+
+ if(iFPSEInterface)
+ {
+ for(column=0;column<dy;column++)
+ {
+ startxy=((1024)*(column+y))+x;
+
+ pD=(unsigned char *)&psxVuw[startxy];
+
+ for(row=0;row<dx;row++)
+ {
+ lu=*((unsigned long *)pD);
+ *((unsigned short *)((surf)+(column*ddsd.lPitch)+(row<<1)))=
+ (unsigned short)
+ (((BLUE(lu)<<7)&0x7c00)|
+ ((GREEN(lu)<<2)&0x3e0)|
+ (RED(lu)>>3));
+ pD+=3;
+ }
+ }
+ }
+ else
+ {
+ for(column=0;column<dy;column++)
+ {
+ startxy=((1024)*(column+y))+x;
+
+ pD=(unsigned char *)&psxVuw[startxy];
+
+ for(row=0;row<dx;row++)
+ {
+ lu=*((unsigned long *)pD);
+ *((unsigned short *)((surf)+(column*ddsd.lPitch)+(row<<1)))=
+ (unsigned short)
+ (((RED(lu)<<7)&0x7c00)|
+ ((GREEN(lu)<<2)&0x3e0)|
+ (BLUE(lu)>>3));
+ pD+=3;
+ }
+ }
+ }
+ }
+ else
+ {
+ unsigned short LineOffset,SurfOffset;
+ unsigned long * SRCPtr = (unsigned long *)(psxVuw +
+ (y<<10) + x);
+
+ unsigned long * DSTPtr =
+ ((unsigned long *)surf)+(PreviousPSXDisplay.Range.x0>>1);
+
+ dx>>=1;
+
+ LineOffset = 512 - dx;
+ SurfOffset = (ddsd.lPitch>>2) - dx;
+
+ for(column=0;column<dy;column++)
+ {
+ for(row=0;row<dx;row++)
+ {
+ lu=*SRCPtr++;
+
+ *DSTPtr++=
+ ((lu<<10)&0x7c007c00)|
+ ((lu)&0x3e003e0)|
+ ((lu>>10)&0x1f001f);
+ }
+ SRCPtr += LineOffset;
+ DSTPtr += SurfOffset;
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void BlitScreen15_2xSaI(unsigned char * surf,long x,long y) // BLIT IN 16bit COLOR MODE
+{
+ unsigned long lu;
+ unsigned short row,column,off1,off2;
+ unsigned short dx=(unsigned short)PreviousPSXDisplay.Range.x1;
+ unsigned short dy=(unsigned short)PreviousPSXDisplay.DisplayMode.y;
+ unsigned char * pS=(unsigned char *)pSaISmallBuff;
+ unsigned long * pS1, * pS2;
+
+ if(PreviousPSXDisplay.DisplayMode.x>512)
+ {BlitScreen15(surf,x,y);return;}
+
+ if(PreviousPSXDisplay.Range.y0) // centering needed?
+ {
+ pS+=PreviousPSXDisplay.Range.y0*1024;
+ dy-=PreviousPSXDisplay.Range.y0;
+ }
+
+ if(PSXDisplay.RGB24)
+ {
+ unsigned char * pD;unsigned int startxy;
+
+ pS+=PreviousPSXDisplay.Range.x0<<1;
+
+ if(iFPSEInterface)
+ {
+ for(column=0;column<dy;column++)
+ {
+ startxy=((1024)*(column+y))+x;
+
+ pD=(unsigned char *)&psxVuw[startxy];
+
+ for(row=0;row<dx;row++)
+ {
+ lu=*((unsigned long *)pD);
+ *((unsigned short *)((pS)+(column*1024)+(row<<1)))=
+ (unsigned short)
+ (((BLUE(lu)<<7)&0x7c00)|
+ ((GREEN(lu)<<2)&0x3e0)|
+ (RED(lu)>>3));
+ pD+=3;
+ }
+ }
+ }
+ else
+ {
+ for(column=0;column<dy;column++)
+ {
+ startxy=((1024)*(column+y))+x;
+
+ pD=(unsigned char *)&psxVuw[startxy];
+
+ for(row=0;row<dx;row++)
+ {
+ lu=*((unsigned long *)pD);
+ *((unsigned short *)((pS)+(column*1024)+(row<<1)))=
+ (unsigned short)
+ (((RED(lu)<<7)&0x7c00)|
+ ((GREEN(lu)<<2)&0x3e0)|
+ (BLUE(lu)>>3));
+ pD+=3;
+ }
+ }
+ }
+ }
+ else
+ {
+ unsigned short LineOffset,SurfOffset;
+ unsigned long * SRCPtr = (unsigned long *)(psxVuw +
+ (y<<10) + x);
+ unsigned long * DSTPtr =
+ ((unsigned long *)pS)+(PreviousPSXDisplay.Range.x0>>1);
+
+ dx>>=1;
+
+ LineOffset = 512 - dx;
+ SurfOffset = 256 - dx;
+
+ for(column=0;column<dy;column++)
+ {
+ for(row=0;row<dx;row++)
+ {
+ lu=*SRCPtr++;
+
+ *DSTPtr++=
+ ((lu<<10)&0x7c007c00)|
+ ((lu)&0x3e003e0)|
+ ((lu>>10)&0x1f001f);
+ }
+ SRCPtr += LineOffset;
+ DSTPtr += SurfOffset;
+ }
+ }
+
+ // ok, here we have filled pSaISmallBuff with PreviousPSXDisplay.DisplayMode.x * PreviousPSXDisplay.DisplayMode.y (*4) data
+ // now do a 2xSai blit to pSaIBigBuff
+
+ p2XSaIFunc((unsigned char *)pSaISmallBuff, 1024,
+ (unsigned char *)pSaIBigBuff,
+ PreviousPSXDisplay.DisplayMode.x,
+ PreviousPSXDisplay.DisplayMode.y);
+
+ // ok, here we have pSaIBigBuff filled with the 2xSai image...
+ // now transfer it to the surface
+
+ dx=(short)PreviousPSXDisplay.DisplayMode.x;
+ dy=(short)PreviousPSXDisplay.DisplayMode.y<<1;
+ off1=(ddsd.lPitch>>2)-dx;
+ off2=512-dx;
+
+ pS1=(unsigned long *)surf;
+ pS2=(unsigned long *)pSaIBigBuff;
+
+ for(column=0;column<dy;column++)
+ {
+ for(row=0;row<dx;row++)
+ {
+ *(pS1++)=*(pS2++);
+ }
+ pS1+=off1;
+ pS2+=off2;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void DoClearScreenBuffer(void) // CLEAR DX BUFFER
+{
+ DDBLTFX ddbltfx;
+
+ ddbltfx.dwSize = sizeof(ddbltfx);
+ ddbltfx.dwFillColor = 0x00000000;
+
+ IDirectDrawSurface_Blt(DX.DDSRender,NULL,NULL,NULL,DDBLT_COLORFILL,&ddbltfx);
+
+ if(iUseNoStretchBlt>=3)
+ {
+ if(pSaISmallBuff) memset(pSaISmallBuff,0,512*512*4);
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void DoClearFrontBuffer(void) // CLEAR PRIMARY BUFFER
+{
+ DDBLTFX ddbltfx;
+
+ ddbltfx.dwSize = sizeof(ddbltfx);
+ ddbltfx.dwFillColor = 0x00000000;
+
+ IDirectDrawSurface_Blt(DX.DDSPrimary,NULL,NULL,NULL,DDBLT_COLORFILL,&ddbltfx);
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void NoStretchedBlit(void)
+{
+ static int iOldDX=0;
+ static int iOldDY=0;
+
+ int iDX,iDY;
+ int iX=iResX-PreviousPSXDisplay.DisplayMode.x;
+ int iY=iResY-PreviousPSXDisplay.DisplayMode.y;
+
+/*
+float fXS,fYS,fS;
+fXS=(float)iResX/(float)PreviousPSXDisplay.DisplayMode.x;
+fYS=(float)iResY/(float)PreviousPSXDisplay.DisplayMode.y;
+if(fXS<fYS) fS=fXS; else fS=fYS;
+*/
+
+ if(iX<0) {iX=0;iDX=iResX;}
+ else {iX=iX/2;iDX=PreviousPSXDisplay.DisplayMode.x;}
+
+ if(iY<0) {iY=0;iDY=iResY;}
+ else {iY=iY/2;iDY=PreviousPSXDisplay.DisplayMode.y;}
+
+ if(iOldDX!=iDX || iOldDY!=iDY)
+ {
+ DDBLTFX ddbltfx;
+ ddbltfx.dwSize = sizeof(ddbltfx);
+ ddbltfx.dwFillColor = 0x00000000;
+ IDirectDrawSurface_Blt(DX.DDSPrimary,NULL,NULL,NULL,DDBLT_COLORFILL,&ddbltfx);
+ iOldDX=iDX;iOldDY=iDY;
+ }
+
+ if(iWindowMode)
+ {
+ RECT ScreenRect,ViewportRect;
+ POINT Point={0,0};
+ ClientToScreen(DX.hWnd,&Point);
+ Point.x+=iX;Point.y+=iY;
+
+ ScreenRect.left = Point.x;
+ ScreenRect.top = Point.y;
+ ScreenRect.right = iDX+Point.x;
+ ScreenRect.bottom = iDY+Point.y;
+
+ ViewportRect.left = 0;
+ ViewportRect.top = 0;
+ ViewportRect.right = iDX;
+ ViewportRect.bottom = iDY;
+
+ WaitVBlank();
+ IDirectDrawSurface_Blt(DX.DDSPrimary,&ScreenRect,DX.DDSRender,&ViewportRect,
+ DDBLT_WAIT,NULL);
+ }
+ else
+ {
+ RECT ScreenRect,ViewportRect;
+
+ ScreenRect.left = iX;
+ ScreenRect.top = iY;
+ ScreenRect.right = iDX+iX;
+ ScreenRect.bottom = iDY+iY;
+
+ ViewportRect.left = 0;
+ ViewportRect.top = 0;
+ ViewportRect.right = iDX;
+ ViewportRect.bottom = iDY;
+
+ WaitVBlank();
+ IDirectDrawSurface_Blt(DX.DDSPrimary,&ScreenRect,DX.DDSRender,&ViewportRect,
+ DDBLT_WAIT,NULL);
+ }
+ if(DX.DDSScreenPic) DisplayPic();
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void NoStretchedBlitEx(void)
+{
+ static int iOldDX=0;
+ static int iOldDY=0;
+
+ int iDX,iDY,iX,iY;float fXS,fYS,fS;
+
+ if(!PreviousPSXDisplay.DisplayMode.x) return;
+ if(!PreviousPSXDisplay.DisplayMode.y) return;
+
+ fXS=(float)iResX/(float)PreviousPSXDisplay.DisplayMode.x;
+ fYS=(float)iResY/(float)PreviousPSXDisplay.DisplayMode.y;
+ if(fXS<fYS) fS=fXS; else fS=fYS;
+
+ iDX=(int)(PreviousPSXDisplay.DisplayMode.x*fS);
+ iDY=(int)(PreviousPSXDisplay.DisplayMode.y*fS);
+
+ iX=iResX-iDX;
+ iY=iResY-iDY;
+
+ if(iX<0) iX=0;
+ else iX=iX/2;
+
+ if(iY<0) iY=0;
+ else iY=iY/2;
+
+ if(iOldDX!=iDX || iOldDY!=iDY)
+ {
+ DDBLTFX ddbltfx;
+ ddbltfx.dwSize = sizeof(ddbltfx);
+ ddbltfx.dwFillColor = 0x00000000;
+ IDirectDrawSurface_Blt(DX.DDSPrimary,NULL,NULL,NULL,DDBLT_COLORFILL,&ddbltfx);
+ iOldDX=iDX;iOldDY=iDY;
+ }
+
+ if(iWindowMode)
+ {
+ RECT ScreenRect,ViewportRect;
+ POINT Point={0,0};
+ ClientToScreen(DX.hWnd,&Point);
+ Point.x+=iX;Point.y+=iY;
+
+ ScreenRect.left = Point.x;
+ ScreenRect.top = Point.y;
+ ScreenRect.right = iDX+Point.x;
+ ScreenRect.bottom = iDY+Point.y;
+
+ ViewportRect.left = 0;
+ ViewportRect.top = 0;
+ ViewportRect.right = PreviousPSXDisplay.DisplayMode.x;
+ ViewportRect.bottom = PreviousPSXDisplay.DisplayMode.y;
+
+ WaitVBlank();
+ IDirectDrawSurface_Blt(DX.DDSPrimary,&ScreenRect,DX.DDSRender,&ViewportRect,
+ DDBLT_WAIT,NULL);
+ }
+ else
+ {
+ RECT ScreenRect,ViewportRect;
+
+ ScreenRect.left = iX;
+ ScreenRect.top = iY;
+ ScreenRect.right = iDX+iX;
+ ScreenRect.bottom = iDY+iY;
+
+ ViewportRect.left = 0;
+ ViewportRect.top = 0;
+ ViewportRect.right = PreviousPSXDisplay.DisplayMode.x;
+ ViewportRect.bottom = PreviousPSXDisplay.DisplayMode.y;
+
+ WaitVBlank();
+ IDirectDrawSurface_Blt(DX.DDSPrimary,&ScreenRect,DX.DDSRender,&ViewportRect,
+ DDBLT_WAIT,NULL);
+ }
+ if(DX.DDSScreenPic) DisplayPic();
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void StretchedBlit2x(void)
+{
+ if(iWindowMode)
+ {
+ RECT ScreenRect,ViewportRect;
+ POINT Point={0,0};
+ ClientToScreen(DX.hWnd,&Point);
+
+ ScreenRect.left = Point.x;
+ ScreenRect.top = Point.y;
+ ScreenRect.right = iResX+Point.x;
+ ScreenRect.bottom = iResY+Point.y;
+
+ ViewportRect.left = 0;
+ ViewportRect.top = 0;
+ ViewportRect.right = PreviousPSXDisplay.DisplayMode.x;
+ ViewportRect.bottom = PreviousPSXDisplay.DisplayMode.y;
+
+ if(ViewportRect.right<=512)
+ {
+ ViewportRect.right+=ViewportRect.right;
+ ViewportRect.bottom+=ViewportRect.bottom;
+ }
+
+ if(iUseScanLines==2) // stupid nvidia scanline mode
+ {
+ RECT HelperRect={0,0,iResX,iResY};
+
+ WaitVBlank();
+
+ IDirectDrawSurface_Blt(DX.DDSHelper,&HelperRect,DX.DDSRender,&ViewportRect,
+ DDBLT_WAIT,NULL);
+ IDirectDrawSurface_Blt(DX.DDSPrimary,&ScreenRect,DX.DDSHelper,&HelperRect,
+ DDBLT_WAIT,NULL);
+ }
+ else
+ {
+ WaitVBlank();
+ IDirectDrawSurface_Blt(DX.DDSPrimary,&ScreenRect,DX.DDSRender,&ViewportRect,
+ DDBLT_WAIT,NULL);
+ }
+ }
+ else
+ {
+ RECT ScreenRect={0,0,iResX,iResY},
+ ViewportRect={0,0,PreviousPSXDisplay.DisplayMode.x,
+ PreviousPSXDisplay.DisplayMode.y};
+
+ if(ViewportRect.right<=512)
+ {
+ ViewportRect.right+=ViewportRect.right;
+ ViewportRect.bottom+=ViewportRect.bottom;
+ }
+
+ if(iUseScanLines==2) // stupid nvidia scanline mode
+ {
+ WaitVBlank();
+
+ IDirectDrawSurface_Blt(DX.DDSHelper,&ScreenRect,DX.DDSRender,&ViewportRect,
+ DDBLT_WAIT,NULL);
+ IDirectDrawSurface_Blt(DX.DDSPrimary,&ScreenRect,DX.DDSHelper,&ScreenRect,
+ DDBLT_WAIT,NULL);
+ }
+ else
+ {
+ WaitVBlank();
+ IDirectDrawSurface_Blt(DX.DDSPrimary,&ScreenRect,DX.DDSRender,&ViewportRect,
+ DDBLT_WAIT,NULL );
+ }
+ }
+
+ if(DX.DDSScreenPic) DisplayPic();
+
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void NoStretchedBlit2x(void)
+{
+ static int iOldDX=0;
+ static int iOldDY=0;
+
+ int iX,iY,iDX,iDY;
+ int iDX2=PreviousPSXDisplay.DisplayMode.x;
+ int iDY2=PreviousPSXDisplay.DisplayMode.y;
+ if(PreviousPSXDisplay.DisplayMode.x<=512)
+ {
+ iDX2<<=1;
+ iDY2<<=1;
+ }
+
+ iX=iResX-iDX2;
+ iY=iResY-iDY2;
+
+ if(iX<0) {iX=0;iDX=iResX;}
+ else {iX=iX/2;iDX=iDX2;}
+
+ if(iY<0) {iY=0;iDY=iResY;}
+ else {iY=iY/2;iDY=iDY2;}
+
+ if(iOldDX!=iDX || iOldDY!=iDY)
+ {
+ DDBLTFX ddbltfx;
+ ddbltfx.dwSize = sizeof(ddbltfx);
+ ddbltfx.dwFillColor = 0x00000000;
+ IDirectDrawSurface_Blt(DX.DDSPrimary,NULL,NULL,NULL,DDBLT_COLORFILL,&ddbltfx);
+ iOldDX=iDX;iOldDY=iDY;
+ }
+
+ if(iWindowMode)
+ {
+ RECT ScreenRect,ViewportRect;
+ POINT Point={0,0};
+ ClientToScreen(DX.hWnd,&Point);
+ Point.x+=iX;Point.y+=iY;
+
+ ScreenRect.left = Point.x;
+ ScreenRect.top = Point.y;
+ ScreenRect.right = iDX+Point.x;
+ ScreenRect.bottom = iDY+Point.y;
+
+ ViewportRect.left = 0;
+ ViewportRect.top = 0;
+ ViewportRect.right = iDX;
+ ViewportRect.bottom = iDY;
+
+ WaitVBlank();
+ IDirectDrawSurface_Blt(DX.DDSPrimary,&ScreenRect,DX.DDSRender,&ViewportRect,
+ DDBLT_WAIT,NULL);
+ }
+ else
+ {
+ RECT ScreenRect,ViewportRect;
+
+ ScreenRect.left = iX;
+ ScreenRect.top = iY;
+ ScreenRect.right = iDX+iX;
+ ScreenRect.bottom = iDY+iY;
+
+ ViewportRect.left = 0;
+ ViewportRect.top = 0;
+ ViewportRect.right = iDX;
+ ViewportRect.bottom = iDY;
+
+ WaitVBlank();
+ IDirectDrawSurface_Blt(DX.DDSPrimary,&ScreenRect,DX.DDSRender,&ViewportRect,
+ DDBLT_WAIT,NULL);
+ }
+ if(DX.DDSScreenPic) DisplayPic();
+}
+
+////////////////////////////////////////////////////////////////////////
+void NoStretchedBlit3x(void)
+{
+ static int iOldDX=0;
+ static int iOldDY=0;
+
+ int iX,iY,iDX,iDY;
+ int iDX2=PreviousPSXDisplay.DisplayMode.x;
+ int iDY2=PreviousPSXDisplay.DisplayMode.y;
+
+ if(PreviousPSXDisplay.DisplayMode.x<=512)
+ {
+ iDX2*=3;
+ iDY2*=3;
+ }
+
+ iX=iResX-iDX2;
+ iY=iResY-iDY2;
+
+ if(iX<0) {iX=0;iDX=iResX;}
+ else {iX=iX/2;iDX=iDX2;}
+
+ if(iY<0) {iY=0;iDY=iResY;}
+ else {iY=iY/2;iDY=iDY2;}
+
+ if(iOldDX!=iDX || iOldDY!=iDY)
+ {
+ DDBLTFX ddbltfx;
+ ddbltfx.dwSize = sizeof(ddbltfx);
+ ddbltfx.dwFillColor = 0x00000000;
+ IDirectDrawSurface_Blt(DX.DDSPrimary,NULL,NULL,NULL,DDBLT_COLORFILL,&ddbltfx);
+ iOldDX=iDX;iOldDY=iDY;
+ }
+
+ if(iWindowMode)
+ {
+ RECT ScreenRect,ViewportRect;
+ POINT Point={0,0};
+ ClientToScreen(DX.hWnd,&Point);
+ Point.x+=iX;Point.y+=iY;
+
+ ScreenRect.left = Point.x;
+ ScreenRect.top = Point.y;
+ ScreenRect.right = iDX+Point.x;
+ ScreenRect.bottom = iDY+Point.y;
+
+ ViewportRect.left = 0;
+ ViewportRect.top = 0;
+ ViewportRect.right = iDX;
+ ViewportRect.bottom = iDY;
+
+ WaitVBlank();
+ IDirectDrawSurface_Blt(DX.DDSPrimary,&ScreenRect,DX.DDSRender,&ViewportRect,
+ DDBLT_WAIT,NULL);
+ }
+ else
+ {
+ RECT ScreenRect,ViewportRect;
+
+ ScreenRect.left = iX;
+ ScreenRect.top = iY;
+ ScreenRect.right = iDX+iX;
+ ScreenRect.bottom = iDY+iY;
+
+ ViewportRect.left = 0;
+ ViewportRect.top = 0;
+ ViewportRect.right = iDX;
+ ViewportRect.bottom = iDY;
+
+ WaitVBlank();
+ IDirectDrawSurface_Blt(DX.DDSPrimary,&ScreenRect,DX.DDSRender,&ViewportRect,
+ DDBLT_WAIT,NULL);
+ }
+ if(DX.DDSScreenPic) DisplayPic();
+}
+
+
+////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+
+void ShowGunCursor(unsigned char * surf)
+{
+ unsigned short dx=(unsigned short)PreviousPSXDisplay.Range.x1;
+ unsigned short dy=(unsigned short)PreviousPSXDisplay.DisplayMode.y;
+ int x,y,iPlayer,sx,ex,sy,ey;
+
+ if(PreviousPSXDisplay.Range.y0) // centering needed?
+ {
+ surf+=PreviousPSXDisplay.Range.y0*ddsd.lPitch;
+ dy-=PreviousPSXDisplay.Range.y0;
+ }
+
+ if(iUseNoStretchBlt>=3 &&iUseNoStretchBlt < 13) // 2xsai is twice as big, of course
+ {dx*=2;dy*=2;}
+ else if(iUseNoStretchBlt >= 13)
+ {dx*=3;dy*=3;}
+
+ if(iDesktopCol==32) // 32 bit color depth
+ {
+ const unsigned long crCursorColor32[8]={0xffff0000,0xff00ff00,0xff0000ff,0xffff00ff,0xffffff00,0xff00ffff,0xffffffff,0xff7f7f7f};
+
+ surf+=PreviousPSXDisplay.Range.x0<<2; // -> add x left border
+
+ for(iPlayer=0;iPlayer<8;iPlayer++) // -> loop all possible players
+ {
+ if(usCursorActive&(1<<iPlayer)) // -> player active?
+ {
+ const int ty=(ptCursorPoint[iPlayer].y*dy)/256; // -> calculate the cursor pos in the current display
+ const int tx=(ptCursorPoint[iPlayer].x*dx)/512;
+ sx=tx-5;if(sx<0) {if(sx&1) sx=1; else sx=0;}
+ sy=ty-5;if(sy<0) {if(sy&1) sy=1; else sy=0;}
+ ex=tx+6;if(ex>dx) ex=dx;
+ ey=ty+6;if(ey>dy) ey=dy;
+
+ for(x=tx,y=sy;y<ey;y+=2) // -> do dotted y line
+ *((unsigned long *)((surf)+(y*ddsd.lPitch)+x*4))=crCursorColor32[iPlayer];
+ for(y=ty,x=sx;x<ex;x+=2) // -> do dotted x line
+ *((unsigned long *)((surf)+(y*ddsd.lPitch)+x*4))=crCursorColor32[iPlayer];
+ }
+ }
+ }
+ else // 16 bit color depth
+ {
+ const unsigned short crCursorColor16[8]={0xf800,0x07c0,0x001f,0xf81f,0xffc0,0x07ff,0xffff,0x7bdf};
+
+ surf+=PreviousPSXDisplay.Range.x0<<1; // -> same stuff as above
+
+ for(iPlayer=0;iPlayer<8;iPlayer++)
+ {
+ if(usCursorActive&(1<<iPlayer))
+ {
+ const int ty=(ptCursorPoint[iPlayer].y*dy)/256;
+ const int tx=(ptCursorPoint[iPlayer].x*dx)/512;
+ sx=tx-5;if(sx<0) {if(sx&1) sx=1; else sx=0;}
+ sy=ty-5;if(sy<0) {if(sy&1) sy=1; else sy=0;}
+ ex=tx+6;if(ex>dx) ex=dx;
+ ey=ty+6;if(ey>dy) ey=dy;
+
+ for(x=tx,y=sy;y<ey;y+=2)
+ *((unsigned short *)((surf)+(y*ddsd.lPitch)+x*2))=crCursorColor16[iPlayer];
+ for(y=ty,x=sx;x<ex;x+=2)
+ *((unsigned short *)((surf)+(y*ddsd.lPitch)+x*2))=crCursorColor16[iPlayer];
+ }
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void DoBufferSwap(void) // SWAP BUFFERS
+{ // (we don't swap... we blit only)
+ HRESULT ddrval;long x,y;
+
+ ddrval=IDirectDrawSurface_Lock(DX.DDSRender,NULL, &ddsd, DDLOCK_WAIT|DDLOCK_WRITEONLY, NULL);
+
+ if(ddrval==DDERR_SURFACELOST)
+ {
+ IDirectDrawSurface_Restore(DX.DDSRender);
+ }
+
+ if(ddrval!=DD_OK)
+ {
+ IDirectDrawSurface_Unlock(DX.DDSRender,&ddsd);
+ return;
+ }
+
+ //----------------------------------------------------//
+
+ x=PSXDisplay.DisplayPosition.x;
+ y=PSXDisplay.DisplayPosition.y;
+
+ //----------------------------------------------------//
+
+ BlitScreen((unsigned char *)ddsd.lpSurface,x,y); // fill DDSRender surface
+
+ if(usCursorActive) ShowGunCursor((unsigned char *)ddsd.lpSurface);
+
+ IDirectDrawSurface_Unlock(DX.DDSRender,&ddsd);
+
+ if(ulKeybits&KEY_SHOWFPS) DisplayText(); // paint menu text
+
+ if(pExtraBltFunc) {pExtraBltFunc();return;}
+
+ if(iWindowMode)
+ {
+ RECT ScreenRect,ViewportRect;
+ POINT Point={0,0};
+ ClientToScreen(DX.hWnd,&Point);
+
+ ScreenRect.left = Point.x;
+ ScreenRect.top = Point.y;
+ ScreenRect.right = iResX+Point.x;
+ ScreenRect.bottom = iResY+Point.y;
+
+ ViewportRect.left = 0;
+ ViewportRect.top = 0;
+
+ if(iDebugMode)
+ {
+ if(iFVDisplay)
+ {
+ ViewportRect.right = 1024;
+ ViewportRect.bottom = iGPUHeight;
+ }
+ else
+ {
+ ViewportRect.right = PreviousPSXDisplay.DisplayMode.x;
+ ViewportRect.bottom = PreviousPSXDisplay.DisplayMode.y;
+ }
+ }
+ else
+ {
+ ViewportRect.right = PreviousPSXDisplay.DisplayMode.x;
+ ViewportRect.bottom = PreviousPSXDisplay.DisplayMode.y;
+ }
+
+ if(iUseScanLines==2) // stupid nvidia scanline mode
+ {
+ RECT HelperRect={0,0,iResX,iResY};
+
+ WaitVBlank();
+
+ IDirectDrawSurface_Blt(DX.DDSHelper,&HelperRect,DX.DDSRender,&ViewportRect,
+ DDBLT_WAIT,NULL);
+ IDirectDrawSurface_Blt(DX.DDSPrimary,&ScreenRect,DX.DDSHelper,&HelperRect,
+ DDBLT_WAIT,NULL);
+ }
+ else
+ {
+ WaitVBlank();
+ IDirectDrawSurface_Blt(DX.DDSPrimary,&ScreenRect,DX.DDSRender,&ViewportRect,
+ DDBLT_WAIT,NULL);
+ }
+ }
+ else
+ {
+ RECT ScreenRect={0,0,iResX,iResY},
+ ViewportRect={0,0,PreviousPSXDisplay.DisplayMode.x,
+ PreviousPSXDisplay.DisplayMode.y};
+
+ if(iDebugMode && iFVDisplay)
+ {
+ ViewportRect.right=1024;
+ ViewportRect.bottom=iGPUHeight;
+ }
+
+ if(iUseScanLines==2) // stupid nvidia scanline mode
+ {
+ WaitVBlank();
+
+ IDirectDrawSurface_Blt(DX.DDSHelper,&ScreenRect,DX.DDSRender,&ViewportRect,
+ DDBLT_WAIT,NULL);
+ IDirectDrawSurface_Blt(DX.DDSPrimary,&ScreenRect,DX.DDSHelper,&ScreenRect,
+ DDBLT_WAIT,NULL);
+ }
+ else
+ {
+ WaitVBlank();
+ IDirectDrawSurface_Blt(DX.DDSPrimary,&ScreenRect,DX.DDSRender,&ViewportRect,
+ DDBLT_WAIT,NULL );
+ }
+ }
+
+ if(DX.DDSScreenPic) DisplayPic();
+}
+
+////////////////////////////////////////////////////////////////////////
+// GAMMA
+////////////////////////////////////////////////////////////////////////
+
+int iUseGammaVal=2048;
+
+void DXSetGamma(void)
+{
+ float g;
+ if(iUseGammaVal==2048) return;
+
+ g=(float)iUseGammaVal;
+ if(g>512) g=((g-512)*2)+512;
+ g=0.5f+((g)/1024.0f);
+
+// some cards will cheat... so we don't trust the caps here
+// if (DD_Caps.dwCaps2 & DDCAPS2_PRIMARYGAMMA)
+ {
+ float f;DDGAMMARAMP ramp;int i;
+ LPDIRECTDRAWGAMMACONTROL DD_Gamma = NULL;
+
+ if FAILED(IDirectDrawSurface_QueryInterface(DX.DDSPrimary,&IID_IDirectDrawGammaControl,(void**)&DD_Gamma))
+ return;
+
+ for (i=0;i<256;i++)
+ {
+ f=(((float)(i*256))*g);
+ if(f>65535) f=65535;
+ ramp.red[i]=ramp.green[i]=ramp.blue[i]=(WORD)f;
+ }
+
+ IDirectDrawGammaControl_SetGammaRamp(DD_Gamma,0,&ramp);
+ IDirectDrawGammaControl_Release(DD_Gamma);
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+// SCAN LINE STUFF
+////////////////////////////////////////////////////////////////////////
+
+void SetScanLineList(LPDIRECTDRAWCLIPPER Clipper)
+{
+ LPRGNDATA lpCL;RECT * pr;int y;POINT Point={0,0};
+
+ IDirectDrawClipper_SetClipList(Clipper,NULL,0);
+
+ lpCL=(LPRGNDATA)malloc(sizeof(RGNDATAHEADER)+((iResY/2)+1)*sizeof(RECT));
+ if(iWindowMode) ClientToScreen(DX.hWnd,&Point);
+
+ lpCL->rdh.dwSize=sizeof(RGNDATAHEADER);
+ lpCL->rdh.iType=RDH_RECTANGLES;
+ lpCL->rdh.nCount=iResY/2;
+ lpCL->rdh.nRgnSize=0;
+ lpCL->rdh.rcBound.left=Point.x;
+ lpCL->rdh.rcBound.top=Point.y;
+ lpCL->rdh.rcBound.bottom=Point.y+iResY;
+ lpCL->rdh.rcBound.right=Point.x+iResX;
+
+ pr=(RECT *)lpCL->Buffer;
+ for(y=0;y<iResY;y+=2)
+ {
+ pr->left=Point.x;
+ pr->top=Point.y+y;
+ pr->right=Point.x+iResX;
+ pr->bottom=Point.y+y+1;
+ pr++;
+ }
+
+ IDirectDrawClipper_SetClipList(Clipper,lpCL,0);
+
+ free(lpCL);
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void MoveScanLineArea(HWND hwnd)
+{
+ LPDIRECTDRAWCLIPPER Clipper;HRESULT h;
+ DDBLTFX ddbltfx;RECT r;
+
+ if(FAILED(h=IDirectDraw_CreateClipper(DX.DD,0,&Clipper,NULL)))
+ return;
+
+ IDirectDrawSurface_SetClipper(DX.DDSPrimary,NULL);
+
+ ddbltfx.dwSize = sizeof(ddbltfx);
+ ddbltfx.dwFillColor = 0x00000000;
+
+ GetClientRect(hwnd,&r);
+ ClientToScreen(hwnd,(LPPOINT)&r.left);
+ r.right+=r.left;
+ r.bottom+=r.top;
+
+ IDirectDrawSurface_Blt(DX.DDSPrimary,&r,NULL,NULL,DDBLT_COLORFILL,&ddbltfx);
+
+ SetScanLineList(Clipper);
+
+ IDirectDrawSurface_SetClipper(DX.DDSPrimary,Clipper);
+ IDirectDrawClipper_Release(Clipper);
+}
+
+////////////////////////////////////////////////////////////////////////
+// MAIN DIRECT DRAW INIT
+////////////////////////////////////////////////////////////////////////
+
+BOOL ReStart=FALSE;
+
+int DXinitialize()
+{
+ LPDIRECTDRAW DD;int i;
+ LPDIRECTDRAWCLIPPER Clipper;HRESULT h;
+ GUID FAR * guid=0;
+ unsigned char * c;
+ DDSCAPS ddscaps;
+ DDBLTFX ddbltfx;
+ DDPIXELFORMAT dd;
+
+ // init some DX vars
+ DX.hWnd = (HWND)hWGPU;
+ DX.DDSHelper=0;
+ DX.DDSScreenPic=0;
+
+ // make guid !
+ c=(unsigned char *)&guiDev;
+ for(i=0;i<sizeof(GUID);i++,c++)
+ {if(*c) {guid=&guiDev;break;}}
+
+ // create dd
+ if(DirectDrawCreate(guid,&DD,0))
+ {
+ MessageBox(NULL, "This GPU requires DirectX!", "Error", MB_OK);
+ return 0;
+ }
+
+ DX.DD=DD;
+
+ //////////////////////////////////////////////////////// co-op level
+
+ if(iWindowMode) // win mode?
+ {
+ if(IDirectDraw_SetCooperativeLevel(DX.DD,DX.hWnd,DDSCL_NORMAL))
+ return 0;
+ }
+ else
+ {
+ if(ReStart)
+ {
+ if(IDirectDraw_SetCooperativeLevel(DX.DD,DX.hWnd, DDSCL_NORMAL | DDSCL_FULLSCREEN | DDSCL_FPUSETUP))
+ return 0;
+ }
+ else
+ {
+ if(IDirectDraw_SetCooperativeLevel(DX.DD,DX.hWnd, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN | DDSCL_FPUSETUP))
+ return 0;
+ }
+
+ if(iRefreshRate)
+ {
+ LPDIRECTDRAW2 DD2;
+ IDirectDraw_QueryInterface(DX.DD,&IID_IDirectDraw2,(LPVOID *)&DD2);
+ if(IDirectDraw2_SetDisplayMode(DD2,iResX,iResY,iColDepth,iRefreshRate,0))
+ return 0;
+ }
+ else
+ {
+ if(IDirectDraw_SetDisplayMode(DX.DD,iResX,iResY,iColDepth))
+ return 0;
+ }
+ }
+
+ //////////////////////////////////////////////////////// main surfaces
+
+ memset(&ddsd, 0, sizeof(DDSURFACEDESC));
+ memset(&ddscaps, 0, sizeof(DDSCAPS));
+ ddsd.dwSize = sizeof(DDSURFACEDESC);
+
+ ddsd.dwFlags = DDSD_CAPS; // front buffer
+
+ if(iSysMemory)
+ ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_SYSTEMMEMORY;
+ else
+ ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_VIDEOMEMORY;
+
+ //ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;//|DDSCAPS_VIDEOMEMORY;
+ if(IDirectDraw_CreateSurface(DX.DD,&ddsd, &DX.DDSPrimary, NULL))
+ return 0;
+
+ //----------------------------------------------------//
+ if(iSysMemory && iUseScanLines==2) iUseScanLines=1; // pete: nvidia hack not needed on system mem
+
+ if(iUseScanLines==2) // special nvidia hack
+ {
+ memset(&ddsd, 0, sizeof(DDSURFACEDESC));
+ ddsd.dwSize = sizeof(DDSURFACEDESC);
+ ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS;
+ ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
+ ddsd.dwWidth = iResX;
+ ddsd.dwHeight = iResY;
+
+ if(IDirectDraw_CreateSurface(DX.DD,&ddsd, &DX.DDSHelper, NULL))
+ return 0;
+ }
+ //----------------------------------------------------//
+
+ memset(&ddsd, 0, sizeof(DDSURFACEDESC)); // back buffer
+ ddsd.dwSize = sizeof(DDSURFACEDESC);
+ ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS;
+// ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;//|DDSCAPS_VIDEOMEMORY;
+ if(iSysMemory)
+ ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;
+ else
+ ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY;
+
+ if(iDebugMode || iUseNoStretchBlt>=3)
+ ddsd.dwWidth = 1024;
+ else ddsd.dwWidth = 640;
+
+ if(iUseNoStretchBlt>=3)
+ ddsd.dwHeight = 1024;
+ else
+ {
+ if(iDebugMode) ddsd.dwHeight = iGPUHeight;
+ else ddsd.dwHeight = 512;
+ }
+
+ if(IDirectDraw_CreateSurface(DX.DD,&ddsd, &DX.DDSRender, NULL))
+ return 0;
+
+ // check for desktop color depth
+ dd.dwSize=sizeof(DDPIXELFORMAT);
+ IDirectDrawSurface_GetPixelFormat(DX.DDSRender,&dd);
+
+ if(dd.dwRBitMask==0x00007c00 &&
+ dd.dwGBitMask==0x000003e0 &&
+ dd.dwBBitMask==0x0000001f)
+ {
+ if(iUseNoStretchBlt>=3)
+ BlitScreen=BlitScreen15_2xSaI;
+ else BlitScreen=BlitScreen15;
+ iDesktopCol=15;
+ }
+ else
+ if(dd.dwRBitMask==0x0000f800 &&
+ dd.dwGBitMask==0x000007e0 &&
+ dd.dwBBitMask==0x0000001f)
+ {
+ if(iUseNoStretchBlt < 4)
+ BlitScreen = BlitScreen16;
+ else if(iUseNoStretchBlt < 13)
+ BlitScreen = BlitScreen16_2xSaI;
+ else
+ BlitScreen = BlitScreen16_3xSaI;
+ iDesktopCol=16;
+ }
+ else
+ {
+ if(iUseNoStretchBlt < 4)
+ BlitScreen = BlitScreen32;
+ else if(iUseNoStretchBlt < 13)
+ BlitScreen = BlitScreen32_2xSaI;
+ else
+ BlitScreen = BlitScreen32_3xSaI;
+ iDesktopCol=32;
+ }
+
+ //////////////////////////////////////////////////////// extra blts
+
+ switch(iUseNoStretchBlt)
+ {
+ case 1:
+ pExtraBltFunc=NoStretchedBlit;
+ p2XSaIFunc=NULL;
+ break;
+ case 2:
+ pExtraBltFunc=NoStretchedBlitEx;
+ p2XSaIFunc=NULL;
+ break;
+ case 3:
+ pExtraBltFunc=StretchedBlit2x;
+ if (iDesktopCol==15) p2XSaIFunc=Std2xSaI_ex5;
+ else if(iDesktopCol==16) p2XSaIFunc=Std2xSaI_ex6;
+ else p2XSaIFunc=Std2xSaI_ex8;
+ break;
+ case 4:
+ pExtraBltFunc=NoStretchedBlit2x;
+ if (iDesktopCol==15) p2XSaIFunc=Std2xSaI_ex5;
+ else if(iDesktopCol==16) p2XSaIFunc=Std2xSaI_ex6;
+ else p2XSaIFunc=Std2xSaI_ex8;
+ break;
+ case 5:
+ pExtraBltFunc=StretchedBlit2x;
+ if (iDesktopCol==15) p2XSaIFunc=Super2xSaI_ex5;
+ else if(iDesktopCol==16) p2XSaIFunc=Super2xSaI_ex6;
+ else p2XSaIFunc=Super2xSaI_ex8;
+ break;
+ case 6:
+ pExtraBltFunc=NoStretchedBlit2x;
+ if (iDesktopCol==15) p2XSaIFunc=Super2xSaI_ex5;
+ else if(iDesktopCol==16) p2XSaIFunc=Super2xSaI_ex6;
+ else p2XSaIFunc=Super2xSaI_ex8;
+ break;
+ case 7:
+ pExtraBltFunc=StretchedBlit2x;
+ if (iDesktopCol==15) p2XSaIFunc=SuperEagle_ex5;
+ else if(iDesktopCol==16) p2XSaIFunc=SuperEagle_ex6;
+ else p2XSaIFunc=SuperEagle_ex8;
+ break;
+ case 8:
+ pExtraBltFunc=NoStretchedBlit2x;
+ if (iDesktopCol==15) p2XSaIFunc=SuperEagle_ex5;
+ else if(iDesktopCol==16) p2XSaIFunc=SuperEagle_ex6;
+ else p2XSaIFunc=SuperEagle_ex8;
+ break;
+ case 9:
+ pExtraBltFunc=StretchedBlit2x;
+ if (iDesktopCol==15) p2XSaIFunc=Scale2x_ex6_5;
+ else if(iDesktopCol==16) p2XSaIFunc=Scale2x_ex6_5;
+ else p2XSaIFunc=Scale2x_ex8;
+ break;
+ case 10:
+ pExtraBltFunc=NoStretchedBlit2x;
+ if (iDesktopCol==15) p2XSaIFunc=Scale2x_ex6_5;
+ else if(iDesktopCol==16) p2XSaIFunc=Scale2x_ex6_5;
+ else p2XSaIFunc=Scale2x_ex8;
+ break;
+ case 11:
+ pExtraBltFunc=NoStretchedBlit2x;
+ if(iDesktopCol==15) p2XSaIFunc=hq2x;
+ else if(iDesktopCol==16) p2XSaIFunc=hq2x;
+ else p2XSaIFunc=hq2x_32;
+ break;
+ case 12:
+ pExtraBltFunc=StretchedBlit2x;
+ if(iDesktopCol==15) p2XSaIFunc=hq2x;
+ else if(iDesktopCol==16) p2XSaIFunc=hq2x;
+ else p2XSaIFunc=hq2x_32;
+ break;
+ case 13:
+ pExtraBltFunc=StretchedBlit2x;
+ if(iDesktopCol==15) p2XSaIFunc=Scale3x_ex6_5;
+ else if(iDesktopCol==16) p2XSaIFunc=Scale3x_ex6_5;
+ else p2XSaIFunc=Scale3x_ex8;
+ break;
+ case 14:
+ pExtraBltFunc=NoStretchedBlit3x;
+ if(iDesktopCol==15) p2XSaIFunc=Scale3x_ex6_5;
+ else if(iDesktopCol==16) p2XSaIFunc=Scale3x_ex6_5;
+ else p2XSaIFunc=Scale3x_ex8;
+ break;
+ case 15:
+ pExtraBltFunc=NoStretchedBlit3x;
+ if (iDesktopCol==15) p2XSaIFunc=hq3x_16;
+ else if(iDesktopCol==16) p2XSaIFunc=hq3x_16;
+ else p2XSaIFunc=hq3x_32;
+ break;
+ default:
+ pExtraBltFunc=NULL;
+ p2XSaIFunc=NULL;
+ break;
+ }
+
+ //////////////////////////////////////////////////////// clipper init
+
+ if(FAILED(h=IDirectDraw_CreateClipper(DX.DD,0,&Clipper,NULL)))
+ return 0;
+
+ if(iUseScanLines)
+ SetScanLineList(Clipper);
+ else IDirectDrawClipper_SetHWnd(Clipper,0,DX.hWnd);
+
+ IDirectDrawSurface_SetClipper(DX.DDSPrimary,Clipper);
+ IDirectDrawClipper_Release(Clipper);
+
+ //////////////////////////////////////////////////////// small screen clean up
+
+ DXSetGamma();
+
+ ddbltfx.dwSize = sizeof(ddbltfx);
+ ddbltfx.dwFillColor = 0x00000000;
+
+ IDirectDrawSurface_Blt(DX.DDSPrimary,NULL,NULL,NULL,DDBLT_COLORFILL,&ddbltfx);
+ IDirectDrawSurface_Blt(DX.DDSRender,NULL,NULL,NULL,DDBLT_COLORFILL,&ddbltfx);
+
+ //////////////////////////////////////////////////////// finish init
+
+ if(iUseNoStretchBlt>=3)
+ {
+ pSaISmallBuff=malloc(512*512*4);
+ memset(pSaISmallBuff,0,512*512*4);
+ pSaIBigBuff=malloc(1024*1024*4);
+ memset(pSaIBigBuff,0,1024*1024*4);
+ }
+
+ bUsingTWin=FALSE;
+
+ InitMenu(); // menu init
+
+ if(iShowFPS) // fps on startup
+ {
+ ulKeybits|=KEY_SHOWFPS;
+ szDispBuf[0]=0;
+ BuildDispMenu(0);
+ }
+
+ bIsFirstFrame = FALSE; // done
+
+ return 0;
+}
+
+////////////////////////////////////////////////////////////////////////
+// clean up DX stuff
+////////////////////////////////////////////////////////////////////////
+
+void DXcleanup() // DX CLEANUP
+{
+ CloseMenu(); // bye display lists
+
+ if(iUseNoStretchBlt>=3)
+ {
+ if(pSaISmallBuff) free(pSaISmallBuff);
+ pSaISmallBuff=NULL;
+ if(pSaIBigBuff) free(pSaIBigBuff);
+ pSaIBigBuff=NULL;
+ }
+
+ if(!bIsFirstFrame)
+ {
+ if(DX.DDSHelper) IDirectDrawSurface_Release(DX.DDSHelper);
+ DX.DDSHelper=0;
+ if(DX.DDSScreenPic) IDirectDrawSurface_Release(DX.DDSScreenPic);
+ DX.DDSScreenPic=0;
+ IDirectDrawSurface_Release(DX.DDSRender);
+ IDirectDrawSurface_Release(DX.DDSPrimary);
+ IDirectDraw_SetCooperativeLevel(DX.DD,DX.hWnd, DDSCL_NORMAL);
+ IDirectDraw_RestoreDisplayMode(DX.DD);
+ IDirectDraw_Release(DX.DD);
+
+ ReStart=TRUE;
+ bIsFirstFrame = TRUE;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+
+DWORD dwGPUStyle=0; // vars to store some wimdows stuff
+HANDLE hGPUMenu=NULL;
+
+unsigned long ulInitDisplay(void)
+{
+ HDC hdc;RECT r;
+
+ if(iWindowMode) // win mode?
+ {
+ DWORD dw=GetWindowLong(hWGPU, GWL_STYLE); // -> adjust wnd style
+ dwGPUStyle=dw;
+ dw&=~WS_THICKFRAME;
+ dw|=WS_BORDER|WS_CAPTION;
+ SetWindowLong(hWGPU, GWL_STYLE, dw);
+
+ iResX=LOWORD(iWinSize);iResY=HIWORD(iWinSize);
+ ShowWindow(hWGPU,SW_SHOWNORMAL);
+
+ if(iUseScanLines)
+ SetWindowPos(hWGPU,HWND_TOPMOST,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE);
+
+ MoveWindow(hWGPU, // -> move wnd
+ GetSystemMetrics(SM_CXFULLSCREEN)/2-iResX/2,
+ GetSystemMetrics(SM_CYFULLSCREEN)/2-iResY/2,
+ iResX+GetSystemMetrics(SM_CXFIXEDFRAME)+3,
+ iResY+GetSystemMetrics(SM_CYFIXEDFRAME)+GetSystemMetrics(SM_CYCAPTION)+3,
+ TRUE);
+ UpdateWindow(hWGPU); // -> let windows do some update
+ }
+ else // no window mode:
+ {
+ DWORD dw=GetWindowLong(hWGPU, GWL_STYLE); // -> adjust wnd style
+ dwGPUStyle=dw;
+ hGPUMenu=GetMenu(hWGPU);
+
+ dw&=~(WS_THICKFRAME|WS_BORDER|WS_CAPTION);
+ SetWindowLong(hWGPU, GWL_STYLE, dw);
+ SetMenu(hWGPU,NULL);
+
+ ShowWindow(hWGPU,SW_SHOWMAXIMIZED); // -> max mode
+ }
+
+ r.left=r.top=0;r.right=iResX;r.bottom=iResY; // init bkg with black
+ hdc = GetDC(hWGPU);
+ FillRect(hdc,&r,(HBRUSH)GetStockObject(BLACK_BRUSH));
+ ReleaseDC(hWGPU, hdc);
+
+ DXinitialize(); // init direct draw (not D3D... oh, well)
+
+ if(!iWindowMode) // fullscreen mode?
+ ShowWindow(hWGPU,SW_SHOWMAXIMIZED); // -> maximize again (fixes strange DX behavior)
+
+ return 1;
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void CloseDisplay(void)
+{
+ DXcleanup(); // cleanup dx
+
+ SetWindowLong(hWGPU, GWL_STYLE,dwGPUStyle); // repair window
+ if(hGPUMenu) SetMenu(hWGPU,(HMENU)hGPUMenu);
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void CreatePic(unsigned char * pMem)
+{
+ DDSURFACEDESC xddsd;HRESULT ddrval;
+ unsigned char * ps;int x,y;
+
+ memset(&xddsd, 0, sizeof(DDSURFACEDESC));
+ xddsd.dwSize = sizeof(DDSURFACEDESC);
+ xddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS;
+// xddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
+
+ if(iSysMemory)
+ xddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;
+ else
+ xddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY;
+
+ xddsd.dwWidth = 128;
+ xddsd.dwHeight = 96;
+
+ if(IDirectDraw_CreateSurface(DX.DD,&xddsd, &DX.DDSScreenPic, NULL))
+ {DX.DDSScreenPic=0;return;}
+
+ ddrval=IDirectDrawSurface_Lock(DX.DDSScreenPic,NULL, &xddsd, DDLOCK_WAIT|DDLOCK_WRITEONLY, NULL);
+
+ if(ddrval==DDERR_SURFACELOST)
+ {
+ IDirectDrawSurface_Restore(DX.DDSScreenPic);
+ }
+
+ if(ddrval!=DD_OK)
+ {
+ IDirectDrawSurface_Unlock(DX.DDSScreenPic,&xddsd);
+ return;
+ }
+
+ ps=(unsigned char *)xddsd.lpSurface;
+
+ if(iDesktopCol==16)
+ {
+ unsigned short s;
+ for(y=0;y<96;y++)
+ {
+ for(x=0;x<128;x++)
+ {
+ s=(*(pMem+0))>>3;
+ s|=((*(pMem+1))&0xfc)<<3;
+ s|=((*(pMem+2))&0xf8)<<8;
+ pMem+=3;
+ *((unsigned short *)(ps+y*xddsd.lPitch+x*2))=s;
+ }
+ }
+ }
+ else
+ if(iDesktopCol==15)
+ {
+ unsigned short s;
+ for(y=0;y<96;y++)
+ {
+ for(x=0;x<128;x++)
+ {
+ s=(*(pMem+0))>>3;
+ s|=((*(pMem+1))&0xfc)<<2;
+ s|=((*(pMem+2))&0xf8)<<7;
+ pMem+=3;
+ *((unsigned short *)(ps+y*xddsd.lPitch+x*2))=s;
+ }
+ }
+ }
+ else
+ if(iDesktopCol==32)
+ {
+ unsigned long l;
+ for(y=0;y<96;y++)
+ {
+ for(x=0;x<128;x++)
+ {
+ l= *(pMem+0);
+ l|=(*(pMem+1))<<8;
+ l|=(*(pMem+2))<<16;
+ pMem+=3;
+ *((unsigned long *)(ps+y*xddsd.lPitch+x*4))=l;
+ }
+ }
+ }
+
+ IDirectDrawSurface_Unlock(DX.DDSScreenPic,&xddsd);
+}
+
+///////////////////////////////////////////////////////////////////////////////////////
+
+void DestroyPic(void)
+{
+ if(DX.DDSScreenPic)
+ {
+ RECT ScreenRect={iResX-128,0,iResX,96};
+ DDBLTFX ddbltfx;
+
+ if(iWindowMode)
+ {
+ POINT Point={0,0};
+ ClientToScreen(DX.hWnd,&Point);
+ ScreenRect.left+=Point.x;
+ ScreenRect.right+=Point.x;
+ ScreenRect.top+=Point.y;
+ ScreenRect.bottom+=Point.y;
+ }
+
+ ddbltfx.dwSize = sizeof(ddbltfx);
+ ddbltfx.dwFillColor = 0x00000000;
+ IDirectDrawSurface_Blt(DX.DDSPrimary,&ScreenRect,NULL,NULL,DDBLT_COLORFILL,&ddbltfx);
+
+ IDirectDrawSurface_Release(DX.DDSScreenPic);
+ DX.DDSScreenPic=0;
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////////////
+
+void DisplayPic(void)
+{
+ RECT ScreenRect={iResX-128,0,iResX,96},
+ HelperRect={0,0,128,96};
+ if(iWindowMode)
+ {
+ POINT Point={0,0};
+ ClientToScreen(DX.hWnd,&Point);
+ ScreenRect.left+=Point.x;
+ ScreenRect.right+=Point.x;
+ ScreenRect.top+=Point.y;
+ ScreenRect.bottom+=Point.y;
+ }
+
+// ??? eh... no need to wait here!
+// WaitVBlank();
+
+ IDirectDrawSurface_Blt(DX.DDSPrimary,&ScreenRect,DX.DDSScreenPic,&HelperRect,
+ DDBLT_WAIT,NULL);
+}
+
+///////////////////////////////////////////////////////////////////////////////////////
+
+void ShowGpuPic(void)
+{
+ HRSRC hR;HGLOBAL hG;unsigned long * pRMem;
+ unsigned char * pMem;int x,y;unsigned long * pDMem;
+
+ // turn off any screen pic, if it does already exist
+ if(DX.DDSScreenPic) {DestroyPic();return;}
+
+ if(ulKeybits&KEY_SHOWFPS) {ShowTextGpuPic();return;}
+
+ // load and lock the bitmap (lock is kinda obsolete in win32)
+ hR=FindResource(hInst,MAKEINTRESOURCE(IDB_GPU),RT_BITMAP);
+ hG=LoadResource(hInst,hR);
+
+ // get long ptr to bmp data
+ pRMem=((unsigned long *)LockResource(hG))+10;
+
+ // change the data upside-down
+ pMem=(unsigned char *)malloc(128*96*3);
+
+ for(y=0;y<96;y++)
+ {
+ pDMem=(unsigned long *)(pMem+(95-y)*128*3);
+ for(x=0;x<96;x++) *pDMem++=*pRMem++;
+ }
+
+ // show the pic
+ CreatePic(pMem);
+
+ // clean up
+ free(pMem);
+ DeleteObject(hG);
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void ShowTextGpuPic(void) // CREATE TEXT SCREEN PIC
+{ // gets an Text and paints
+ unsigned char * pMem;BITMAPINFO bmi; // it into a rgb24 bitmap
+ HDC hdc,hdcMem;HBITMAP hBmp,hBmpMem;HFONT hFontMem; // to display it in the gpu
+ HBRUSH hBrush,hBrushMem;HPEN hPen,hPenMem;
+ char szB[256];
+ RECT r={0,0,128,96}; // size of bmp... don't change that
+ COLORREF crFrame = RGB(128,255,128); // some example color inits
+ COLORREF crBkg = RGB(0,0,0);
+ COLORREF crText = RGB(0,255,0);
+
+ if(DX.DDSScreenPic) DestroyPic();
+
+ //----------------------------------------------------// creation of the dc & bitmap
+
+ hdc =GetDC(NULL); // create a dc
+ hdcMem=CreateCompatibleDC(hdc);
+ ReleaseDC(NULL,hdc);
+
+ memset(&bmi,0,sizeof(BITMAPINFO)); // create a 24bit dib
+ bmi.bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
+ bmi.bmiHeader.biWidth=128;
+ bmi.bmiHeader.biHeight=-96;
+ bmi.bmiHeader.biPlanes=1;
+ bmi.bmiHeader.biBitCount=24;
+ bmi.bmiHeader.biCompression=BI_RGB;
+ hBmp=CreateDIBSection(hdcMem,&bmi,DIB_RGB_COLORS,
+ (void **)&pMem,NULL,0); // pMem will point to 128x96x3 bitmap data
+
+ hBmpMem = (HBITMAP)SelectObject(hdcMem,hBmp); // sel the bmp into the dc
+
+ //----------------------------------------------------// ok, the following is just a drawing example... change it...
+ // create & select an additional font... whatever you want to paint, paint it in the dc :)
+ hBrush=CreateSolidBrush(crBkg);
+ hPen=CreatePen(PS_SOLID,0,crFrame);
+
+ hBrushMem = (HBRUSH)SelectObject(hdcMem,hBrush);
+ hPenMem = (HPEN)SelectObject(hdcMem,hPen);
+ hFontMem = (HFONT)SelectObject(hdcMem,hGFont);
+
+ SetTextColor(hdcMem,crText);
+ SetBkColor(hdcMem,crBkg);
+
+ Rectangle(hdcMem,r.left,r.top,r.right,r.bottom); // our example: fill rect and paint border
+ InflateRect(&r,-3,-2); // reduce the text area
+
+ LoadString(hInst,IDS_INFO0+iMPos,szB,255);
+ DrawText(hdcMem,szB,strlen(szB),&r, // paint the text (including clipping and word break)
+ DT_LEFT|DT_WORDBREAK);
+
+ //----------------------------------------------------// ok, now store the pMem data, or just call the gpu func
+
+ CreatePic(pMem);
+
+ //----------------------------------------------------// finished, now we clean up... needed, or you will get resource leaks :)
+
+ SelectObject(hdcMem,hBmpMem); // sel old mem dc objects
+ SelectObject(hdcMem,hBrushMem);
+ SelectObject(hdcMem,hPenMem);
+ SelectObject(hdcMem,hFontMem);
+ DeleteDC(hdcMem); // delete mem dcs
+ DeleteObject(hBmp);
+ DeleteObject(hBrush); // delete created objects
+ DeleteObject(hPen);
+}
+
+///////////////////////////////////////////////////////////////////////
+
+static void hqx_init(unsigned bits_per_pixel)
+{
+ interp_set(bits_per_pixel);
+}
+
+static void hq2x_16_def(unsigned short* dst0, unsigned short* dst1, const unsigned short* src0, const unsigned short* src1, const unsigned short* src2, unsigned count)
+{
+ unsigned i;
+
+ for(i=0;i<count;++i) {
+ unsigned char mask;
+
+ unsigned short c[9];
+
+ c[1] = src0[0];
+ c[4] = src1[0];
+ c[7] = src2[0];
+
+ if (i>0) {
+ c[0] = src0[-1];
+ c[3] = src1[-1];
+ c[6] = src2[-1];
+ } else {
+ c[0] = c[1];
+ c[3] = c[4];
+ c[6] = c[7];
+ }
+
+ if (i<count-1) {
+ c[2] = src0[1];
+ c[5] = src1[1];
+ c[8] = src2[1];
+ } else {
+ c[2] = c[1];
+ c[5] = c[4];
+ c[8] = c[7];
+ }
+
+ mask = 0;
+
+ if (interp_16_diff(c[0], c[4]))
+ mask |= 1 << 0;
+ if (interp_16_diff(c[1], c[4]))
+ mask |= 1 << 1;
+ if (interp_16_diff(c[2], c[4]))
+ mask |= 1 << 2;
+ if (interp_16_diff(c[3], c[4]))
+ mask |= 1 << 3;
+ if (interp_16_diff(c[5], c[4]))
+ mask |= 1 << 4;
+ if (interp_16_diff(c[6], c[4]))
+ mask |= 1 << 5;
+ if (interp_16_diff(c[7], c[4]))
+ mask |= 1 << 6;
+ if (interp_16_diff(c[8], c[4]))
+ mask |= 1 << 7;
+
+ switch (mask) {
+#include "hq2x.h"
+ }
+
+ src0 += 1;
+ src1 += 1;
+ src2 += 1;
+ dst0 += 2;
+ dst1 += 2;
+ }
+}
+
+void hq2x( unsigned char * srcPtr, DWORD srcPitch, unsigned char * dstPtr, int width, int height)
+{
+
+ //const int srcpitch = srcPitch;
+ const int dstPitch = srcPitch;
+
+ int count = height;
+
+ unsigned short *dst0 = (unsigned short *)dstPtr;
+ unsigned short *dst1 = dst0 + dstPitch;
+
+ unsigned short *src0 = (unsigned short *)srcPtr;
+ unsigned short *src1 = src0 + (srcPitch >> 1);
+ unsigned short *src2 = src1 + (srcPitch >> 1);
+ hqx_init(16);
+ hq2x_16_def(dst0, dst1, src0, src0, src1, width);
+
+ count -= 2;
+ while(count) {
+ dst0 += dstPitch << 1;
+ dst1 += dstPitch << 1;
+ hq2x_16_def(dst0, dst1, src0, src1, src2, width);
+ src0 = src1;
+ src1 = src2;
+ src2 += srcPitch >> 1;
+ --count;
+ }
+ dst0 += dstPitch << 1;
+ dst1 += dstPitch << 1;
+ hq2x_16_def(dst0, dst1, src0, src1, src1, width);
+}
+
+///////////////////////////////////////////////////////////////////
+
+static void hq2x_32_def(unsigned long * dst0, unsigned long * dst1, const unsigned long * src0, const unsigned long * src1, const unsigned long * src2, unsigned count)
+{
+ unsigned i;
+
+ for(i=0;i<count;++i) {
+ unsigned char mask;
+
+ unsigned long c[9];
+
+ c[1] = src0[0];
+ c[4] = src1[0];
+ c[7] = src2[0];
+
+ if (i>0) {
+ c[0] = src0[-1];
+ c[3] = src1[-1];
+ c[6] = src2[-1];
+ } else {
+ c[0] = c[1];
+ c[3] = c[4];
+ c[6] = c[7];
+ }
+
+ if (i<count-1) {
+ c[2] = src0[1];
+ c[5] = src1[1];
+ c[8] = src2[1];
+ } else {
+ c[2] = c[1];
+ c[5] = c[4];
+ c[8] = c[7];
+ }
+
+ mask = 0;
+
+ if (interp_32_diff(c[0], c[4]))
+ mask |= 1 << 0;
+ if (interp_32_diff(c[1], c[4]))
+ mask |= 1 << 1;
+ if (interp_32_diff(c[2], c[4]))
+ mask |= 1 << 2;
+ if (interp_32_diff(c[3], c[4]))
+ mask |= 1 << 3;
+ if (interp_32_diff(c[5], c[4]))
+ mask |= 1 << 4;
+ if (interp_32_diff(c[6], c[4]))
+ mask |= 1 << 5;
+ if (interp_32_diff(c[7], c[4]))
+ mask |= 1 << 6;
+ if (interp_32_diff(c[8], c[4]))
+ mask |= 1 << 7;
+
+ switch (mask) {
+#include "hq2x.h"
+ }
+
+ src0 += 1;
+ src1 += 1;
+ src2 += 1;
+ dst0 += 2;
+ dst1 += 2;
+ }
+}
+
+
+
+void hq2x_32( unsigned char * srcPtr, DWORD srcPitch, unsigned char * dstPtr, int width, int height)
+{
+ const int dstPitch = srcPitch<<1;
+
+ int count = height;
+
+ unsigned long *dst0 = (unsigned long *)dstPtr;
+ unsigned long *dst1 = dst0 + (dstPitch >> 2);
+
+ unsigned long *src0 = (unsigned long *)srcPtr;
+ unsigned long *src1 = src0 + (srcPitch >> 2);
+ unsigned long *src2 = src1 + (srcPitch >> 2);
+ hq2x_32_def(dst0, dst1, src0, src0, src1, width);
+
+
+
+ count -= 2;
+ while(count) {
+ dst0 += dstPitch >> 1;
+ dst1 += dstPitch >> 1;
+ hq2x_32_def(dst0, dst1, src0, src1, src2, width);
+ src0 = src1;
+ src1 = src2;
+ src2 += srcPitch >> 2;
+ --count;
+ }
+ dst0 += dstPitch >> 1;
+ dst1 += dstPitch >> 1;
+ hq2x_32_def(dst0, dst1, src0, src1, src1, width);
+}
+
+static void hq3x_32_def(unsigned long* dst0, unsigned long* dst1, unsigned long* dst2, const unsigned long* src0, const unsigned long* src1, const unsigned long* src2, unsigned count)
+{
+
+ unsigned i;
+
+ for(i=0;i<count;++i) {
+ unsigned char mask;
+
+ unsigned long c[9];
+
+ c[1] = src0[0];
+ c[4] = src1[0];
+ c[7] = src2[0];
+
+ if (i>0) {
+ c[0] = src0[-1];
+ c[3] = src1[-1];
+ c[6] = src2[-1];
+ } else {
+ c[0] = c[1];
+ c[3] = c[4];
+ c[6] = c[7];
+ }
+
+ if (i<count-1) {
+ c[2] = src0[1];
+ c[5] = src1[1];
+ c[8] = src2[1];
+ } else {
+ c[2] = c[1];
+ c[5] = c[4];
+ c[8] = c[7];
+ }
+
+ mask = 0;
+
+ if (interp_32_diff(c[0], c[4]))
+ mask |= 1 << 0;
+ if (interp_32_diff(c[1], c[4]))
+ mask |= 1 << 1;
+ if (interp_32_diff(c[2], c[4]))
+ mask |= 1 << 2;
+ if (interp_32_diff(c[3], c[4]))
+ mask |= 1 << 3;
+ if (interp_32_diff(c[5], c[4]))
+ mask |= 1 << 4;
+ if (interp_32_diff(c[6], c[4]))
+ mask |= 1 << 5;
+ if (interp_32_diff(c[7], c[4]))
+ mask |= 1 << 6;
+ if (interp_32_diff(c[8], c[4]))
+ mask |= 1 << 7;
+
+#define P0 dst0[0]
+#define P1 dst0[1]
+#define P2 dst0[2]
+#define P3 dst1[0]
+#define P4 dst1[1]
+#define P5 dst1[2]
+#define P6 dst2[0]
+#define P7 dst2[1]
+#define P8 dst2[2]
+#define MUR interp_32_diff(c[1], c[5])
+#define MDR interp_32_diff(c[5], c[7])
+#define MDL interp_32_diff(c[7], c[3])
+#define MUL interp_32_diff(c[3], c[1])
+#define IC(p0) c[p0]
+#define I11(p0,p1) interp_32_11(c[p0], c[p1])
+#define I211(p0,p1,p2) interp_32_211(c[p0], c[p1], c[p2])
+#define I31(p0,p1) interp_32_31(c[p0], c[p1])
+#define I332(p0,p1,p2) interp_32_332(c[p0], c[p1], c[p2])
+#define I431(p0,p1,p2) interp_32_431(c[p0], c[p1], c[p2])
+#define I521(p0,p1,p2) interp_32_521(c[p0], c[p1], c[p2])
+#define I53(p0,p1) interp_32_53(c[p0], c[p1])
+#define I611(p0,p1,p2) interp_32_611(c[p0], c[p1], c[p2])
+#define I71(p0,p1) interp_32_71(c[p0], c[p1])
+#define I772(p0,p1,p2) interp_32_772(c[p0], c[p1], c[p2])
+#define I97(p0,p1) interp_32_97(c[p0], c[p1])
+#define I1411(p0,p1,p2) interp_32_1411(c[p0], c[p1], c[p2])
+#define I151(p0,p1) interp_32_151(c[p0], c[p1])
+
+ switch (mask) {
+#include "hq3x.h"
+ }
+
+
+#undef P0
+#undef P1
+#undef P2
+#undef P3
+#undef P4
+#undef P5
+#undef P6
+#undef P7
+#undef P8
+#undef MUR
+#undef MDR
+#undef MDL
+#undef MUL
+#undef IC
+#undef I11
+#undef I211
+#undef I31
+#undef I332
+#undef I431
+#undef I521
+#undef I53
+#undef I611
+#undef I71
+#undef I772
+#undef I97
+#undef I1411
+#undef I151
+
+ src0 += 1;
+ src1 += 1;
+ src2 += 1;
+ dst0 += 3;
+ dst1 += 3;
+ dst2 += 3;
+ }
+}
+
+void hq3x_32( unsigned char * srcPtr, DWORD srcPitch, unsigned char * dstPtr, int width, int height)
+{
+
+
+
+ int count = height;
+
+ int dstPitch = srcPitch >> 1;
+
+ unsigned long *dst0 = (unsigned long *)dstPtr;
+ unsigned long *dst1 = dst0 + dstPitch;
+ unsigned long *dst2 = dst1 + dstPitch;
+
+ unsigned long *src0 = (unsigned long *)srcPtr;
+ unsigned long *src1 = src0 + (srcPitch >> 2);
+ unsigned long *src2 = src1 + (srcPitch >> 2);
+ hq3x_32_def(dst0, dst1, dst2, src0, src0, src2, width);
+
+ count -= 2;
+ while(count) {
+
+ dst0 += dstPitch * 3;
+ dst1 += dstPitch * 3;
+ dst2 += dstPitch * 3;
+
+ hq3x_32_def(dst0, dst1, dst2, src0, src1, src2, width);
+ src0 = src1;
+ src1 = src2;
+ src2 += srcPitch >> 2;
+ --count;
+ }
+ dst0 += dstPitch * 3;
+ dst1 += dstPitch * 3;
+ dst2 += dstPitch * 3;
+
+
+ hq3x_32_def(dst0, dst1, dst2, src0, src1, src1, width);
+
+}
+
+static void hq3x_16_def(unsigned short* dst0, unsigned short* dst1, unsigned short* dst2, const unsigned short* src0, const unsigned short* src1, const unsigned short* src2, unsigned count)
+{
+ unsigned i;
+
+ for(i=0;i<count;++i) {
+ unsigned char mask;
+
+ unsigned short c[9];
+
+ c[1] = src0[0];
+ c[4] = src1[0];
+ c[7] = src2[0];
+
+ if (i>0) {
+ c[0] = src0[-1];
+ c[3] = src1[-1];
+ c[6] = src2[-1];
+ } else {
+ c[0] = c[1];
+ c[3] = c[4];
+ c[6] = c[7];
+ }
+
+ if (i<count-1) {
+ c[2] = src0[1];
+ c[5] = src1[1];
+ c[8] = src2[1];
+ } else {
+ c[2] = c[1];
+ c[5] = c[4];
+ c[8] = c[7];
+ }
+
+ mask = 0;
+
+ if (interp_16_diff(c[0], c[4]))
+ mask |= 1 << 0;
+ if (interp_16_diff(c[1], c[4]))
+ mask |= 1 << 1;
+ if (interp_16_diff(c[2], c[4]))
+ mask |= 1 << 2;
+ if (interp_16_diff(c[3], c[4]))
+ mask |= 1 << 3;
+ if (interp_16_diff(c[5], c[4]))
+ mask |= 1 << 4;
+ if (interp_16_diff(c[6], c[4]))
+ mask |= 1 << 5;
+ if (interp_16_diff(c[7], c[4]))
+ mask |= 1 << 6;
+ if (interp_16_diff(c[8], c[4]))
+ mask |= 1 << 7;
+
+ switch (mask) {
+ #include "hq3x.h"
+ }
+
+ src0 += 1;
+ src1 += 1;
+ src2 += 1;
+ dst0 += 3;
+ dst1 += 3;
+ dst2 += 3;
+ }
+}
+
+void hq3x_16( unsigned char * srcPtr, DWORD srcPitch, unsigned char * dstPtr, int width, int height)
+{
+ int count = height;
+ int dstPitch = srcPitch;
+
+ unsigned short *dst0 = (unsigned short *)dstPtr;
+ unsigned short *dst1 = dst0 + dstPitch;
+ unsigned short *dst2 = dst1 + dstPitch;
+
+ unsigned short *src0 = (unsigned short *)srcPtr;
+ unsigned short *src1 = src0 + (srcPitch >> 1);
+ unsigned short *src2 = src1 + (srcPitch >> 1);
+ hqx_init(16);
+ hq3x_16_def(dst0, dst1, dst2, src0, src0, src2, width);
+
+ count -= 2;
+ while(count) {
+
+ dst0 += dstPitch * 3;
+ dst1 += dstPitch * 3;
+ dst2 += dstPitch * 3;
+
+ hq3x_16_def(dst0, dst1, dst2, src0, src1, src2, width);
+ src0 = src1;
+ src1 = src2;
+ src2 += srcPitch >> 1;
+ --count;
+ }
+ dst0 += dstPitch * 3;
+ dst1 += dstPitch * 3;
+ dst2 += dstPitch * 3;
+
+ hq3x_16_def(dst0, dst1, dst2, src0, src1, src1, width);
+}
+