added configure script
[drnoksnes] / 2xsaiwin.cpp
1 /*
2  * Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
3  *
4  * (c) Copyright 1996 - 2001 Gary Henderson (gary.henderson@ntlworld.com) and
5  *                           Jerremy Koot (jkoot@snes9x.com)
6  *
7  * Super FX C emulator code 
8  * (c) Copyright 1997 - 1999 Ivar (ivar@snes9x.com) and
9  *                           Gary Henderson.
10  * Super FX assembler emulator code (c) Copyright 1998 zsKnight and _Demo_.
11  *
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).
15  *
16  * DOS port code contains the works of other authors. See headers in
17  * individual files.
18  *
19  * Snes9x homepage: http://www.snes9x.com
20  *
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.
25  *
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.
29  *
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.
33  *
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
36  * in future versions.
37  *
38  * Super NES and Super Nintendo Entertainment System are trademarks of
39  * Nintendo Co., Limited and its subsidiary companies.
40  */
41
42 #include "snes9x.h"
43 #include "port.h"
44 #include "gfx.h"
45
46 #ifdef MMX
47 EXTERN_C void _2xSaILine  (uint8 *srcPtr, uint8 *deltaPtr, uint32 srcPitch, uint32 width,
48                         uint8 *dstPtr, uint32 dstPitch);
49 EXTERN_C void _2xSaISuperEagleLine  (uint8 *srcPtr, uint8 *deltaPtr, uint32 srcPitch, uint32 width,
50                         uint8 *dstPtr, uint32 dstPitch);
51 EXTERN_C int Init_2xSaIMMX (uint32 BitFormat);
52 #endif
53
54 bool mmx_cpu = false;
55
56 static uint32 colorMask = 0xF7DEF7DE;
57 static uint32 lowPixelMask = 0x08210821;
58 static uint32 qcolorMask = 0xE79CE79C;
59 static uint32 qlowpixelMask = 0x18631863;
60
61
62 int Init_2xSaI(uint32 BitFormat)
63 {
64         if (BitFormat == 565)
65         {
66                 colorMask = 0xF7DEF7DE;
67                 lowPixelMask = 0x08210821;
68                 qcolorMask = 0xE79CE79C;
69                 qlowpixelMask = 0x18631863;
70         }
71         else
72         if (BitFormat == 555)
73         {
74                 colorMask = 0x7BDE7BDE;
75                 lowPixelMask = 0x04210421;
76                 qcolorMask = 0x739C739C;
77                 qlowpixelMask = 0x0C630C63;
78         }
79         else
80         {
81                 return 0;
82         }
83 #ifdef MMX
84         Init_2xSaIMMX(BitFormat);
85 #endif
86         return 1;
87 }
88
89 STATIC inline int GetResult1(uint32 A, uint32 B, uint32 C, uint32 D, uint32 E)
90 {
91  int x = 0; 
92  int y = 0;
93  int r = 0;
94  if (A == C) x+=1; else if (B == C) y+=1;
95  if (A == D) x+=1; else if (B == D) y+=1;
96  if (x <= 1) r+=1; 
97  if (y <= 1) r-=1;
98  return r;
99 }
100
101 STATIC inline int GetResult2(uint32 A, uint32 B, uint32 C, uint32 D, uint32 E) 
102 {
103  int x = 0; 
104  int y = 0;
105  int r = 0;
106  if (A == C) x+=1; else if (B == C) y+=1;
107  if (A == D) x+=1; else if (B == D) y+=1;
108  if (x <= 1) r-=1; 
109  if (y <= 1) r+=1;
110  return r;
111 }
112
113
114 STATIC inline int GetResult(uint32 A, uint32 B, uint32 C, uint32 D)
115 {
116  int x = 0; 
117  int y = 0;
118  int r = 0;
119  if (A == C) x+=1; else if (B == C) y+=1;
120  if (A == D) x+=1; else if (B == D) y+=1;
121  if (x <= 1) r+=1; 
122  if (y <= 1) r-=1;
123  return r;
124 }
125
126
127 STATIC inline uint32 INTERPOLATE(uint32 A, uint32 B)
128 {
129     if (A !=B)
130     {
131        return ( ((A & colorMask) >> 1) + ((B & colorMask) >> 1) + (A & B & lowPixelMask) );
132     }
133     else return A;
134 }
135
136
137 STATIC inline uint32 Q_INTERPOLATE(uint32 A, uint32 B, uint32 C, uint32 D)
138 {
139         register uint32 x = ((A & qcolorMask) >> 2) +
140                             ((B & qcolorMask) >> 2) +
141                             ((C & qcolorMask) >> 2) +
142                             ((D & qcolorMask) >> 2);
143         register uint32 y = (A & qlowpixelMask) +
144                             (B & qlowpixelMask) +
145                             (C & qlowpixelMask) +
146                             (D & qlowpixelMask);
147         y = (y>>2) & qlowpixelMask;
148         return x+y;
149 }
150
151
152
153
154 #define HOR
155 #define VER
156 void Super2xSaI(uint8 *srcPtr, uint32 srcPitch,
157              uint8 *deltaPtr,
158              uint8 *dstPtr, uint32 dstPitch, int width, int height)
159 {
160     uint32 *dP;
161     uint16 *bP;
162
163 #ifdef MMX_BLA  //no MMX version yet
164     if (cpu_mmx && width != 512)
165     {
166         for (; height; height--)
167         {
168                 bP = (uint16 *) srcPtr;
169                 xP = (uint16 *) deltaPtr;
170                 dP = (uint32 *) dstPtr;
171                 _2xSaISuperEagleLine  ((uint8 *) bP, (uint8 *) xP, srcPitch, width, (uint8 *) dP, dstPitch);
172                 dstPtr += dstPitch << 1;
173                 srcPtr += srcPitch;
174                 deltaPtr += srcPitch;
175         }
176     }
177     else
178     {
179 #endif
180         uint32 Nextline = srcPitch >> 1;
181
182                 for (; height; height--)
183         {
184             bP = (uint16 *) srcPtr;
185             dP = (uint32 *) dstPtr;
186             for (uint32 finish = width; finish; finish -= 1 )
187             {
188                 uint32 color4, color5, color6;
189                 uint32 color1, color2, color3;
190                 uint32 colorA0, colorA1, colorA2, colorA3,
191                         colorB0, colorB1, colorB2, colorB3,
192                         colorS1, colorS2;
193                 uint32 product1a, product1b,
194                         product2a, product2b;
195
196 //---------------------------------------    B1 B2
197 //                                         4  5  6 S2
198 //                                         1  2  3 S1
199 //                                           A1 A2
200
201                 colorB0 = *(bP- Nextline - 1);
202                 colorB1 = *(bP- Nextline);
203                 colorB2 = *(bP- Nextline + 1);
204                 colorB3 = *(bP- Nextline + 2);
205
206                 color4 = *(bP - 1);
207                 color5 = *(bP);
208                 color6 = *(bP + 1);
209                 colorS2 = *(bP + 2);
210
211                 color1 = *(bP + Nextline - 1);
212                 color2 = *(bP + Nextline);
213                 color3 = *(bP + Nextline + 1);
214                 colorS1 = *(bP + Nextline + 2);
215
216                 colorA0 = *(bP + Nextline + Nextline - 1);
217                 colorA1 = *(bP + Nextline + Nextline);
218                 colorA2 = *(bP + Nextline + Nextline + 1);
219                 colorA3 = *(bP + Nextline + Nextline + 2);
220
221
222 //--------------------------------------
223                 if (color2 == color6 && color5 != color3)
224                 {
225                    product2b = product1b = color2;
226                 }
227                 else
228                 if (color5 == color3 && color2 != color6)
229                 {
230                    product2b = product1b = color5;
231                 }
232                 else
233                 if (color5 == color3 && color2 == color6 && color5 != color6)
234                 {
235                    register int r = 0;
236
237                    r += GetResult (color6, color5, color1, colorA1);
238                    r += GetResult (color6, color5, color4, colorB1);
239                    r += GetResult (color6, color5, colorA2, colorS1);
240                    r += GetResult (color6, color5, colorB2, colorS2);
241
242                    if (r > 0)
243                       product2b = product1b = color6;
244                    else
245                    if (r < 0)
246                       product2b = product1b = color5;
247                    else
248                    {
249                       product2b = product1b = INTERPOLATE (color5, color6);
250                    }
251
252                 }
253                 else
254                 {
255
256 #ifdef VER
257                    if (color6 == color3 && color3 == colorA1 && color2 != colorA2 && color3 != colorA0)
258                       product2b = Q_INTERPOLATE (color3, color3, color3, color2);
259                    else
260                    if (color5 == color2 && color2 == colorA2 && colorA1 != color3 && color2 != colorA3)
261                       product2b = Q_INTERPOLATE (color2, color2, color2, color3);
262                    else
263 #endif
264                       product2b = INTERPOLATE (color2, color3);
265
266 #ifdef VER
267                    if (color6 == color3 && color6 == colorB1 && color5 != colorB2 && color6 != colorB0)
268                       product1b = Q_INTERPOLATE (color6, color6, color6, color5);
269                    else
270                    if (color5 == color2 && color5 == colorB2 && colorB1 != color6 && color5 != colorB3)
271                       product1b = Q_INTERPOLATE (color6, color5, color5, color5);
272                    else
273 #endif
274                       product1b = INTERPOLATE (color5, color6);
275                 }
276
277 #ifdef HOR
278                 if (color5 == color3 && color2 != color6 && color4 == color5 && color5 != colorA2)
279                    product2a = INTERPOLATE (color2, color5);
280                 else
281                 if (color5 == color1 && color6 == color5 && color4 != color2 && color5 != colorA0)
282                    product2a = INTERPOLATE(color2, color5);
283                 else
284 #endif
285                    product2a = color2;
286
287 #ifdef HOR
288                 if (color2 == color6 && color5 != color3 && color1 == color2 && color2 != colorB2)
289                    product1a = INTERPOLATE (color2, color5);
290                 else
291                 if (color4 == color2 && color3 == color2 && color1 != color5 && color2 != colorB0)
292                    product1a = INTERPOLATE(color2, color5);
293                 else
294 #endif
295                    product1a = color5;
296
297
298                 product1a = product1a | (product1b << 16);
299                 product2a = product2a | (product2b << 16);
300
301                 *(dP) = product1a;
302                 *(dP+(dstPitch>>2)) = product2a;
303
304                 bP += 1;
305                 dP += 1;
306             }//end of for ( finish= width etc..)
307
308             dstPtr += dstPitch << 1;
309             srcPtr += srcPitch;
310             deltaPtr += srcPitch;
311         }; //endof: for (height; height; height--)
312 #ifdef MMX_BLA
313     }
314 #endif
315 }
316
317
318
319
320
321
322 /*ONLY use with 640x480x16 or higher resolutions*/
323 /*Only use this if 2*width * 2*height fits on the current screen*/
324 void SuperEagle(uint8 *srcPtr, uint32 srcPitch,
325              uint8 *deltaPtr,
326                  uint8 *dstPtr, uint32 dstPitch, int width, int height)
327 {
328     uint32 *dP;
329     uint16 *bP;
330 #ifdef MMX
331     uint16 *xP;
332 #endif
333
334 #ifdef MMX
335     if (mmx_cpu && width != 512)
336     {
337         for (; height; height--)
338         {
339                 bP = (uint16 *) srcPtr;
340                 xP = (uint16 *) deltaPtr;
341                 dP = (uint32 *) dstPtr;
342                 _2xSaISuperEagleLine  ((uint8 *) bP, (uint8 *) xP, srcPitch, width, (uint8 *)dP, dstPitch);
343                 dstPtr += dstPitch << 1;
344                 srcPtr += srcPitch;
345                 deltaPtr += srcPitch;
346         }
347     }
348     else
349     {
350 #endif
351         uint32 Nextline = srcPitch >> 1;
352
353         for (; height; height--)
354         {
355             bP = (uint16 *) srcPtr;
356             dP = (uint32 *) dstPtr;
357             for (uint32 finish = width; finish; finish -= 1 )
358             {
359
360                 uint32 color4, color5, color6;
361                 uint32 color1, color2, color3;
362                 uint32 colorA0, colorA1, colorA2, colorA3,
363                   colorB0, colorB1, colorB2, colorB3,
364                   colorS1, colorS2;
365                 uint32 product1a, product1b,
366                   product2a, product2b;
367
368                 colorB0 = *(bP- Nextline - 1);
369                 colorB1 = *(bP- Nextline);
370                 colorB2 = *(bP- Nextline + 1);
371                 colorB3 = *(bP- Nextline + 2);
372
373                 color4 = *(bP - 1);
374                 color5 = *(bP);
375                 color6 = *(bP + 1);
376                 colorS2 = *(bP + 2);
377
378                 color1 = *(bP + Nextline - 1);
379                 color2 = *(bP + Nextline);
380                 color3 = *(bP + Nextline + 1);
381                 colorS1 = *(bP + Nextline + 2);
382
383                 colorA0 = *(bP + Nextline + Nextline - 1);
384                 colorA1 = *(bP + Nextline + Nextline);
385                 colorA2 = *(bP + Nextline + Nextline + 1);
386                 colorA3 = *(bP + Nextline + Nextline + 2);
387
388
389                 //--------------------------------------
390                 if (color2 == color6 && color5 != color3)
391                 {
392                    product1b = product2a = color2;
393                    if ((color1 == color2 && color6 == colorS2) ||
394                        (color2 == colorA1 && color6 == colorB2))
395                    {
396                        product1a = INTERPOLATE (color2, color5);
397                        product1a = INTERPOLATE (color2, product1a);
398                        product2b = INTERPOLATE (color2, color3);
399                        product2b = INTERPOLATE (color2, product2b);
400 //                       product1a = color2;
401 //                       product2b = color2;
402                    }
403                    else
404                    {
405                       product1a = INTERPOLATE (color5, color6);
406                       product2b = INTERPOLATE (color2, color3);
407                    }
408                 }
409                 else
410                 if (color5 == color3 && color2 != color6)
411                 {
412                    product2b = product1a = color5;
413                    if ((colorB1 == color5 && color3 == colorA2) ||
414                        (color4 == color5 && color3 == colorS1))
415                    {
416                        product1b = INTERPOLATE (color5, color6);
417                        product1b = INTERPOLATE (color5, product1b);
418                        product2a = INTERPOLATE (color5, color2);
419                        product2a = INTERPOLATE (color5, product2a);
420 //                       product1b = color5;
421 //                       product2a = color5;
422                    }
423                    else
424                    {
425                       product1b = INTERPOLATE (color5, color6);
426                       product2a = INTERPOLATE (color2, color3);
427                    }
428                 }
429                 else
430                 if (color5 == color3 && color2 == color6 && color5 != color6)
431                 {
432                    register int r = 0;
433
434                    r += GetResult (color6, color5, color1, colorA1);
435                    r += GetResult (color6, color5, color4, colorB1);
436                    r += GetResult (color6, color5, colorA2, colorS1);
437                    r += GetResult (color6, color5, colorB2, colorS2);
438
439                    if (r > 0)
440                    {
441                       product1b = product2a = color2;
442                       product1a = product2b = INTERPOLATE (color5, color6);
443                    }
444                    else
445                    if (r < 0)
446                    {
447                       product2b = product1a = color5;
448                       product1b = product2a = INTERPOLATE (color5, color6);
449                    }
450                    else
451                    {
452                       product2b = product1a = color5;
453                       product1b = product2a = color2;
454                    }
455                 }
456                 else
457                 {
458
459                    if ((color2 == color5) || (color3 == color6))
460                    {
461                       product1a = color5;
462                       product2a = color2;
463                       product1b = color6;
464                       product2b = color3;
465
466                    }
467                    else
468                    {
469                       product1b = product1a = INTERPOLATE (color5, color6);
470                       product1a = INTERPOLATE (color5, product1a);
471                       product1b = INTERPOLATE (color6, product1b);
472
473                       product2a = product2b = INTERPOLATE (color2, color3);
474                       product2a = INTERPOLATE (color2, product2a);
475                       product2b = INTERPOLATE (color3, product2b);
476                    }
477                 }
478
479
480                 product1a = product1a | (product1b << 16);
481                 product2a = product2a | (product2b << 16);
482
483                 *(dP) = product1a;
484                 *(dP+(dstPitch>>2)) = product2a;
485
486                 bP += 1;
487                 dP += 1;
488             }//end of for ( finish= width etc..)
489
490             dstPtr += dstPitch << 1;
491             srcPtr += srcPitch;
492             deltaPtr += srcPitch;
493         }; //endof: for (height; height; height--)
494 #ifdef MMX
495     }
496 #endif
497 }
498
499
500
501 /*ONLY use with 640x480x16 or higher resolutions*/
502 /*Only use this if 2*width * 2*height fits on the current screen*/
503 void _2xSaI(uint8 *srcPtr, uint32 srcPitch,
504              uint8 *deltaPtr,
505              uint8 *dstPtr, uint32 dstPitch, int width, int height)
506 {
507     uint32 *dP;
508     uint16 *bP;
509 #ifdef MMX
510     uint16 *xP;
511 #endif
512
513 #ifdef MMX
514     if (mmx_cpu && width != 512)
515     {
516         for (; height; height--)
517         {
518
519             bP = (uint16 *) srcPtr;
520             xP = (uint16 *) deltaPtr;
521             dP = (uint32 *) dstPtr;
522             _2xSaILine  ((uint8 *) bP, (uint8 *) xP, srcPitch, width, (uint8 *)dP, dstPitch);
523             dstPtr += dstPitch << 1;
524             srcPtr += srcPitch;
525             deltaPtr += srcPitch;
526         }
527     }
528     else
529     {
530 #endif
531         uint32 Nextline = srcPitch >> 1;
532
533         for (; height; height--)
534         {
535             bP = (uint16 *) srcPtr;
536             dP = (uint32 *) dstPtr;
537             for (uint32 finish = width; finish; finish -= 1 )
538             {
539
540
541                 register uint32 colorA, colorB;
542                 uint32 colorC, colorD,
543                        colorE, colorF, colorG, colorH,
544                        colorI, colorJ, colorK, colorL,
545                        colorM, colorN, colorO, colorP;
546                 uint32 product, product1, product2;
547
548
549 //---------------------------------------
550 // Map of the pixels:                    I|E F|J
551 //                                       G|A B|K
552 //                                       H|C D|L
553 //                                       M|N O|P
554                 colorI = *(bP- Nextline - 1);
555                 colorE = *(bP- Nextline);
556                 colorF = *(bP- Nextline + 1);
557                 colorJ = *(bP- Nextline + 2);
558
559                 colorG = *(bP - 1);
560                 colorA = *(bP);
561                 colorB = *(bP + 1);
562                 colorK = *(bP + 2);
563
564                 colorH = *(bP + Nextline - 1);
565                 colorC = *(bP + Nextline);
566                 colorD = *(bP + Nextline + 1);
567                 colorL = *(bP + Nextline + 2);
568
569                 colorM = *(bP + Nextline + Nextline - 1);
570                 colorN = *(bP + Nextline + Nextline);
571                 colorO = *(bP + Nextline + Nextline + 1);
572                 colorP = *(bP + Nextline + Nextline + 2);
573
574                         if ((colorA == colorD) && (colorB != colorC))
575                         {
576                            if ( ((colorA == colorE) && (colorB == colorL)) ||
577                                 ((colorA == colorC) && (colorA == colorF) && (colorB != colorE) && (colorB == colorJ)) )
578                            {
579                               product = colorA;
580                            }
581                            else
582                            {
583                               product = INTERPOLATE(colorA, colorB);
584                            }
585
586                            if (((colorA == colorG) && (colorC == colorO)) ||
587                                ((colorA == colorB) && (colorA == colorH) && (colorG != colorC) && (colorC == colorM)) )
588                            {
589                               product1 = colorA;
590                            }
591                            else
592                            {
593                               product1 = INTERPOLATE(colorA, colorC);
594                            }
595                            product2 = colorA;
596                         }
597                         else
598                         if ((colorB == colorC) && (colorA != colorD))
599                         {
600                            if (((colorB == colorF) && (colorA == colorH)) ||
601                                ((colorB == colorE) && (colorB == colorD) && (colorA != colorF) && (colorA == colorI)) )
602                            {
603                               product = colorB;
604                            }
605                            else
606                            {
607                               product = INTERPOLATE(colorA, colorB);
608                            }
609
610                            if (((colorC == colorH) && (colorA == colorF)) ||
611                                ((colorC == colorG) && (colorC == colorD) && (colorA != colorH) && (colorA == colorI)) )
612                            {
613                               product1 = colorC;
614                            }
615                            else
616                            {
617                               product1 = INTERPOLATE(colorA, colorC);
618                            }
619                            product2 = colorB;
620                         }
621                         else
622                         if ((colorA == colorD) && (colorB == colorC))
623                         {
624                            if (colorA == colorB)
625                            {
626                               product = colorA;
627                               product1 = colorA;
628                               product2 = colorA;
629                            }
630                            else
631                            {
632                               register int r = 0;
633                               product1 = INTERPOLATE(colorA, colorC);
634                               product = INTERPOLATE(colorA, colorB);
635
636                               r += GetResult1 (colorA, colorB, colorG, colorE, colorI);
637                               r += GetResult2 (colorB, colorA, colorK, colorF, colorJ);
638                               r += GetResult2 (colorB, colorA, colorH, colorN, colorM);
639                               r += GetResult1 (colorA, colorB, colorL, colorO, colorP);
640
641                               if (r > 0)
642                                   product2 = colorA;
643                               else
644                               if (r < 0)
645                                   product2 = colorB;
646                               else
647                               {
648                                   product2 = Q_INTERPOLATE(colorA, colorB, colorC, colorD);
649                               }
650                            }
651                         }
652                         else
653                         {
654                            product2 = Q_INTERPOLATE(colorA, colorB, colorC, colorD);
655
656                            if ((colorA == colorC) && (colorA == colorF) && (colorB != colorE) && (colorB == colorJ))
657                            {
658                               product = colorA;
659                            }
660                            else
661                            if ((colorB == colorE) && (colorB == colorD) && (colorA != colorF) && (colorA == colorI))
662                            {
663                               product = colorB;
664                            }
665                            else
666                            {
667                               product = INTERPOLATE(colorA, colorB);
668                            }
669
670                            if ((colorA == colorB) && (colorA == colorH) && (colorG != colorC) && (colorC == colorM))
671                            {
672                               product1 = colorA;
673                            }
674                            else
675                            if ((colorC == colorG) && (colorC == colorD) && (colorA != colorH) && (colorA == colorI))
676                            {
677                               product1 = colorC;
678                            }
679                            else
680                            {
681                               product1 = INTERPOLATE(colorA, colorC);
682                            }
683                         }
684                         product = colorA | (product << 16);
685                         product1 = product1 | (product2 << 16);
686                         *(dP) = product;
687                         *(dP+(dstPitch>>2)) = product1;
688
689                     bP += 1;
690                     dP += 1;
691                 }//end of for ( finish= width etc..)
692
693             dstPtr += dstPitch << 1;
694             srcPtr += srcPitch;
695             deltaPtr += srcPitch;
696         }; //endof: for (height; height; height--)
697 #ifdef MMX
698     }
699 #endif
700 }