diff options
Diffstat (limited to 'plugins/dfxvideo/draw.c')
| -rw-r--r-- | plugins/dfxvideo/draw.c | 4302 |
1 files changed, 2153 insertions, 2149 deletions
diff --git a/plugins/dfxvideo/draw.c b/plugins/dfxvideo/draw.c index 52d665a9..26281753 100644 --- a/plugins/dfxvideo/draw.c +++ b/plugins/dfxvideo/draw.c @@ -1,2149 +1,2153 @@ -/*************************************************************************** - 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" -#include "swap.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 iMaintainAspect = 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]; - -#include <sys/ipc.h> -#include <sys/shm.h> -#include <X11/extensions/Xv.h> -#include <X11/extensions/Xvlib.h> -#include <X11/extensions/XShm.h> -int xv_port = -1; -int xv_id = -1; -int xv_depth = 0; -int yuv_port = -1; -int yuv_id = -1; -int use_yuv = 0; -int xv_vsync = 0; - -XShmSegmentInfo shminfo; -int finalw,finalh; - -#include <time.h> - -// prototypes -void hq2x_32( 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; -} - -/* Convert RGB to YUV */ -static __inline uint32_t rgb_to_yuv(uint8_t R, uint8_t G, uint8_t B) { - uint8_t Y = min(abs(R * 2104 + G * 4130 + B * 802 + 4096 + 131072) >> 13, 235); - uint8_t U = min(abs(R * -1214 + G * -2384 + B * 3598 + 4096 + 1048576) >> 13, 240); - uint8_t V = min(abs(R * 3598 + G * -3013 + B * -585 + 4096 + 1048576) >> 13, 240); - -#ifdef __BIG_ENDIAN__ - return Y << 24 | U << 16 | Y << 8 | V; -#else - return Y << 24 | V << 16 | Y << 8 | U; -#endif -} - -#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)))) - - -static 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; - - finalw=width<<1; - finalh=height<<1; - - 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--) - } -} - -//////////////////////////////////////////////////////////////////////// - -static 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; - - finalw=width<<1; - finalh=height<<1; - - 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--) - } -} - -//////////////////////////////////////////////////////////////////////// - -static 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; - - finalw=width<<1; - finalh=height<<1; - - 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--) - } -} - -///////////////////////// - -//#include <assert.h> - -static __inline void scale2x_32_def_whole(uint32_t* dst0, uint32_t* dst1, const uint32_t* src0, const uint32_t* src1, const uint32_t* src2, unsigned count) -{ - - //assert(count >= 2); - - // 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]; - } -} - -static void Scale2x_ex8(unsigned char *srcPtr, DWORD srcPitch, - unsigned char *dstPtr, int width, int height) -{ - //const int srcpitch = srcPitch; - const int dstPitch = srcPitch<<1; - - int count = height; - - finalw=width<<1; - finalh=height<<1; - - uint32_t *dst0 = (uint32_t *)dstPtr; - uint32_t *dst1 = dst0 + (dstPitch >> 2); - - uint32_t *src0 = (uint32_t *)srcPtr; - uint32_t *src1 = src0 + (srcPitch >> 2); - uint32_t *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(uint32_t* dst0, uint32_t* dst1, uint32_t* dst2, const uint32_t* src0, const uint32_t* src1, const uint32_t* 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]; - } -} - - -static void Scale3x_ex8(unsigned char *srcPtr, DWORD srcPitch, - unsigned char *dstPtr, int width, int height) -{ - int count = height; - - int dstPitch = srcPitch*3; - int dstRowPixels = dstPitch>>2; - - finalw=width*3; - finalh=height*3; - - uint32_t *dst0 = (uint32_t *)dstPtr; - uint32_t *dst1 = dst0 + dstRowPixels; - uint32_t *dst2 = dst1 + dstRowPixels; - - uint32_t *src0 = (uint32_t *)srcPtr; - uint32_t *src1 = src0 + (srcPitch >> 2); - uint32_t *src2 = src1 + (srcPitch >> 2); - scale3x_32_def_whole(dst0, dst1, dst2, src0, src0, src2, width); - - count -= 2; - while(count) { - dst0 += dstRowPixels*3; - dst1 += dstRowPixels*3; - dst2 += dstRowPixels*3; - - scale3x_32_def_whole(dst0, dst1, dst2, src0, src1, src2, width); - src0 = src1; - src1 = src2; - src2 += srcPitch >> 2; - --count; - } - - dst0 += dstRowPixels*3; - dst1 += dstRowPixels*3; - dst2 += dstRowPixels*3; - - scale3x_32_def_whole(dst0, dst1, dst2, src0, src1, src1, width); -} - - -//////////////////////////////////////////////////////////////////////// - -#ifndef MAX -#define MAX(a,b) (((a) > (b)) ? (a) : (b)) -#define MIN(a,b) (((a) < (b)) ? (a) : (b)) -#endif - - -//////////////////////////////////////////////////////////////////////// -// X STUFF :) -//////////////////////////////////////////////////////////////////////// - - -static Cursor cursor; -XVisualInfo vi; -static XVisualInfo *myvisual; -Display *display; -static Colormap colormap; -Window window; -static GC hGC; -static XImage * Ximage; -static XvImage * XCimage; -static XImage * XPimage=0; -char * Xpixels; -char * pCaptionText; - -static int fx=0; - - -static Atom xv_intern_atom_if_exists( Display *display, char const * atom_name ) -{ - XvAttribute * attributes; - int attrib_count,i; - Atom xv_atom = None; - - attributes = XvQueryPortAttributes( display, xv_port, &attrib_count ); - if( attributes!=NULL ) - { - for ( i = 0; i < attrib_count; ++i ) - { - if ( strcmp(attributes[i].name, atom_name ) == 0 ) - { - xv_atom = XInternAtom( display, atom_name, False ); - break; // found what we want, break out - } - } - XFree( attributes ); - } - - return xv_atom; -} - - - -// close display - -static void DestroyDisplay(void) -{ - if(display) - { - XFreeColormap(display, colormap); - if(hGC) - { - XFreeGC(display,hGC); - hGC = 0; - } - if(Ximage) - { - XDestroyImage(Ximage); - Ximage=0; - } - if(XCimage) - { - XFree(XCimage); - XCimage=0; - } - - XShmDetach(display,&shminfo); - shmdt(shminfo.shmaddr); - shmctl(shminfo.shmid,IPC_RMID,NULL); - - Atom atom_vsync = xv_intern_atom_if_exists(display, "XV_SYNC_TO_VBLANK"); - if (atom_vsync != None) { - XvSetPortAttribute(display, xv_port, atom_vsync, xv_vsync); - } - - XSync(display,False); - - XCloseDisplay(display); - } -} - -static int depth=0; -int root_window_id=0; - - -// Create display - -static void CreateDisplay(void) -{ - XSetWindowAttributes winattr; - int myscreen; - Screen * screen; - XEvent event; - XSizeHints hints; - XWMHints wm_hints; - MotifWmHints mwmhints; - Atom mwmatom; - - Atom delwindow; - - XGCValues gcv; - int i; - - int ret, j, p; - int formats; - unsigned int p_num_adaptors=0, p_num_ports=0; - - XvAdaptorInfo *ai; - XvImageFormatValues *fo; - - // Open display - display = XOpenDisplay(NULL); - - if (!display) - { - fprintf (stderr,"Failed to open display!!!\n"); - DestroyDisplay(); - return; - } - - myscreen=DefaultScreen(display); - - // desktop fullscreen switch - if (!iWindowMode) fx = 1; - - screen=DefaultScreenOfDisplay(display); - - root_window_id=RootWindow(display,DefaultScreen(display)); - - //Look for an Xvideo RGB port - ret = XvQueryAdaptors(display, root_window_id, &p_num_adaptors, &ai); - if (ret != Success) { - if (ret == XvBadExtension) - printf("XvBadExtension returned at XvQueryExtension.\n"); - else - if (ret == XvBadAlloc) - printf("XvBadAlloc returned at XvQueryExtension.\n"); - else - printf("other error happaned at XvQueryAdaptors.\n"); - - exit(-1); - } - - depth = DefaultDepth(display, myscreen); - - for (i = 0; i < p_num_adaptors; i++) { - p_num_ports = ai[i].base_id + ai[i].num_ports; - for (p = ai[i].base_id; p < p_num_ports; p++) { - fo = XvListImageFormats(display, p, &formats); - for (j = 0; j < formats; j++) { - //backup YUV mode - //hmm, should I bother check guid == 55595659-0000-0010-8000-00aa00389b71? - //and check byte order? fo[j].byte_order == LSBFirst -#ifdef __BIG_ENDIAN__ - if ( fo[j].type == XvYUV && fo[j].bits_per_pixel == 16 && fo[j].format == XvPacked && strncmp("YUYV", fo[j].component_order, 5) == 0 ) -#else - if ( fo[j].type == XvYUV && fo[j].bits_per_pixel == 16 && fo[j].format == XvPacked && strncmp("UYVY", fo[j].component_order, 5) == 0 ) -#endif - { - yuv_port = p; - yuv_id = fo[j].id; - } - if (fo[j].type == XvRGB && fo[j].bits_per_pixel == 32) - { - xv_port = p; - xv_id = fo[j].id; - xv_depth = fo[j].depth; - printf("RGB mode found. id: %x, depth: %d\n", xv_id, xv_depth); - - if (xv_depth != depth) { - printf("Warning: Depth does not match screen depth (%d)\n", depth); - } - else { - //break out of loops - j = formats; - p = p_num_ports; - i = p_num_adaptors; - } - } - } - if (fo) - XFree(fo); - } - } - if (p_num_adaptors > 0) - XvFreeAdaptorInfo(ai); - if (xv_port == -1 && yuv_port == -1) - { - printf("RGB & YUV not found. Quitting.\n"); - exit(-1); - } - else if (xv_port == -1 && yuv_port != -1) - { - use_yuv = 1; - printf("RGB not found. Using YUV.\n"); - xv_port = yuv_port; - xv_id = yuv_id; - } - else if (xv_depth && xv_depth != depth && yuv_port != -1) - { - use_yuv = 1; - printf("Acceptable RGB mode not found. Using YUV.\n"); - xv_port = yuv_port; - xv_id = yuv_id; - } - - Atom atom_vsync = xv_intern_atom_if_exists(display, "XV_SYNC_TO_VBLANK"); - if (atom_vsync != None) { - XvGetPortAttribute(display, xv_port, atom_vsync, &xv_vsync); - XvSetPortAttribute(display, xv_port, atom_vsync, 0); - } - -myvisual = 0; - -if(XMatchVisualInfo(display,myscreen, depth, TrueColor, &vi)) - myvisual = &vi; - -if (!myvisual) -{ - fprintf(stderr,"Failed to obtain visual!\n"); - DestroyDisplay(); - return; -} - - if(myvisual->red_mask==0x00007c00 && - myvisual->green_mask==0x000003e0 && - myvisual->blue_mask==0x0000001f) - {iColDepth=15;} - else - if(myvisual->red_mask==0x0000f800 && - myvisual->green_mask==0x000007e0 && - myvisual->blue_mask==0x0000001f) - {iColDepth=16;} - else - if(myvisual->red_mask==0x00ff0000 && - myvisual->green_mask==0x0000ff00 && - myvisual->blue_mask==0x000000ff) - {iColDepth=32;} - else - { - iColDepth=0; -/* fprintf(stderr,"COLOR DEPTH NOT SUPPORTED!\n"); - fprintf(stderr,"r: %08lx\n",myvisual->red_mask); - fprintf(stderr,"g: %08lx\n",myvisual->green_mask); - fprintf(stderr,"b: %08lx\n",myvisual->blue_mask); - DestroyDisplay(); - return;*/ - } - - // pffff... much work for a simple blank cursor... oh, well... - if(iWindowMode) cursor=XCreateFontCursor(display,XC_trek); - else - { - Pixmap p1,p2; - XImage * img; - XColor b,w; - char * idata; - XGCValues GCv; - GC GCc; - - memset(&b,0,sizeof(XColor)); - memset(&w,0,sizeof(XColor)); - idata=(char *)malloc(8); - memset(idata,0,8); - - p1=XCreatePixmap(display,RootWindow(display,myvisual->screen),8,8,1); - p2=XCreatePixmap(display,RootWindow(display,myvisual->screen),8,8,1); - - img = XCreateImage(display,myvisual->visual, - 1,XYBitmap,0,idata,8,8,8,1); - - GCv.function = GXcopy; - GCv.foreground = ~0; - GCv.background = 0; - GCv.plane_mask = AllPlanes; - GCc = XCreateGC(display,p1, - (GCFunction|GCForeground|GCBackground|GCPlaneMask),&GCv); - - XPutImage(display, p1,GCc,img,0,0,0,0,8,8); - XPutImage(display, p2,GCc,img,0,0,0,0,8,8); - XFreeGC(display, GCc); - - cursor = XCreatePixmapCursor(display,p1,p2,&b,&w,0,0); - - XFreePixmap(display,p1); - XFreePixmap(display,p2); - XDestroyImage(img); // will free idata as well - } - - colormap=XCreateColormap(display,root_window_id, - myvisual->visual,AllocNone); - - winattr.background_pixel=BlackPixelOfScreen(screen); - winattr.border_pixel=WhitePixelOfScreen(screen); - winattr.bit_gravity=ForgetGravity; - winattr.win_gravity=NorthWestGravity; - winattr.backing_store=NotUseful; - - winattr.override_redirect=False; - winattr.save_under=False; - winattr.event_mask=0; - winattr.do_not_propagate_mask=0; - winattr.colormap=colormap; - winattr.cursor=None; - - window=XCreateWindow(display,root_window_id, - 0,0,iResX,iResY, - 0,myvisual->depth, - InputOutput,myvisual->visual, - CWBorderPixel | CWBackPixel | - CWEventMask | CWDontPropagate | - CWColormap | CWCursor, - &winattr); - - if(!window) - { - fprintf(stderr,"Failed in XCreateWindow()!!!\n"); - DestroyDisplay(); - return; - } - - delwindow = XInternAtom(display,"WM_DELETE_WINDOW",0); - XSetWMProtocols(display, window, &delwindow, 1); - - hints.flags=USPosition|USSize; - hints.base_width = iResX; - hints.base_height = iResY; - - wm_hints.input=1; - wm_hints.flags=InputHint; - - XSetWMHints(display,window,&wm_hints); - XSetWMNormalHints(display,window,&hints); - if(pCaptionText) - XStoreName(display,window,pCaptionText); - else XStoreName(display,window,"P.E.Op.S SoftX PSX Gpu"); - - XDefineCursor(display,window,cursor); - - // hack to get rid of window title bar - if (fx) - { - mwmhints.flags=MWM_HINTS_DECORATIONS; - mwmhints.decorations=0; - mwmatom=XInternAtom(display,"_MOTIF_WM_HINTS",0); - XChangeProperty(display,window,mwmatom,mwmatom,32, - PropModeReplace,(unsigned char *)&mwmhints,4); - } - - // key stuff - XSelectInput(display, - window, - FocusChangeMask | ExposureMask | - KeyPressMask | KeyReleaseMask - ); - - XMapRaised(display,window); - XClearWindow(display,window); - XWindowEvent(display,window,ExposureMask,&event); - - if (fx) // fullscreen - { - XResizeWindow(display,window,screen->width,screen->height); - - hints.min_width = hints.max_width = hints.base_width = screen->width; - hints.min_height= hints.max_height = hints.base_height = screen->height; - - XSetWMNormalHints(display,window,&hints); - - // set the window layer for GNOME - { - XEvent xev; - - memset(&xev, 0, sizeof(xev)); - xev.xclient.type = ClientMessage; - xev.xclient.serial = 0; - xev.xclient.send_event = 1; - xev.xclient.message_type = XInternAtom(display, "_NET_WM_STATE", 0); - xev.xclient.window = window; - xev.xclient.format = 32; - xev.xclient.data.l[0] = 1; - xev.xclient.data.l[1] = XInternAtom(display, "_NET_WM_STATE_FULLSCREEN", 0); - xev.xclient.data.l[2] = 0; - xev.xclient.data.l[3] = 0; - xev.xclient.data.l[4] = 0; - - XSendEvent(display, root_window_id, 0, - SubstructureRedirectMask | SubstructureNotifyMask, &xev); - } - } - - gcv.foreground = 0x0000FF00; // green letters for the FPS bar; do we need to take care of endianess? - gcv.background = 0x00000000; - gcv.graphics_exposures = False; - hGC = XCreateGC(display,window, - GCGraphicsExposures | GCForeground | GCBackground, &gcv); - if(!hGC) - { - fprintf(stderr,"No gfx context!!!\n"); - DestroyDisplay(); - } - - uint32_t color; - - /* fix the green back ground in YUV mode */ - if(use_yuv) - color = rgb_to_yuv(0x00, 0x00, 0x00); - else - color = 0; - - Xpixels = (char *)malloc(8*8*4); - for(i = 0; i < 8*8; ++i) - ((uint32_t *)Xpixels)[i] = color; - - XCimage = XvCreateImage(display,xv_port,xv_id, - (char *)Xpixels, 8, 8); - - -/* -Allocate max that could be needed: -Big(est?) PSX res: 640x512 -32bpp (times 4) -2xsai func= 3xwidth,3xheight -= approx 11.8mb -*/ -shminfo.shmid = shmget(IPC_PRIVATE, 640*512*4*3*3, IPC_CREAT | 0777); -shminfo.shmaddr = shmat(shminfo.shmid, 0, 0); -shminfo.readOnly = 0; - - if (!XShmAttach(display, &shminfo)) { - printf("XShmAttach failed !\n"); - exit (-1); - } - - { - uint32_t *pShmaddr = (uint32_t *)shminfo.shmaddr; - for(i = 0; i < 640*512*3*3; ++i) - pShmaddr[i] = color; - } -} - -void (*p2XSaIFunc) (unsigned char *, DWORD, unsigned char *, int, int); -unsigned char *pBackBuffer = 0; - -static void BlitScreen32(unsigned char *surf, int32_t x, int32_t y) -{ - unsigned char *pD; - unsigned int startxy; - uint32_t lu; - unsigned short s; - unsigned short row, column; - unsigned short dx = PreviousPSXDisplay.Range.x1; - unsigned short dy = PreviousPSXDisplay.DisplayMode.y; - - int32_t lPitch = PSXDisplay.DisplayMode.x << 2; - - uint32_t *destpix; - - if (PreviousPSXDisplay.Range.y0) // centering needed? - { - memset(surf, 0, (PreviousPSXDisplay.Range.y0 >> 1) * lPitch); - - dy -= PreviousPSXDisplay.Range.y0; - surf += (PreviousPSXDisplay.Range.y0 >> 1) * lPitch; - - memset(surf + dy * lPitch, - 0, ((PreviousPSXDisplay.Range.y0 + 1) >> 1) * lPitch); - } - - if (PreviousPSXDisplay.Range.x0) - { - for (column = 0; column < dy; column++) - { - destpix = (uint32_t *)(surf + (column * lPitch)); - memset(destpix, 0, PreviousPSXDisplay.Range.x0 << 2); - } - surf += PreviousPSXDisplay.Range.x0 << 2; - } - - if (PSXDisplay.RGB24) - { - for (column = 0; column < dy; column++) - { - startxy = ((1024) * (column + y)) + x; - pD = (unsigned char *)&psxVuw[startxy]; - destpix = (uint32_t *)(surf + (column * lPitch)); - for (row = 0; row < dx; row++) - { - lu = *((uint32_t *)pD); - destpix[row] = - 0xff000000 | (RED(lu) << 16) | (GREEN(lu) << 8) | (BLUE(lu)); - pD += 3; - } - } - } - else - { - for (column = 0;column<dy;column++) - { - startxy = (1024 * (column + y)) + x; - destpix = (uint32_t *)(surf + (column * lPitch)); - for (row = 0; row < dx; row++) - { - s = GETLE16(&psxVuw[startxy++]); - destpix[row] = - (((s << 19) & 0xf80000) | ((s << 6) & 0xf800) | ((s >> 7) & 0xf8)) | 0xff000000; - } - } - } -} - - - -static void BlitToYUV(unsigned char * surf,int32_t x,int32_t y) -{ - unsigned char * pD; - unsigned int startxy; - uint32_t lu;unsigned short s; - unsigned short row,column; - unsigned short dx = PreviousPSXDisplay.Range.x1; - unsigned short dy = PreviousPSXDisplay.DisplayMode.y; - int R,G,B; - - int32_t lPitch = PSXDisplay.DisplayMode.x << 2; - uint32_t *destpix; - - if (PreviousPSXDisplay.Range.y0) // centering needed? - { - for (column = 0; column < (PreviousPSXDisplay.Range.y0 >> 1); column++) - { - destpix = (uint32_t *)(surf + column * lPitch); - for (row = 0; row < dx; row++) - { - destpix[row] = (4 << 24) | (128 << 16) | (4 << 8) | 128; - } - } - - dy -= PreviousPSXDisplay.Range.y0; - surf += (PreviousPSXDisplay.Range.y0 >> 1) * lPitch; - - for (column = 0; column < (PreviousPSXDisplay.Range.y0 + 1) >> 1; column++) - { - destpix = (uint32_t *)(surf + (dy + column) * lPitch); - for (row = 0; row < dx; row++) - { - destpix[row] = (4 << 24) | (128 << 16) | (4 << 8) | 128; - } - } - } - - if (PreviousPSXDisplay.Range.x0) - { - for (column = 0; column < dy; column++) - { - destpix = (uint32_t *)(surf + (column * lPitch)); - for (row = 0; row < PreviousPSXDisplay.Range.x0; row++) - { - destpix[row] = (4 << 24) | (128 << 16) | (4 << 8) | 128; - } - } - surf += PreviousPSXDisplay.Range.x0 << 2; - } - - if (PSXDisplay.RGB24) - { - for (column = 0; column < dy; column++) - { - startxy = (1024 * (column + y)) + x; - pD = (unsigned char *)&psxVuw[startxy]; - destpix = (uint32_t *)(surf + (column * lPitch)); - for (row = 0; row < dx; row++) - { - lu = *((uint32_t *)pD); - - R = RED(lu); - G = GREEN(lu); - B = BLUE(lu); - - destpix[row] = rgb_to_yuv(R, G, B); - - pD += 3; - } - } - } - else - { - for (column = 0; column < dy; column++) - { - startxy = (1024 * (column + y)) + x; - destpix = (uint32_t *)(surf + (column * lPitch)); - for (row = 0; row < dx; row++) - { - s = GETLE16(&psxVuw[startxy++]); - - R = (s << 3) &0xf8; - G = (s >> 2) &0xf8; - B = (s >> 7) &0xf8; - - destpix[row] = rgb_to_yuv(R, G, B); - - } - } - } -} - -//dst will have half the pitch (32bit to 16bit) -static void RGB2YUV(uint32_t *s, int width, int height, uint32_t *d) -{ - int x,y; - int R,G,B, Y1,Y2,U,V; - - for (y=0; y<height; y++) { - for(x=0; x<width>>1; x++) { - R = (*s >> 16) & 0xff; - G = (*s >> 8) & 0xff; - B = *s & 0xff; - s++; - - Y1 = min(abs(R * 2104 + G * 4130 + B * 802 + 4096 + 131072) >> 13, 235); - U = min(abs(R * -1214 + G * -2384 + B * 3598 + 4096 + 1048576) >> 13, 240); - V = min(abs(R * 3598 + G * -3013 + B * -585 + 4096 + 1048576) >> 13, 240); - - R = (*s >> 16) & 0xff; - G = (*s >> 8) & 0xff; - B = *s & 0xff; - s++; - - Y2 = min(abs(R * 2104 + G * 4130 + B * 802 + 4096 + 131072) >> 13, 235); - -#ifdef __BIG_ENDIAN__ - *d = V | Y2 << 8 | U << 16 | Y1 << 24; -#else - *d = U | Y1 << 8 | V << 16 | Y2 << 24; -#endif - d++; - } - } -} - -/* compute the position and the size of output screen - * The aspect of the psx output mode is preserved. - * Note: dest dx,dy,dw,dh are both input and output variables - */ -static __inline void MaintainAspect(uint32_t * dx, uint32_t * dy, uint32_t * dw, uint32_t * dh) -{ - - double ratio_x = ((double)*dw) / ((double)PSXDisplay.DisplayMode.x) ; - double ratio_y = ((double)*dh) / ((double)PSXDisplay.DisplayMode.y); - - double ratio; - if (ratio_x < ratio_y) { - ratio = ratio_x; - } else { - ratio = ratio_y; - } - - uint32_t tw = (uint32_t) floor(PSXDisplay.DisplayMode.x * ratio); - uint32_t th = (uint32_t) floor(PSXDisplay.DisplayMode.y * ratio); - - *dx = (uint32_t) floor((*dw - tw) / 2.0); - *dy = (uint32_t) floor((*dh - th) / 2.0); - *dw = tw; - *dh = th; -} - -void DoBufferSwap(void) -{ - Screen *screen; - Window _dw; - XvImage *xvi; - unsigned int dstx, dsty; - unsigned int _d, _w, _h; //don't care about _d - - finalw = PSXDisplay.DisplayMode.x; - finalh = PSXDisplay.DisplayMode.y; - - if (finalw == 0 || finalh == 0) - return; - - XSync(display,False); - - if(use_yuv) { - if (iUseNoStretchBlt==0 || finalw > 320 || finalh > 256) { - BlitToYUV((unsigned char *)shminfo.shmaddr, PSXDisplay.DisplayPosition.x, PSXDisplay.DisplayPosition.y); - finalw <<= 1; - } else { - BlitScreen32((unsigned char *)pBackBuffer, PSXDisplay.DisplayPosition.x, PSXDisplay.DisplayPosition.y); - p2XSaIFunc(pBackBuffer, finalw<<2, (unsigned char *)pSaIBigBuff,finalw,finalh); - RGB2YUV( (uint32_t*)pSaIBigBuff, finalw, finalh, (uint32_t*)shminfo.shmaddr); - } - } else if(iUseNoStretchBlt==0 || finalw > 320 || finalh > 256) { - BlitScreen32((unsigned char *)shminfo.shmaddr, PSXDisplay.DisplayPosition.x, PSXDisplay.DisplayPosition.y); - } else { - BlitScreen32((unsigned char *)pBackBuffer, PSXDisplay.DisplayPosition.x, PSXDisplay.DisplayPosition.y); - p2XSaIFunc(pBackBuffer, finalw<<2, (unsigned char *)shminfo.shmaddr,finalw,finalh); - } - - XGetGeometry(display, window, &_dw, (int *)&_d, (int *)&_d, &_w, &_h, &_d, &_d); - if (use_yuv) { - xvi = XvShmCreateImage(display, yuv_port, yuv_id, 0, finalw, finalh, &shminfo); - } else - xvi = XvShmCreateImage(display, xv_port, xv_id, 0, finalw, finalh, &shminfo); - - xvi->data = shminfo.shmaddr; - - screen=DefaultScreenOfDisplay(display); - //screennum = DefaultScreen(display); - - if (!iWindowMode) { - _w = screen->width; - _h = screen->height; - } - - dstx = 0; - dsty = 0; - - if (iMaintainAspect) - MaintainAspect(&dstx, &dsty, &_w, &_h); - -/*Whistler: too slow/laggy so commented out for now - if(iRumbleTime) - { - dstx += (rand() % iRumbleVal) - iRumbleVal / 2; - _w -= (rand() % iRumbleVal) - iRumbleVal / 2; - dsty += (rand() % iRumbleVal) - iRumbleVal / 2; - _h -= (rand() % iRumbleVal) - iRumbleVal / 2; - iRumbleTime--; - } -*/ - XvShmPutImage(display, xv_port, window, hGC, xvi, - 0,0, //src x,y - finalw,finalh, //src w,h - dstx,dsty, //dst x,y - _w, _h, //dst w,h - 1 - ); - - if(ulKeybits&KEY_SHOWFPS) //DisplayText(); c // paint menu text - { - if(szDebugText[0] && ((time(NULL) - tStart) < 2)) - { - strcpy(szDispBuf,szDebugText); - } - else - { - szDebugText[0]=0; - strcat(szDispBuf,szMenuBuf); - } - - //XPutImage(display,window,hGC, XFimage, - // 0, 0, 0, 0, 220,15); - - XDrawImageString(display,window,hGC,2,13,szDispBuf,strlen(szDispBuf)); - } - - //if(XPimage) DisplayPic(); - - XFree(xvi); -} - -void DoClearScreenBuffer(void) // CLEAR DX BUFFER -{ - Window _dw; - unsigned int _d, _w, _h; //don't care about _d - - XGetGeometry(display, window, &_dw, (int *)&_d, (int *)&_d, &_w, &_h, &_d, &_d); - - XvPutImage(display, xv_port, window, hGC, XCimage, - 0, 0, 8, 8, 0, 0, _w, _h); - //XSync(display,False); -} - -void DoClearFrontBuffer(void) // CLEAR DX BUFFER -{/* - XPutImage(display,window,hGC, XCimage, - 0, 0, 0, 0, iResX, iResY); - XSync(display,False);*/ -} - -static int Xinitialize() -{ - iDesktopCol=32; - - - if(iUseNoStretchBlt>0) - { - pBackBuffer=(unsigned char *)malloc(640*512*sizeof(uint32_t)); - memset(pBackBuffer,0,640*512*sizeof(uint32_t)); - if (use_yuv) { - pSaIBigBuff=malloc(640*512*4*3*3); - memset(pSaIBigBuff,0,640*512*4*3*3); - } - } - - p2XSaIFunc=NULL; - - if(iUseNoStretchBlt==1) - { - p2XSaIFunc=Std2xSaI_ex8; - } - - if(iUseNoStretchBlt==2) - { - p2XSaIFunc=Super2xSaI_ex8; - } - - if(iUseNoStretchBlt==3) - { - p2XSaIFunc=SuperEagle_ex8; - } - - if(iUseNoStretchBlt==4) - { - p2XSaIFunc=Scale2x_ex8; - } - if(iUseNoStretchBlt==5) - { - p2XSaIFunc=Scale3x_ex8; - } - if(iUseNoStretchBlt==6) - { - p2XSaIFunc=hq2x_32; - } - if(iUseNoStretchBlt==7) - { - p2XSaIFunc=hq3x_32; - } - - bUsingTWin=FALSE; - - InitMenu(); - - bIsFirstFrame = FALSE; // done - - if(iShowFPS) - { - iShowFPS=0; - ulKeybits|=KEY_SHOWFPS; - szDispBuf[0]=0; - BuildDispMenu(0); - } - - return 0; -} - -static void Xcleanup() // X CLEANUP -{ - CloseMenu(); - - if(iUseNoStretchBlt>0) - { - if(pBackBuffer) free(pBackBuffer); - pBackBuffer=0; - if(pSaIBigBuff) free(pSaIBigBuff); - pSaIBigBuff=0; - } -} - -unsigned long ulInitDisplay(void) -{ - CreateDisplay(); // x stuff - Xinitialize(); // init x - return (unsigned long)display; -} - -void CloseDisplay(void) -{ - Xcleanup(); // cleanup dx - DestroyDisplay(); -} - -void CreatePic(unsigned char * pMem) -{ - unsigned char * p=(unsigned char *)malloc(128*96*4); - unsigned char * ps; int x,y; - - ps=p; - - 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*256+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*256+x*2))=s; - } - } - } - else - if(iDesktopCol==32) - { - uint32_t 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; - *((uint32_t *)(ps+y*512+x*4))=l; - } - } - } - - XPimage = XCreateImage(display,myvisual->visual, - depth, ZPixmap, 0, - (char *)p, - 128, 96, - depth>16 ? 32 : 16, - 0); -} - -void DestroyPic(void) -{ - if(XPimage) - { /* - XPutImage(display,window,hGC, XCimage, - 0, 0, 0, 0, iResX, iResY);*/ - XDestroyImage(XPimage); - XPimage=0; - } -} - -void DisplayPic(void) -{ - XPutImage(display,window,hGC, XPimage, - 0, 0, iResX-128, 0,128,96); -} - -void ShowGpuPic(void) -{ -} - -void ShowTextGpuPic(void) -{ -} - -static void hq2x_32_def(uint32_t * dst0, uint32_t * dst1, const uint32_t * src0, const uint32_t * src1, const uint32_t * src2, unsigned count) -{ - static unsigned char cache_vert_mask[640]; - unsigned char cache_horiz_mask = 0; - - unsigned i; - unsigned char mask; - uint32_t c[9]; - - if (src0 == src1) //processing first row - memset(cache_vert_mask, 0, count); - - for(i=0;i<count;++i) { - 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; - - mask |= interp_32_diff(c[0], c[4]) << 0; - mask |= cache_vert_mask[i]; - mask |= interp_32_diff(c[2], c[4]) << 2; - mask |= cache_horiz_mask; - cache_horiz_mask = interp_32_diff(c[5], c[4]) << 3; - mask |= cache_horiz_mask << 1; // << 3 << 1 == << 4 - mask |= interp_32_diff(c[6], c[4]) << 5; - cache_vert_mask[i] = interp_32_diff(c[7], c[4]) << 1; - mask |= cache_vert_mask[i] << 5; // << 1 << 5 == << 6 - mask |= interp_32_diff(c[8], c[4]) << 7; - -#define P0 dst0[0] -#define P1 dst0[1] -#define P2 dst1[0] -#define P3 dst1[1] -#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 "hq2x.h" - } - -#undef P0 -#undef P1 -#undef P2 -#undef P3 -#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 += 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; - - finalw=width*2; - finalh=height*2; - - uint32_t *dst0 = (uint32_t *)dstPtr; - uint32_t *dst1 = dst0 + (dstPitch >> 2); - - uint32_t *src0 = (uint32_t *)srcPtr; - uint32_t *src1 = src0 + (srcPitch >> 2); - uint32_t *src2 = src1 + (srcPitch >> 2); - hq2x_32_def(dst0, dst1, src0, src0, src1, width); - - - count -= 2; - while(count) { - dst0 += dstPitch >> 1; //next 2 lines (dstPitch / 4 char per int * 2) - 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(uint32_t* dst0, uint32_t* dst1, uint32_t* dst2, const uint32_t* src0, const uint32_t* src1, const uint32_t* src2, unsigned count) -{ - static unsigned char cache_vert_mask[640]; - unsigned char cache_horiz_mask = 0; - - unsigned i; - unsigned char mask; - uint32_t c[9]; - - if (src0 == src1) //processing first row - memset(cache_vert_mask, 0, count); - - for(i=0;i<count;++i) { - 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; - - mask |= interp_32_diff(c[0], c[4]) << 0; - mask |= cache_vert_mask[i]; - mask |= interp_32_diff(c[2], c[4]) << 2; - mask |= cache_horiz_mask; - cache_horiz_mask = interp_32_diff(c[5], c[4]) << 3; - mask |= cache_horiz_mask << 1; // << 3 << 1 == << 4 - mask |= interp_32_diff(c[6], c[4]) << 5; - cache_vert_mask[i] = interp_32_diff(c[7], c[4]) << 1; - mask |= cache_vert_mask[i] << 5; // << 1 << 5 == << 6 - mask |= interp_32_diff(c[8], c[4]) << 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*3; - int dstRowPixels = dstPitch>>2; - - finalw=width*3; - finalh=height*3; - - uint32_t *dst0 = (uint32_t *)dstPtr; - uint32_t *dst1 = dst0 + dstRowPixels; - uint32_t *dst2 = dst1 + dstRowPixels; - - uint32_t *src0 = (uint32_t *)srcPtr; - uint32_t *src1 = src0 + (srcPitch >> 2); - uint32_t *src2 = src1 + (srcPitch >> 2); - hq3x_32_def(dst0, dst1, dst2, src0, src0, src2, width); - - count -= 2; - while(count) { - dst0 += dstRowPixels * 3; - dst1 += dstRowPixels * 3; - dst2 += dstRowPixels * 3; - - hq3x_32_def(dst0, dst1, dst2, src0, src1, src2, width); - src0 = src1; - src1 = src2; - src2 += srcPitch >> 2; - --count; - } - dst0 += dstRowPixels * 3; - dst1 += dstRowPixels * 3; - dst2 += dstRowPixels * 3; - - hq3x_32_def(dst0, dst1, dst2, src0, src1, src1, width); - -} +/***************************************************************************
+ 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"
+#include "swap.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 iMaintainAspect = 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];
+
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#include <X11/extensions/Xv.h>
+#include <X11/extensions/Xvlib.h>
+#include <X11/extensions/XShm.h>
+int xv_port = -1;
+int xv_id = -1;
+int xv_depth = 0;
+int yuv_port = -1;
+int yuv_id = -1;
+int use_yuv = 0;
+int xv_vsync = 0;
+
+XShmSegmentInfo shminfo;
+int finalw,finalh;
+
+extern XvImage *XvShmCreateImage(Display*, XvPortID, int, char*, int, int, XShmSegmentInfo*);
+
+#include <time.h>
+
+// prototypes
+void hq2x_32( 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;
+}
+
+/* Convert RGB to YUV */
+__inline uint32_t rgb_to_yuv(uint8_t R, uint8_t G, uint8_t B) {
+ uint8_t Y = min(abs(R * 2104 + G * 4130 + B * 802 + 4096 + 131072) >> 13, 235);
+ uint8_t U = min(abs(R * -1214 + G * -2384 + B * 3598 + 4096 + 1048576) >> 13, 240);
+ uint8_t V = min(abs(R * 3598 + G * -3013 + B * -585 + 4096 + 1048576) >> 13, 240);
+
+#ifdef __BIG_ENDIAN__
+ return Y << 24 | U << 16 | Y << 8 | V;
+#else
+ return Y << 24 | V << 16 | Y << 8 | U;
+#endif
+}
+
+#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;
+
+ finalw=width<<1;
+ finalh=height<<1;
+
+ 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;
+
+ finalw=width<<1;
+ finalh=height<<1;
+
+ 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;
+
+ finalw=width<<1;
+ finalh=height<<1;
+
+ 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--)
+ }
+}
+
+/////////////////////////
+
+//#include <assert.h>
+
+static __inline void scale2x_32_def_whole(uint32_t* dst0, uint32_t* dst1, const uint32_t* src0, const uint32_t* src1, const uint32_t* src2, unsigned count)
+{
+
+ //assert(count >= 2);
+
+ // 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 srcpitch = srcPitch;
+ const int dstPitch = srcPitch<<1;
+
+ int count = height;
+
+ finalw=width<<1;
+ finalh=height<<1;
+
+ uint32_t *dst0 = (uint32_t *)dstPtr;
+ uint32_t *dst1 = dst0 + (dstPitch >> 2);
+
+ uint32_t *src0 = (uint32_t *)srcPtr;
+ uint32_t *src1 = src0 + (srcPitch >> 2);
+ uint32_t *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(uint32_t* dst0, uint32_t* dst1, uint32_t* dst2, const uint32_t* src0, const uint32_t* src1, const uint32_t* 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_ex8(unsigned char *srcPtr, DWORD srcPitch,
+ unsigned char *dstPtr, int width, int height)
+{
+ int count = height;
+
+ int dstPitch = srcPitch*3;
+ int dstRowPixels = dstPitch>>2;
+
+ finalw=width*3;
+ finalh=height*3;
+
+ uint32_t *dst0 = (uint32_t *)dstPtr;
+ uint32_t *dst1 = dst0 + dstRowPixels;
+ uint32_t *dst2 = dst1 + dstRowPixels;
+
+ uint32_t *src0 = (uint32_t *)srcPtr;
+ uint32_t *src1 = src0 + (srcPitch >> 2);
+ uint32_t *src2 = src1 + (srcPitch >> 2);
+ scale3x_32_def_whole(dst0, dst1, dst2, src0, src0, src2, width);
+
+ count -= 2;
+ while(count) {
+ dst0 += dstRowPixels*3;
+ dst1 += dstRowPixels*3;
+ dst2 += dstRowPixels*3;
+
+ scale3x_32_def_whole(dst0, dst1, dst2, src0, src1, src2, width);
+ src0 = src1;
+ src1 = src2;
+ src2 += srcPitch >> 2;
+ --count;
+ }
+
+ dst0 += dstRowPixels*3;
+ dst1 += dstRowPixels*3;
+ dst2 += dstRowPixels*3;
+
+ scale3x_32_def_whole(dst0, dst1, dst2, src0, src1, src1, width);
+}
+
+
+////////////////////////////////////////////////////////////////////////
+
+#ifndef MAX
+#define MAX(a,b) (((a) > (b)) ? (a) : (b))
+#define MIN(a,b) (((a) < (b)) ? (a) : (b))
+#endif
+
+
+////////////////////////////////////////////////////////////////////////
+// X STUFF :)
+////////////////////////////////////////////////////////////////////////
+
+
+static Cursor cursor;
+XVisualInfo vi;
+static XVisualInfo *myvisual;
+Display *display;
+static Colormap colormap;
+Window window;
+static GC hGC;
+static XImage * Ximage;
+static XvImage * XCimage;
+static XImage * XPimage=0;
+char * Xpixels;
+char * pCaptionText;
+
+static int fx=0;
+
+
+static Atom xv_intern_atom_if_exists( Display *display, char const * atom_name )
+{
+ XvAttribute * attributes;
+ int attrib_count,i;
+ Atom xv_atom = None;
+
+ attributes = XvQueryPortAttributes( display, xv_port, &attrib_count );
+ if( attributes!=NULL )
+ {
+ for ( i = 0; i < attrib_count; ++i )
+ {
+ if ( strcmp(attributes[i].name, atom_name ) == 0 )
+ {
+ xv_atom = XInternAtom( display, atom_name, False );
+ break; // found what we want, break out
+ }
+ }
+ XFree( attributes );
+ }
+
+ return xv_atom;
+}
+
+
+
+// close display
+
+void DestroyDisplay(void)
+{
+ if(display)
+ {
+ XFreeColormap(display, colormap);
+ if(hGC)
+ {
+ XFreeGC(display,hGC);
+ hGC = 0;
+ }
+ if(Ximage)
+ {
+ XDestroyImage(Ximage);
+ Ximage=0;
+ }
+ if(XCimage)
+ {
+ XFree(XCimage);
+ XCimage=0;
+ }
+
+ XShmDetach(display,&shminfo);
+ shmdt(shminfo.shmaddr);
+ shmctl(shminfo.shmid,IPC_RMID,NULL);
+
+ Atom atom_vsync = xv_intern_atom_if_exists(display, "XV_SYNC_TO_VBLANK");
+ if (atom_vsync != None) {
+ XvSetPortAttribute(display, xv_port, atom_vsync, xv_vsync);
+ }
+
+ XSync(display,False);
+
+ XCloseDisplay(display);
+ }
+}
+
+static int depth=0;
+int root_window_id=0;
+
+
+// Create display
+
+void CreateDisplay(void)
+{
+ XSetWindowAttributes winattr;
+ int myscreen;
+ Screen * screen;
+ XEvent event;
+ XSizeHints hints;
+ XWMHints wm_hints;
+ MotifWmHints mwmhints;
+ Atom mwmatom;
+
+ Atom delwindow;
+
+ XGCValues gcv;
+ int i;
+
+ int ret, j, p;
+ int formats;
+ unsigned int p_num_adaptors=0, p_num_ports=0;
+
+ XvAdaptorInfo *ai;
+ XvImageFormatValues *fo;
+
+ // Open display
+ display = XOpenDisplay(NULL);
+
+ if (!display)
+ {
+ fprintf (stderr,"Failed to open display!!!\n");
+ DestroyDisplay();
+ return;
+ }
+
+ myscreen=DefaultScreen(display);
+
+ // desktop fullscreen switch
+ if (!iWindowMode) fx = 1;
+
+ screen=DefaultScreenOfDisplay(display);
+
+ root_window_id=RootWindow(display,DefaultScreen(display));
+
+ //Look for an Xvideo RGB port
+ ret = XvQueryAdaptors(display, root_window_id, &p_num_adaptors, &ai);
+ if (ret != Success) {
+ if (ret == XvBadExtension)
+ printf("XvBadExtension returned at XvQueryExtension.\n");
+ else
+ if (ret == XvBadAlloc)
+ printf("XvBadAlloc returned at XvQueryExtension.\n");
+ else
+ printf("other error happaned at XvQueryAdaptors.\n");
+
+ exit(-1);
+ }
+
+ depth = DefaultDepth(display, myscreen);
+
+ for (i = 0; i < p_num_adaptors; i++) {
+ p_num_ports = ai[i].base_id + ai[i].num_ports;
+ for (p = ai[i].base_id; p < p_num_ports; p++) {
+ fo = XvListImageFormats(display, p, &formats);
+ for (j = 0; j < formats; j++) {
+ //backup YUV mode
+ //hmm, should I bother check guid == 55595659-0000-0010-8000-00aa00389b71?
+ //and check byte order? fo[j].byte_order == LSBFirst
+#ifdef __BIG_ENDIAN__
+ if ( fo[j].type == XvYUV && fo[j].bits_per_pixel == 16 && fo[j].format == XvPacked && strncmp("YUYV", fo[j].component_order, 5) == 0 )
+#else
+ if ( fo[j].type == XvYUV && fo[j].bits_per_pixel == 16 && fo[j].format == XvPacked && strncmp("UYVY", fo[j].component_order, 5) == 0 )
+#endif
+ {
+ yuv_port = p;
+ yuv_id = fo[j].id;
+ }
+ if (fo[j].type == XvRGB && fo[j].bits_per_pixel == 32)
+ {
+ xv_port = p;
+ xv_id = fo[j].id;
+ xv_depth = fo[j].depth;
+ printf("RGB mode found. id: %x, depth: %d\n", xv_id, xv_depth);
+
+ if (xv_depth != depth) {
+ printf("Warning: Depth does not match screen depth (%d)\n", depth);
+ }
+ else {
+ //break out of loops
+ j = formats;
+ p = p_num_ports;
+ i = p_num_adaptors;
+ }
+ }
+ }
+ if (fo)
+ XFree(fo);
+ }
+ }
+ if (p_num_adaptors > 0)
+ XvFreeAdaptorInfo(ai);
+ if (xv_port == -1 && yuv_port == -1)
+ {
+ printf("RGB & YUV not found. Quitting.\n");
+ exit(-1);
+ }
+ else if (xv_port == -1 && yuv_port != -1)
+ {
+ use_yuv = 1;
+ printf("RGB not found. Using YUV.\n");
+ xv_port = yuv_port;
+ xv_id = yuv_id;
+ }
+ else if (xv_depth && xv_depth != depth && yuv_port != -1)
+ {
+ use_yuv = 1;
+ printf("Acceptable RGB mode not found. Using YUV.\n");
+ xv_port = yuv_port;
+ xv_id = yuv_id;
+ }
+
+ Atom atom_vsync = xv_intern_atom_if_exists(display, "XV_SYNC_TO_VBLANK");
+ if (atom_vsync != None) {
+ XvGetPortAttribute(display, xv_port, atom_vsync, &xv_vsync);
+ XvSetPortAttribute(display, xv_port, atom_vsync, 0);
+ }
+
+myvisual = 0;
+
+if(XMatchVisualInfo(display,myscreen, depth, TrueColor, &vi))
+ myvisual = &vi;
+
+if (!myvisual)
+{
+ fprintf(stderr,"Failed to obtain visual!\n");
+ DestroyDisplay();
+ return;
+}
+
+ if(myvisual->red_mask==0x00007c00 &&
+ myvisual->green_mask==0x000003e0 &&
+ myvisual->blue_mask==0x0000001f)
+ {iColDepth=15;}
+ else
+ if(myvisual->red_mask==0x0000f800 &&
+ myvisual->green_mask==0x000007e0 &&
+ myvisual->blue_mask==0x0000001f)
+ {iColDepth=16;}
+ else
+ if(myvisual->red_mask==0x00ff0000 &&
+ myvisual->green_mask==0x0000ff00 &&
+ myvisual->blue_mask==0x000000ff)
+ {iColDepth=32;}
+ else
+ {
+ iColDepth=0;
+/* fprintf(stderr,"COLOR DEPTH NOT SUPPORTED!\n");
+ fprintf(stderr,"r: %08lx\n",myvisual->red_mask);
+ fprintf(stderr,"g: %08lx\n",myvisual->green_mask);
+ fprintf(stderr,"b: %08lx\n",myvisual->blue_mask);
+ DestroyDisplay();
+ return;*/
+ }
+
+ // pffff... much work for a simple blank cursor... oh, well...
+ if(iWindowMode) cursor=XCreateFontCursor(display,XC_trek);
+ else
+ {
+ Pixmap p1,p2;
+ XImage * img;
+ XColor b,w;
+ char * idata;
+ XGCValues GCv;
+ GC GCc;
+
+ memset(&b,0,sizeof(XColor));
+ memset(&w,0,sizeof(XColor));
+ idata=(char *)malloc(8);
+ memset(idata,0,8);
+
+ p1=XCreatePixmap(display,RootWindow(display,myvisual->screen),8,8,1);
+ p2=XCreatePixmap(display,RootWindow(display,myvisual->screen),8,8,1);
+
+ img = XCreateImage(display,myvisual->visual,
+ 1,XYBitmap,0,idata,8,8,8,1);
+
+ GCv.function = GXcopy;
+ GCv.foreground = ~0;
+ GCv.background = 0;
+ GCv.plane_mask = AllPlanes;
+ GCc = XCreateGC(display,p1,
+ (GCFunction|GCForeground|GCBackground|GCPlaneMask),&GCv);
+
+ XPutImage(display, p1,GCc,img,0,0,0,0,8,8);
+ XPutImage(display, p2,GCc,img,0,0,0,0,8,8);
+ XFreeGC(display, GCc);
+
+ cursor = XCreatePixmapCursor(display,p1,p2,&b,&w,0,0);
+
+ XFreePixmap(display,p1);
+ XFreePixmap(display,p2);
+ XDestroyImage(img); // will free idata as well
+ }
+
+ colormap=XCreateColormap(display,root_window_id,
+ myvisual->visual,AllocNone);
+
+ winattr.background_pixel=BlackPixelOfScreen(screen);
+ winattr.border_pixel=WhitePixelOfScreen(screen);
+ winattr.bit_gravity=ForgetGravity;
+ winattr.win_gravity=NorthWestGravity;
+ winattr.backing_store=NotUseful;
+
+ winattr.override_redirect=False;
+ winattr.save_under=False;
+ winattr.event_mask=0;
+ winattr.do_not_propagate_mask=0;
+ winattr.colormap=colormap;
+ winattr.cursor=None;
+
+ window=XCreateWindow(display,root_window_id,
+ 0,0,iResX,iResY,
+ 0,myvisual->depth,
+ InputOutput,myvisual->visual,
+ CWBorderPixel | CWBackPixel |
+ CWEventMask | CWDontPropagate |
+ CWColormap | CWCursor,
+ &winattr);
+
+ if(!window)
+ {
+ fprintf(stderr,"Failed in XCreateWindow()!!!\n");
+ DestroyDisplay();
+ return;
+ }
+
+ delwindow = XInternAtom(display,"WM_DELETE_WINDOW",0);
+ XSetWMProtocols(display, window, &delwindow, 1);
+
+ hints.flags=USPosition|USSize;
+ hints.base_width = iResX;
+ hints.base_height = iResY;
+
+ wm_hints.input=1;
+ wm_hints.flags=InputHint;
+
+ XSetWMHints(display,window,&wm_hints);
+ XSetWMNormalHints(display,window,&hints);
+ if(pCaptionText)
+ XStoreName(display,window,pCaptionText);
+ else XStoreName(display,window,"P.E.Op.S SoftX PSX Gpu");
+
+ XDefineCursor(display,window,cursor);
+
+ // hack to get rid of window title bar
+ if (fx)
+ {
+ mwmhints.flags=MWM_HINTS_DECORATIONS;
+ mwmhints.decorations=0;
+ mwmatom=XInternAtom(display,"_MOTIF_WM_HINTS",0);
+ XChangeProperty(display,window,mwmatom,mwmatom,32,
+ PropModeReplace,(unsigned char *)&mwmhints,4);
+ }
+
+ // key stuff
+ XSelectInput(display,
+ window,
+ FocusChangeMask | ExposureMask |
+ KeyPressMask | KeyReleaseMask
+ );
+
+ XMapRaised(display,window);
+ XClearWindow(display,window);
+ XWindowEvent(display,window,ExposureMask,&event);
+
+ if (fx) // fullscreen
+ {
+ XResizeWindow(display,window,screen->width,screen->height);
+
+ hints.min_width = hints.max_width = hints.base_width = screen->width;
+ hints.min_height= hints.max_height = hints.base_height = screen->height;
+
+ XSetWMNormalHints(display,window,&hints);
+
+ // set the window layer for GNOME
+ {
+ XEvent xev;
+
+ memset(&xev, 0, sizeof(xev));
+ xev.xclient.type = ClientMessage;
+ xev.xclient.serial = 0;
+ xev.xclient.send_event = 1;
+ xev.xclient.message_type = XInternAtom(display, "_NET_WM_STATE", 0);
+ xev.xclient.window = window;
+ xev.xclient.format = 32;
+ xev.xclient.data.l[0] = 1;
+ xev.xclient.data.l[1] = XInternAtom(display, "_NET_WM_STATE_FULLSCREEN", 0);
+ xev.xclient.data.l[2] = 0;
+ xev.xclient.data.l[3] = 0;
+ xev.xclient.data.l[4] = 0;
+
+ XSendEvent(display, root_window_id, 0,
+ SubstructureRedirectMask | SubstructureNotifyMask, &xev);
+ }
+ }
+
+ gcv.foreground = 0x0000FF00; // green letters for the FPS bar; do we need to take care of endianess?
+ gcv.background = 0x00000000;
+ gcv.graphics_exposures = False;
+ hGC = XCreateGC(display,window,
+ GCGraphicsExposures | GCForeground | GCBackground, &gcv);
+ if(!hGC)
+ {
+ fprintf(stderr,"No gfx context!!!\n");
+ DestroyDisplay();
+ }
+
+ uint32_t color;
+
+ /* fix the green back ground in YUV mode */
+ if(use_yuv)
+ color = rgb_to_yuv(0x00, 0x00, 0x00);
+ else
+ color = 0;
+
+ Xpixels = (char *)malloc(8*8*4);
+ for(i = 0; i < 8*8; ++i)
+ ((uint32_t *)Xpixels)[i] = color;
+
+ XCimage = XvCreateImage(display,xv_port,xv_id,
+ (char *)Xpixels, 8, 8);
+
+
+/*
+Allocate max that could be needed:
+Big(est?) PSX res: 640x512
+32bpp (times 4)
+2xsai func= 3xwidth,3xheight
+= approx 11.8mb
+*/
+shminfo.shmid = shmget(IPC_PRIVATE, 640*512*4*3*3, IPC_CREAT | 0777);
+shminfo.shmaddr = shmat(shminfo.shmid, 0, 0);
+shminfo.readOnly = 0;
+
+ if (!XShmAttach(display, &shminfo)) {
+ printf("XShmAttach failed !\n");
+ exit (-1);
+ }
+
+ {
+ uint32_t *pShmaddr = (uint32_t *)shminfo.shmaddr;
+ for(i = 0; i < 640*512*3*3; ++i)
+ pShmaddr[i] = color;
+ }
+}
+
+void (*p2XSaIFunc) (unsigned char *, DWORD, unsigned char *, int, int);
+unsigned char *pBackBuffer = 0;
+
+void BlitScreen32(unsigned char *surf, int32_t x, int32_t y)
+{
+ unsigned char *pD;
+ unsigned int startxy;
+ uint32_t lu;
+ unsigned short s;
+ unsigned short row, column;
+ unsigned short dx = PreviousPSXDisplay.Range.x1;
+ unsigned short dy = PreviousPSXDisplay.DisplayMode.y;
+
+ int32_t lPitch = PSXDisplay.DisplayMode.x << 2;
+
+ uint32_t *destpix;
+
+ if (PreviousPSXDisplay.Range.y0) // centering needed?
+ {
+ memset(surf, 0, (PreviousPSXDisplay.Range.y0 >> 1) * lPitch);
+
+ dy -= PreviousPSXDisplay.Range.y0;
+ surf += (PreviousPSXDisplay.Range.y0 >> 1) * lPitch;
+
+ memset(surf + dy * lPitch,
+ 0, ((PreviousPSXDisplay.Range.y0 + 1) >> 1) * lPitch);
+ }
+
+ if (PreviousPSXDisplay.Range.x0)
+ {
+ for (column = 0; column < dy; column++)
+ {
+ destpix = (uint32_t *)(surf + (column * lPitch));
+ memset(destpix, 0, PreviousPSXDisplay.Range.x0 << 2);
+ }
+ surf += PreviousPSXDisplay.Range.x0 << 2;
+ }
+
+ if (PSXDisplay.RGB24)
+ {
+ for (column = 0; column < dy; column++)
+ {
+ startxy = ((1024) * (column + y)) + x;
+ pD = (unsigned char *)&psxVuw[startxy];
+ destpix = (uint32_t *)(surf + (column * lPitch));
+ for (row = 0; row < dx; row++)
+ {
+ lu = *((uint32_t *)pD);
+ destpix[row] =
+ 0xff000000 | (RED(lu) << 16) | (GREEN(lu) << 8) | (BLUE(lu));
+ pD += 3;
+ }
+ }
+ }
+ else
+ {
+ for (column = 0;column<dy;column++)
+ {
+ startxy = (1024 * (column + y)) + x;
+ destpix = (uint32_t *)(surf + (column * lPitch));
+ for (row = 0; row < dx; row++)
+ {
+ s = GETLE16(&psxVuw[startxy++]);
+ destpix[row] =
+ (((s << 19) & 0xf80000) | ((s << 6) & 0xf800) | ((s >> 7) & 0xf8)) | 0xff000000;
+ }
+ }
+ }
+}
+
+
+
+void BlitToYUV(unsigned char * surf,int32_t x,int32_t y)
+{
+ unsigned char * pD;
+ unsigned int startxy;
+ uint32_t lu;unsigned short s;
+ unsigned short row,column;
+ unsigned short dx = PreviousPSXDisplay.Range.x1;
+ unsigned short dy = PreviousPSXDisplay.DisplayMode.y;
+ int R,G,B;
+
+ int32_t lPitch = PSXDisplay.DisplayMode.x << 2;
+ uint32_t *destpix;
+
+ if (PreviousPSXDisplay.Range.y0) // centering needed?
+ {
+ for (column = 0; column < (PreviousPSXDisplay.Range.y0 >> 1); column++)
+ {
+ destpix = (uint32_t *)(surf + column * lPitch);
+ for (row = 0; row < dx; row++)
+ {
+ destpix[row] = (4 << 24) | (128 << 16) | (4 << 8) | 128;
+ }
+ }
+
+ dy -= PreviousPSXDisplay.Range.y0;
+ surf += (PreviousPSXDisplay.Range.y0 >> 1) * lPitch;
+
+ for (column = 0; column < (PreviousPSXDisplay.Range.y0 + 1) >> 1; column++)
+ {
+ destpix = (uint32_t *)(surf + (dy + column) * lPitch);
+ for (row = 0; row < dx; row++)
+ {
+ destpix[row] = (4 << 24) | (128 << 16) | (4 << 8) | 128;
+ }
+ }
+ }
+
+ if (PreviousPSXDisplay.Range.x0)
+ {
+ for (column = 0; column < dy; column++)
+ {
+ destpix = (uint32_t *)(surf + (column * lPitch));
+ for (row = 0; row < PreviousPSXDisplay.Range.x0; row++)
+ {
+ destpix[row] = (4 << 24) | (128 << 16) | (4 << 8) | 128;
+ }
+ }
+ surf += PreviousPSXDisplay.Range.x0 << 2;
+ }
+
+ if (PSXDisplay.RGB24)
+ {
+ for (column = 0; column < dy; column++)
+ {
+ startxy = (1024 * (column + y)) + x;
+ pD = (unsigned char *)&psxVuw[startxy];
+ destpix = (uint32_t *)(surf + (column * lPitch));
+ for (row = 0; row < dx; row++)
+ {
+ lu = *((uint32_t *)pD);
+
+ R = RED(lu);
+ G = GREEN(lu);
+ B = BLUE(lu);
+
+ destpix[row] = rgb_to_yuv(R, G, B);
+
+ pD += 3;
+ }
+ }
+ }
+ else
+ {
+ for (column = 0; column < dy; column++)
+ {
+ startxy = (1024 * (column + y)) + x;
+ destpix = (uint32_t *)(surf + (column * lPitch));
+ for (row = 0; row < dx; row++)
+ {
+ s = GETLE16(&psxVuw[startxy++]);
+
+ R = (s << 3) &0xf8;
+ G = (s >> 2) &0xf8;
+ B = (s >> 7) &0xf8;
+
+ destpix[row] = rgb_to_yuv(R, G, B);
+
+ }
+ }
+ }
+}
+
+//dst will have half the pitch (32bit to 16bit)
+void RGB2YUV(uint32_t *s, int width, int height, uint32_t *d)
+{
+ int x,y;
+ int R,G,B, Y1,Y2,U,V;
+
+ for (y=0; y<height; y++) {
+ for(x=0; x<width>>1; x++) {
+ R = (*s >> 16) & 0xff;
+ G = (*s >> 8) & 0xff;
+ B = *s & 0xff;
+ s++;
+
+ Y1 = min(abs(R * 2104 + G * 4130 + B * 802 + 4096 + 131072) >> 13, 235);
+ U = min(abs(R * -1214 + G * -2384 + B * 3598 + 4096 + 1048576) >> 13, 240);
+ V = min(abs(R * 3598 + G * -3013 + B * -585 + 4096 + 1048576) >> 13, 240);
+
+ R = (*s >> 16) & 0xff;
+ G = (*s >> 8) & 0xff;
+ B = *s & 0xff;
+ s++;
+
+ Y2 = min(abs(R * 2104 + G * 4130 + B * 802 + 4096 + 131072) >> 13, 235);
+
+#ifdef __BIG_ENDIAN__
+ *d = V | Y2 << 8 | U << 16 | Y1 << 24;
+#else
+ *d = U | Y1 << 8 | V << 16 | Y2 << 24;
+#endif
+ d++;
+ }
+ }
+}
+
+extern time_t tStart;
+
+/* compute the position and the size of output screen
+ * The aspect of the psx output mode is preserved.
+ * Note: dest dx,dy,dw,dh are both input and output variables
+ */
+__inline void MaintainAspect(uint32_t * dx, uint32_t * dy, uint32_t * dw, uint32_t * dh)
+{
+
+ double ratio_x = ((double)*dw) / ((double)PSXDisplay.DisplayMode.x) ;
+ double ratio_y = ((double)*dh) / ((double)PSXDisplay.DisplayMode.y);
+
+ double ratio;
+ if (ratio_x < ratio_y) {
+ ratio = ratio_x;
+ } else {
+ ratio = ratio_y;
+ }
+
+ uint32_t tw = (uint32_t) floor(PSXDisplay.DisplayMode.x * ratio);
+ uint32_t th = (uint32_t) floor(PSXDisplay.DisplayMode.y * ratio);
+
+ *dx = (uint32_t) floor((*dw - tw) / 2.0);
+ *dy = (uint32_t) floor((*dh - th) / 2.0);
+ *dw = tw;
+ *dh = th;
+}
+
+void DoBufferSwap(void)
+{
+ Screen *screen;
+ Window _dw;
+ XvImage *xvi;
+ unsigned int dstx, dsty;
+ unsigned int _d, _w, _h; //don't care about _d
+
+ finalw = PSXDisplay.DisplayMode.x;
+ finalh = PSXDisplay.DisplayMode.y;
+
+ if (finalw == 0 || finalh == 0)
+ return;
+
+ XSync(display,False);
+
+ if(use_yuv) {
+ if (iUseNoStretchBlt==0 || finalw > 320 || finalh > 256) {
+ BlitToYUV((unsigned char *)shminfo.shmaddr, PSXDisplay.DisplayPosition.x, PSXDisplay.DisplayPosition.y);
+ finalw <<= 1;
+ } else {
+ BlitScreen32((unsigned char *)pBackBuffer, PSXDisplay.DisplayPosition.x, PSXDisplay.DisplayPosition.y);
+ p2XSaIFunc(pBackBuffer, finalw<<2, (unsigned char *)pSaIBigBuff,finalw,finalh);
+ RGB2YUV( (uint32_t*)pSaIBigBuff, finalw, finalh, (uint32_t*)shminfo.shmaddr);
+ }
+ } else if(iUseNoStretchBlt==0 || finalw > 320 || finalh > 256) {
+ BlitScreen32((unsigned char *)shminfo.shmaddr, PSXDisplay.DisplayPosition.x, PSXDisplay.DisplayPosition.y);
+ } else {
+ BlitScreen32((unsigned char *)pBackBuffer, PSXDisplay.DisplayPosition.x, PSXDisplay.DisplayPosition.y);
+ p2XSaIFunc(pBackBuffer, finalw<<2, (unsigned char *)shminfo.shmaddr,finalw,finalh);
+ }
+
+ XGetGeometry(display, window, &_dw, (int *)&_d, (int *)&_d, &_w, &_h, &_d, &_d);
+ if (use_yuv) {
+ xvi = XvShmCreateImage(display, yuv_port, yuv_id, 0, finalw, finalh, &shminfo);
+ } else
+ xvi = XvShmCreateImage(display, xv_port, xv_id, 0, finalw, finalh, &shminfo);
+
+ xvi->data = shminfo.shmaddr;
+
+ screen=DefaultScreenOfDisplay(display);
+ //screennum = DefaultScreen(display);
+
+ if (!iWindowMode) {
+ _w = screen->width;
+ _h = screen->height;
+ }
+
+ dstx = 0;
+ dsty = 0;
+
+ if (iMaintainAspect)
+ MaintainAspect(&dstx, &dsty, &_w, &_h);
+
+/*Whistler: too slow/laggy so commented out for now
+ if(iRumbleTime)
+ {
+ dstx += (rand() % iRumbleVal) - iRumbleVal / 2;
+ _w -= (rand() % iRumbleVal) - iRumbleVal / 2;
+ dsty += (rand() % iRumbleVal) - iRumbleVal / 2;
+ _h -= (rand() % iRumbleVal) - iRumbleVal / 2;
+ iRumbleTime--;
+ }
+*/
+ XvShmPutImage(display, xv_port, window, hGC, xvi,
+ 0,0, //src x,y
+ finalw,finalh, //src w,h
+ dstx,dsty, //dst x,y
+ _w, _h, //dst w,h
+ 1
+ );
+
+ if(ulKeybits&KEY_SHOWFPS) //DisplayText(); c // paint menu text
+ {
+ if(szDebugText[0] && ((time(NULL) - tStart) < 2))
+ {
+ strcpy(szDispBuf,szDebugText);
+ }
+ else
+ {
+ szDebugText[0]=0;
+ strcat(szDispBuf,szMenuBuf);
+ }
+
+ //XPutImage(display,window,hGC, XFimage,
+ // 0, 0, 0, 0, 220,15);
+
+ XDrawImageString(display,window,hGC,2,13,szDispBuf,strlen(szDispBuf));
+ }
+
+ //if(XPimage) DisplayPic();
+
+ XFree(xvi);
+}
+
+void DoClearScreenBuffer(void) // CLEAR DX BUFFER
+{
+ Window _dw;
+ unsigned int _d, _w, _h; //don't care about _d
+
+ XGetGeometry(display, window, &_dw, (int *)&_d, (int *)&_d, &_w, &_h, &_d, &_d);
+
+ XvPutImage(display, xv_port, window, hGC, XCimage,
+ 0, 0, 8, 8, 0, 0, _w, _h);
+ //XSync(display,False);
+}
+
+void DoClearFrontBuffer(void) // CLEAR DX BUFFER
+{/*
+ XPutImage(display,window,hGC, XCimage,
+ 0, 0, 0, 0, iResX, iResY);
+ XSync(display,False);*/
+}
+
+int Xinitialize()
+{
+ iDesktopCol=32;
+
+
+ if(iUseNoStretchBlt>0)
+ {
+ pBackBuffer=(unsigned char *)malloc(640*512*sizeof(uint32_t));
+ memset(pBackBuffer,0,640*512*sizeof(uint32_t));
+ if (use_yuv) {
+ pSaIBigBuff=malloc(640*512*4*3*3);
+ memset(pSaIBigBuff,0,640*512*4*3*3);
+ }
+ }
+
+ p2XSaIFunc=NULL;
+
+ if(iUseNoStretchBlt==1)
+ {
+ p2XSaIFunc=Std2xSaI_ex8;
+ }
+
+ if(iUseNoStretchBlt==2)
+ {
+ p2XSaIFunc=Super2xSaI_ex8;
+ }
+
+ if(iUseNoStretchBlt==3)
+ {
+ p2XSaIFunc=SuperEagle_ex8;
+ }
+
+ if(iUseNoStretchBlt==4)
+ {
+ p2XSaIFunc=Scale2x_ex8;
+ }
+ if(iUseNoStretchBlt==5)
+ {
+ p2XSaIFunc=Scale3x_ex8;
+ }
+ if(iUseNoStretchBlt==6)
+ {
+ p2XSaIFunc=hq2x_32;
+ }
+ if(iUseNoStretchBlt==7)
+ {
+ p2XSaIFunc=hq3x_32;
+ }
+
+ bUsingTWin=FALSE;
+
+ InitMenu();
+
+ bIsFirstFrame = FALSE; // done
+
+ if(iShowFPS)
+ {
+ iShowFPS=0;
+ ulKeybits|=KEY_SHOWFPS;
+ szDispBuf[0]=0;
+ BuildDispMenu(0);
+ }
+
+ return 0;
+}
+
+void Xcleanup() // X CLEANUP
+{
+ CloseMenu();
+
+ if(iUseNoStretchBlt>0)
+ {
+ if(pBackBuffer) free(pBackBuffer);
+ pBackBuffer=0;
+ if(pSaIBigBuff) free(pSaIBigBuff);
+ pSaIBigBuff=0;
+ }
+}
+
+unsigned long ulInitDisplay(void)
+{
+ CreateDisplay(); // x stuff
+ Xinitialize(); // init x
+ return (unsigned long)display;
+}
+
+void CloseDisplay(void)
+{
+ Xcleanup(); // cleanup dx
+ DestroyDisplay();
+}
+
+void CreatePic(unsigned char * pMem)
+{
+ unsigned char * p=(unsigned char *)malloc(128*96*4);
+ unsigned char * ps; int x,y;
+
+ ps=p;
+
+ 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*256+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*256+x*2))=s;
+ }
+ }
+ }
+ else
+ if(iDesktopCol==32)
+ {
+ uint32_t 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;
+ *((uint32_t *)(ps+y*512+x*4))=l;
+ }
+ }
+ }
+
+ XPimage = XCreateImage(display,myvisual->visual,
+ depth, ZPixmap, 0,
+ (char *)p,
+ 128, 96,
+ depth>16 ? 32 : 16,
+ 0);
+}
+
+void DestroyPic(void)
+{
+ if(XPimage)
+ { /*
+ XPutImage(display,window,hGC, XCimage,
+ 0, 0, 0, 0, iResX, iResY);*/
+ XDestroyImage(XPimage);
+ XPimage=0;
+ }
+}
+
+void DisplayPic(void)
+{
+ XPutImage(display,window,hGC, XPimage,
+ 0, 0, iResX-128, 0,128,96);
+}
+
+void ShowGpuPic(void)
+{
+}
+
+void ShowTextGpuPic(void)
+{
+}
+
+static void hq2x_32_def(uint32_t * dst0, uint32_t * dst1, const uint32_t * src0, const uint32_t * src1, const uint32_t * src2, unsigned count)
+{
+ static unsigned char cache_vert_mask[640];
+ unsigned char cache_horiz_mask = 0;
+
+ unsigned i;
+ unsigned char mask;
+ uint32_t c[9];
+
+ if (src0 == src1) //processing first row
+ memset(cache_vert_mask, 0, count);
+
+ for(i=0;i<count;++i) {
+ 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;
+
+ mask |= interp_32_diff(c[0], c[4]) << 0;
+ mask |= cache_vert_mask[i];
+ mask |= interp_32_diff(c[2], c[4]) << 2;
+ mask |= cache_horiz_mask;
+ cache_horiz_mask = interp_32_diff(c[5], c[4]) << 3;
+ mask |= cache_horiz_mask << 1; // << 3 << 1 == << 4
+ mask |= interp_32_diff(c[6], c[4]) << 5;
+ cache_vert_mask[i] = interp_32_diff(c[7], c[4]) << 1;
+ mask |= cache_vert_mask[i] << 5; // << 1 << 5 == << 6
+ mask |= interp_32_diff(c[8], c[4]) << 7;
+
+#define P0 dst0[0]
+#define P1 dst0[1]
+#define P2 dst1[0]
+#define P3 dst1[1]
+#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 "hq2x.h"
+ }
+
+#undef P0
+#undef P1
+#undef P2
+#undef P3
+#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 += 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;
+
+ finalw=width*2;
+ finalh=height*2;
+
+ uint32_t *dst0 = (uint32_t *)dstPtr;
+ uint32_t *dst1 = dst0 + (dstPitch >> 2);
+
+ uint32_t *src0 = (uint32_t *)srcPtr;
+ uint32_t *src1 = src0 + (srcPitch >> 2);
+ uint32_t *src2 = src1 + (srcPitch >> 2);
+ hq2x_32_def(dst0, dst1, src0, src0, src1, width);
+
+
+ count -= 2;
+ while(count) {
+ dst0 += dstPitch >> 1; //next 2 lines (dstPitch / 4 char per int * 2)
+ 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(uint32_t* dst0, uint32_t* dst1, uint32_t* dst2, const uint32_t* src0, const uint32_t* src1, const uint32_t* src2, unsigned count)
+{
+ static unsigned char cache_vert_mask[640];
+ unsigned char cache_horiz_mask = 0;
+
+ unsigned i;
+ unsigned char mask;
+ uint32_t c[9];
+
+ if (src0 == src1) //processing first row
+ memset(cache_vert_mask, 0, count);
+
+ for(i=0;i<count;++i) {
+ 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;
+
+ mask |= interp_32_diff(c[0], c[4]) << 0;
+ mask |= cache_vert_mask[i];
+ mask |= interp_32_diff(c[2], c[4]) << 2;
+ mask |= cache_horiz_mask;
+ cache_horiz_mask = interp_32_diff(c[5], c[4]) << 3;
+ mask |= cache_horiz_mask << 1; // << 3 << 1 == << 4
+ mask |= interp_32_diff(c[6], c[4]) << 5;
+ cache_vert_mask[i] = interp_32_diff(c[7], c[4]) << 1;
+ mask |= cache_vert_mask[i] << 5; // << 1 << 5 == << 6
+ mask |= interp_32_diff(c[8], c[4]) << 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*3;
+ int dstRowPixels = dstPitch>>2;
+
+ finalw=width*3;
+ finalh=height*3;
+
+ uint32_t *dst0 = (uint32_t *)dstPtr;
+ uint32_t *dst1 = dst0 + dstRowPixels;
+ uint32_t *dst2 = dst1 + dstRowPixels;
+
+ uint32_t *src0 = (uint32_t *)srcPtr;
+ uint32_t *src1 = src0 + (srcPitch >> 2);
+ uint32_t *src2 = src1 + (srcPitch >> 2);
+ hq3x_32_def(dst0, dst1, dst2, src0, src0, src2, width);
+
+ count -= 2;
+ while(count) {
+ dst0 += dstRowPixels * 3;
+ dst1 += dstRowPixels * 3;
+ dst2 += dstRowPixels * 3;
+
+ hq3x_32_def(dst0, dst1, dst2, src0, src1, src2, width);
+ src0 = src1;
+ src1 = src2;
+ src2 += srcPitch >> 2;
+ --count;
+ }
+ dst0 += dstRowPixels * 3;
+ dst1 += dstRowPixels * 3;
+ dst2 += dstRowPixels * 3;
+
+ hq3x_32_def(dst0, dst1, dst2, src0, src1, src1, width);
+
+}
|
