2 * Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
4 * (c) Copyright 1996 - 2001 Gary Henderson (gary.henderson@ntlworld.com) and
5 * Jerremy Koot (jkoot@snes9x.com)
7 * Super FX C emulator code
8 * (c) Copyright 1997 - 1999 Ivar (ivar@snes9x.com) and
10 * Super FX assembler emulator code (c) Copyright 1998 zsKnight and _Demo_.
12 * DSP1 emulator code (c) Copyright 1998 Ivar, _Demo_ and Gary Henderson.
13 * C4 asm and some C emulation code (c) Copyright 2000 zsKnight and _Demo_.
14 * C4 C code (c) Copyright 2001 Gary Henderson (gary.henderson@ntlworld.com).
16 * DOS port code contains the works of other authors. See headers in
19 * Snes9x homepage: http://www.snes9x.com
21 * Permission to use, copy, modify and distribute Snes9x in both binary and
22 * source form, for non-commercial purposes, is hereby granted without fee,
23 * providing that this license information and copyright notice appear with
24 * all copies and any derived work.
26 * This software is provided 'as-is', without any express or implied
27 * warranty. In no event shall the authors be held liable for any damages
28 * arising from the use of this software.
30 * Snes9x is freeware for PERSONAL USE only. Commercial users should
31 * seek permission of the copyright holders first. Commercial use includes
32 * charging money for Snes9x or software derived from Snes9x.
34 * The copyright holders request that bug fixes and improvements to the code
35 * should be forwarded to them so everyone can benefit from the modifications
38 * Super NES and Super Nintendo Entertainment System are trademarks of
39 * Nintendo Co., Limited and its subsidiary companies.
43 #if !defined(_SNESPPC) && !defined(__GIZ__) && !defined(__GP2X__)
44 #include "snes9x/snes9x.h"
45 #include "snes9x/port.h"
46 #include "snes9x/gfx.h"
54 EXTERN_C void _2xSaILine (uint8 *srcPtr, uint8 *deltaPtr, uint32 srcPitch, uint32 width,
55 uint8 *dstPtr, uint32 dstPitch);
56 EXTERN_C void _2xSaISuperEagleLine (uint8 *srcPtr, uint8 *deltaPtr, uint32 srcPitch, uint32 width,
57 uint8 *dstPtr, uint32 dstPitch);
58 EXTERN_C int Init_2xSaIMMX (uint32 BitFormat);
63 static uint32 colorMask = 0xF7DEF7DE;
64 static uint32 lowPixelMask = 0x08210821;
65 static uint32 qcolorMask = 0xE79CE79C;
66 static uint32 qlowpixelMask = 0x18631863;
69 int Init_2xSaI(uint32 BitFormat)
73 colorMask = 0xF7DEF7DE;
74 lowPixelMask = 0x08210821;
75 qcolorMask = 0xE79CE79C;
76 qlowpixelMask = 0x18631863;
81 colorMask = 0x7BDE7BDE;
82 lowPixelMask = 0x04210421;
83 qcolorMask = 0x739C739C;
84 qlowpixelMask = 0x0C630C63;
91 Init_2xSaIMMX(BitFormat);
96 STATIC inline int GetResult1(uint32 A, uint32 B, uint32 C, uint32 D, uint32 E)
101 if (A == C) x+=1; else if (B == C) y+=1;
102 if (A == D) x+=1; else if (B == D) y+=1;
108 STATIC inline int GetResult2(uint32 A, uint32 B, uint32 C, uint32 D, uint32 E)
113 if (A == C) x+=1; else if (B == C) y+=1;
114 if (A == D) x+=1; else if (B == D) y+=1;
121 STATIC inline int GetResult(uint32 A, uint32 B, uint32 C, uint32 D)
126 if (A == C) x+=1; else if (B == C) y+=1;
127 if (A == D) x+=1; else if (B == D) y+=1;
134 STATIC inline uint32 INTERPOLATE(uint32 A, uint32 B)
138 return ( ((A & colorMask) >> 1) + ((B & colorMask) >> 1) + (A & B & lowPixelMask) );
144 STATIC inline uint32 Q_INTERPOLATE(uint32 A, uint32 B, uint32 C, uint32 D)
146 register uint32 x = ((A & qcolorMask) >> 2) +
147 ((B & qcolorMask) >> 2) +
148 ((C & qcolorMask) >> 2) +
149 ((D & qcolorMask) >> 2);
150 register uint32 y = (A & qlowpixelMask) +
151 (B & qlowpixelMask) +
152 (C & qlowpixelMask) +
154 y = (y>>2) & qlowpixelMask;
163 void Super2xSaI(uint8 *srcPtr, uint32 srcPitch,
165 uint8 *dstPtr, uint32 dstPitch, int width, int height)
170 #ifdef MMX_BLA //no MMX version yet
171 if (cpu_mmx && width != 512)
173 for (height; height; height-=1)
175 bP = (uint16 *) srcPtr;
176 xP = (uint16 *) deltaPtr;
177 dP = (uint32 *) dstPtr;
178 _2xSaISuperEagleLine ((uint8 *) bP, (uint8 *) xP, srcPitch, width, (uint8 *) dP, dstPitch);
179 dstPtr += dstPitch << 1;
181 deltaPtr += srcPitch;
187 uint32 Nextline = srcPitch >> 1;
189 for (height; height; height-=1)
191 bP = (uint16 *) srcPtr;
192 dP = (uint32 *) dstPtr;
193 for (uint32 finish = width; finish; finish -= 1 )
195 uint32 color4, color5, color6;
196 uint32 color1, color2, color3;
197 uint32 colorA0, colorA1, colorA2, colorA3,
198 colorB0, colorB1, colorB2, colorB3,
200 uint32 product1a, product1b,
201 product2a, product2b;
203 //--------------------------------------- B1 B2
208 colorB0 = *(bP- Nextline - 1);
209 colorB1 = *(bP- Nextline);
210 colorB2 = *(bP- Nextline + 1);
211 colorB3 = *(bP- Nextline + 2);
218 color1 = *(bP + Nextline - 1);
219 color2 = *(bP + Nextline);
220 color3 = *(bP + Nextline + 1);
221 colorS1 = *(bP + Nextline + 2);
223 colorA0 = *(bP + Nextline + Nextline - 1);
224 colorA1 = *(bP + Nextline + Nextline);
225 colorA2 = *(bP + Nextline + Nextline + 1);
226 colorA3 = *(bP + Nextline + Nextline + 2);
229 //--------------------------------------
230 if (color2 == color6 && color5 != color3)
232 product2b = product1b = color2;
235 if (color5 == color3 && color2 != color6)
237 product2b = product1b = color5;
240 if (color5 == color3 && color2 == color6 && color5 != color6)
244 r += GetResult (color6, color5, color1, colorA1);
245 r += GetResult (color6, color5, color4, colorB1);
246 r += GetResult (color6, color5, colorA2, colorS1);
247 r += GetResult (color6, color5, colorB2, colorS2);
250 product2b = product1b = color6;
253 product2b = product1b = color5;
256 product2b = product1b = INTERPOLATE (color5, color6);
264 if (color6 == color3 && color3 == colorA1 && color2 != colorA2 && color3 != colorA0)
265 product2b = Q_INTERPOLATE (color3, color3, color3, color2);
267 if (color5 == color2 && color2 == colorA2 && colorA1 != color3 && color2 != colorA3)
268 product2b = Q_INTERPOLATE (color2, color2, color2, color3);
271 product2b = INTERPOLATE (color2, color3);
274 if (color6 == color3 && color6 == colorB1 && color5 != colorB2 && color6 != colorB0)
275 product1b = Q_INTERPOLATE (color6, color6, color6, color5);
277 if (color5 == color2 && color5 == colorB2 && colorB1 != color6 && color5 != colorB3)
278 product1b = Q_INTERPOLATE (color6, color5, color5, color5);
281 product1b = INTERPOLATE (color5, color6);
285 if (color5 == color3 && color2 != color6 && color4 == color5 && color5 != colorA2)
286 product2a = INTERPOLATE (color2, color5);
288 if (color5 == color1 && color6 == color5 && color4 != color2 && color5 != colorA0)
289 product2a = INTERPOLATE(color2, color5);
295 if (color2 == color6 && color5 != color3 && color1 == color2 && color2 != colorB2)
296 product1a = INTERPOLATE (color2, color5);
298 if (color4 == color2 && color3 == color2 && color1 != color5 && color2 != colorB0)
299 product1a = INTERPOLATE(color2, color5);
305 product1a = product1a | (product1b << 16);
306 product2a = product2a | (product2b << 16);
309 *(dP+(dstPitch>>2)) = product2a;
313 }//end of for ( finish= width etc..)
315 dstPtr += dstPitch << 1;
317 deltaPtr += srcPitch;
318 }; //endof: for (height; height; height--)
329 /*ONLY use with 640x480x16 or higher resolutions*/
330 /*Only use this if 2*width * 2*height fits on the current screen*/
331 void SuperEagle(uint8 *srcPtr, uint32 srcPitch,
333 uint8 *dstPtr, uint32 dstPitch, int width, int height)
337 #if !defined(_SNESPPC) && !defined(__GIZ__) && !defined(__GP2X__)
342 if (mmx_cpu && width != 512)
344 for (height; height; height-=1)
346 bP = (uint16 *) srcPtr;
347 xP = (uint16 *) deltaPtr;
348 dP = (uint32 *) dstPtr;
349 _2xSaISuperEagleLine ((uint8 *) bP, (uint8 *) xP, srcPitch, width, (uint8 *)dP, dstPitch);
350 dstPtr += dstPitch << 1;
352 deltaPtr += srcPitch;
358 uint32 Nextline = srcPitch >> 1;
360 for (height; height; height-=1)
362 bP = (uint16 *) srcPtr;
363 dP = (uint32 *) dstPtr;
364 for (uint32 finish = width; finish; finish -= 1 )
367 uint32 color4, color5, color6;
368 uint32 color1, color2, color3;
369 uint32 colorA0, colorA1, colorA2, colorA3,
370 colorB0, colorB1, colorB2, colorB3,
372 uint32 product1a, product1b,
373 product2a, product2b;
375 colorB0 = *(bP- Nextline - 1);
376 colorB1 = *(bP- Nextline);
377 colorB2 = *(bP- Nextline + 1);
378 colorB3 = *(bP- Nextline + 2);
385 color1 = *(bP + Nextline - 1);
386 color2 = *(bP + Nextline);
387 color3 = *(bP + Nextline + 1);
388 colorS1 = *(bP + Nextline + 2);
390 colorA0 = *(bP + Nextline + Nextline - 1);
391 colorA1 = *(bP + Nextline + Nextline);
392 colorA2 = *(bP + Nextline + Nextline + 1);
393 colorA3 = *(bP + Nextline + Nextline + 2);
396 //--------------------------------------
397 if (color2 == color6 && color5 != color3)
399 product1b = product2a = color2;
400 if ((color1 == color2 && color6 == colorS2) ||
401 (color2 == colorA1 && color6 == colorB2))
403 product1a = INTERPOLATE (color2, color5);
404 product1a = INTERPOLATE (color2, product1a);
405 product2b = INTERPOLATE (color2, color3);
406 product2b = INTERPOLATE (color2, product2b);
407 // product1a = color2;
408 // product2b = color2;
412 product1a = INTERPOLATE (color5, color6);
413 product2b = INTERPOLATE (color2, color3);
417 if (color5 == color3 && color2 != color6)
419 product2b = product1a = color5;
420 if ((colorB1 == color5 && color3 == colorA2) ||
421 (color4 == color5 && color3 == colorS1))
423 product1b = INTERPOLATE (color5, color6);
424 product1b = INTERPOLATE (color5, product1b);
425 product2a = INTERPOLATE (color5, color2);
426 product2a = INTERPOLATE (color5, product2a);
427 // product1b = color5;
428 // product2a = color5;
432 product1b = INTERPOLATE (color5, color6);
433 product2a = INTERPOLATE (color2, color3);
437 if (color5 == color3 && color2 == color6 && color5 != color6)
441 r += GetResult (color6, color5, color1, colorA1);
442 r += GetResult (color6, color5, color4, colorB1);
443 r += GetResult (color6, color5, colorA2, colorS1);
444 r += GetResult (color6, color5, colorB2, colorS2);
448 product1b = product2a = color2;
449 product1a = product2b = INTERPOLATE (color5, color6);
454 product2b = product1a = color5;
455 product1b = product2a = INTERPOLATE (color5, color6);
459 product2b = product1a = color5;
460 product1b = product2a = color2;
466 if ((color2 == color5) || (color3 == color6))
476 product1b = product1a = INTERPOLATE (color5, color6);
477 product1a = INTERPOLATE (color5, product1a);
478 product1b = INTERPOLATE (color6, product1b);
480 product2a = product2b = INTERPOLATE (color2, color3);
481 product2a = INTERPOLATE (color2, product2a);
482 product2b = INTERPOLATE (color3, product2b);
487 product1a = product1a | (product1b << 16);
488 product2a = product2a | (product2b << 16);
491 *(dP+(dstPitch>>2)) = product2a;
495 }//end of for ( finish= width etc..)
497 dstPtr += dstPitch << 1;
499 deltaPtr += srcPitch;
500 }; //endof: for (height; height; height--)
508 /*ONLY use with 640x480x16 or higher resolutions*/
509 /*Only use this if 2*width * 2*height fits on the current screen*/
510 void _2xSaI(uint8 *srcPtr, uint32 srcPitch,
512 uint8 *dstPtr, uint32 dstPitch, int width, int height)
516 #if !defined(_SNESPPC) && !defined(__GIZ__) && !defined(__GP2X__)
521 if (mmx_cpu && width != 512)
523 for (height; height; height-=1)
526 bP = (uint16 *) srcPtr;
527 xP = (uint16 *) deltaPtr;
528 dP = (uint32 *) dstPtr;
529 _2xSaILine ((uint8 *) bP, (uint8 *) xP, srcPitch, width, (uint8 *)dP, dstPitch);
530 dstPtr += dstPitch << 1;
532 deltaPtr += srcPitch;
538 uint32 Nextline = srcPitch >> 1;
540 for (height; height; height-=1)
542 bP = (uint16 *) srcPtr;
543 dP = (uint32 *) dstPtr;
544 for (uint32 finish = width; finish; finish -= 1 )
548 register uint32 colorA, colorB;
549 uint32 colorC, colorD,
550 colorE, colorF, colorG, colorH,
551 colorI, colorJ, colorK, colorL,
552 colorM, colorN, colorO, colorP;
553 uint32 product, product1, product2;
556 //---------------------------------------
557 // Map of the pixels: I|E F|J
561 colorI = *(bP- Nextline - 1);
562 colorE = *(bP- Nextline);
563 colorF = *(bP- Nextline + 1);
564 colorJ = *(bP- Nextline + 2);
571 colorH = *(bP + Nextline - 1);
572 colorC = *(bP + Nextline);
573 colorD = *(bP + Nextline + 1);
574 colorL = *(bP + Nextline + 2);
576 colorM = *(bP + Nextline + Nextline - 1);
577 colorN = *(bP + Nextline + Nextline);
578 colorO = *(bP + Nextline + Nextline + 1);
579 colorP = *(bP + Nextline + Nextline + 2);
581 if ((colorA == colorD) && (colorB != colorC))
583 if ( ((colorA == colorE) && (colorB == colorL)) ||
584 ((colorA == colorC) && (colorA == colorF) && (colorB != colorE) && (colorB == colorJ)) )
590 product = INTERPOLATE(colorA, colorB);
593 if (((colorA == colorG) && (colorC == colorO)) ||
594 ((colorA == colorB) && (colorA == colorH) && (colorG != colorC) && (colorC == colorM)) )
600 product1 = INTERPOLATE(colorA, colorC);
605 if ((colorB == colorC) && (colorA != colorD))
607 if (((colorB == colorF) && (colorA == colorH)) ||
608 ((colorB == colorE) && (colorB == colorD) && (colorA != colorF) && (colorA == colorI)) )
614 product = INTERPOLATE(colorA, colorB);
617 if (((colorC == colorH) && (colorA == colorF)) ||
618 ((colorC == colorG) && (colorC == colorD) && (colorA != colorH) && (colorA == colorI)) )
624 product1 = INTERPOLATE(colorA, colorC);
629 if ((colorA == colorD) && (colorB == colorC))
631 if (colorA == colorB)
640 product1 = INTERPOLATE(colorA, colorC);
641 product = INTERPOLATE(colorA, colorB);
643 r += GetResult1 (colorA, colorB, colorG, colorE, colorI);
644 r += GetResult2 (colorB, colorA, colorK, colorF, colorJ);
645 r += GetResult2 (colorB, colorA, colorH, colorN, colorM);
646 r += GetResult1 (colorA, colorB, colorL, colorO, colorP);
655 product2 = Q_INTERPOLATE(colorA, colorB, colorC, colorD);
661 product2 = Q_INTERPOLATE(colorA, colorB, colorC, colorD);
663 if ((colorA == colorC) && (colorA == colorF) && (colorB != colorE) && (colorB == colorJ))
668 if ((colorB == colorE) && (colorB == colorD) && (colorA != colorF) && (colorA == colorI))
674 product = INTERPOLATE(colorA, colorB);
677 if ((colorA == colorB) && (colorA == colorH) && (colorG != colorC) && (colorC == colorM))
682 if ((colorC == colorG) && (colorC == colorD) && (colorA != colorH) && (colorA == colorI))
688 product1 = INTERPOLATE(colorA, colorC);
691 product = colorA | (product << 16);
692 product1 = product1 | (product2 << 16);
694 *(dP+(dstPitch>>2)) = product1;
698 }//end of for ( finish= width etc..)
700 dstPtr += dstPitch << 1;
702 deltaPtr += srcPitch;
703 }; //endof: for (height; height; height--)