dfxvideo: use bit31 handling from pcsxr-svn
[pcsx_rearmed.git] / plugins / dfxvideo / draw.c
1 /***************************************************************************
2                           draw.c  -  description
3                              -------------------
4     begin                : Sun Oct 28 2001
5     copyright            : (C) 2001 by Pete Bernert
6     email                : BlackDove@addcom.de
7  ***************************************************************************/
8 /***************************************************************************
9  *                                                                         *
10  *   This program is free software; you can redistribute it and/or modify  *
11  *   it under the terms of the GNU General Public License as published by  *
12  *   the Free Software Foundation; either version 2 of the License, or     *
13  *   (at your option) any later version. See also the license.txt file for *
14  *   additional informations.                                              *
15  *                                                                         *
16  ***************************************************************************/
17
18 #define _IN_DRAW
19
20 #include <X11/Xlib.h>
21 #include <X11/Xutil.h>
22 #include <X11/cursorfont.h>
23
24 #include "gpu.h"
25
26 // misc globals
27 int            iResX=640;
28 int            iResY=480;
29 long           lLowerpart;
30 BOOL           bIsFirstFrame = TRUE;
31 BOOL           bCheckMask = FALSE;
32 unsigned short sSetMask = 0;
33 unsigned long  lSetMask = 0;
34 int            iDesktopCol = 16;
35 int            iShowFPS = 0;
36 int            iWinSize; 
37 int            iMaintainAspect = 0;
38 int            iUseNoStretchBlt = 0;
39 int            iFastFwd = 0;
40 //int            iDebugMode = 0;
41 int            iFVDisplay = 0;
42 PSXPoint_t     ptCursorPoint[8];
43 unsigned short usCursorActive = 0;
44 unsigned long  ulKeybits;
45
46 int            iWindowMode=1;
47 int            iColDepth=32;
48 char           szDispBuf[64];
49 char           szMenuBuf[36];
50 char           szDebugText[512];
51 void InitMenu(void) {}
52 void CloseMenu(void) {}
53
54 //unsigned int   LUT16to32[65536];
55 //unsigned int   RGBtoYUV[65536];
56
57 #include <sys/ipc.h>
58 #include <sys/shm.h>
59 #include <X11/extensions/Xv.h>
60 #include <X11/extensions/Xvlib.h>
61 #include <X11/extensions/XShm.h>
62 int xv_port = -1;
63 int xv_id = -1;
64 int xv_depth = 0;
65 int yuv_port = -1;
66 int yuv_id = -1;
67 int use_yuv = 0;
68 int xv_vsync = 0;
69
70 XShmSegmentInfo shminfo;
71 int finalw,finalh;
72
73 typedef struct {
74 #define MWM_HINTS_DECORATIONS   2
75   long flags;
76   long functions;
77   long decorations;
78   long input_mode;
79 } MotifWmHints;
80
81 extern XvImage  *XvShmCreateImage(Display*, XvPortID, int, char*, int, int, XShmSegmentInfo*);
82
83 #include <time.h>
84
85 // prototypes
86 void hq2x_32( unsigned char * srcPtr, DWORD srcPitch, unsigned char * dstPtr, int width, int height);
87 void hq3x_32( unsigned char * srcPtr,  DWORD srcPitch, unsigned char * dstPtr, int width, int height);
88
89 ////////////////////////////////////////////////////////////////////////
90 // generic 2xSaI helpers
91 ////////////////////////////////////////////////////////////////////////
92
93 void *         pSaISmallBuff=NULL;
94 void *         pSaIBigBuff=NULL;
95
96 #define GET_RESULT(A, B, C, D) ((A != C || A != D) - (B != C || B != D))
97
98 static __inline int GetResult1(DWORD A, DWORD B, DWORD C, DWORD D, DWORD E)
99 {
100  int x = 0;
101  int y = 0;
102  int r = 0;
103  if (A == C) x+=1; else if (B == C) y+=1;
104  if (A == D) x+=1; else if (B == D) y+=1;
105  if (x <= 1) r+=1; 
106  if (y <= 1) r-=1;
107  return r;
108 }
109
110 static __inline int GetResult2(DWORD A, DWORD B, DWORD C, DWORD D, DWORD E) 
111 {
112  int x = 0; 
113  int y = 0;
114  int r = 0;
115  if (A == C) x+=1; else if (B == C) y+=1;
116  if (A == D) x+=1; else if (B == D) y+=1;
117  if (x <= 1) r-=1; 
118  if (y <= 1) r+=1;
119  return r;
120 }
121
122 #define colorMask8     0x00FEFEFE
123 #define lowPixelMask8  0x00010101
124 #define qcolorMask8    0x00FCFCFC
125 #define qlowpixelMask8 0x00030303
126
127 #define INTERPOLATE8(A, B) ((((A & colorMask8) >> 1) + ((B & colorMask8) >> 1) + (A & B & lowPixelMask8)))
128 #define Q_INTERPOLATE8(A, B, C, D) (((((A & qcolorMask8) >> 2) + ((B & qcolorMask8) >> 2) + ((C & qcolorMask8) >> 2) + ((D & qcolorMask8) >> 2) \
129         + ((((A & qlowpixelMask8) + (B & qlowpixelMask8) + (C & qlowpixelMask8) + (D & qlowpixelMask8)) >> 2) & qlowpixelMask8))))
130
131
132 void Super2xSaI_ex8(unsigned char *srcPtr, DWORD srcPitch,
133                     unsigned char  *dstBitmap, int width, int height)
134 {
135  DWORD dstPitch        = srcPitch<<1;
136  DWORD srcPitchHalf    = srcPitch>>1;
137  int   finWidth        = srcPitch>>2;
138  DWORD line;
139  DWORD *dP;
140  DWORD *bP;
141  int iXA,iXB,iXC,iYA,iYB,iYC,finish;
142  DWORD color4, color5, color6;
143  DWORD color1, color2, color3;
144  DWORD colorA0, colorA1, colorA2, colorA3,
145        colorB0, colorB1, colorB2, colorB3,
146        colorS1, colorS2;
147  DWORD product1a, product1b,
148        product2a, product2b;
149
150  finalw=width<<1;
151  finalh=height<<1;
152
153  line = 0;
154
155   {
156    for (; height; height-=1)
157         {
158      bP = (DWORD *)srcPtr;
159          dP = (DWORD *)(dstBitmap + line*dstPitch);
160      for (finish = width; finish; finish -= 1 )
161       {
162 //---------------------------------------    B1 B2
163 //                                         4  5  6 S2
164 //                                         1  2  3 S1
165 //                                           A1 A2
166        if(finish==finWidth) iXA=0;
167        else                 iXA=1;
168        if(finish>4) {iXB=1;iXC=2;}
169        else
170        if(finish>3) {iXB=1;iXC=1;}
171        else         {iXB=0;iXC=0;}
172        if(line==0)  {iYA=0;}
173        else         {iYA=finWidth;}
174        if(height>4) {iYB=finWidth;iYC=srcPitchHalf;}
175        else
176        if(height>3) {iYB=finWidth;iYC=finWidth;}
177        else         {iYB=0;iYC=0;}
178
179        colorB0 = *(bP- iYA - iXA);
180        colorB1 = *(bP- iYA);
181        colorB2 = *(bP- iYA + iXB);
182        colorB3 = *(bP- iYA + iXC);
183
184        color4 = *(bP  - iXA);
185        color5 = *(bP);
186        color6 = *(bP  + iXB);
187        colorS2 = *(bP + iXC);
188
189        color1 = *(bP  + iYB  - iXA);
190        color2 = *(bP  + iYB);
191        color3 = *(bP  + iYB  + iXB);
192        colorS1= *(bP  + iYB  + iXC);
193
194        colorA0 = *(bP + iYC - iXA);
195        colorA1 = *(bP + iYC);
196        colorA2 = *(bP + iYC + iXB);
197        colorA3 = *(bP + iYC + iXC);
198
199        if (color2 == color6 && color5 != color3)
200         {
201          product2b = product1b = color2;
202         }
203        else
204        if (color5 == color3 && color2 != color6)
205         {
206          product2b = product1b = color5;
207         }
208        else
209        if (color5 == color3 && color2 == color6)
210         {
211          register int r = 0;
212
213          r += GET_RESULT ((color6&0x00ffffff), (color5&0x00ffffff), (color1&0x00ffffff),  (colorA1&0x00ffffff));
214          r += GET_RESULT ((color6&0x00ffffff), (color5&0x00ffffff), (color4&0x00ffffff),  (colorB1&0x00ffffff));
215          r += GET_RESULT ((color6&0x00ffffff), (color5&0x00ffffff), (colorA2&0x00ffffff), (colorS1&0x00ffffff));
216          r += GET_RESULT ((color6&0x00ffffff), (color5&0x00ffffff), (colorB2&0x00ffffff), (colorS2&0x00ffffff));
217
218          if (r > 0)
219           product2b = product1b = color6;
220          else
221          if (r < 0)
222           product2b = product1b = color5;
223          else
224           {
225            product2b = product1b = INTERPOLATE8(color5, color6);
226           }
227         }
228        else
229         {
230          if (color6 == color3 && color3 == colorA1 && color2 != colorA2 && color3 != colorA0)
231              product2b = Q_INTERPOLATE8 (color3, color3, color3, color2);
232          else
233          if (color5 == color2 && color2 == colorA2 && colorA1 != color3 && color2 != colorA3)
234              product2b = Q_INTERPOLATE8 (color2, color2, color2, color3);
235          else
236              product2b = INTERPOLATE8 (color2, color3);
237
238          if (color6 == color3 && color6 == colorB1 && color5 != colorB2 && color6 != colorB0)
239              product1b = Q_INTERPOLATE8 (color6, color6, color6, color5);
240          else
241          if (color5 == color2 && color5 == colorB2 && colorB1 != color6 && color5 != colorB3)
242              product1b = Q_INTERPOLATE8 (color6, color5, color5, color5);
243          else
244              product1b = INTERPOLATE8 (color5, color6);
245         }
246
247        if (color5 == color3 && color2 != color6 && color4 == color5 && color5 != colorA2)
248         product2a = INTERPOLATE8(color2, color5);
249        else
250        if (color5 == color1 && color6 == color5 && color4 != color2 && color5 != colorA0)
251         product2a = INTERPOLATE8(color2, color5);
252        else
253         product2a = color2;
254
255        if (color2 == color6 && color5 != color3 && color1 == color2 && color2 != colorB2)
256         product1a = INTERPOLATE8(color2, color5);
257        else
258        if (color4 == color2 && color3 == color2 && color1 != color5 && color2 != colorB0)
259         product1a = INTERPOLATE8(color2, color5);
260        else
261         product1a = color5;
262
263        *dP=product1a;
264        *(dP+1)=product1b;
265        *(dP+(srcPitchHalf))=product2a;
266        *(dP+1+(srcPitchHalf))=product2b;
267
268        bP += 1;
269        dP += 2;
270       }//end of for ( finish= width etc..)
271
272      line += 2;
273      srcPtr += srcPitch;
274         }; //endof: for (; height; height--)
275   }
276 }
277
278 ////////////////////////////////////////////////////////////////////////
279
280 void Std2xSaI_ex8(unsigned char *srcPtr, DWORD srcPitch,
281                   unsigned char *dstBitmap, int width, int height)
282 {
283  DWORD dstPitch        = srcPitch<<1;
284  DWORD srcPitchHalf    = srcPitch>>1;
285  int   finWidth        = srcPitch>>2;
286  DWORD line;
287  DWORD *dP;
288  DWORD *bP;
289  int iXA,iXB,iXC,iYA,iYB,iYC,finish;
290
291  finalw=width<<1;
292  finalh=height<<1;
293
294  DWORD colorA, colorB;
295  DWORD colorC, colorD,
296        colorE, colorF, colorG, colorH,
297        colorI, colorJ, colorK, colorL,
298        colorM, colorN, colorO, colorP;
299  DWORD product, product1, product2;
300
301  line = 0;
302
303   {
304    for (; height; height-=1)
305         {
306      bP = (DWORD *)srcPtr;
307          dP = (DWORD *)(dstBitmap + line*dstPitch);
308      for (finish = width; finish; finish -= 1 )
309       {
310 //---------------------------------------
311 // Map of the pixels:                    I|E F|J
312 //                                       G|A B|K
313 //                                       H|C D|L
314 //                                       M|N O|P
315        if(finish==finWidth) iXA=0;
316        else                 iXA=1;
317        if(finish>4) {iXB=1;iXC=2;}
318        else
319        if(finish>3) {iXB=1;iXC=1;}
320        else         {iXB=0;iXC=0;}
321        if(line==0)  {iYA=0;}
322        else         {iYA=finWidth;}
323        if(height>4) {iYB=finWidth;iYC=srcPitchHalf;}
324        else
325        if(height>3) {iYB=finWidth;iYC=finWidth;}
326        else         {iYB=0;iYC=0;}
327
328        colorI = *(bP- iYA - iXA);
329        colorE = *(bP- iYA);
330        colorF = *(bP- iYA + iXB);
331        colorJ = *(bP- iYA + iXC);
332
333        colorG = *(bP  - iXA);
334        colorA = *(bP);
335        colorB = *(bP  + iXB);
336        colorK = *(bP + iXC);
337
338        colorH = *(bP  + iYB  - iXA);
339        colorC = *(bP  + iYB);
340        colorD = *(bP  + iYB  + iXB);
341        colorL = *(bP  + iYB  + iXC);
342
343        colorM = *(bP + iYC - iXA);
344        colorN = *(bP + iYC);
345        colorO = *(bP + iYC + iXB);
346        colorP = *(bP + iYC + iXC);
347
348
349        if((colorA == colorD) && (colorB != colorC))
350         {
351          if(((colorA == colorE) && (colorB == colorL)) ||
352             ((colorA == colorC) && (colorA == colorF) && 
353              (colorB != colorE) && (colorB == colorJ)))
354           {
355            product = colorA;
356           }
357          else
358           {
359            product = INTERPOLATE8(colorA, colorB);
360           }
361
362          if(((colorA == colorG) && (colorC == colorO)) ||
363             ((colorA == colorB) && (colorA == colorH) && 
364              (colorG != colorC) && (colorC == colorM)))
365           {
366            product1 = colorA;
367           }
368          else
369           {
370            product1 = INTERPOLATE8(colorA, colorC);
371           }
372          product2 = colorA;
373         }
374        else
375        if((colorB == colorC) && (colorA != colorD))
376         {
377          if(((colorB == colorF) && (colorA == colorH)) ||
378             ((colorB == colorE) && (colorB == colorD) && 
379              (colorA != colorF) && (colorA == colorI)))
380           {
381            product = colorB;
382           }
383          else
384           {
385            product = INTERPOLATE8(colorA, colorB);
386           }
387
388          if(((colorC == colorH) && (colorA == colorF)) ||
389             ((colorC == colorG) && (colorC == colorD) && 
390              (colorA != colorH) && (colorA == colorI)))
391           {
392            product1 = colorC;
393           }
394          else
395           {
396            product1=INTERPOLATE8(colorA, colorC);
397           }
398          product2 = colorB;
399         }
400        else
401        if((colorA == colorD) && (colorB == colorC))
402         {
403          if (colorA == colorB)
404           {
405            product = colorA;
406            product1 = colorA;
407            product2 = colorA;
408           }
409          else
410           {
411            register int r = 0;
412            product1 = INTERPOLATE8(colorA, colorC);
413            product = INTERPOLATE8(colorA, colorB);
414
415            r += GetResult1 (colorA&0x00FFFFFF, colorB&0x00FFFFFF, colorG&0x00FFFFFF, colorE&0x00FFFFFF, colorI&0x00FFFFFF);
416            r += GetResult2 (colorB&0x00FFFFFF, colorA&0x00FFFFFF, colorK&0x00FFFFFF, colorF&0x00FFFFFF, colorJ&0x00FFFFFF);
417            r += GetResult2 (colorB&0x00FFFFFF, colorA&0x00FFFFFF, colorH&0x00FFFFFF, colorN&0x00FFFFFF, colorM&0x00FFFFFF);
418            r += GetResult1 (colorA&0x00FFFFFF, colorB&0x00FFFFFF, colorL&0x00FFFFFF, colorO&0x00FFFFFF, colorP&0x00FFFFFF);
419
420            if (r > 0)
421             product2 = colorA;
422            else
423            if (r < 0)
424             product2 = colorB;
425            else
426             {
427              product2 = Q_INTERPOLATE8(colorA, colorB, colorC, colorD);
428             }
429           }
430         }
431        else
432         {
433          product2 = Q_INTERPOLATE8(colorA, colorB, colorC, colorD);
434
435          if ((colorA == colorC) && (colorA == colorF) && 
436              (colorB != colorE) && (colorB == colorJ))
437           {
438            product = colorA;
439           }
440          else
441          if ((colorB == colorE) && (colorB == colorD) && (colorA != colorF) && (colorA == colorI))
442           {
443            product = colorB;
444           }
445          else
446           {
447            product = INTERPOLATE8(colorA, colorB);
448           }
449
450          if ((colorA == colorB) && (colorA == colorH) && 
451              (colorG != colorC) && (colorC == colorM))
452           {
453            product1 = colorA;
454           }
455          else
456          if ((colorC == colorG) && (colorC == colorD) && 
457              (colorA != colorH) && (colorA == colorI))
458           {
459            product1 = colorC;
460           }
461          else
462           {
463            product1 = INTERPOLATE8(colorA, colorC);
464           }
465         }
466
467 //////////////////////////
468
469        *dP=colorA;
470        *(dP+1)=product;
471        *(dP+(srcPitchHalf))=product1;
472        *(dP+1+(srcPitchHalf))=product2;
473
474        bP += 1;
475        dP += 2;
476       }//end of for ( finish= width etc..)
477
478      line += 2;
479      srcPtr += srcPitch;
480         }; //endof: for (; height; height--)
481   }
482 }
483
484 ////////////////////////////////////////////////////////////////////////
485
486 void SuperEagle_ex8(unsigned char *srcPtr, DWORD srcPitch,
487                         unsigned char  *dstBitmap, int width, int height)
488 {
489  DWORD dstPitch        = srcPitch<<1;
490  DWORD srcPitchHalf    = srcPitch>>1;
491  int   finWidth        = srcPitch>>2;
492  DWORD line;
493  DWORD *dP;
494  DWORD *bP;
495  int iXA,iXB,iXC,iYA,iYB,iYC,finish;
496  DWORD color4, color5, color6;
497  DWORD color1, color2, color3;
498  DWORD colorA1, colorA2, 
499        colorB1, colorB2,
500        colorS1, colorS2;
501  DWORD product1a, product1b,
502        product2a, product2b;
503
504  finalw=width<<1;
505  finalh=height<<1;
506
507  line = 0;
508
509   {
510    for (; height; height-=1)
511         {
512      bP = (DWORD *)srcPtr;
513          dP = (DWORD *)(dstBitmap + line*dstPitch);
514      for (finish = width; finish; finish -= 1 )
515       {
516        if(finish==finWidth) iXA=0;
517        else                 iXA=1;
518        if(finish>4) {iXB=1;iXC=2;}
519        else
520        if(finish>3) {iXB=1;iXC=1;}
521        else         {iXB=0;iXC=0;}
522        if(line==0)  {iYA=0;}
523        else         {iYA=finWidth;}
524        if(height>4) {iYB=finWidth;iYC=srcPitchHalf;}
525        else
526        if(height>3) {iYB=finWidth;iYC=finWidth;}
527        else         {iYB=0;iYC=0;}
528
529        colorB1 = *(bP- iYA);
530        colorB2 = *(bP- iYA + iXB);
531
532        color4 = *(bP  - iXA);
533        color5 = *(bP);
534        color6 = *(bP  + iXB);
535        colorS2 = *(bP + iXC);
536
537        color1 = *(bP  + iYB  - iXA);
538        color2 = *(bP  + iYB);
539        color3 = *(bP  + iYB  + iXB);
540        colorS1= *(bP  + iYB  + iXC);
541
542        colorA1 = *(bP + iYC);
543        colorA2 = *(bP + iYC + iXB);
544
545        if(color2 == color6 && color5 != color3)
546         {
547          product1b = product2a = color2;
548          if((color1 == color2) ||
549             (color6 == colorB2))
550           {
551            product1a = INTERPOLATE8(color2, color5);
552            product1a = INTERPOLATE8(color2, product1a);
553           }
554          else
555           {
556            product1a = INTERPOLATE8(color5, color6);
557           }
558  
559          if((color6 == colorS2) ||
560             (color2 == colorA1))
561           {
562            product2b = INTERPOLATE8(color2, color3);
563            product2b = INTERPOLATE8(color2, product2b);
564           }
565          else
566           {
567            product2b = INTERPOLATE8(color2, color3);
568           }
569         }
570        else
571        if (color5 == color3 && color2 != color6)
572         {
573          product2b = product1a = color5;
574
575          if ((colorB1 == color5) ||
576              (color3 == colorS1))
577           {
578            product1b = INTERPOLATE8(color5, color6);
579            product1b = INTERPOLATE8(color5, product1b);
580           }
581          else
582           {
583            product1b = INTERPOLATE8(color5, color6);
584           }
585
586          if ((color3 == colorA2) ||
587              (color4 == color5))
588           {
589            product2a = INTERPOLATE8(color5, color2);
590            product2a = INTERPOLATE8(color5, product2a);
591           }
592          else
593           {
594            product2a = INTERPOLATE8(color2, color3);
595           }
596         }
597        else
598        if (color5 == color3 && color2 == color6)
599         {
600          register int r = 0;
601
602          r += GET_RESULT ((color6&0x00ffffff), (color5&0x00ffffff), (color1&0x00ffffff),  (colorA1&0x00ffffff));
603          r += GET_RESULT ((color6&0x00ffffff), (color5&0x00ffffff), (color4&0x00ffffff),  (colorB1&0x00ffffff));
604          r += GET_RESULT ((color6&0x00ffffff), (color5&0x00ffffff), (colorA2&0x00ffffff), (colorS1&0x00ffffff));
605          r += GET_RESULT ((color6&0x00ffffff), (color5&0x00ffffff), (colorB2&0x00ffffff), (colorS2&0x00ffffff));
606
607          if (r > 0)
608           {
609            product1b = product2a = color2;
610            product1a = product2b = INTERPOLATE8(color5, color6);
611           }
612          else
613          if (r < 0)
614           {
615            product2b = product1a = color5;
616            product1b = product2a = INTERPOLATE8(color5, color6);
617           }
618          else
619           {
620            product2b = product1a = color5;
621            product1b = product2a = color2;
622           }
623         }
624        else
625         {
626          product2b = product1a = INTERPOLATE8(color2, color6);
627          product2b = Q_INTERPOLATE8(color3, color3, color3, product2b);
628          product1a = Q_INTERPOLATE8(color5, color5, color5, product1a);
629
630          product2a = product1b = INTERPOLATE8(color5, color3);
631          product2a = Q_INTERPOLATE8(color2, color2, color2, product2a);
632          product1b = Q_INTERPOLATE8(color6, color6, color6, product1b);
633         }
634
635 ////////////////////////////////
636
637        *dP=product1a;
638        *(dP+1)=product1b;
639        *(dP+(srcPitchHalf))=product2a;
640        *(dP+1+(srcPitchHalf))=product2b;
641
642        bP += 1;
643        dP += 2;
644       }//end of for ( finish= width etc..)
645
646      line += 2;
647      srcPtr += srcPitch;
648         }; //endof: for (; height; height--)
649   }
650 }
651
652 /////////////////////////
653
654 //#include <assert.h>
655
656 static __inline void scale2x_32_def_whole(uint32_t*  dst0, uint32_t* dst1, const uint32_t* src0, const uint32_t* src1, const uint32_t* src2, unsigned count)
657 {
658
659         //assert(count >= 2);
660
661         // first pixel
662         if (src0[0] != src2[0] && src1[0] != src1[1]) {
663                 dst0[0] = src1[0] == src0[0] ? src0[0] : src1[0];
664                 dst0[1] = src1[1] == src0[0] ? src0[0] : src1[0];
665                 dst1[0] = src1[0] == src2[0] ? src2[0] : src1[0];
666                 dst1[1] = src1[1] == src2[0] ? src2[0] : src1[0];
667         } else {
668                 dst0[0] = src1[0];
669                 dst0[1] = src1[0];
670                 dst1[0] = src1[0];
671                 dst1[1] = src1[0];
672         }
673         ++src0;
674         ++src1;
675         ++src2;
676         dst0 += 2;
677         dst1 += 2;
678
679         // central pixels
680         count -= 2;
681         while (count) {
682                 if (src0[0] != src2[0] && src1[-1] != src1[1]) {
683                         dst0[0] = src1[-1] == src0[0] ? src0[0] : src1[0];
684                         dst0[1] = src1[1] == src0[0] ? src0[0] : src1[0];
685                         dst1[0] = src1[-1] == src2[0] ? src2[0] : src1[0];
686                         dst1[1] = src1[1] == src2[0] ? src2[0] : src1[0];
687                 } else {
688                         dst0[0] = src1[0];
689                         dst0[1] = src1[0];
690                         dst1[0] = src1[0];
691                         dst1[1] = src1[0];
692                 }
693
694                 ++src0;
695                 ++src1;
696                 ++src2;
697                 dst0 += 2;
698                 dst1 += 2;
699                 --count;
700         }
701
702         // last pixel
703         if (src0[0] != src2[0] && src1[-1] != src1[0]) {
704                 dst0[0] = src1[-1] == src0[0] ? src0[0] : src1[0];
705                 dst0[1] = src1[0] == src0[0] ? src0[0] : src1[0];
706                 dst1[0] = src1[-1] == src2[0] ? src2[0] : src1[0];
707                 dst1[1] = src1[0] == src2[0] ? src2[0] : src1[0];
708         } else {
709                 dst0[0] = src1[0];
710                 dst0[1] = src1[0];
711                 dst1[0] = src1[0];
712                 dst1[1] = src1[0];
713         }
714 }
715
716 void Scale2x_ex8(unsigned char *srcPtr, DWORD srcPitch,
717                                  unsigned char  *dstPtr, int width, int height)
718 {
719         //const int srcpitch = srcPitch;
720         const int dstPitch = srcPitch<<1;
721
722         int count = height;
723
724         finalw=width<<1;
725         finalh=height<<1;
726
727         uint32_t  *dst0 = (uint32_t  *)dstPtr;
728         uint32_t  *dst1 = dst0 + (dstPitch >> 2);
729
730         uint32_t  *src0 = (uint32_t  *)srcPtr;
731         uint32_t  *src1 = src0 + (srcPitch >> 2);
732         uint32_t  *src2 = src1 + (srcPitch >> 2);
733         scale2x_32_def_whole(dst0, dst1, src0, src0, src1, width);
734
735         count -= 2;
736         while(count) {
737                 dst0 += dstPitch >> 1;
738                 dst1 += dstPitch >> 1;
739                 scale2x_32_def_whole(dst0, dst1, src0, src0, src1, width);
740                 src0 = src1;
741                 src1 = src2;
742                 src2 += srcPitch >> 2;
743                 --count;
744         }
745         dst0 += dstPitch >> 1;
746         dst1 += dstPitch >> 1;
747         scale2x_32_def_whole(dst0, dst1, src0, src1, src1, width);
748
749 }
750
751 ////////////////////////////////////////////////////////////////////////
752
753 static __inline void scale3x_32_def_whole(uint32_t* dst0, uint32_t* dst1, uint32_t* dst2, const uint32_t* src0, const uint32_t* src1, const uint32_t* src2, unsigned count)
754 {
755         //assert(count >= 2);
756
757         //first pixel
758         if (src0[0] != src2[0] && src1[0] != src1[1]) {
759                 dst0[0] = src1[0];
760                 dst0[1] = (src1[0] == src0[0] && src1[0] != src0[1]) || (src1[1] == src0[0] && src1[0] != src0[0]) ? src0[0] : src1[0];
761                 dst0[2] = src1[1] == src0[0] ? src1[1] : src1[0];
762                 dst1[0] = (src1[0] == src0[0] && src1[0] != src2[0]) || (src1[0] == src2[0] && src1[0] != src0[0]) ? src1[0] : src1[0];
763                 dst1[1] = src1[0];
764                 dst1[2] = (src1[1] == src0[0] && src1[0] != src2[1]) || (src1[1] == src2[0] && src1[0] != src0[1]) ? src1[1] : src1[0];
765                 dst2[0] = src1[0];
766                 dst2[1] = (src1[0] == src2[0] && src1[0] != src2[1]) || (src1[1] == src2[0] && src1[0] != src2[0]) ? src2[0] : src1[0];
767                 dst2[2] = src1[1] == src2[0] ? src1[1] : src1[0];
768         } else {
769                 dst0[0] = src1[0];
770                 dst0[1] = src1[0];
771                 dst0[2] = src1[0];
772                 dst1[0] = src1[0];
773                 dst1[1] = src1[0];
774                 dst1[2] = src1[0];
775                 dst2[0] = src1[0];
776                 dst2[1] = src1[0];
777                 dst2[2] = src1[0];
778         }
779         ++src0;
780         ++src1;
781         ++src2;
782         dst0 += 3;
783         dst1 += 3;
784         dst2 += 3;
785
786         //central pixels
787         count -= 2;
788         while (count) {
789                 if (src0[0] != src2[0] && src1[-1] != src1[1]) {
790                         dst0[0] = src1[-1] == src0[0] ? src1[-1] : src1[0];
791                         dst0[1] = (src1[-1] == src0[0] && src1[0] != src0[1]) || (src1[1] == src0[0] && src1[0] != src0[-1]) ? src0[0] : src1[0];
792                         dst0[2] = src1[1] == src0[0] ? src1[1] : src1[0];
793                         dst1[0] = (src1[-1] == src0[0] && src1[0] != src2[-1]) || (src1[-1] == src2[0] && src1[0] != src0[-1]) ? src1[-1] : src1[0];
794                         dst1[1] = src1[0];
795                         dst1[2] = (src1[1] == src0[0] && src1[0] != src2[1]) || (src1[1] == src2[0] && src1[0] != src0[1]) ? src1[1] : src1[0];
796                         dst2[0] = src1[-1] == src2[0] ? src1[-1] : src1[0];
797                         dst2[1] = (src1[-1] == src2[0] && src1[0] != src2[1]) || (src1[1] == src2[0] && src1[0] != src2[-1]) ? src2[0] : src1[0];
798                         dst2[2] = src1[1] == src2[0] ? src1[1] : src1[0];
799                 } else {
800                         dst0[0] = src1[0];
801                         dst0[1] = src1[0];
802                         dst0[2] = src1[0];
803                         dst1[0] = src1[0];
804                         dst1[1] = src1[0];
805                         dst1[2] = src1[0];
806                         dst2[0] = src1[0];
807                         dst2[1] = src1[0];
808                         dst2[2] = src1[0];
809                 }
810
811                 ++src0;
812                 ++src1;
813                 ++src2;
814                 dst0 += 3;
815                 dst1 += 3;
816                 dst2 += 3;
817                 --count;
818         }
819
820         // last pixel
821         if (src0[0] != src2[0] && src1[-1] != src1[0]) {
822                 dst0[0] = src1[-1] == src0[0] ? src1[-1] : src1[0];
823                 dst0[1] = (src1[-1] == src0[0] && src1[0] != src0[0]) || (src1[0] == src0[0] && src1[0] != src0[-1]) ? src0[0] : src1[0];
824                 dst0[2] = src1[0];
825                 dst1[0] = (src1[-1] == src0[0] && src1[0] != src2[-1]) || (src1[-1] == src2[0] && src1[0] != src0[-1]) ? src1[-1] : src1[0];
826                 dst1[1] = src1[0];
827                 dst1[2] = (src1[0] == src0[0] && src1[0] != src2[0]) || (src1[0] == src2[0] && src1[0] != src0[0]) ? src1[0] : src1[0];
828                 dst2[0] = src1[-1] == src2[0] ? src1[-1] : src1[0];
829                 dst2[1] = (src1[-1] == src2[0] && src1[0] != src2[0]) || (src1[0] == src2[0] && src1[0] != src2[-1]) ? src2[0] : src1[0];
830                 dst2[2] = src1[0];
831         } else {
832                 dst0[0] = src1[0];
833                 dst0[1] = src1[0];
834                 dst0[2] = src1[0];
835                 dst1[0] = src1[0];
836                 dst1[1] = src1[0];
837                 dst1[2] = src1[0];
838                 dst2[0] = src1[0];
839                 dst2[1] = src1[0];
840                 dst2[2] = src1[0];
841         }
842 }
843
844
845 void Scale3x_ex8(unsigned char *srcPtr, DWORD srcPitch,
846                                  unsigned char  *dstPtr, int width, int height)
847 {
848         int count = height;
849
850         int dstPitch = srcPitch*3;
851         int dstRowPixels = dstPitch>>2; 
852
853         finalw=width*3;
854         finalh=height*3;
855
856         uint32_t  *dst0 = (uint32_t  *)dstPtr;
857         uint32_t  *dst1 = dst0 + dstRowPixels;
858         uint32_t  *dst2 = dst1 + dstRowPixels;
859
860         uint32_t  *src0 = (uint32_t  *)srcPtr;
861         uint32_t  *src1 = src0 + (srcPitch >> 2);
862         uint32_t  *src2 = src1 + (srcPitch >> 2);
863         scale3x_32_def_whole(dst0, dst1, dst2, src0, src0, src2, width);
864
865         count -= 2;
866         while(count) {
867                 dst0 += dstRowPixels*3;
868                 dst1 += dstRowPixels*3;
869                 dst2 += dstRowPixels*3;
870
871                 scale3x_32_def_whole(dst0, dst1, dst2, src0, src1, src2, width);
872                 src0 = src1;
873                 src1 = src2;
874                 src2 += srcPitch >> 2;
875                 --count;
876         }
877
878         dst0 += dstRowPixels*3;
879         dst1 += dstRowPixels*3;
880         dst2 += dstRowPixels*3;
881
882         scale3x_32_def_whole(dst0, dst1, dst2, src0, src1, src1, width);
883 }
884
885
886 ////////////////////////////////////////////////////////////////////////
887
888 #ifndef MAX
889 #define MAX(a,b)    (((a) > (b)) ? (a) : (b))
890 #define MIN(a,b)    (((a) < (b)) ? (a) : (b))
891 #endif
892
893
894 ////////////////////////////////////////////////////////////////////////
895 // X STUFF :)
896 ////////////////////////////////////////////////////////////////////////
897
898
899 static Cursor        cursor;
900 XVisualInfo          vi;
901 static XVisualInfo   *myvisual;
902 Display              *display;
903 static Colormap      colormap;
904 Window        window;
905 static GC            hGC;
906 static XImage      * Ximage;
907 static XvImage     * XCimage; 
908 static XImage      * XFimage; 
909 static XImage      * XPimage=0 ; 
910 char *               Xpixels;
911 char *               pCaptionText;
912
913 static int fx=0;
914
915
916 static Atom xv_intern_atom_if_exists( Display *display, char const * atom_name )
917 {
918   XvAttribute * attributes;
919   int attrib_count,i;
920   Atom xv_atom = None;
921
922   attributes = XvQueryPortAttributes( display, xv_port, &attrib_count );
923   if( attributes!=NULL )
924   {
925     for ( i = 0; i < attrib_count; ++i )
926     {
927       if ( strcmp(attributes[i].name, atom_name ) == 0 )
928       {
929         xv_atom = XInternAtom( display, atom_name, False );
930         break; // found what we want, break out
931       }
932     }
933     XFree( attributes );
934   }
935
936   return xv_atom;
937 }
938
939
940
941 // close display
942
943 void DestroyDisplay(void)
944 {
945  if(display)
946   {
947    XFreeColormap(display, colormap);
948    if(hGC) 
949     {
950      XFreeGC(display,hGC);
951      hGC = 0;
952     }
953    if(Ximage)
954     {
955      XDestroyImage(Ximage);
956      Ximage=0;
957     }
958    if(XCimage) 
959     { 
960      XFree(XCimage); 
961      XCimage=0; 
962     } 
963    if(XFimage) 
964     { 
965      XDestroyImage(XFimage);
966      XFimage=0; 
967     } 
968
969         XShmDetach(display,&shminfo);
970         shmdt(shminfo.shmaddr);
971         shmctl(shminfo.shmid,IPC_RMID,NULL);
972
973   Atom atom_vsync = xv_intern_atom_if_exists(display, "XV_SYNC_TO_VBLANK");
974   if (atom_vsync != None) {
975         XvSetPortAttribute(display, xv_port, atom_vsync, xv_vsync);
976   }
977
978    XSync(display,False);
979
980    XCloseDisplay(display);
981   }
982 }
983
984 static int depth=0;
985 int root_window_id=0;
986
987
988 // Create display
989
990 void CreateDisplay(void)
991 {
992  XSetWindowAttributes winattr;
993  int                  myscreen;
994  Screen *             screen;
995  XEvent               event;
996  XSizeHints           hints;
997  XWMHints             wm_hints;
998  MotifWmHints         mwmhints;
999  Atom                 mwmatom;
1000
1001  Atom                   delwindow;
1002
1003  XGCValues            gcv;
1004  int i;
1005
1006  int ret, j, p;
1007  int formats;
1008  unsigned int p_num_adaptors=0, p_num_ports=0;
1009
1010  XvAdaptorInfo          *ai;
1011  XvImageFormatValues    *fo;
1012
1013  // Open display
1014  display = XOpenDisplay(NULL);
1015
1016  if (!display)
1017   {
1018    fprintf (stderr,"Failed to open display!!!\n");
1019    DestroyDisplay();
1020    return;
1021   }
1022
1023  myscreen=DefaultScreen(display);
1024
1025  // desktop fullscreen switch
1026  if (!iWindowMode) fx = 1;
1027
1028  screen=DefaultScreenOfDisplay(display);
1029
1030  root_window_id=RootWindow(display,DefaultScreen(display));
1031
1032   //Look for an Xvideo RGB port
1033   ret = XvQueryAdaptors(display, root_window_id, &p_num_adaptors, &ai);
1034   if (ret != Success) {
1035     if (ret == XvBadExtension)
1036       printf("XvBadExtension returned at XvQueryExtension.\n");
1037     else
1038       if (ret == XvBadAlloc)
1039         printf("XvBadAlloc returned at XvQueryExtension.\n");
1040       else
1041         printf("other error happaned at XvQueryAdaptors.\n");
1042
1043     exit(-1);
1044   }
1045
1046   depth = DefaultDepth(display, myscreen);
1047
1048   for (i = 0; i < p_num_adaptors; i++) {
1049         p_num_ports = ai[i].base_id + ai[i].num_ports;
1050         for (p = ai[i].base_id; p < p_num_ports; p++) {
1051                 fo = XvListImageFormats(display, p, &formats);
1052                 for (j = 0; j < formats; j++) {
1053                         //backup YUV mode
1054                         //hmm, should I bother check guid == 55595659-0000-0010-8000-00aa00389b71?
1055                         //and check byte order?   fo[j].byte_order == LSBFirst
1056 #ifdef __BIG_ENDIAN__
1057                         if ( fo[j].type == XvYUV && fo[j].bits_per_pixel == 16 && fo[j].format == XvPacked && strncmp("YUYV", fo[j].component_order, 5) == 0 )
1058 #else
1059                         if ( fo[j].type == XvYUV && fo[j].bits_per_pixel == 16 && fo[j].format == XvPacked && strncmp("UYVY", fo[j].component_order, 5) == 0 )
1060 #endif
1061                         {
1062                                 yuv_port = p;
1063                                 yuv_id = fo[j].id;
1064                         }
1065                         if (fo[j].type == XvRGB && fo[j].bits_per_pixel == 32)
1066                         {
1067                                 xv_port = p;
1068                                 xv_id = fo[j].id;
1069                                 xv_depth = fo[j].depth;
1070                                 printf("RGB mode found.  id: %x, depth: %d\n", xv_id, xv_depth);
1071
1072                                 if (xv_depth != depth) {
1073                                         printf("Warning: Depth does not match screen depth (%d)\n", depth);
1074                                 }
1075                                 else {
1076                                         //break out of loops
1077                                         j = formats;
1078                                         p = p_num_ports;
1079                                         i = p_num_adaptors;
1080                                 }
1081                         }
1082                 }
1083                 if (fo)
1084                         XFree(fo);
1085         }
1086   }
1087   if (p_num_adaptors > 0)
1088     XvFreeAdaptorInfo(ai);
1089   if (xv_port == -1 && yuv_port == -1)
1090   {
1091         printf("RGB & YUV not found.  Quitting.\n");
1092         exit(-1);
1093   }
1094   else if (xv_port == -1 && yuv_port != -1)
1095   {
1096         use_yuv = 1;
1097         printf("RGB not found.  Using YUV.\n");
1098         xv_port = yuv_port;
1099         xv_id = yuv_id;
1100   }
1101   else if (xv_depth && xv_depth != depth && yuv_port != -1)
1102   {
1103         use_yuv = 1;
1104         printf("Acceptable RGB mode not found.  Using YUV.\n");
1105         xv_port = yuv_port;
1106         xv_id = yuv_id;
1107   }
1108
1109   Atom atom_vsync = xv_intern_atom_if_exists(display, "XV_SYNC_TO_VBLANK");
1110   if (atom_vsync != None) {
1111         XvGetPortAttribute(display, xv_port, atom_vsync, &xv_vsync);
1112         XvSetPortAttribute(display, xv_port, atom_vsync, 0);
1113   }
1114
1115 myvisual = 0;
1116
1117 if(XMatchVisualInfo(display,myscreen, depth, TrueColor, &vi))
1118         myvisual = &vi;
1119
1120 if (!myvisual)
1121 {
1122         fprintf(stderr,"Failed to obtain visual!\n");
1123         DestroyDisplay();
1124         return;
1125 }
1126
1127  if(myvisual->red_mask==0x00007c00 &&
1128     myvisual->green_mask==0x000003e0 &&
1129     myvisual->blue_mask==0x0000001f)
1130      {iColDepth=15;}
1131  else
1132  if(myvisual->red_mask==0x0000f800 &&
1133     myvisual->green_mask==0x000007e0 &&
1134     myvisual->blue_mask==0x0000001f)
1135      {iColDepth=16;}
1136  else
1137  if(myvisual->red_mask==0x00ff0000 &&
1138     myvisual->green_mask==0x0000ff00 &&
1139     myvisual->blue_mask==0x000000ff)
1140      {iColDepth=32;}
1141  else
1142   {
1143    iColDepth=0;
1144 /*   fprintf(stderr,"COLOR DEPTH NOT SUPPORTED!\n");
1145    fprintf(stderr,"r: %08lx\n",myvisual->red_mask);
1146    fprintf(stderr,"g: %08lx\n",myvisual->green_mask);
1147    fprintf(stderr,"b: %08lx\n",myvisual->blue_mask);
1148    DestroyDisplay();
1149    return;*/
1150   }
1151
1152  // pffff... much work for a simple blank cursor... oh, well...
1153  if(iWindowMode) cursor=XCreateFontCursor(display,XC_trek);
1154  else
1155   {
1156    Pixmap p1,p2;
1157    XImage * img;
1158    XColor b,w;
1159    char * idata;
1160    XGCValues GCv;
1161    GC        GCc;
1162
1163    memset(&b,0,sizeof(XColor));
1164    memset(&w,0,sizeof(XColor));
1165    idata=(char *)malloc(8);
1166    memset(idata,0,8);
1167
1168    p1=XCreatePixmap(display,RootWindow(display,myvisual->screen),8,8,1);
1169    p2=XCreatePixmap(display,RootWindow(display,myvisual->screen),8,8,1);
1170
1171    img = XCreateImage(display,myvisual->visual,
1172                       1,XYBitmap,0,idata,8,8,8,1);
1173
1174    GCv.function   = GXcopy;
1175    GCv.foreground = ~0;
1176    GCv.background =  0;
1177    GCv.plane_mask = AllPlanes;
1178    GCc = XCreateGC(display,p1,
1179                    (GCFunction|GCForeground|GCBackground|GCPlaneMask),&GCv);
1180
1181    XPutImage(display, p1,GCc,img,0,0,0,0,8,8);
1182    XPutImage(display, p2,GCc,img,0,0,0,0,8,8);
1183    XFreeGC(display, GCc);
1184
1185    cursor = XCreatePixmapCursor(display,p1,p2,&b,&w,0,0);
1186
1187    XFreePixmap(display,p1);
1188    XFreePixmap(display,p2);
1189    XDestroyImage(img); // will free idata as well
1190   }
1191
1192  colormap=XCreateColormap(display,root_window_id,
1193                           myvisual->visual,AllocNone);
1194
1195  winattr.background_pixel=0;
1196  winattr.border_pixel=WhitePixelOfScreen(screen);
1197  winattr.bit_gravity=ForgetGravity;
1198  winattr.win_gravity=NorthWestGravity;
1199  winattr.backing_store=NotUseful;
1200
1201  winattr.override_redirect=False;
1202  winattr.save_under=False;
1203  winattr.event_mask=0;
1204  winattr.do_not_propagate_mask=0;
1205  winattr.colormap=colormap;
1206  winattr.cursor=None;
1207
1208  window=XCreateWindow(display,root_window_id,
1209                       0,0,iResX,iResY,
1210                       0,myvisual->depth,
1211                       InputOutput,myvisual->visual,
1212                       CWBorderPixel | CWBackPixel |
1213                       CWEventMask | CWDontPropagate |
1214                       CWColormap | CWCursor,
1215                       &winattr);
1216
1217  if(!window)
1218   {
1219    fprintf(stderr,"Failed in XCreateWindow()!!!\n");
1220    DestroyDisplay();
1221    return;
1222   }
1223
1224  delwindow = XInternAtom(display,"WM_DELETE_WINDOW",0);
1225  XSetWMProtocols(display, window, &delwindow, 1);
1226
1227  hints.flags=USPosition|USSize;
1228  hints.base_width = iResX;
1229  hints.base_height = iResY;
1230
1231  wm_hints.input=1;
1232  wm_hints.flags=InputHint;
1233
1234  XSetWMHints(display,window,&wm_hints);
1235  XSetWMNormalHints(display,window,&hints);
1236  if(pCaptionText)
1237       XStoreName(display,window,pCaptionText);
1238  else XStoreName(display,window,"P.E.Op.S SoftX PSX Gpu");
1239
1240  XDefineCursor(display,window,cursor);
1241
1242  // hack to get rid of window title bar 
1243  if (fx)
1244   {
1245    mwmhints.flags=MWM_HINTS_DECORATIONS;
1246    mwmhints.decorations=0;
1247    mwmatom=XInternAtom(display,"_MOTIF_WM_HINTS",0);
1248    XChangeProperty(display,window,mwmatom,mwmatom,32,
1249                    PropModeReplace,(unsigned char *)&mwmhints,4);
1250   }
1251
1252  // key stuff
1253  XSelectInput(display,
1254               window,
1255               FocusChangeMask | ExposureMask |
1256               KeyPressMask | KeyReleaseMask
1257              );
1258
1259  XMapRaised(display,window);
1260  XClearWindow(display,window);
1261  XWindowEvent(display,window,ExposureMask,&event);
1262
1263  if (fx) // fullscreen
1264   {
1265    XResizeWindow(display,window,screen->width,screen->height);
1266
1267    hints.min_width   = hints.max_width = hints.base_width = screen->width;
1268    hints.min_height= hints.max_height = hints.base_height = screen->height;
1269
1270    XSetWMNormalHints(display,window,&hints);
1271
1272    // set the window layer for GNOME
1273    {
1274     XEvent xev;
1275
1276     memset(&xev, 0, sizeof(xev));
1277     xev.xclient.type = ClientMessage;
1278     xev.xclient.serial = 0;
1279     xev.xclient.send_event = 1;
1280     xev.xclient.message_type = XInternAtom(display, "_NET_WM_STATE", 0);
1281     xev.xclient.window = window;
1282     xev.xclient.format = 32;
1283     xev.xclient.data.l[0] = 1;
1284     xev.xclient.data.l[1] = XInternAtom(display, "_NET_WM_STATE_FULLSCREEN", 0);
1285     xev.xclient.data.l[2] = 0;
1286     xev.xclient.data.l[3] = 0;
1287     xev.xclient.data.l[4] = 0;
1288
1289     XSendEvent(display, root_window_id, 0,
1290       SubstructureRedirectMask | SubstructureNotifyMask, &xev);
1291    }
1292   }
1293
1294  gcv.graphics_exposures = False;
1295  hGC = XCreateGC(display,window,
1296                  GCGraphicsExposures, &gcv);
1297  if(!hGC) 
1298   {
1299    fprintf(stderr,"No gfx context!!!\n");
1300    DestroyDisplay();
1301   }
1302
1303
1304
1305  Xpixels = (char *)malloc(220*15*4);
1306  memset(Xpixels,255,220*15*4);
1307  XFimage = XCreateImage(display,myvisual->visual, 
1308                       depth, ZPixmap, 0, 
1309                       (char *)Xpixels,  
1310                       220, 15, 
1311                       depth>16 ? 32 : 16,
1312                       0); 
1313
1314  Xpixels = (char *)malloc(8*8*4);
1315  memset(Xpixels,0,8*8*4);
1316  XCimage = XvCreateImage(display,xv_port,xv_id,
1317                       (char *)Xpixels, 8, 8);
1318
1319
1320 /*
1321 Allocate max that could be needed:
1322 Big(est?) PSX res: 640x512
1323 32bpp (times 4)
1324 2xsai func= 3xwidth,3xheight
1325 = approx 11.8mb
1326 */
1327 shminfo.shmid = shmget(IPC_PRIVATE, 640*512*4*3*3, IPC_CREAT | 0777);
1328 shminfo.shmaddr = shmat(shminfo.shmid, 0, 0);
1329 shminfo.readOnly = 0;
1330  
1331  if (!XShmAttach(display, &shminfo)) {
1332     printf("XShmAttach failed !\n");
1333     exit (-1);
1334  }
1335 }
1336
1337 void (*p2XSaIFunc) (unsigned char *, DWORD, unsigned char *, int, int);
1338 unsigned char *pBackBuffer = 0;
1339
1340 void BlitScreen32(unsigned char *surf, int32_t x, int32_t y)
1341 {
1342  unsigned char *pD;
1343  unsigned int startxy;
1344  uint32_t lu;
1345  unsigned short s;
1346  unsigned short row, column;
1347  unsigned short dx = PreviousPSXDisplay.Range.x1;
1348  unsigned short dy = PreviousPSXDisplay.DisplayMode.y;
1349
1350  int32_t lPitch = PSXDisplay.DisplayMode.x << 2;
1351
1352  uint32_t *destpix;
1353
1354  if (PreviousPSXDisplay.Range.y0) // centering needed?
1355   {
1356    memset(surf, 0, (PreviousPSXDisplay.Range.y0 >> 1) * lPitch);
1357
1358    dy -= PreviousPSXDisplay.Range.y0;
1359    surf += (PreviousPSXDisplay.Range.y0 >> 1) * lPitch;
1360
1361    memset(surf + dy * lPitch,
1362           0, ((PreviousPSXDisplay.Range.y0 + 1) >> 1) * lPitch);
1363   }
1364
1365  if (PreviousPSXDisplay.Range.x0)
1366   {
1367    for (column = 0; column < dy; column++)
1368     {
1369      destpix = (uint32_t *)(surf + (column * lPitch));
1370      memset(destpix, 0, PreviousPSXDisplay.Range.x0 << 2);
1371     }
1372    surf += PreviousPSXDisplay.Range.x0 << 2;
1373   }
1374
1375  if (PSXDisplay.RGB24)
1376   {
1377    for (column = 0; column < dy; column++)
1378     {
1379      startxy = ((1024) * (column + y)) + x;
1380      pD = (unsigned char *)&psxVuw[startxy];
1381      destpix = (uint32_t *)(surf + (column * lPitch));
1382      for (row = 0; row < dx; row++)
1383       {
1384        lu = *((uint32_t *)pD);
1385        destpix[row] = 
1386           0xff000000 | (RED(lu) << 16) | (GREEN(lu) << 8) | (BLUE(lu));
1387        pD += 3;
1388       }
1389     }
1390   }
1391  else
1392   {
1393    for (column = 0;column<dy;column++)
1394     {
1395      startxy = (1024 * (column + y)) + x;
1396      destpix = (uint32_t *)(surf + (column * lPitch));
1397      for (row = 0; row < dx; row++)
1398       {
1399        s = GETLE16(&psxVuw[startxy++]);
1400        destpix[row] = 
1401           (((s << 19) & 0xf80000) | ((s << 6) & 0xf800) | ((s >> 7) & 0xf8)) | 0xff000000;
1402       }
1403     }
1404   }
1405 }
1406
1407 void BlitToYUV(unsigned char * surf,int32_t x,int32_t y)
1408 {
1409  unsigned char * pD;
1410  unsigned int startxy;
1411  uint32_t lu;unsigned short s;
1412  unsigned short row,column;
1413  unsigned short dx = PreviousPSXDisplay.Range.x1;
1414  unsigned short dy = PreviousPSXDisplay.DisplayMode.y;
1415  int Y,U,V, R,G,B;
1416
1417  int32_t lPitch = PSXDisplay.DisplayMode.x << 2;
1418  uint32_t *destpix;
1419
1420  if (PreviousPSXDisplay.Range.y0) // centering needed?
1421   {
1422    for (column = 0; column < (PreviousPSXDisplay.Range.y0 >> 1); column++)
1423     {
1424      destpix = (uint32_t *)(surf + column * lPitch);
1425      for (row = 0; row < dx; row++)
1426      {
1427       destpix[row] = (4 << 24) | (128 << 16) | (4 << 8) | 128;
1428      }
1429     }
1430
1431    dy -= PreviousPSXDisplay.Range.y0;
1432    surf += (PreviousPSXDisplay.Range.y0 >> 1) * lPitch;
1433
1434    for (column = 0; column < (PreviousPSXDisplay.Range.y0 + 1) >> 1; column++)
1435     {
1436      destpix = (uint32_t *)(surf + (dy + column) * lPitch);
1437      for (row = 0; row < dx; row++)
1438      {
1439       destpix[row] = (4 << 24) | (128 << 16) | (4 << 8) | 128;
1440      }
1441     }
1442   }
1443
1444  if (PreviousPSXDisplay.Range.x0)
1445   {
1446    for (column = 0; column < dy; column++)
1447     {
1448      destpix = (uint32_t *)(surf + (column * lPitch));
1449      for (row = 0; row < PreviousPSXDisplay.Range.x0; row++)
1450       {
1451        destpix[row] = (4 << 24) | (128 << 16) | (4 << 8) | 128;
1452       }
1453     }
1454    surf += PreviousPSXDisplay.Range.x0 << 2;
1455   }
1456
1457  if (PSXDisplay.RGB24)
1458   {
1459    for (column = 0; column < dy; column++)
1460     {
1461      startxy = (1024 * (column + y)) + x;
1462      pD = (unsigned char *)&psxVuw[startxy];
1463      destpix = (uint32_t *)(surf + (column * lPitch));
1464      for (row = 0; row < dx; row++)
1465       {
1466        lu = *((uint32_t *)pD);
1467
1468        R = RED(lu);
1469        G = GREEN(lu);
1470        B = BLUE(lu);
1471
1472        Y = min(abs(R * 2104 + G * 4130 + B * 802 + 4096 + 131072) >> 13, 235);
1473        U = min(abs(R * -1214 + G * -2384 + B * 3598 + 4096 + 1048576) >> 13, 240);
1474        V = min(abs(R * 3598 + G * -3013 + B * -585 + 4096 + 1048576) >> 13, 240);
1475
1476 #ifdef __BIG_ENDIAN__
1477        destpix[row] = Y << 24 | U << 16 | Y << 8 | V;
1478 #else
1479        destpix[row] = Y << 24 | V << 16 | Y << 8 | U;
1480 #endif
1481        pD += 3;
1482       }
1483     }
1484   }
1485  else
1486   {
1487    for (column = 0; column < dy; column++)
1488     {
1489      startxy = (1024 * (column + y)) + x;
1490      destpix = (uint32_t *)(surf + (column * lPitch));
1491      for (row = 0; row < dx; row++)
1492       {
1493        s = GETLE16(&psxVuw[startxy++]);
1494
1495        R = (s << 3) &0xf8;
1496        G = (s >> 2) &0xf8;
1497        B = (s >> 7) &0xf8;
1498
1499        Y = min(abs(R * 2104 + G * 4130 + B * 802 + 4096 + 131072) >> 13, 235);
1500        U = min(abs(R * -1214 + G * -2384 + B * 3598 + 4096 + 1048576) >> 13, 240);
1501        V = min(abs(R * 3598 + G * -3013 + B * -585 + 4096 + 1048576) >> 13, 240);
1502
1503 #ifdef __BIG_ENDIAN__
1504        destpix[row] = Y << 24 | U << 16 | Y << 8 | V;
1505 #else
1506        destpix[row] = Y << 24 | V << 16 | Y << 8 | U;
1507 #endif
1508       }
1509     }
1510   }
1511 }
1512
1513 //dst will have half the pitch (32bit to 16bit)
1514 void RGB2YUV(uint32_t *s, int width, int height, uint32_t *d)
1515 {
1516         int x,y;
1517         int R,G,B, Y1,Y2,U,V;
1518
1519         for (y=0; y<height; y++) {
1520                 for(x=0; x<width>>1; x++) {
1521                         R = (*s >> 16) & 0xff;
1522                         G = (*s >> 8) & 0xff;
1523                         B = *s & 0xff;
1524                         s++;
1525
1526                         Y1 = min(abs(R * 2104 + G * 4130 + B * 802 + 4096 + 131072) >> 13, 235);
1527                         U = min(abs(R * -1214 + G * -2384 + B * 3598 + 4096 + 1048576) >> 13, 240);
1528                         V = min(abs(R * 3598 + G * -3013 + B * -585 + 4096 + 1048576) >> 13, 240);
1529
1530                         R = (*s >> 16) & 0xff;
1531                         G = (*s >> 8) & 0xff;
1532                         B = *s & 0xff;
1533                         s++;
1534
1535                         Y2 = min(abs(R * 2104 + G * 4130 + B * 802 + 4096 + 131072) >> 13, 235);
1536
1537 #ifdef __BIG_ENDIAN__
1538                         *d = V | Y2 << 8 | U << 16 | Y1 << 24;
1539 #else
1540                         *d = U | Y1 << 8 | V << 16 | Y2 << 24;
1541 #endif
1542                         d++;
1543                 }
1544         }
1545 }
1546
1547 time_t tStart;
1548
1549 //Note: dest x,y,w,h are both input and output variables
1550 inline void MaintainAspect(unsigned int *dx,unsigned int *dy,unsigned int *dw,unsigned int *dh)
1551 {
1552         //Currently just 4/3 aspect ratio
1553         int t;
1554
1555         if (*dw * 3 > *dh * 4) {
1556                 t = *dh * 4.0f / 3;     //new width aspect
1557                 *dx = (*dw - t) / 2;    //centering
1558                 *dw = t;
1559         } else {
1560                 t = *dw * 3.0f / 4;
1561                 *dy = (*dh - t) / 2;
1562                 *dh = t;
1563         }
1564 }
1565
1566 void DoBufferSwap(void)
1567 {
1568         Screen *screen;
1569         Window _dw;
1570         XvImage *xvi;
1571         unsigned int dstx, dsty, srcy = 0;
1572         unsigned int _d, _w, _h;        //don't care about _d
1573
1574         finalw = PSXDisplay.DisplayMode.x;
1575         finalh = PSXDisplay.DisplayMode.y;
1576
1577         if (finalw == 0 || finalh == 0)
1578                 return;
1579
1580         XSync(display,False);
1581
1582         if(use_yuv) {
1583                 if (iUseNoStretchBlt==0 || finalw > 320 || finalh > 256) {
1584                         BlitToYUV((unsigned char *)shminfo.shmaddr, PSXDisplay.DisplayPosition.x, PSXDisplay.DisplayPosition.y);
1585                         finalw <<= 1;
1586                 } else {
1587                         BlitScreen32((unsigned char *)pBackBuffer, PSXDisplay.DisplayPosition.x, PSXDisplay.DisplayPosition.y);
1588                         p2XSaIFunc(pBackBuffer, finalw<<2, (unsigned char *)pSaIBigBuff,finalw,finalh);
1589                         RGB2YUV( (uint32_t*)pSaIBigBuff, finalw, finalh, (uint32_t*)shminfo.shmaddr);
1590                 }
1591         } else if(iUseNoStretchBlt==0 || finalw > 320 || finalh > 256) {
1592                 BlitScreen32((unsigned char *)shminfo.shmaddr, PSXDisplay.DisplayPosition.x, PSXDisplay.DisplayPosition.y);
1593         } else {
1594                 BlitScreen32((unsigned char *)pBackBuffer, PSXDisplay.DisplayPosition.x, PSXDisplay.DisplayPosition.y);
1595                 p2XSaIFunc(pBackBuffer, finalw<<2, (unsigned char *)shminfo.shmaddr,finalw,finalh);
1596         }
1597
1598         XGetGeometry(display, window, &_dw, (int *)&_d, (int *)&_d, &_w, &_h, &_d, &_d);
1599         if (use_yuv) {
1600                 xvi = XvShmCreateImage(display, yuv_port, yuv_id, 0, finalw, finalh, &shminfo);
1601         } else
1602                 xvi = XvShmCreateImage(display, xv_port, xv_id, 0, finalw, finalh, &shminfo);
1603
1604         xvi->data = shminfo.shmaddr;
1605
1606         screen=DefaultScreenOfDisplay(display); 
1607         //screennum = DefaultScreen(display);
1608
1609         if (!iWindowMode) {
1610                 _w = screen->width;
1611                 _h = screen->height;
1612         }
1613
1614         dstx = 0;
1615         dsty = 0;
1616
1617         if (iMaintainAspect)
1618                 MaintainAspect(&dstx, &dsty, &_w, &_h);
1619
1620         if (ulKeybits&KEY_SHOWFPS)      //to avoid flicker, don't paint overtop FPS bar
1621         {
1622                 srcy = 15 * finalh / _h;
1623                 dsty += 15;
1624         }
1625
1626         XvShmPutImage(display, xv_port, window, hGC, xvi, 
1627                 0,srcy,         //src x,y
1628                 finalw,finalh,  //src w,h
1629                 dstx,dsty,      //dst x,y
1630                 _w,_h,          //dst w,h
1631                 1
1632                 );
1633
1634         if(ulKeybits&KEY_SHOWFPS) //DisplayText();               // paint menu text 
1635         {
1636                 if(szDebugText[0] && ((time(NULL) - tStart) < 2))
1637                 {
1638                         strcpy(szDispBuf,szDebugText);
1639                 }
1640                 else 
1641                 {
1642                         szDebugText[0]=0;
1643                         strcat(szDispBuf,szMenuBuf);
1644                 }
1645
1646                 //XPutImage(display,window,hGC, XFimage, 
1647                 //          0, 0, 0, 0, 220,15);
1648                 XFree(xvi);
1649                 xvi = XvCreateImage(display, xv_port, xv_id, XFimage->data, 220, 15);
1650                 XvPutImage(display, xv_port, window, hGC, xvi, 
1651                         0,0,            //src x,y
1652                         220,15,         //src w,h
1653                         0,0,            //dst x,y
1654                         220,15          //dst w,h
1655                         );
1656
1657                 XDrawString(display,window,hGC,2,13,szDispBuf,strlen(szDispBuf));
1658         }
1659         
1660         //if(XPimage) DisplayPic();
1661         
1662
1663         XFree(xvi);
1664 }
1665
1666 void DoClearScreenBuffer(void)                         // CLEAR DX BUFFER
1667 {
1668  Window _dw;
1669  unsigned int _d, _w, _h;       //don't care about _d
1670
1671  XGetGeometry(display, window, &_dw, (int *)&_d, (int *)&_d, &_w, &_h, &_d, &_d);
1672
1673  XvPutImage(display, xv_port, window, hGC, XCimage,
1674            0, 0, 8, 8, 0, 0, _w, _h);
1675  //XSync(display,False);
1676 }
1677
1678 void DoClearFrontBuffer(void)                          // CLEAR DX BUFFER
1679 {/*
1680  XPutImage(display,window,hGC, XCimage,
1681            0, 0, 0, 0, iResX, iResY);
1682  XSync(display,False);*/
1683 }
1684
1685 int Xinitialize()
1686 {
1687    iDesktopCol=32;
1688
1689
1690  if(iUseNoStretchBlt>0)
1691   {
1692    pBackBuffer=(unsigned char *)malloc(640*512*sizeof(uint32_t));
1693    memset(pBackBuffer,0,640*512*sizeof(uint32_t));
1694    if (use_yuv) {
1695     pSaIBigBuff=malloc(640*512*4*3*3);
1696     memset(pSaIBigBuff,0,640*512*4*3*3);
1697    }
1698   }
1699
1700  p2XSaIFunc=NULL;
1701
1702 #if 0
1703  if(iUseNoStretchBlt==1)
1704   {
1705    p2XSaIFunc=Std2xSaI_ex8;
1706   }
1707
1708  if(iUseNoStretchBlt==2)
1709   {
1710    p2XSaIFunc=Super2xSaI_ex8;
1711   }
1712
1713  if(iUseNoStretchBlt==3)
1714   {
1715    p2XSaIFunc=SuperEagle_ex8;
1716   }
1717
1718  if(iUseNoStretchBlt==4)
1719   {
1720    p2XSaIFunc=Scale2x_ex8;
1721   }
1722  if(iUseNoStretchBlt==5)
1723   {
1724    p2XSaIFunc=Scale3x_ex8;
1725   }
1726  if(iUseNoStretchBlt==6)
1727   {
1728    p2XSaIFunc=hq2x_32;
1729   }
1730  if(iUseNoStretchBlt==7)
1731   {
1732    p2XSaIFunc=hq3x_32;
1733   }
1734 #endif
1735
1736  bUsingTWin=FALSE;
1737
1738  InitMenu();
1739
1740  bIsFirstFrame = FALSE;                                // done
1741
1742  if(iShowFPS)
1743   {
1744    iShowFPS=0;
1745    ulKeybits|=KEY_SHOWFPS;
1746    szDispBuf[0]=0;
1747    //BuildDispMenu(0);
1748   }
1749
1750  return 0;
1751 }
1752
1753 void Xcleanup()                                        // X CLEANUP
1754 {
1755  CloseMenu();
1756
1757  if(iUseNoStretchBlt>0) 
1758   {
1759    if(pBackBuffer)  free(pBackBuffer);
1760    pBackBuffer=0;
1761    if(pSaIBigBuff) free(pSaIBigBuff);
1762    pSaIBigBuff=0;
1763   }
1764 }
1765
1766 unsigned long ulInitDisplay(void)
1767 {
1768  CreateDisplay();                                      // x stuff
1769  Xinitialize();                                        // init x
1770  return (unsigned long)display;
1771 }
1772
1773 void CloseDisplay(void)
1774 {
1775  Xcleanup();                                           // cleanup dx
1776  DestroyDisplay();
1777 }
1778
1779 void CreatePic(unsigned char * pMem)
1780 {
1781  unsigned char * p=(unsigned char *)malloc(128*96*4);
1782  unsigned char * ps; int x,y;
1783
1784  ps=p;
1785
1786  if(iDesktopCol==16)
1787   {
1788    unsigned short s;
1789    for(y=0;y<96;y++)
1790     {
1791      for(x=0;x<128;x++)
1792       {
1793        s=(*(pMem+0))>>3;
1794        s|=((*(pMem+1))&0xfc)<<3;
1795        s|=((*(pMem+2))&0xf8)<<8;
1796        pMem+=3;
1797        *((unsigned short *)(ps+y*256+x*2))=s;
1798       }
1799     }
1800   }
1801  else
1802  if(iDesktopCol==15)
1803   {
1804    unsigned short s;
1805    for(y=0;y<96;y++)
1806     {
1807      for(x=0;x<128;x++)
1808       {
1809        s=(*(pMem+0))>>3;
1810        s|=((*(pMem+1))&0xfc)<<2;
1811        s|=((*(pMem+2))&0xf8)<<7;
1812        pMem+=3;
1813        *((unsigned short *)(ps+y*256+x*2))=s;
1814       }
1815     }
1816   }
1817  else
1818  if(iDesktopCol==32)
1819   {
1820    uint32_t l;
1821    for(y=0;y<96;y++)
1822     {
1823      for(x=0;x<128;x++)
1824       {
1825        l=  *(pMem+0);
1826        l|=(*(pMem+1))<<8;
1827        l|=(*(pMem+2))<<16;
1828        pMem+=3;
1829        *((uint32_t *)(ps+y*512+x*4))=l;
1830       }
1831     }
1832   }
1833
1834  XPimage = XCreateImage(display,myvisual->visual,
1835                         depth, ZPixmap, 0,
1836                         (char *)p, 
1837                         128, 96,
1838                         depth>16 ? 32 : 16,
1839                         0);
1840 }
1841
1842 void DestroyPic(void)
1843 {
1844  if(XPimage) 
1845   { /*
1846    XPutImage(display,window,hGC, XCimage,
1847           0, 0, 0, 0, iResX, iResY);*/
1848    XDestroyImage(XPimage);
1849    XPimage=0; 
1850   } 
1851 }
1852
1853 void DisplayPic(void)
1854 {
1855  XPutImage(display,window,hGC, XPimage,
1856            0, 0, iResX-128, 0,128,96);
1857 }
1858
1859 void ShowGpuPic(void)
1860 {
1861 }
1862
1863 void ShowTextGpuPic(void)
1864 {
1865 }
1866
1867 #if 0
1868 static void hq2x_32_def(uint32_t * dst0, uint32_t * dst1, const uint32_t * src0, const uint32_t * src1, const uint32_t * src2, unsigned count)
1869 {
1870         static unsigned char cache_vert_mask[640];
1871         unsigned char cache_horiz_mask = 0;
1872         
1873         unsigned i;
1874         unsigned char mask;
1875         uint32_t  c[9];
1876
1877         if (src0 == src1)       //processing first row
1878                 memset(cache_vert_mask, 0, count);      
1879         
1880         for(i=0;i<count;++i) {
1881                 c[1] = src0[0];
1882                 c[4] = src1[0];
1883                 c[7] = src2[0];
1884
1885                 if (i>0) {
1886                         c[0] = src0[-1];
1887                         c[3] = src1[-1];
1888                         c[6] = src2[-1];
1889                 } else {
1890                         c[0] = c[1];
1891                         c[3] = c[4];
1892                         c[6] = c[7];
1893                 }
1894
1895                 if (i<count-1) {
1896                         c[2] = src0[1];
1897                         c[5] = src1[1];
1898                         c[8] = src2[1];
1899                 } else {
1900                         c[2] = c[1];
1901                         c[5] = c[4];
1902                         c[8] = c[7];
1903                 }
1904
1905                 mask = 0;
1906
1907                 mask |= interp_32_diff(c[0], c[4]) << 0;
1908                 mask |= cache_vert_mask[i];
1909                 mask |= interp_32_diff(c[2], c[4]) << 2;
1910                 mask |= cache_horiz_mask;
1911                 cache_horiz_mask = interp_32_diff(c[5], c[4]) << 3;
1912                 mask |= cache_horiz_mask << 1;  // << 3 << 1 == << 4
1913                 mask |= interp_32_diff(c[6], c[4]) << 5;
1914                 cache_vert_mask[i] = interp_32_diff(c[7], c[4]) << 1;
1915                 mask |= cache_vert_mask[i] << 5; // << 1 << 5 == << 6
1916                 mask |= interp_32_diff(c[8], c[4]) << 7;
1917
1918
1919                 switch (mask) {
1920 #include "hq2x.h"
1921                 }
1922
1923
1924                 src0 += 1;
1925                 src1 += 1;
1926                 src2 += 1;
1927                 dst0 += 2;
1928                 dst1 += 2;
1929         }
1930 }
1931
1932 void hq2x_32( unsigned char * srcPtr,  DWORD srcPitch, unsigned char * dstPtr, int width, int height)
1933 {
1934         const int dstPitch = srcPitch<<1;
1935
1936         int count = height;
1937
1938         finalw=width*2;
1939         finalh=height*2;
1940
1941         uint32_t  *dst0 = (uint32_t  *)dstPtr;
1942         uint32_t  *dst1 = dst0 + (dstPitch >> 2);
1943
1944         uint32_t  *src0 = (uint32_t  *)srcPtr;
1945         uint32_t  *src1 = src0 + (srcPitch >> 2);
1946         uint32_t  *src2 = src1 + (srcPitch >> 2);
1947         hq2x_32_def(dst0, dst1, src0, src0, src1, width);
1948
1949
1950         count -= 2;
1951         while(count) {
1952                 dst0 += dstPitch >> 1;          //next 2 lines (dstPitch / 4 char per int * 2)
1953                 dst1 += dstPitch >> 1;
1954                 hq2x_32_def(dst0, dst1, src0, src1, src2, width);
1955                 src0 = src1;
1956                 src1 = src2;
1957                 src2 += srcPitch >> 2;
1958                 --count;
1959         }
1960         dst0 += dstPitch >> 1;
1961         dst1 += dstPitch >> 1;
1962         hq2x_32_def(dst0, dst1, src0, src1, src1, width);
1963 }
1964
1965 static void hq3x_32_def(uint32_t*  dst0, uint32_t*  dst1, uint32_t*  dst2, const uint32_t* src0, const uint32_t* src1, const uint32_t* src2, unsigned count)
1966 {
1967         static unsigned char cache_vert_mask[640];
1968         unsigned char cache_horiz_mask = 0;
1969
1970         unsigned i;
1971         unsigned char mask;
1972         uint32_t  c[9];
1973
1974         if (src0 == src1)       //processing first row
1975                 memset(cache_vert_mask, 0, count);      
1976
1977         for(i=0;i<count;++i) {
1978                 c[1] = src0[0];
1979                 c[4] = src1[0];
1980                 c[7] = src2[0];
1981
1982                 if (i>0) {
1983                         c[0] = src0[-1];
1984                         c[3] = src1[-1];
1985                         c[6] = src2[-1];
1986                 } else {
1987                         c[0] = c[1];
1988                         c[3] = c[4];
1989                         c[6] = c[7];
1990                 }
1991
1992                 if (i<count-1) {
1993                         c[2] = src0[1];
1994                         c[5] = src1[1];
1995                         c[8] = src2[1];
1996                 } else {
1997                         c[2] = c[1];
1998                         c[5] = c[4];
1999                         c[8] = c[7];
2000                 }
2001
2002                 mask = 0;
2003                 
2004                 mask |= interp_32_diff(c[0], c[4]) << 0;
2005                 mask |= cache_vert_mask[i];
2006                 mask |= interp_32_diff(c[2], c[4]) << 2;
2007                 mask |= cache_horiz_mask;
2008                 cache_horiz_mask = interp_32_diff(c[5], c[4]) << 3;
2009                 mask |= cache_horiz_mask << 1;  // << 3 << 1 == << 4
2010                 mask |= interp_32_diff(c[6], c[4]) << 5;
2011                 cache_vert_mask[i] = interp_32_diff(c[7], c[4]) << 1;
2012                 mask |= cache_vert_mask[i] << 5; // << 1 << 5 == << 6
2013                 mask |= interp_32_diff(c[8], c[4]) << 7;
2014
2015                 switch (mask) {
2016 #include "hq3x.h"
2017                 }
2018
2019                 src0 += 1;
2020                 src1 += 1;
2021                 src2 += 1;
2022                 dst0 += 3;
2023                 dst1 += 3;
2024                 dst2 += 3;
2025         }
2026 }
2027
2028 void hq3x_32( unsigned char * srcPtr,  DWORD srcPitch, unsigned char * dstPtr, int width, int height)
2029 {
2030         int count = height;
2031
2032         int dstPitch = srcPitch*3;
2033         int dstRowPixels = dstPitch>>2;
2034
2035         finalw=width*3;
2036         finalh=height*3;
2037
2038         uint32_t  *dst0 = (uint32_t  *)dstPtr;
2039         uint32_t  *dst1 = dst0 + dstRowPixels;
2040         uint32_t  *dst2 = dst1 + dstRowPixels;
2041
2042         uint32_t  *src0 = (uint32_t  *)srcPtr;
2043         uint32_t  *src1 = src0 + (srcPitch >> 2);
2044         uint32_t  *src2 = src1 + (srcPitch >> 2);
2045         hq3x_32_def(dst0, dst1, dst2, src0, src0, src2, width);
2046
2047         count -= 2;
2048         while(count) {
2049                 dst0 += dstRowPixels * 3;
2050                 dst1 += dstRowPixels * 3;
2051                 dst2 += dstRowPixels * 3;
2052
2053                 hq3x_32_def(dst0, dst1, dst2, src0, src1, src2, width);
2054                 src0 = src1;
2055                 src1 = src2;
2056                 src2 += srcPitch >> 2;
2057                 --count;
2058         }
2059         dst0 += dstRowPixels * 3;
2060         dst1 += dstRowPixels * 3;
2061         dst2 += dstRowPixels * 3;
2062
2063         hq3x_32_def(dst0, dst1, dst2, src0, src1, src1, width);
2064
2065 }
2066 #endif