📄 2xsai.cpp
字号:
/* * Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. * * (c) Copyright 1996 - 2001 Gary Henderson (gary@daniver.demon.co.uk) 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@daniver.demon.co.uk). * * DOS port code contains the works of other authors. See headers in * individual files. * * Snes9x homepage: 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. */#ifdef __DJGPP#include <allegro.h>#endif#include "snes9x.h"#include "port.h"#include "gfx.h"extern "C"{#ifdef MMX void _2xSaILine (uint8 *srcPtr, uint8 *deltaPtr, uint32 srcPitch, uint32 width, uint8 *dstPtr, uint32 dstPitch); void _2xSaISuperEagleLine (uint8 *srcPtr, uint8 *deltaPtr, uint32 srcPitch, uint32 width, uint8 *dstPtr, uint32 dstPitch); void _2xSaISuper2xSaILine (uint8 *srcPtr, uint8 *deltaPtr, uint32 srcPitch, uint32 width, uint8 *dstPtr, uint32 dstPitch); void Init_2xSaIMMX (uint32 BitFormat); void BilinearMMX (uint16 * A, uint16 * B, uint16 * C, uint16 * D, uint16 * dx, uint16 * dy, uint8 *dP); void BilinearMMXGrid0 (uint16 * A, uint16 * B, uint16 * C, uint16 * D, uint16 * dx, uint16 * dy, uint8 *dP); void BilinearMMXGrid1 (uint16 * A, uint16 * B, uint16 * C, uint16 * D, uint16 * dx, uint16 * dy, uint8 *dP); void EndMMX ();static bool8 cpu_mmx = 1;#endif} static uint32 colorMask = 0xF7DEF7DE;static uint32 lowPixelMask = 0x08210821;static uint32 qcolorMask = 0xE79CE79C;static uint32 qlowpixelMask = 0x18631863;static uint32 redblueMask = 0xF81F;static uint32 greenMask = 0x7E0;int Init_2xSaI (uint32 BitFormat){ if (BitFormat == 565) { colorMask = 0xF7DEF7DE; lowPixelMask = 0x08210821; qcolorMask = 0xE79CE79C; qlowpixelMask = 0x18631863; redblueMask = 0xF81F; greenMask = 0x7E0; } else if (BitFormat == 555) { colorMask = 0x7BDE7BDE; lowPixelMask = 0x04210421; qcolorMask = 0x739C739C; qlowpixelMask = 0x0C630C63; redblueMask = 0x7C1F; greenMask = 0x3E0; } 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 BLUE_MASK565 0x001F001F#define RED_MASK565 0xF800F800#define GREEN_MASK565 0x07E007E0#define BLUE_MASK555 0x001F001F#define RED_MASK555 0x7C007C00#define GREEN_MASK555 0x03E003E0void Super2xSaI (uint8 *srcPtr, uint32 srcPitch, uint8 *deltaPtr, uint8 *dstPtr, uint32 dstPitch, int width, int height){ uint16 *bP; uint8 *dP; uint32 inc_bP; uint32 Nextline = srcPitch >> 1;#ifdef MMX if (cpu_mmx) { for (; height; height--) { _2xSaISuper2xSaILine (srcPtr, deltaPtr, srcPitch, width, dstPtr, dstPitch); srcPtr += srcPitch; dstPtr += dstPitch * 2; deltaPtr += srcPitch; } } else#endif { inc_bP = 1; for (; height; height--) { bP = (uint16 *) srcPtr; dP = (uint8 *) dstPtr; for (uint32 finish = width; finish; finish -= inc_bP) { 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) { 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 { 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 product2b = INTERPOLATE (color2, color3); 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 product1b = INTERPOLATE (color5, color6); } 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 product2a = color2; 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 product1a = color5; product1a = product1a | (product1b << 16); product2a = product2a | (product2b << 16); *((uint32 *) dP) = product1a; *((uint32 *) (dP + dstPitch)) = product2a; bP += inc_bP; dP += sizeof (uint32); } // end of for ( finish= width etc..) srcPtr += srcPitch; dstPtr += dstPitch * 2; deltaPtr += srcPitch; } // endof: for (; height; height--) }}void SuperEagle (uint8 *srcPtr, uint32 srcPitch, uint8 *deltaPtr, uint8 *dstPtr, uint32 dstPitch, int width, int height){ uint8 *dP; uint16 *bP; uint16 *xP; uint32 inc_bP;#ifdef MMX if (cpu_mmx) { for (; height; height--) { _2xSaISuperEagleLine (srcPtr, deltaPtr, srcPitch, width, dstPtr, dstPitch); srcPtr += srcPitch; dstPtr += dstPitch * 2; deltaPtr += srcPitch; } } else#endif { inc_bP = 1; uint32 Nextline = srcPitch >> 1; for (; height; height--) { bP = (uint16 *) srcPtr; xP = (uint16 *) deltaPtr; dP = dstPtr; for (uint32 finish = width; finish; finish -= inc_bP) { uint32 color4, color5, color6; uint32 color1, color2, color3; uint32 colorA1, colorA2, colorB1, colorB2, colorS1, colorS2; uint32 product1a, product1b, product2a, product2b; colorB1 = *(bP - Nextline); colorB2 = *(bP - Nextline + 1); 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); colorA1 = *(bP + Nextline + Nextline); colorA2 = *(bP + Nextline + Nextline + 1); // -------------------------------------- if (color2 == color6 && color5 != color3) { product1b = product2a = color2; if ((color1 == color2) || (color6 == colorB2)) { product1a = INTERPOLATE (color2, color5); product1a = INTERPOLATE (color2, product1a);// product1a = color2; } else { product1a = INTERPOLATE (color5, color6); } if ((color6 == colorS2) || (color2 == colorA1)) { product2b = INTERPOLATE (color2, color3); product2b = INTERPOLATE (color2, product2b);// product2b = color2; } else { product2b = INTERPOLATE (color2, color3); } } else if (color5 == color3 && color2 != color6) { product2b = product1a = color5; if ((colorB1 == color5) || (color3 == colorS1)) { product1b = INTERPOLATE (color5, color6); product1b = INTERPOLATE (color5, product1b);// product1b = color5; } else { product1b = INTERPOLATE (color5, color6); } if ((color3 == colorA2) || (color4 == color5)) { product2a = INTERPOLATE (color5, color2); product2a = INTERPOLATE (color5, product2a);// product2a = color5; } else { product2a = INTERPOLATE (color2, color3); } } else if (color5 == color3 && color2 == 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 { product2b = product1a = INTERPOLATE (color2, color6); product2b = Q_INTERPOLATE (color3, color3, color3, product2b); product1a = Q_INTERPOLATE (color5, color5, color5, product1a); product2a = product1b = INTERPOLATE (color5, color3); product2a = Q_INTERPOLATE (color2, color2, color2, product2a); product1b = Q_INTERPOLATE (color6, color6, color6, product1b);// product1a = color5;// product1b = color6;// product2a = color2;// product2b = color3; } product1a = product1a | (product1b << 16); product2a = product2a | (product2b << 16); *((uint32 *) dP) = product1a; *((uint32 *) (dP + dstPitch)) = product2a; *xP = color5; bP += inc_bP; xP += inc_bP; dP += sizeof (uint32); } // end of for ( finish= width etc..) srcPtr += srcPitch; dstPtr += dstPitch * 2; deltaPtr += srcPitch; } // endof: for (height; height; height--) }}void _2xSaI (uint8 *srcPtr, uint32 srcPitch, uint8 *deltaPtr, uint8 *dstPtr, uint32 dstPitch, int width, int height){ uint8 *dP; uint16 *bP; uint32 inc_bP;#ifdef MMX if (cpu_mmx) { for (; height; height -= 1) { _2xSaILine (srcPtr, deltaPtr, srcPitch, width, dstPtr, dstPitch); srcPtr += srcPitch; dstPtr += dstPitch * 2; deltaPtr += srcPitch; } } else#endif { inc_bP = 1; uint32 Nextline = srcPitch >> 1; for (; height; height--) { bP = (uint16 *) srcPtr; dP = dstPtr; for (uint32 finish = width; finish; finish -= inc_bP) { 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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -