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