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];
InitMenu(void)51 void InitMenu(void) {}
CloseMenu(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 
GetResult1(DWORD A,DWORD B,DWORD C,DWORD D,DWORD E)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 
GetResult2(DWORD A,DWORD B,DWORD C,DWORD D,DWORD E)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 
Super2xSaI_ex8(unsigned char * srcPtr,DWORD srcPitch,unsigned char * dstBitmap,int width,int height)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 
Std2xSaI_ex8(unsigned char * srcPtr,DWORD srcPitch,unsigned char * dstBitmap,int width,int height)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 
SuperEagle_ex8(unsigned char * srcPtr,DWORD srcPitch,unsigned char * dstBitmap,int width,int height)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 
scale2x_32_def_whole(uint32_t * dst0,uint32_t * dst1,const uint32_t * src0,const uint32_t * src1,const uint32_t * src2,unsigned count)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 
Scale2x_ex8(unsigned char * srcPtr,DWORD srcPitch,unsigned char * dstPtr,int width,int height)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 
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)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 
Scale3x_ex8(unsigned char * srcPtr,DWORD srcPitch,unsigned char * dstPtr,int width,int height)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 
xv_intern_atom_if_exists(Display * display,char const * atom_name)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 
DestroyDisplay(void)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 
CreateDisplay(void)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 
BlitScreen32(unsigned char * surf,int32_t x,int32_t y)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 
BlitToYUV(unsigned char * surf,int32_t x,int32_t y)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)
RGB2YUV(uint32_t * s,int width,int height,uint32_t * d)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
MaintainAspect(unsigned int * dx,unsigned int * dy,unsigned int * dw,unsigned int * dh)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 
DoBufferSwap(void)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 
DoClearScreenBuffer(void)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 
DoClearFrontBuffer(void)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 
Xinitialize()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 
Xcleanup()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 
ulInitDisplay(void)1766 unsigned long ulInitDisplay(void)
1767 {
1768  CreateDisplay();                                      // x stuff
1769  Xinitialize();                                        // init x
1770  return (unsigned long)display;
1771 }
1772 
CloseDisplay(void)1773 void CloseDisplay(void)
1774 {
1775  Xcleanup();                                           // cleanup dx
1776  DestroyDisplay();
1777 }
1778 
CreatePic(unsigned char * pMem)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 
DestroyPic(void)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 
DisplayPic(void)1853 void DisplayPic(void)
1854 {
1855  XPutImage(display,window,hGC, XPimage,
1856            0, 0, iResX-128, 0,128,96);
1857 }
1858 
ShowGpuPic(void)1859 void ShowGpuPic(void)
1860 {
1861 }
1862 
ShowTextGpuPic(void)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
2067