diff options
Diffstat (limited to 'src/2xsaiwin.cpp')
-rw-r--r-- | src/2xsaiwin.cpp | 707 |
1 files changed, 707 insertions, 0 deletions
diff --git a/src/2xsaiwin.cpp b/src/2xsaiwin.cpp new file mode 100644 index 0000000..fbff856 --- /dev/null +++ b/src/2xsaiwin.cpp @@ -0,0 +1,707 @@ +/* + * Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. + * + * (c) Copyright 1996 - 2001 Gary Henderson (gary.henderson@ntlworld.com) and + * Jerremy Koot (jkoot@snes9x.com) + * + * Super FX C emulator code + * (c) Copyright 1997 - 1999 Ivar (ivar@snes9x.com) and + * Gary Henderson. + * Super FX assembler emulator code (c) Copyright 1998 zsKnight and _Demo_. + * + * DSP1 emulator code (c) Copyright 1998 Ivar, _Demo_ and Gary Henderson. + * C4 asm and some C emulation code (c) Copyright 2000 zsKnight and _Demo_. + * C4 C code (c) Copyright 2001 Gary Henderson (gary.henderson@ntlworld.com). + * + * DOS port code contains the works of other authors. See headers in + * individual files. + * + * Snes9x homepage: http://www.snes9x.com + * + * Permission to use, copy, modify and distribute Snes9x in both binary and + * source form, for non-commercial purposes, is hereby granted without fee, + * providing that this license information and copyright notice appear with + * all copies and any derived work. + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event shall the authors be held liable for any damages + * arising from the use of this software. + * + * Snes9x is freeware for PERSONAL USE only. Commercial users should + * seek permission of the copyright holders first. Commercial use includes + * charging money for Snes9x or software derived from Snes9x. + * + * The copyright holders request that bug fixes and improvements to the code + * should be forwarded to them so everyone can benefit from the modifications + * in future versions. + * + * Super NES and Super Nintendo Entertainment System are trademarks of + * Nintendo Co., Limited and its subsidiary companies. + */ +//#define MMX + +#if !defined(_SNESPPC) && !defined(__GIZ__) && !defined(__GP2X__) && !defined(__WIZ__) +#include "snes9x/snes9x.h" +#include "snes9x/port.h" +#include "snes9x/gfx.h" +#else +#include "snes9x.h" +#include "port.h" +#include "gfx.h" +#endif + +#ifdef MMX +EXTERN_C void _2xSaILine (uint8 *srcPtr, uint8 *deltaPtr, uint32 srcPitch, uint32 width, + uint8 *dstPtr, uint32 dstPitch); +EXTERN_C void _2xSaISuperEagleLine (uint8 *srcPtr, uint8 *deltaPtr, uint32 srcPitch, uint32 width, + uint8 *dstPtr, uint32 dstPitch); +EXTERN_C int Init_2xSaIMMX (uint32 BitFormat); +#endif + +bool mmx_cpu = false; + +static uint32 colorMask = 0xF7DEF7DE; +static uint32 lowPixelMask = 0x08210821; +static uint32 qcolorMask = 0xE79CE79C; +static uint32 qlowpixelMask = 0x18631863; + + +int Init_2xSaI(uint32 BitFormat) +{ + if (BitFormat == 565) + { + colorMask = 0xF7DEF7DE; + lowPixelMask = 0x08210821; + qcolorMask = 0xE79CE79C; + qlowpixelMask = 0x18631863; + } + else + if (BitFormat == 555) + { + colorMask = 0x7BDE7BDE; + lowPixelMask = 0x04210421; + qcolorMask = 0x739C739C; + qlowpixelMask = 0x0C630C63; + } + else + { + return 0; + } +#ifdef MMX + Init_2xSaIMMX(BitFormat); +#endif + return 1; +} + +STATIC inline int GetResult1(uint32 A, uint32 B, uint32 C, uint32 D, uint32 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(uint32 A, uint32 B, uint32 C, uint32 D, uint32 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 GetResult(uint32 A, uint32 B, uint32 C, uint32 D) +{ + 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 uint32 INTERPOLATE(uint32 A, uint32 B) +{ + if (A !=B) + { + return ( ((A & colorMask) >> 1) + ((B & colorMask) >> 1) + (A & B & lowPixelMask) ); + } + else return A; +} + + +STATIC inline uint32 Q_INTERPOLATE(uint32 A, uint32 B, uint32 C, uint32 D) +{ + register uint32 x = ((A & qcolorMask) >> 2) + + ((B & qcolorMask) >> 2) + + ((C & qcolorMask) >> 2) + + ((D & qcolorMask) >> 2); + register uint32 y = (A & qlowpixelMask) + + (B & qlowpixelMask) + + (C & qlowpixelMask) + + (D & qlowpixelMask); + y = (y>>2) & qlowpixelMask; + return x+y; +} + + + + +#define HOR +#define VER +void Super2xSaI(uint8 *srcPtr, uint32 srcPitch, + uint8 *deltaPtr, + uint8 *dstPtr, uint32 dstPitch, int width, int height) +{ + uint32 *dP; + uint16 *bP; + +#ifdef MMX_BLA //no MMX version yet + if (cpu_mmx && width != 512) + { + for (height; height; height-=1) + { + bP = (uint16 *) srcPtr; + xP = (uint16 *) deltaPtr; + dP = (uint32 *) dstPtr; + _2xSaISuperEagleLine ((uint8 *) bP, (uint8 *) xP, srcPitch, width, (uint8 *) dP, dstPitch); + dstPtr += dstPitch << 1; + srcPtr += srcPitch; + deltaPtr += srcPitch; + } + } + else + { +#endif + uint32 Nextline = srcPitch >> 1; + + for (height; height; height-=1) + { + bP = (uint16 *) srcPtr; + dP = (uint32 *) dstPtr; + for (uint32 finish = width; finish; finish -= 1 ) + { + uint32 color4, color5, color6; + uint32 color1, color2, color3; + uint32 colorA0, colorA1, colorA2, colorA3, + colorB0, colorB1, colorB2, colorB3, + colorS1, colorS2; + uint32 product1a, product1b, + product2a, product2b; + +//--------------------------------------- B1 B2 +// 4 5 6 S2 +// 1 2 3 S1 +// A1 A2 + + colorB0 = *(bP- Nextline - 1); + colorB1 = *(bP- Nextline); + colorB2 = *(bP- Nextline + 1); + colorB3 = *(bP- Nextline + 2); + + color4 = *(bP - 1); + color5 = *(bP); + color6 = *(bP + 1); + colorS2 = *(bP + 2); + + color1 = *(bP + Nextline - 1); + color2 = *(bP + Nextline); + color3 = *(bP + Nextline + 1); + colorS1 = *(bP + Nextline + 2); + + colorA0 = *(bP + Nextline + Nextline - 1); + colorA1 = *(bP + Nextline + Nextline); + colorA2 = *(bP + Nextline + Nextline + 1); + colorA3 = *(bP + Nextline + Nextline + 2); + + +//-------------------------------------- + if (color2 == color6 && color5 != color3) + { + product2b = product1b = color2; + } + else + if (color5 == color3 && color2 != color6) + { + product2b = product1b = color5; + } + else + if (color5 == color3 && color2 == color6 && color5 != color6) + { + register int r = 0; + + r += GetResult (color6, color5, color1, colorA1); + r += GetResult (color6, color5, color4, colorB1); + r += GetResult (color6, color5, colorA2, colorS1); + r += GetResult (color6, color5, colorB2, colorS2); + + if (r > 0) + product2b = product1b = color6; + else + if (r < 0) + product2b = product1b = color5; + else + { + product2b = product1b = INTERPOLATE (color5, color6); + } + + } + else + { + +#ifdef VER + if (color6 == color3 && color3 == colorA1 && color2 != colorA2 && color3 != colorA0) + product2b = Q_INTERPOLATE (color3, color3, color3, color2); + else + if (color5 == color2 && color2 == colorA2 && colorA1 != color3 && color2 != colorA3) + product2b = Q_INTERPOLATE (color2, color2, color2, color3); + else +#endif + product2b = INTERPOLATE (color2, color3); + +#ifdef VER + if (color6 == color3 && color6 == colorB1 && color5 != colorB2 && color6 != colorB0) + product1b = Q_INTERPOLATE (color6, color6, color6, color5); + else + if (color5 == color2 && color5 == colorB2 && colorB1 != color6 && color5 != colorB3) + product1b = Q_INTERPOLATE (color6, color5, color5, color5); + else +#endif + product1b = INTERPOLATE (color5, color6); + } + +#ifdef HOR + if (color5 == color3 && color2 != color6 && color4 == color5 && color5 != colorA2) + product2a = INTERPOLATE (color2, color5); + else + if (color5 == color1 && color6 == color5 && color4 != color2 && color5 != colorA0) + product2a = INTERPOLATE(color2, color5); + else +#endif + product2a = color2; + +#ifdef HOR + if (color2 == color6 && color5 != color3 && color1 == color2 && color2 != colorB2) + product1a = INTERPOLATE (color2, color5); + else + if (color4 == color2 && color3 == color2 && color1 != color5 && color2 != colorB0) + product1a = INTERPOLATE(color2, color5); + else +#endif + product1a = color5; + + + product1a = product1a | (product1b << 16); + product2a = product2a | (product2b << 16); + + *(dP) = product1a; + *(dP+(dstPitch>>2)) = product2a; + + bP += 1; + dP += 1; + }//end of for ( finish= width etc..) + + dstPtr += dstPitch << 1; + srcPtr += srcPitch; + deltaPtr += srcPitch; + }; //endof: for (height; height; height--) +#ifdef MMX_BLA + } +#endif +} + + + + + + +/*ONLY use with 640x480x16 or higher resolutions*/ +/*Only use this if 2*width * 2*height fits on the current screen*/ +void SuperEagle(uint8 *srcPtr, uint32 srcPitch, + uint8 *deltaPtr, + uint8 *dstPtr, uint32 dstPitch, int width, int height) +{ + uint32 *dP; + uint16 *bP; +#if !defined(_SNESPPC) && !defined(__GIZ__) && !defined(__GP2X__) && !defined(__WIZ__) + uint16 *xP; +#endif + +#ifdef MMX + if (mmx_cpu && width != 512) + { + for (height; height; height-=1) + { + bP = (uint16 *) srcPtr; + xP = (uint16 *) deltaPtr; + dP = (uint32 *) dstPtr; + _2xSaISuperEagleLine ((uint8 *) bP, (uint8 *) xP, srcPitch, width, (uint8 *)dP, dstPitch); + dstPtr += dstPitch << 1; + srcPtr += srcPitch; + deltaPtr += srcPitch; + } + } + else + { +#endif + uint32 Nextline = srcPitch >> 1; + + for (height; height; height-=1) + { + bP = (uint16 *) srcPtr; + dP = (uint32 *) dstPtr; + for (uint32 finish = width; finish; finish -= 1 ) + { + + uint32 color4, color5, color6; + uint32 color1, color2, color3; + uint32 colorA0, colorA1, colorA2, colorA3, + colorB0, colorB1, colorB2, colorB3, + colorS1, colorS2; + uint32 product1a, product1b, + product2a, product2b; + + colorB0 = *(bP- Nextline - 1); + colorB1 = *(bP- Nextline); + colorB2 = *(bP- Nextline + 1); + colorB3 = *(bP- Nextline + 2); + + color4 = *(bP - 1); + color5 = *(bP); + color6 = *(bP + 1); + colorS2 = *(bP + 2); + + color1 = *(bP + Nextline - 1); + color2 = *(bP + Nextline); + color3 = *(bP + Nextline + 1); + colorS1 = *(bP + Nextline + 2); + + colorA0 = *(bP + Nextline + Nextline - 1); + colorA1 = *(bP + Nextline + Nextline); + colorA2 = *(bP + Nextline + Nextline + 1); + colorA3 = *(bP + Nextline + Nextline + 2); + + + //-------------------------------------- + if (color2 == color6 && color5 != color3) + { + product1b = product2a = color2; + if ((color1 == color2 && color6 == colorS2) || + (color2 == colorA1 && color6 == colorB2)) + { + product1a = INTERPOLATE (color2, color5); + product1a = INTERPOLATE (color2, product1a); + product2b = INTERPOLATE (color2, color3); + product2b = INTERPOLATE (color2, product2b); +// product1a = color2; +// product2b = color2; + } + else + { + product1a = INTERPOLATE (color5, color6); + product2b = INTERPOLATE (color2, color3); + } + } + else + if (color5 == color3 && color2 != color6) + { + product2b = product1a = color5; + if ((colorB1 == color5 && color3 == colorA2) || + (color4 == color5 && color3 == colorS1)) + { + product1b = INTERPOLATE (color5, color6); + product1b = INTERPOLATE (color5, product1b); + product2a = INTERPOLATE (color5, color2); + product2a = INTERPOLATE (color5, product2a); +// product1b = color5; +// product2a = color5; + } + else + { + product1b = INTERPOLATE (color5, color6); + product2a = INTERPOLATE (color2, color3); + } + } + else + if (color5 == color3 && color2 == color6 && color5 != color6) + { + register int r = 0; + + r += GetResult (color6, color5, color1, colorA1); + r += GetResult (color6, color5, color4, colorB1); + r += GetResult (color6, color5, colorA2, colorS1); + r += GetResult (color6, color5, colorB2, colorS2); + + if (r > 0) + { + product1b = product2a = color2; + product1a = product2b = INTERPOLATE (color5, color6); + } + else + if (r < 0) + { + product2b = product1a = color5; + product1b = product2a = INTERPOLATE (color5, color6); + } + else + { + product2b = product1a = color5; + product1b = product2a = color2; + } + } + else + { + + if ((color2 == color5) || (color3 == color6)) + { + product1a = color5; + product2a = color2; + product1b = color6; + product2b = color3; + + } + else + { + product1b = product1a = INTERPOLATE (color5, color6); + product1a = INTERPOLATE (color5, product1a); + product1b = INTERPOLATE (color6, product1b); + + product2a = product2b = INTERPOLATE (color2, color3); + product2a = INTERPOLATE (color2, product2a); + product2b = INTERPOLATE (color3, product2b); + } + } + + + product1a = product1a | (product1b << 16); + product2a = product2a | (product2b << 16); + + *(dP) = product1a; + *(dP+(dstPitch>>2)) = product2a; + + bP += 1; + dP += 1; + }//end of for ( finish= width etc..) + + dstPtr += dstPitch << 1; + srcPtr += srcPitch; + deltaPtr += srcPitch; + }; //endof: for (height; height; height--) +#ifdef MMX + } +#endif +} + + + +/*ONLY use with 640x480x16 or higher resolutions*/ +/*Only use this if 2*width * 2*height fits on the current screen*/ +void _2xSaI(uint8 *srcPtr, uint32 srcPitch, + uint8 *deltaPtr, + uint8 *dstPtr, uint32 dstPitch, int width, int height) +{ + uint32 *dP; + uint16 *bP; +#if !defined(_SNESPPC) && !defined(__GIZ__) && !defined(__GP2X__) && !defined(__WIZ__) + uint16 *xP; +#endif + +#ifdef MMX + if (mmx_cpu && width != 512) + { + for (height; height; height-=1) + { + + bP = (uint16 *) srcPtr; + xP = (uint16 *) deltaPtr; + dP = (uint32 *) dstPtr; + _2xSaILine ((uint8 *) bP, (uint8 *) xP, srcPitch, width, (uint8 *)dP, dstPitch); + dstPtr += dstPitch << 1; + srcPtr += srcPitch; + deltaPtr += srcPitch; + } + } + else + { +#endif + uint32 Nextline = srcPitch >> 1; + + for (height; height; height-=1) + { + bP = (uint16 *) srcPtr; + dP = (uint32 *) dstPtr; + for (uint32 finish = width; finish; finish -= 1 ) + { + + + register uint32 colorA, colorB; + uint32 colorC, colorD, + colorE, colorF, colorG, colorH, + colorI, colorJ, colorK, colorL, + colorM, colorN, colorO, colorP; + uint32 product, product1, product2; + + +//--------------------------------------- +// Map of the pixels: I|E F|J +// G|A B|K +// H|C D|L +// M|N O|P + colorI = *(bP- Nextline - 1); + colorE = *(bP- Nextline); + colorF = *(bP- Nextline + 1); + colorJ = *(bP- Nextline + 2); + + colorG = *(bP - 1); + colorA = *(bP); + colorB = *(bP + 1); + colorK = *(bP + 2); + + colorH = *(bP + Nextline - 1); + colorC = *(bP + Nextline); + colorD = *(bP + Nextline + 1); + colorL = *(bP + Nextline + 2); + + colorM = *(bP + Nextline + Nextline - 1); + colorN = *(bP + Nextline + Nextline); + colorO = *(bP + Nextline + Nextline + 1); + colorP = *(bP + Nextline + Nextline + 2); + + if ((colorA == colorD) && (colorB != colorC)) + { + if ( ((colorA == colorE) && (colorB == colorL)) || + ((colorA == colorC) && (colorA == colorF) && (colorB != colorE) && (colorB == colorJ)) ) + { + product = colorA; + } + else + { + product = INTERPOLATE(colorA, colorB); + } + + if (((colorA == colorG) && (colorC == colorO)) || + ((colorA == colorB) && (colorA == colorH) && (colorG != colorC) && (colorC == colorM)) ) + { + product1 = colorA; + } + else + { + product1 = INTERPOLATE(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 = INTERPOLATE(colorA, colorB); + } + + if (((colorC == colorH) && (colorA == colorF)) || + ((colorC == colorG) && (colorC == colorD) && (colorA != colorH) && (colorA == colorI)) ) + { + product1 = colorC; + } + else + { + product1 = INTERPOLATE(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 = INTERPOLATE(colorA, colorC); + product = INTERPOLATE(colorA, colorB); + + r += GetResult1 (colorA, colorB, colorG, colorE, colorI); + r += GetResult2 (colorB, colorA, colorK, colorF, colorJ); + r += GetResult2 (colorB, colorA, colorH, colorN, colorM); + r += GetResult1 (colorA, colorB, colorL, colorO, colorP); + + if (r > 0) + product2 = colorA; + else + if (r < 0) + product2 = colorB; + else + { + product2 = Q_INTERPOLATE(colorA, colorB, colorC, colorD); + } + } + } + else + { + product2 = Q_INTERPOLATE(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 = INTERPOLATE(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 = INTERPOLATE(colorA, colorC); + } + } + product = colorA | (product << 16); + product1 = product1 | (product2 << 16); + *(dP) = product; + *(dP+(dstPitch>>2)) = product1; + + bP += 1; + dP += 1; + }//end of for ( finish= width etc..) + + dstPtr += dstPitch << 1; + srcPtr += srcPitch; + deltaPtr += srcPitch; + }; //endof: for (height; height; height--) +#ifdef MMX + } +#endif +} |