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  *                                                                         *
11  *   This program is free software; you can redistribute it and/or modify  *
12  *   it under the terms of the GNU General Public License as published by  *
13  *   the Free Software Foundation; either version 2 of the License, or     *
14  *   (at your option) any later version. See also the license.txt file for *
15  *   additional informations.                                              *
16  *                                                                         *
17  ***************************************************************************/
18 
19 #define _IN_DRAW
20 
21 #include "externals.h"
22 #include "gpu.h"
23 #include "draw.h"
24 #include "prim.h"
25 #include "menu.h"
26 #include "interp.h"
27 
28 ////////////////////////////////////////////////////////////////////////////////////
29 // misc globals
30 ////////////////////////////////////////////////////////////////////////////////////
31 
32 int            iResX;
33 int            iResY;
34 long           lLowerpart;
35 BOOL           bIsFirstFrame = TRUE;
36 BOOL           bCheckMask=FALSE;
37 unsigned short sSetMask=0;
38 unsigned long  lSetMask=0;
39 int            iDesktopCol=16;
40 int            iShowFPS=0;
41 int            iWinSize;
42 int            iUseScanLines=0;
43 int            iUseNoStretchBlt=0;
44 int            iFastFwd=0;
45 int            iDebugMode=0;
46 int            iFVDisplay=0;
47 PSXPoint_t     ptCursorPoint[8];
48 unsigned short usCursorActive=0;
49 
50 unsigned int   LUT16to32[65536];
51 unsigned int   RGBtoYUV[65536];
52 
53 // prototypes
54 void hq2x_32( unsigned char * srcPtr, DWORD srcPitch, unsigned char * dstPtr, int width, int height);
55 void hq2x( unsigned char * srcPtr,  DWORD srcPitch, unsigned char * dstPtr, int width, int height);
56 void hq3x_16( unsigned char * srcPtr,  DWORD srcPitch, unsigned char * dstPtr, int width, int height);
57 void hq3x_32( unsigned char * srcPtr,  DWORD srcPitch, unsigned char * dstPtr, int width, int height);
58 
59 ////////////////////////////////////////////////////////////////////////
60 // generic 2xSaI helpers
61 ////////////////////////////////////////////////////////////////////////
62 
63 void *         pSaISmallBuff=NULL;
64 void *         pSaIBigBuff=NULL;
65 
66 #define GET_RESULT(A, B, C, D) ((A != C || A != D) - (B != C || B != D))
67 
GetResult1(DWORD A,DWORD B,DWORD C,DWORD D,DWORD E)68 static __inline int GetResult1(DWORD A, DWORD B, DWORD C, DWORD D, DWORD E)
69 {
70  int x = 0;
71  int y = 0;
72  int r = 0;
73  if (A == C) x+=1; else if (B == C) y+=1;
74  if (A == D) x+=1; else if (B == D) y+=1;
75  if (x <= 1) r+=1;
76  if (y <= 1) r-=1;
77  return r;
78 }
79 
GetResult2(DWORD A,DWORD B,DWORD C,DWORD D,DWORD E)80 static __inline int GetResult2(DWORD A, DWORD B, DWORD C, DWORD D, DWORD E)
81 {
82  int x = 0;
83  int y = 0;
84  int r = 0;
85  if (A == C) x+=1; else if (B == C) y+=1;
86  if (A == D) x+=1; else if (B == D) y+=1;
87  if (x <= 1) r-=1;
88  if (y <= 1) r+=1;
89  return r;
90 }
91 
92 #define colorMask8     0x00FEFEFE
93 #define lowPixelMask8  0x00010101
94 #define qcolorMask8    0x00FCFCFC
95 #define qlowpixelMask8 0x00030303
96 
97 #define INTERPOLATE8(A, B) ((((A & colorMask8) >> 1) + ((B & colorMask8) >> 1) + (A & B & lowPixelMask8)))
98 #define Q_INTERPOLATE8(A, B, C, D) (((((A & qcolorMask8) >> 2) + ((B & qcolorMask8) >> 2) + ((C & qcolorMask8) >> 2) + ((D & qcolorMask8) >> 2) \
99 	+ ((((A & qlowpixelMask8) + (B & qlowpixelMask8) + (C & qlowpixelMask8) + (D & qlowpixelMask8)) >> 2) & qlowpixelMask8))))
100 
101 
Super2xSaI_ex8(unsigned char * srcPtr,DWORD srcPitch,unsigned char * dstBitmap,int width,int height)102 void Super2xSaI_ex8(unsigned char *srcPtr, DWORD srcPitch,
103 	            unsigned char  *dstBitmap, int width, int height)
104 {
105  DWORD dstPitch        = srcPitch<<1;
106  DWORD srcPitchHalf    = srcPitch>>1;
107  int   finWidth        = srcPitch>>2;
108  DWORD line;
109  DWORD *dP;
110  DWORD *bP;
111  int iXA,iXB,iXC,iYA,iYB,iYC,finish;
112  DWORD color4, color5, color6;
113  DWORD color1, color2, color3;
114  DWORD colorA0, colorA1, colorA2, colorA3,
115        colorB0, colorB1, colorB2, colorB3,
116        colorS1, colorS2;
117  DWORD product1a, product1b,
118        product2a, product2b;
119 
120  line = 0;
121 
122   {
123    for (; height; height-=1)
124 	{
125      bP = (DWORD *)srcPtr;
126 	 dP = (DWORD *)(dstBitmap + line*dstPitch);
127      for (finish = width; finish; finish -= 1 )
128       {
129 //---------------------------------------    B1 B2
130 //                                         4  5  6 S2
131 //                                         1  2  3 S1
132 //                                           A1 A2
133        if(finish==finWidth) iXA=0;
134        else                 iXA=1;
135        if(finish>4) {iXB=1;iXC=2;}
136        else
137        if(finish>3) {iXB=1;iXC=1;}
138        else         {iXB=0;iXC=0;}
139        if(line==0)  {iYA=0;}
140        else         {iYA=finWidth;}
141        if(height>4) {iYB=finWidth;iYC=srcPitchHalf;}
142        else
143        if(height>3) {iYB=finWidth;iYC=finWidth;}
144        else         {iYB=0;iYC=0;}
145 
146        colorB0 = *(bP- iYA - iXA);
147        colorB1 = *(bP- iYA);
148        colorB2 = *(bP- iYA + iXB);
149        colorB3 = *(bP- iYA + iXC);
150 
151        color4 = *(bP  - iXA);
152        color5 = *(bP);
153        color6 = *(bP  + iXB);
154        colorS2 = *(bP + iXC);
155 
156        color1 = *(bP  + iYB  - iXA);
157        color2 = *(bP  + iYB);
158        color3 = *(bP  + iYB  + iXB);
159        colorS1= *(bP  + iYB  + iXC);
160 
161        colorA0 = *(bP + iYC - iXA);
162        colorA1 = *(bP + iYC);
163        colorA2 = *(bP + iYC + iXB);
164        colorA3 = *(bP + iYC + iXC);
165 
166        if (color2 == color6 && color5 != color3)
167         {
168          product2b = product1b = color2;
169         }
170        else
171        if (color5 == color3 && color2 != color6)
172         {
173          product2b = product1b = color5;
174         }
175        else
176        if (color5 == color3 && color2 == color6)
177         {
178          register int r = 0;
179 
180          r += GET_RESULT ((color6&0x00ffffff), (color5&0x00ffffff), (color1&0x00ffffff),  (colorA1&0x00ffffff));
181          r += GET_RESULT ((color6&0x00ffffff), (color5&0x00ffffff), (color4&0x00ffffff),  (colorB1&0x00ffffff));
182          r += GET_RESULT ((color6&0x00ffffff), (color5&0x00ffffff), (colorA2&0x00ffffff), (colorS1&0x00ffffff));
183          r += GET_RESULT ((color6&0x00ffffff), (color5&0x00ffffff), (colorB2&0x00ffffff), (colorS2&0x00ffffff));
184 
185          if (r > 0)
186           product2b = product1b = color6;
187          else
188          if (r < 0)
189           product2b = product1b = color5;
190          else
191           {
192            product2b = product1b = INTERPOLATE8(color5, color6);
193           }
194         }
195        else
196         {
197          if (color6 == color3 && color3 == colorA1 && color2 != colorA2 && color3 != colorA0)
198              product2b = Q_INTERPOLATE8 (color3, color3, color3, color2);
199          else
200          if (color5 == color2 && color2 == colorA2 && colorA1 != color3 && color2 != colorA3)
201              product2b = Q_INTERPOLATE8 (color2, color2, color2, color3);
202          else
203              product2b = INTERPOLATE8 (color2, color3);
204 
205          if (color6 == color3 && color6 == colorB1 && color5 != colorB2 && color6 != colorB0)
206              product1b = Q_INTERPOLATE8 (color6, color6, color6, color5);
207          else
208          if (color5 == color2 && color5 == colorB2 && colorB1 != color6 && color5 != colorB3)
209              product1b = Q_INTERPOLATE8 (color6, color5, color5, color5);
210          else
211              product1b = INTERPOLATE8 (color5, color6);
212         }
213 
214        if (color5 == color3 && color2 != color6 && color4 == color5 && color5 != colorA2)
215         product2a = INTERPOLATE8(color2, color5);
216        else
217        if (color5 == color1 && color6 == color5 && color4 != color2 && color5 != colorA0)
218         product2a = INTERPOLATE8(color2, color5);
219        else
220         product2a = color2;
221 
222        if (color2 == color6 && color5 != color3 && color1 == color2 && color2 != colorB2)
223         product1a = INTERPOLATE8(color2, color5);
224        else
225        if (color4 == color2 && color3 == color2 && color1 != color5 && color2 != colorB0)
226         product1a = INTERPOLATE8(color2, color5);
227        else
228         product1a = color5;
229 
230        *dP=product1a;
231        *(dP+1)=product1b;
232        *(dP+(srcPitchHalf))=product2a;
233        *(dP+1+(srcPitchHalf))=product2b;
234 
235        bP += 1;
236        dP += 2;
237       }//end of for ( finish= width etc..)
238 
239      line += 2;
240      srcPtr += srcPitch;
241 	}; //endof: for (; height; height--)
242   }
243 }
244 
245 ////////////////////////////////////////////////////////////////////////
246 
Std2xSaI_ex8(unsigned char * srcPtr,DWORD srcPitch,unsigned char * dstBitmap,int width,int height)247 void Std2xSaI_ex8(unsigned char *srcPtr, DWORD srcPitch,
248                   unsigned char *dstBitmap, int width, int height)
249 {
250  DWORD dstPitch        = srcPitch<<1;
251  DWORD srcPitchHalf    = srcPitch>>1;
252  int   finWidth        = srcPitch>>2;
253  DWORD line;
254  DWORD *dP;
255  DWORD *bP;
256  int iXA,iXB,iXC,iYA,iYB,iYC,finish;
257 
258  DWORD colorA, colorB;
259  DWORD colorC, colorD,
260        colorE, colorF, colorG, colorH,
261        colorI, colorJ, colorK, colorL,
262        colorM, colorN, colorO, colorP;
263  DWORD product, product1, product2;
264 
265  line = 0;
266 
267   {
268    for (; height; height-=1)
269 	{
270      bP = (DWORD *)srcPtr;
271 	 dP = (DWORD *)(dstBitmap + line*dstPitch);
272      for (finish = width; finish; finish -= 1 )
273       {
274 //---------------------------------------
275 // Map of the pixels:                    I|E F|J
276 //                                       G|A B|K
277 //                                       H|C D|L
278 //                                       M|N O|P
279        if(finish==finWidth) iXA=0;
280        else                 iXA=1;
281        if(finish>4) {iXB=1;iXC=2;}
282        else
283        if(finish>3) {iXB=1;iXC=1;}
284        else         {iXB=0;iXC=0;}
285        if(line==0)  {iYA=0;}
286        else         {iYA=finWidth;}
287        if(height>4) {iYB=finWidth;iYC=srcPitchHalf;}
288        else
289        if(height>3) {iYB=finWidth;iYC=finWidth;}
290        else         {iYB=0;iYC=0;}
291 
292        colorI = *(bP- iYA - iXA);
293        colorE = *(bP- iYA);
294        colorF = *(bP- iYA + iXB);
295        colorJ = *(bP- iYA + iXC);
296 
297        colorG = *(bP  - iXA);
298        colorA = *(bP);
299        colorB = *(bP  + iXB);
300        colorK = *(bP + iXC);
301 
302        colorH = *(bP  + iYB  - iXA);
303        colorC = *(bP  + iYB);
304        colorD = *(bP  + iYB  + iXB);
305        colorL = *(bP  + iYB  + iXC);
306 
307        colorM = *(bP + iYC - iXA);
308        colorN = *(bP + iYC);
309        colorO = *(bP + iYC + iXB);
310        colorP = *(bP + iYC + iXC);
311 
312 
313        if((colorA == colorD) && (colorB != colorC))
314         {
315          if(((colorA == colorE) && (colorB == colorL)) ||
316             ((colorA == colorC) && (colorA == colorF) &&
317              (colorB != colorE) && (colorB == colorJ)))
318           {
319            product = colorA;
320           }
321          else
322           {
323            product = INTERPOLATE8(colorA, colorB);
324           }
325 
326          if(((colorA == colorG) && (colorC == colorO)) ||
327             ((colorA == colorB) && (colorA == colorH) &&
328              (colorG != colorC) && (colorC == colorM)))
329           {
330            product1 = colorA;
331           }
332          else
333           {
334            product1 = INTERPOLATE8(colorA, colorC);
335           }
336          product2 = colorA;
337         }
338        else
339        if((colorB == colorC) && (colorA != colorD))
340         {
341          if(((colorB == colorF) && (colorA == colorH)) ||
342             ((colorB == colorE) && (colorB == colorD) &&
343              (colorA != colorF) && (colorA == colorI)))
344           {
345            product = colorB;
346           }
347          else
348           {
349            product = INTERPOLATE8(colorA, colorB);
350           }
351 
352          if(((colorC == colorH) && (colorA == colorF)) ||
353             ((colorC == colorG) && (colorC == colorD) &&
354              (colorA != colorH) && (colorA == colorI)))
355           {
356            product1 = colorC;
357           }
358          else
359           {
360            product1=INTERPOLATE8(colorA, colorC);
361           }
362          product2 = colorB;
363         }
364        else
365        if((colorA == colorD) && (colorB == colorC))
366         {
367          if (colorA == colorB)
368           {
369            product = colorA;
370            product1 = colorA;
371            product2 = colorA;
372           }
373          else
374           {
375            register int r = 0;
376            product1 = INTERPOLATE8(colorA, colorC);
377            product = INTERPOLATE8(colorA, colorB);
378 
379            r += GetResult1 (colorA&0x00FFFFFF, colorB&0x00FFFFFF, colorG&0x00FFFFFF, colorE&0x00FFFFFF, colorI&0x00FFFFFF);
380            r += GetResult2 (colorB&0x00FFFFFF, colorA&0x00FFFFFF, colorK&0x00FFFFFF, colorF&0x00FFFFFF, colorJ&0x00FFFFFF);
381            r += GetResult2 (colorB&0x00FFFFFF, colorA&0x00FFFFFF, colorH&0x00FFFFFF, colorN&0x00FFFFFF, colorM&0x00FFFFFF);
382            r += GetResult1 (colorA&0x00FFFFFF, colorB&0x00FFFFFF, colorL&0x00FFFFFF, colorO&0x00FFFFFF, colorP&0x00FFFFFF);
383 
384            if (r > 0)
385             product2 = colorA;
386            else
387            if (r < 0)
388             product2 = colorB;
389            else
390             {
391              product2 = Q_INTERPOLATE8(colorA, colorB, colorC, colorD);
392             }
393           }
394         }
395        else
396         {
397          product2 = Q_INTERPOLATE8(colorA, colorB, colorC, colorD);
398 
399          if ((colorA == colorC) && (colorA == colorF) &&
400              (colorB != colorE) && (colorB == colorJ))
401           {
402            product = colorA;
403           }
404          else
405          if ((colorB == colorE) && (colorB == colorD) && (colorA != colorF) && (colorA == colorI))
406           {
407            product = colorB;
408           }
409          else
410           {
411            product = INTERPOLATE8(colorA, colorB);
412           }
413 
414          if ((colorA == colorB) && (colorA == colorH) &&
415              (colorG != colorC) && (colorC == colorM))
416           {
417            product1 = colorA;
418           }
419          else
420          if ((colorC == colorG) && (colorC == colorD) &&
421              (colorA != colorH) && (colorA == colorI))
422           {
423            product1 = colorC;
424           }
425          else
426           {
427            product1 = INTERPOLATE8(colorA, colorC);
428           }
429         }
430 
431 //////////////////////////
432 
433        *dP=colorA;
434        *(dP+1)=product;
435        *(dP+(srcPitchHalf))=product1;
436        *(dP+1+(srcPitchHalf))=product2;
437 
438        bP += 1;
439        dP += 2;
440       }//end of for ( finish= width etc..)
441 
442      line += 2;
443      srcPtr += srcPitch;
444 	}; //endof: for (; height; height--)
445   }
446 }
447 
448 ////////////////////////////////////////////////////////////////////////
449 
SuperEagle_ex8(unsigned char * srcPtr,DWORD srcPitch,unsigned char * dstBitmap,int width,int height)450 void SuperEagle_ex8(unsigned char *srcPtr, DWORD srcPitch,
451 	                unsigned char  *dstBitmap, int width, int height)
452 {
453  DWORD dstPitch        = srcPitch<<1;
454  DWORD srcPitchHalf    = srcPitch>>1;
455  int   finWidth        = srcPitch>>2;
456  DWORD line;
457  DWORD *dP;
458  DWORD *bP;
459  int iXA,iXB,iXC,iYA,iYB,iYC,finish;
460  DWORD color4, color5, color6;
461  DWORD color1, color2, color3;
462  DWORD colorA1, colorA2,
463        colorB1, colorB2,
464        colorS1, colorS2;
465  DWORD product1a, product1b,
466        product2a, product2b;
467 
468  line = 0;
469 
470   {
471    for (; height; height-=1)
472 	{
473      bP = (DWORD *)srcPtr;
474 	 dP = (DWORD *)(dstBitmap + line*dstPitch);
475      for (finish = width; finish; finish -= 1 )
476       {
477        if(finish==finWidth) iXA=0;
478        else                 iXA=1;
479        if(finish>4) {iXB=1;iXC=2;}
480        else
481        if(finish>3) {iXB=1;iXC=1;}
482        else         {iXB=0;iXC=0;}
483        if(line==0)  {iYA=0;}
484        else         {iYA=finWidth;}
485        if(height>4) {iYB=finWidth;iYC=srcPitchHalf;}
486        else
487        if(height>3) {iYB=finWidth;iYC=finWidth;}
488        else         {iYB=0;iYC=0;}
489 
490        colorB1 = *(bP- iYA);
491        colorB2 = *(bP- iYA + iXB);
492 
493        color4 = *(bP  - iXA);
494        color5 = *(bP);
495        color6 = *(bP  + iXB);
496        colorS2 = *(bP + iXC);
497 
498        color1 = *(bP  + iYB  - iXA);
499        color2 = *(bP  + iYB);
500        color3 = *(bP  + iYB  + iXB);
501        colorS1= *(bP  + iYB  + iXC);
502 
503        colorA1 = *(bP + iYC);
504        colorA2 = *(bP + iYC + iXB);
505 
506        if(color2 == color6 && color5 != color3)
507         {
508          product1b = product2a = color2;
509          if((color1 == color2) ||
510             (color6 == colorB2))
511           {
512            product1a = INTERPOLATE8(color2, color5);
513            product1a = INTERPOLATE8(color2, product1a);
514           }
515          else
516           {
517            product1a = INTERPOLATE8(color5, color6);
518           }
519 
520          if((color6 == colorS2) ||
521             (color2 == colorA1))
522           {
523            product2b = INTERPOLATE8(color2, color3);
524            product2b = INTERPOLATE8(color2, product2b);
525           }
526          else
527           {
528            product2b = INTERPOLATE8(color2, color3);
529           }
530         }
531        else
532        if (color5 == color3 && color2 != color6)
533         {
534          product2b = product1a = color5;
535 
536          if ((colorB1 == color5) ||
537              (color3 == colorS1))
538           {
539            product1b = INTERPOLATE8(color5, color6);
540            product1b = INTERPOLATE8(color5, product1b);
541           }
542          else
543           {
544            product1b = INTERPOLATE8(color5, color6);
545           }
546 
547          if ((color3 == colorA2) ||
548              (color4 == color5))
549           {
550            product2a = INTERPOLATE8(color5, color2);
551            product2a = INTERPOLATE8(color5, product2a);
552           }
553          else
554           {
555            product2a = INTERPOLATE8(color2, color3);
556           }
557         }
558        else
559        if (color5 == color3 && color2 == color6)
560         {
561          register int r = 0;
562 
563          r += GET_RESULT ((color6&0x00ffffff), (color5&0x00ffffff), (color1&0x00ffffff),  (colorA1&0x00ffffff));
564          r += GET_RESULT ((color6&0x00ffffff), (color5&0x00ffffff), (color4&0x00ffffff),  (colorB1&0x00ffffff));
565          r += GET_RESULT ((color6&0x00ffffff), (color5&0x00ffffff), (colorA2&0x00ffffff), (colorS1&0x00ffffff));
566          r += GET_RESULT ((color6&0x00ffffff), (color5&0x00ffffff), (colorB2&0x00ffffff), (colorS2&0x00ffffff));
567 
568          if (r > 0)
569           {
570            product1b = product2a = color2;
571            product1a = product2b = INTERPOLATE8(color5, color6);
572           }
573          else
574          if (r < 0)
575           {
576            product2b = product1a = color5;
577            product1b = product2a = INTERPOLATE8(color5, color6);
578           }
579          else
580           {
581            product2b = product1a = color5;
582            product1b = product2a = color2;
583           }
584         }
585        else
586         {
587          product2b = product1a = INTERPOLATE8(color2, color6);
588          product2b = Q_INTERPOLATE8(color3, color3, color3, product2b);
589          product1a = Q_INTERPOLATE8(color5, color5, color5, product1a);
590 
591          product2a = product1b = INTERPOLATE8(color5, color3);
592          product2a = Q_INTERPOLATE8(color2, color2, color2, product2a);
593          product1b = Q_INTERPOLATE8(color6, color6, color6, product1b);
594         }
595 
596 ////////////////////////////////
597 
598        *dP=product1a;
599        *(dP+1)=product1b;
600        *(dP+(srcPitchHalf))=product2a;
601        *(dP+1+(srcPitchHalf))=product2b;
602 
603        bP += 1;
604        dP += 2;
605       }//end of for ( finish= width etc..)
606 
607      line += 2;
608      srcPtr += srcPitch;
609 	}; //endof: for (; height; height--)
610   }
611 }
612 
613 /////////////////////////
614 
scale2x_32_def_whole(unsigned long * dst0,unsigned long * dst1,const unsigned long * src0,const unsigned long * src1,const unsigned long * src2,unsigned count)615 static __inline void scale2x_32_def_whole(unsigned long*  dst0, unsigned long* dst1, const unsigned long* src0, const unsigned long* src1, const unsigned long* src2, unsigned count)
616 {
617 	// first pixel
618 	if (src0[0] != src2[0] && src1[0] != src1[1]) {
619 		dst0[0] = src1[0] == src0[0] ? src0[0] : src1[0];
620 		dst0[1] = src1[1] == src0[0] ? src0[0] : src1[0];
621 		dst1[0] = src1[0] == src2[0] ? src2[0] : src1[0];
622 		dst1[1] = src1[1] == src2[0] ? src2[0] : src1[0];
623 	} else {
624 		dst0[0] = src1[0];
625 		dst0[1] = src1[0];
626 		dst1[0] = src1[0];
627 		dst1[1] = src1[0];
628 	}
629 	++src0;
630 	++src1;
631 	++src2;
632 	dst0 += 2;
633 	dst1 += 2;
634 
635 	// central pixels
636 	count -= 2;
637 	while (count) {
638 		if (src0[0] != src2[0] && src1[-1] != src1[1]) {
639 			dst0[0] = src1[-1] == src0[0] ? src0[0] : src1[0];
640 			dst0[1] = src1[1] == src0[0] ? src0[0] : src1[0];
641 			dst1[0] = src1[-1] == src2[0] ? src2[0] : src1[0];
642 			dst1[1] = src1[1] == src2[0] ? src2[0] : src1[0];
643 		} else {
644 			dst0[0] = src1[0];
645 			dst0[1] = src1[0];
646 			dst1[0] = src1[0];
647 			dst1[1] = src1[0];
648 		}
649 
650 		++src0;
651 		++src1;
652 		++src2;
653 		dst0 += 2;
654 		dst1 += 2;
655 		--count;
656 	}
657 
658 	// last pixel
659 	if (src0[0] != src2[0] && src1[-1] != src1[0]) {
660 		dst0[0] = src1[-1] == src0[0] ? src0[0] : src1[0];
661 		dst0[1] = src1[0] == src0[0] ? src0[0] : src1[0];
662 		dst1[0] = src1[-1] == src2[0] ? src2[0] : src1[0];
663 		dst1[1] = src1[0] == src2[0] ? src2[0] : src1[0];
664 	} else {
665 		dst0[0] = src1[0];
666 		dst0[1] = src1[0];
667 		dst1[0] = src1[0];
668 		dst1[1] = src1[0];
669 	}
670 }
671 
Scale2x_ex8(unsigned char * srcPtr,DWORD srcPitch,unsigned char * dstPtr,int width,int height)672 void Scale2x_ex8(unsigned char *srcPtr, DWORD srcPitch,
673 				 unsigned char  *dstPtr, int width, int height)
674 {
675 	const int dstPitch = srcPitch<<1;
676 
677 	int count = height;
678 
679 	unsigned long  *dst0 = (unsigned long  *)dstPtr;
680 	unsigned long  *dst1 = dst0 + (dstPitch >> 2);
681 
682 	unsigned long  *src0 = (unsigned long  *)srcPtr;
683 	unsigned long  *src1 = src0 + (srcPitch >> 2);
684 	unsigned long  *src2 = src1 + (srcPitch >> 2);
685 	scale2x_32_def_whole(dst0, dst1, src0, src0, src1, width);
686 
687 	count -= 2;
688 	while(count) {
689 		dst0 += dstPitch >> 1;
690 		dst1 += dstPitch >> 1;
691 		scale2x_32_def_whole(dst0, dst1, src0, src0, src1, width);
692 		src0 = src1;
693 		src1 = src2;
694 		src2 += srcPitch >> 2;
695 		--count;
696 	}
697 	dst0 += dstPitch >> 1;
698 	dst1 += dstPitch >> 1;
699 	scale2x_32_def_whole(dst0, dst1, src0, src1, src1, width);
700 
701 }
702 
703 ////////////////////////////////////////////////////////////////////////
704 
scale3x_32_def_whole(unsigned long * dst0,unsigned long * dst1,unsigned long * dst2,const unsigned long * src0,const unsigned long * src1,const unsigned long * src2,unsigned count)705 static __inline void scale3x_32_def_whole(unsigned long* dst0, unsigned long* dst1, unsigned long* dst2, const unsigned long* src0, const unsigned long* src1, const unsigned long* src2, unsigned count)
706 {
707 	//first pixel
708 	if (src0[0] != src2[0] && src1[0] != src1[1]) {
709 		dst0[0] = src1[0];
710 		dst0[1] = (src1[0] == src0[0] && src1[0] != src0[1]) || (src1[1] == src0[0] && src1[0] != src0[0]) ? src0[0] : src1[0];
711 		dst0[2] = src1[1] == src0[0] ? src1[1] : src1[0];
712 		dst1[0] = (src1[0] == src0[0] && src1[0] != src2[0]) || (src1[0] == src2[0] && src1[0] != src0[0]) ? src1[0] : src1[0];
713 		dst1[1] = src1[0];
714 		dst1[2] = (src1[1] == src0[0] && src1[0] != src2[1]) || (src1[1] == src2[0] && src1[0] != src0[1]) ? src1[1] : src1[0];
715 		dst2[0] = src1[0];
716 		dst2[1] = (src1[0] == src2[0] && src1[0] != src2[1]) || (src1[1] == src2[0] && src1[0] != src2[0]) ? src2[0] : src1[0];
717 		dst2[2] = src1[1] == src2[0] ? src1[1] : src1[0];
718 	} else {
719 		dst0[0] = src1[0];
720 		dst0[1] = src1[0];
721 		dst0[2] = src1[0];
722 		dst1[0] = src1[0];
723 		dst1[1] = src1[0];
724 		dst1[2] = src1[0];
725 		dst2[0] = src1[0];
726 		dst2[1] = src1[0];
727 		dst2[2] = src1[0];
728 	}
729 	++src0;
730 	++src1;
731 	++src2;
732 	dst0 += 3;
733 	dst1 += 3;
734 	dst2 += 3;
735 
736 	//central pixels
737 	count -= 2;
738 	while (count) {
739 		if (src0[0] != src2[0] && src1[-1] != src1[1]) {
740 			dst0[0] = src1[-1] == src0[0] ? src1[-1] : src1[0];
741 			dst0[1] = (src1[-1] == src0[0] && src1[0] != src0[1]) || (src1[1] == src0[0] && src1[0] != src0[-1]) ? src0[0] : src1[0];
742 			dst0[2] = src1[1] == src0[0] ? src1[1] : src1[0];
743 			dst1[0] = (src1[-1] == src0[0] && src1[0] != src2[-1]) || (src1[-1] == src2[0] && src1[0] != src0[-1]) ? src1[-1] : src1[0];
744 			dst1[1] = src1[0];
745 			dst1[2] = (src1[1] == src0[0] && src1[0] != src2[1]) || (src1[1] == src2[0] && src1[0] != src0[1]) ? src1[1] : src1[0];
746 			dst2[0] = src1[-1] == src2[0] ? src1[-1] : src1[0];
747 			dst2[1] = (src1[-1] == src2[0] && src1[0] != src2[1]) || (src1[1] == src2[0] && src1[0] != src2[-1]) ? src2[0] : src1[0];
748 			dst2[2] = src1[1] == src2[0] ? src1[1] : src1[0];
749 		} else {
750 			dst0[0] = src1[0];
751 			dst0[1] = src1[0];
752 			dst0[2] = src1[0];
753 			dst1[0] = src1[0];
754 			dst1[1] = src1[0];
755 			dst1[2] = src1[0];
756 			dst2[0] = src1[0];
757 			dst2[1] = src1[0];
758 			dst2[2] = src1[0];
759 		}
760 
761 		++src0;
762 		++src1;
763 		++src2;
764 		dst0 += 3;
765 		dst1 += 3;
766 		dst2 += 3;
767 		--count;
768 	}
769 
770 	// last pixel
771 	if (src0[0] != src2[0] && src1[-1] != src1[0]) {
772 		dst0[0] = src1[-1] == src0[0] ? src1[-1] : src1[0];
773 		dst0[1] = (src1[-1] == src0[0] && src1[0] != src0[0]) || (src1[0] == src0[0] && src1[0] != src0[-1]) ? src0[0] : src1[0];
774 		dst0[2] = src1[0];
775 		dst1[0] = (src1[-1] == src0[0] && src1[0] != src2[-1]) || (src1[-1] == src2[0] && src1[0] != src0[-1]) ? src1[-1] : src1[0];
776 		dst1[1] = src1[0];
777 		dst1[2] = (src1[0] == src0[0] && src1[0] != src2[0]) || (src1[0] == src2[0] && src1[0] != src0[0]) ? src1[0] : src1[0];
778 		dst2[0] = src1[-1] == src2[0] ? src1[-1] : src1[0];
779 		dst2[1] = (src1[-1] == src2[0] && src1[0] != src2[0]) || (src1[0] == src2[0] && src1[0] != src2[-1]) ? src2[0] : src1[0];
780 		dst2[2] = src1[0];
781 	} else {
782 		dst0[0] = src1[0];
783 		dst0[1] = src1[0];
784 		dst0[2] = src1[0];
785 		dst1[0] = src1[0];
786 		dst1[1] = src1[0];
787 		dst1[2] = src1[0];
788 		dst2[0] = src1[0];
789 		dst2[1] = src1[0];
790 		dst2[2] = src1[0];
791 	}
792 }
793 
794 
Scale3x_ex8(unsigned char * srcPtr,DWORD srcPitch,unsigned char * dstPtr,int width,int height)795 void Scale3x_ex8(unsigned char *srcPtr, DWORD srcPitch,
796 				 unsigned char  *dstPtr, int width, int height)
797 {
798 	int count = height;
799 
800 	int dstPitch = srcPitch >> 1;
801 
802 
803 	unsigned long  *dst0 = (unsigned long  *)dstPtr;
804 	unsigned long  *dst1 = dst0 + dstPitch;
805 	unsigned long  *dst2 = dst1 + dstPitch;
806 
807 	unsigned long  *src0 = (unsigned long  *)srcPtr;
808 	unsigned long  *src1 = src0 + (srcPitch >> 2);
809 	unsigned long  *src2 = src1 + (srcPitch >> 2);
810 	scale3x_32_def_whole(dst0, dst1, dst2, src0, src0, src2, width);
811 
812 	count -= 2;
813 	while(count) {
814 		dst0 += dstPitch * 3;
815 		dst1 += dstPitch * 3;
816 		dst2 += dstPitch * 3;
817 
818 		scale3x_32_def_whole(dst0, dst1, dst2, src0, src1, src2, width);
819 		src0 = src1;
820 		src1 = src2;
821 		src2 += srcPitch >> 2;
822 		--count;
823 	}
824 	dst0 += dstPitch * 3;
825 	dst1 += dstPitch * 3;
826 	dst2 += dstPitch * 3;
827 
828 	scale3x_32_def_whole(dst0, dst1, dst2, src0, src1, src1, width);
829 }
830 
831 
832 ////////////////////////////////////////////////////////////////////////
833 
834 #define colorMask6     0x0000F7DE
835 #define lowPixelMask6  0x00000821
836 #define qcolorMask6    0x0000E79c
837 #define qlowpixelMask6 0x00001863
838 
839 #define INTERPOLATE6(A, B) ((((A & colorMask6) >> 1) + ((B & colorMask6) >> 1) + (A & B & lowPixelMask6)))
840 #define Q_INTERPOLATE6(A, B, C, D) (((((A & qcolorMask6) >> 2) + ((B & qcolorMask6) >> 2) + ((C & qcolorMask6) >> 2) + ((D & qcolorMask6) >> 2) \
841 	+ ((((A & qlowpixelMask6) + (B & qlowpixelMask6) + (C & qlowpixelMask6) + (D & qlowpixelMask6)) >> 2) & qlowpixelMask6))))
842 
Super2xSaI_ex6(unsigned char * srcPtr,DWORD srcPitch,unsigned char * dstBitmap,int width,int height)843 void Super2xSaI_ex6(unsigned char *srcPtr, DWORD srcPitch,
844 	            unsigned char  *dstBitmap, int width, int height)
845 {
846  DWORD dstPitch        = srcPitch<<1;
847  int   finWidth        = srcPitch>>1;
848  DWORD line;
849  unsigned short *dP;
850  unsigned short *bP;
851  int iXA,iXB,iXC,iYA,iYB,iYC,finish;
852  DWORD color4, color5, color6;
853  DWORD color1, color2, color3;
854  DWORD colorA0, colorA1, colorA2, colorA3,
855        colorB0, colorB1, colorB2, colorB3,
856        colorS1, colorS2;
857  DWORD product1a, product1b,
858        product2a, product2b;
859 
860  line = 0;
861 
862   {
863    for (; height; height-=1)
864 	{
865      bP = (unsigned short *)srcPtr;
866 	 dP = (unsigned short *)(dstBitmap + line*dstPitch);
867      for (finish = width; finish; finish -= 1 )
868       {
869 //---------------------------------------    B1 B2
870 //                                         4  5  6 S2
871 //                                         1  2  3 S1
872 //                                           A1 A2
873        if(finish==finWidth) iXA=0;
874        else                 iXA=1;
875        if(finish>4) {iXB=1;iXC=2;}
876        else
877        if(finish>3) {iXB=1;iXC=1;}
878        else         {iXB=0;iXC=0;}
879        if(line==0) iYA=0;
880        else        iYA=finWidth;
881        if(height>4) {iYB=finWidth;iYC=srcPitch;}
882        else
883        if(height>3) {iYB=finWidth;iYC=finWidth;}
884        else         {iYB=0;iYC=0;}
885 
886 
887        colorB0 = *(bP- iYA - iXA);
888        colorB1 = *(bP- iYA);
889        colorB2 = *(bP- iYA + iXB);
890        colorB3 = *(bP- iYA + iXC);
891 
892        color4 = *(bP  - iXA);
893        color5 = *(bP);
894        color6 = *(bP  + iXB);
895        colorS2 = *(bP + iXC);
896 
897        color1 = *(bP  + iYB  - iXA);
898        color2 = *(bP  + iYB);
899        color3 = *(bP  + iYB  + iXB);
900        colorS1= *(bP  + iYB  + iXC);
901 
902        colorA0 = *(bP + iYC - iXA);
903        colorA1 = *(bP + iYC);
904        colorA2 = *(bP + iYC + iXB);
905        colorA3 = *(bP + iYC + iXC);
906 
907 //--------------------------------------
908        if (color2 == color6 && color5 != color3)
909         {
910          product2b = product1b = color2;
911         }
912        else
913        if (color5 == color3 && color2 != color6)
914         {
915          product2b = product1b = color5;
916         }
917        else
918        if (color5 == color3 && color2 == color6)
919         {
920          register int r = 0;
921 
922          r += GET_RESULT ((color6), (color5), (color1),  (colorA1));
923          r += GET_RESULT ((color6), (color5), (color4),  (colorB1));
924          r += GET_RESULT ((color6), (color5), (colorA2), (colorS1));
925          r += GET_RESULT ((color6), (color5), (colorB2), (colorS2));
926 
927          if (r > 0)
928           product2b = product1b = color6;
929          else
930          if (r < 0)
931           product2b = product1b = color5;
932          else
933           {
934            product2b = product1b = INTERPOLATE6 (color5, color6);
935           }
936         }
937        else
938         {
939          if (color6 == color3 && color3 == colorA1 && color2 != colorA2 && color3 != colorA0)
940              product2b = Q_INTERPOLATE6 (color3, color3, color3, color2);
941          else
942          if (color5 == color2 && color2 == colorA2 && colorA1 != color3 && color2 != colorA3)
943              product2b = Q_INTERPOLATE6 (color2, color2, color2, color3);
944          else
945              product2b = INTERPOLATE6 (color2, color3);
946 
947          if (color6 == color3 && color6 == colorB1 && color5 != colorB2 && color6 != colorB0)
948              product1b = Q_INTERPOLATE6 (color6, color6, color6, color5);
949          else
950          if (color5 == color2 && color5 == colorB2 && colorB1 != color6 && color5 != colorB3)
951              product1b = Q_INTERPOLATE6 (color6, color5, color5, color5);
952          else
953              product1b = INTERPOLATE6 (color5, color6);
954         }
955 
956        if (color5 == color3 && color2 != color6 && color4 == color5 && color5 != colorA2)
957         product2a = INTERPOLATE6 (color2, color5);
958        else
959        if (color5 == color1 && color6 == color5 && color4 != color2 && color5 != colorA0)
960         product2a = INTERPOLATE6(color2, color5);
961        else
962         product2a = color2;
963 
964        if (color2 == color6 && color5 != color3 && color1 == color2 && color2 != colorB2)
965         product1a = INTERPOLATE6(color2, color5);
966        else
967        if (color4 == color2 && color3 == color2 && color1 != color5 && color2 != colorB0)
968         product1a = INTERPOLATE6(color2, color5);
969        else
970         product1a = color5;
971 
972        *dP=(unsigned short)product1a;
973        *(dP+1)=(unsigned short)product1b;
974        *(dP+(srcPitch))=(unsigned short)product2a;
975        *(dP+1+(srcPitch))=(unsigned short)product2b;
976 
977        bP += 1;
978        dP += 2;
979       }//end of for ( finish= width etc..)
980 
981      line += 2;
982      srcPtr += srcPitch;
983 	}; //endof: for (; height; height--)
984   }
985 }
986 
987 ////////////////////////////////////////////////////////////////////////
988 
Std2xSaI_ex6(unsigned char * srcPtr,DWORD srcPitch,unsigned char * dstBitmap,int width,int height)989 void Std2xSaI_ex6(unsigned char *srcPtr, DWORD srcPitch,
990 	            unsigned char  *dstBitmap, int width, int height)
991 {
992  DWORD dstPitch        = srcPitch<<1;
993  int   finWidth        = srcPitch>>1;
994  DWORD line;
995  unsigned short *dP;
996  unsigned short *bP;
997  int iXA,iXB,iXC,iYA,iYB,iYC,finish;
998 
999  DWORD colorA, colorB;
1000  DWORD colorC, colorD,
1001        colorE, colorF, colorG, colorH,
1002        colorI, colorJ, colorK, colorL,
1003        colorM, colorN, colorO, colorP;
1004  DWORD product, product1, product2;
1005 
1006  line = 0;
1007 
1008   {
1009    for (; height; height-=1)
1010 	{
1011      bP = (unsigned short *)srcPtr;
1012 	 dP = (unsigned short *)(dstBitmap + line*dstPitch);
1013      for (finish = width; finish; finish -= 1 )
1014       {
1015 //---------------------------------------
1016 // Map of the pixels:                    I|E F|J
1017 //                                       G|A B|K
1018 //                                       H|C D|L
1019 //                                       M|N O|P
1020        if(finish==finWidth) iXA=0;
1021        else                 iXA=1;
1022        if(finish>4) {iXB=1;iXC=2;}
1023        else
1024        if(finish>3) {iXB=1;iXC=1;}
1025        else         {iXB=0;iXC=0;}
1026        if(line==0) iYA=0;
1027        else        iYA=finWidth;
1028        if(height>4) {iYB=finWidth;iYC=srcPitch;}
1029        else
1030        if(height>3) {iYB=finWidth;iYC=finWidth;}
1031        else         {iYB=0;iYC=0;}
1032 
1033        colorI = *(bP- iYA - iXA);
1034        colorE = *(bP- iYA);
1035        colorF = *(bP- iYA + iXB);
1036        colorJ = *(bP- iYA + iXC);
1037 
1038        colorG = *(bP  - iXA);
1039        colorA = *(bP);
1040        colorB = *(bP  + iXB);
1041        colorK = *(bP + iXC);
1042 
1043        colorH = *(bP  + iYB  - iXA);
1044        colorC = *(bP  + iYB);
1045        colorD = *(bP  + iYB  + iXB);
1046        colorL = *(bP  + iYB  + iXC);
1047 
1048        colorM = *(bP + iYC - iXA);
1049        colorN = *(bP + iYC);
1050        colorO = *(bP + iYC + iXB);
1051        colorP = *(bP + iYC + iXC);
1052 
1053        if((colorA == colorD) && (colorB != colorC))
1054         {
1055          if(((colorA == colorE) && (colorB == colorL)) ||
1056             ((colorA == colorC) && (colorA == colorF) &&
1057              (colorB != colorE) && (colorB == colorJ)))
1058           {
1059            product = colorA;
1060           }
1061          else
1062           {
1063            product = INTERPOLATE6(colorA, colorB);
1064           }
1065 
1066          if(((colorA == colorG) && (colorC == colorO)) ||
1067             ((colorA == colorB) && (colorA == colorH) &&
1068              (colorG != colorC) && (colorC == colorM)))
1069           {
1070            product1 = colorA;
1071           }
1072          else
1073           {
1074            product1 = INTERPOLATE6(colorA, colorC);
1075           }
1076          product2 = colorA;
1077         }
1078        else
1079        if((colorB == colorC) && (colorA != colorD))
1080         {
1081          if(((colorB == colorF) && (colorA == colorH)) ||
1082             ((colorB == colorE) && (colorB == colorD) &&
1083              (colorA != colorF) && (colorA == colorI)))
1084           {
1085            product = colorB;
1086           }
1087          else
1088           {
1089            product = INTERPOLATE6(colorA, colorB);
1090           }
1091 
1092          if(((colorC == colorH) && (colorA == colorF)) ||
1093             ((colorC == colorG) && (colorC == colorD) &&
1094              (colorA != colorH) && (colorA == colorI)))
1095           {
1096            product1 = colorC;
1097           }
1098          else
1099           {
1100            product1=INTERPOLATE6(colorA, colorC);
1101           }
1102          product2 = colorB;
1103         }
1104        else
1105        if((colorA == colorD) && (colorB == colorC))
1106         {
1107          if (colorA == colorB)
1108           {
1109            product = colorA;
1110            product1 = colorA;
1111            product2 = colorA;
1112           }
1113          else
1114           {
1115            register int r = 0;
1116            product1 = INTERPOLATE6(colorA, colorC);
1117            product = INTERPOLATE6(colorA, colorB);
1118 
1119            r += GetResult1 (colorA, colorB, colorG, colorE, colorI);
1120            r += GetResult2 (colorB, colorA, colorK, colorF, colorJ);
1121            r += GetResult2 (colorB, colorA, colorH, colorN, colorM);
1122            r += GetResult1 (colorA, colorB, colorL, colorO, colorP);
1123 
1124            if (r > 0)
1125             product2 = colorA;
1126            else
1127            if (r < 0)
1128             product2 = colorB;
1129            else
1130             {
1131              product2 = Q_INTERPOLATE6(colorA, colorB, colorC, colorD);
1132             }
1133           }
1134         }
1135        else
1136         {
1137          product2 = Q_INTERPOLATE6(colorA, colorB, colorC, colorD);
1138 
1139          if ((colorA == colorC) && (colorA == colorF) &&
1140              (colorB != colorE) && (colorB == colorJ))
1141           {
1142            product = colorA;
1143           }
1144          else
1145          if ((colorB == colorE) && (colorB == colorD) && (colorA != colorF) && (colorA == colorI))
1146           {
1147            product = colorB;
1148           }
1149          else
1150           {
1151            product = INTERPOLATE6(colorA, colorB);
1152           }
1153 
1154          if ((colorA == colorB) && (colorA == colorH) &&
1155              (colorG != colorC) && (colorC == colorM))
1156           {
1157            product1 = colorA;
1158           }
1159          else
1160          if ((colorC == colorG) && (colorC == colorD) &&
1161              (colorA != colorH) && (colorA == colorI))
1162           {
1163            product1 = colorC;
1164           }
1165          else
1166           {
1167            product1 = INTERPOLATE6(colorA, colorC);
1168           }
1169         }
1170 
1171        *dP=(unsigned short)colorA;
1172        *(dP+1)=(unsigned short)product;
1173        *(dP+(srcPitch))=(unsigned short)product1;
1174        *(dP+1+(srcPitch))=(unsigned short)product2;
1175 
1176        bP += 1;
1177        dP += 2;
1178       }//end of for ( finish= width etc..)
1179 
1180      line += 2;
1181      srcPtr += srcPitch;
1182 	}; //endof: for (; height; height--)
1183   }
1184 }
1185 
1186 ////////////////////////////////////////////////////////////////////////
1187 
SuperEagle_ex6(unsigned char * srcPtr,DWORD srcPitch,unsigned char * dstBitmap,int width,int height)1188 void SuperEagle_ex6(unsigned char *srcPtr, DWORD srcPitch,
1189 	            unsigned char  *dstBitmap, int width, int height)
1190 {
1191  DWORD dstPitch        = srcPitch<<1;
1192  int   finWidth        = srcPitch>>1;
1193  DWORD line;
1194  unsigned short *dP;
1195  unsigned short *bP;
1196  int iXA,iXB,iXC,iYA,iYB,iYC,finish;
1197  DWORD color4, color5, color6;
1198  DWORD color1, color2, color3;
1199  DWORD colorA1, colorA2,
1200        colorB1, colorB2,
1201        colorS1, colorS2;
1202  DWORD product1a, product1b,
1203        product2a, product2b;
1204 
1205  line = 0;
1206 
1207   {
1208    for (; height; height-=1)
1209 	{
1210      bP = (unsigned short *)srcPtr;
1211 	 dP = (unsigned short *)(dstBitmap + line*dstPitch);
1212      for (finish = width; finish; finish -= 1 )
1213       {
1214        if(finish==finWidth) iXA=0;
1215        else                 iXA=1;
1216        if(finish>4) {iXB=1;iXC=2;}
1217        else
1218        if(finish>3) {iXB=1;iXC=1;}
1219        else         {iXB=0;iXC=0;}
1220        if(line==0) iYA=0;
1221        else        iYA=finWidth;
1222        if(height>4) {iYB=finWidth;iYC=srcPitch;}
1223        else
1224        if(height>3) {iYB=finWidth;iYC=finWidth;}
1225        else         {iYB=0;iYC=0;}
1226 
1227        colorB1 = *(bP- iYA);
1228        colorB2 = *(bP- iYA + iXB);
1229 
1230        color4 = *(bP  - iXA);
1231        color5 = *(bP);
1232        color6 = *(bP  + iXB);
1233        colorS2 = *(bP + iXC);
1234 
1235        color1 = *(bP  + iYB  - iXA);
1236        color2 = *(bP  + iYB);
1237        color3 = *(bP  + iYB  + iXB);
1238        colorS1= *(bP  + iYB  + iXC);
1239 
1240        colorA1 = *(bP + iYC);
1241        colorA2 = *(bP + iYC + iXB);
1242 
1243        if(color2 == color6 && color5 != color3)
1244         {
1245          product1b = product2a = color2;
1246          if((color1 == color2) ||
1247             (color6 == colorB2))
1248           {
1249            product1a = INTERPOLATE6(color2, color5);
1250            product1a = INTERPOLATE6(color2, product1a);
1251           }
1252          else
1253           {
1254            product1a = INTERPOLATE6(color5, color6);
1255           }
1256 
1257          if((color6 == colorS2) ||
1258             (color2 == colorA1))
1259           {
1260            product2b = INTERPOLATE6(color2, color3);
1261            product2b = INTERPOLATE6(color2, product2b);
1262           }
1263          else
1264           {
1265            product2b = INTERPOLATE6(color2, color3);
1266           }
1267         }
1268        else
1269        if (color5 == color3 && color2 != color6)
1270         {
1271          product2b = product1a = color5;
1272 
1273          if ((colorB1 == color5) ||
1274              (color3 == colorS1))
1275           {
1276            product1b = INTERPOLATE6(color5, color6);
1277            product1b = INTERPOLATE6(color5, product1b);
1278           }
1279          else
1280           {
1281            product1b = INTERPOLATE6(color5, color6);
1282           }
1283 
1284          if ((color3 == colorA2) ||
1285              (color4 == color5))
1286           {
1287            product2a = INTERPOLATE6(color5, color2);
1288            product2a = INTERPOLATE6(color5, product2a);
1289           }
1290          else
1291           {
1292            product2a = INTERPOLATE6(color2, color3);
1293           }
1294         }
1295        else
1296        if (color5 == color3 && color2 == color6)
1297         {
1298          register int r = 0;
1299 
1300          r += GET_RESULT ((color6), (color5), (color1),  (colorA1));
1301          r += GET_RESULT ((color6), (color5), (color4),  (colorB1));
1302          r += GET_RESULT ((color6), (color5), (colorA2), (colorS1));
1303          r += GET_RESULT ((color6), (color5), (colorB2), (colorS2));
1304 
1305          if (r > 0)
1306           {
1307            product1b = product2a = color2;
1308            product1a = product2b = INTERPOLATE6(color5, color6);
1309           }
1310          else
1311          if (r < 0)
1312           {
1313            product2b = product1a = color5;
1314            product1b = product2a = INTERPOLATE6(color5, color6);
1315           }
1316          else
1317           {
1318            product2b = product1a = color5;
1319            product1b = product2a = color2;
1320           }
1321         }
1322        else
1323         {
1324          product2b = product1a = INTERPOLATE6(color2, color6);
1325          product2b = Q_INTERPOLATE6(color3, color3, color3, product2b);
1326          product1a = Q_INTERPOLATE6(color5, color5, color5, product1a);
1327 
1328          product2a = product1b = INTERPOLATE6(color5, color3);
1329          product2a = Q_INTERPOLATE6(color2, color2, color2, product2a);
1330          product1b = Q_INTERPOLATE6(color6, color6, color6, product1b);
1331         }
1332 
1333        *dP=(unsigned short)product1a;
1334        *(dP+1)=(unsigned short)product1b;
1335        *(dP+(srcPitch))=(unsigned short)product2a;
1336        *(dP+1+(srcPitch))=(unsigned short)product2b;
1337 
1338        bP += 1;
1339        dP += 2;
1340       }//end of for ( finish= width etc..)
1341 
1342      line += 2;
1343      srcPtr += srcPitch;
1344 	}; //endof: for (; height; height--)
1345   }
1346 }
1347 
1348 ////////////////////////////////////////////////////////////////////////
1349 
1350 #ifndef MAX
1351 #define MAX(a,b)    (((a) > (b)) ? (a) : (b))
1352 #define MIN(a,b)    (((a) < (b)) ? (a) : (b))
1353 #endif
1354 
Scale2x_ex6_5(unsigned char * srcPtr,DWORD srcPitch,unsigned char * dstBitmap,int width,int height)1355 void Scale2x_ex6_5(unsigned char *srcPtr, DWORD srcPitch,
1356 	               unsigned char  *dstBitmap, int width, int height)
1357 {
1358  int looph, loopw;
1359 
1360  unsigned char * srcpix = srcPtr;
1361  unsigned char * dstpix = dstBitmap;
1362 
1363  const int srcpitch = srcPitch;
1364  const int dstpitch = srcPitch<<1;
1365 
1366  unsigned short E0, E1, E2, E3, B, D, E, F, H;
1367  for(looph = 0; looph < height; ++looph)
1368   {
1369    for(loopw = 0; loopw < width; ++ loopw)
1370     {
1371      B = *(unsigned short*)(srcpix + (MAX(0,looph-1)*srcpitch) + (2*loopw));
1372      D = *(unsigned short*)(srcpix + (looph*srcpitch) + (2*MAX(0,loopw-1)));
1373      E = *(unsigned short*)(srcpix + (looph*srcpitch) + (2*loopw));
1374      F = *(unsigned short*)(srcpix + (looph*srcpitch) + (2*MIN(width-1,loopw+1)));
1375      H = *(unsigned short*)(srcpix + (MIN(height-1,looph+1)*srcpitch) + (2*loopw));
1376 
1377 		    if (B != H && D != F) {
1378 				E0 = D == B ? D : E;
1379 				E1 = B == F ? F : E;
1380 				E2 = D == H ? D : E;
1381 				E3 = H == F ? F : E;
1382 			} else {
1383 				E0 = E;
1384 				E1 = E;
1385 				E2 = E;
1386 				E3 = E;
1387 			}
1388 
1389 
1390      *(unsigned short*)(dstpix + looph*2*dstpitch + loopw*2*2) = E0;
1391      *(unsigned short*)(dstpix + looph*2*dstpitch + (loopw*2+1)*2) = E1;
1392      *(unsigned short*)(dstpix + (looph*2+1)*dstpitch + loopw*2*2) = E2;
1393      *(unsigned short*)(dstpix + (looph*2+1)*dstpitch + (loopw*2+1)*2) = E3;
1394     }
1395   }
1396 }
1397 
1398 ////////////////////////////////////////////////////////////////////////
scale3x_16_def_whole(unsigned short * dst0,unsigned short * dst1,unsigned short * dst2,const unsigned short * src0,const unsigned short * src1,const unsigned short * src2,unsigned count)1399 static __inline void scale3x_16_def_whole(unsigned short* dst0, unsigned short *dst1, unsigned short *dst2, const unsigned short *src0, const unsigned short *src1, const unsigned short *src2, unsigned count)
1400 {
1401 	//assert(count >= 2);
1402 
1403 	/* first pixel */
1404 	if (src0[0] != src2[0] && src1[0] != src1[1]) {
1405 		dst0[0] = src1[0];
1406 		dst0[1] = (src1[0] == src0[0] && src1[0] != src0[1]) || (src1[1] == src0[0] && src1[0] != src0[0]) ? src0[0] : src1[0];
1407 		dst0[2] = src1[1] == src0[0] ? src1[1] : src1[0];
1408 		dst1[0] = (src1[0] == src0[0] && src1[0] != src2[0]) || (src1[0] == src2[0] && src1[0] != src0[0]) ? src1[0] : src1[0];
1409 		dst1[1] = src1[0];
1410 		dst1[2] = (src1[1] == src0[0] && src1[0] != src2[1]) || (src1[1] == src2[0] && src1[0] != src0[1]) ? src1[1] : src1[0];
1411 		dst2[0] = src1[0];
1412 		dst2[1] = (src1[0] == src2[0] && src1[0] != src2[1]) || (src1[1] == src2[0] && src1[0] != src2[0]) ? src2[0] : src1[0];
1413 		dst2[2] = src1[1] == src2[0] ? src1[1] : src1[0];
1414 	} else {
1415 		dst0[0] = src1[0];
1416 		dst0[1] = src1[0];
1417 		dst0[2] = src1[0];
1418 		dst1[0] = src1[0];
1419 		dst1[1] = src1[0];
1420 		dst1[2] = src1[0];
1421 		dst2[0] = src1[0];
1422 		dst2[1] = src1[0];
1423 		dst2[2] = src1[0];
1424 	}
1425 	++src0;
1426 	++src1;
1427 	++src2;
1428 	dst0 += 3;
1429 	dst1 += 3;
1430 	dst2 += 3;
1431 
1432 	/* central pixels */
1433 	count -= 2;
1434 	while (count) {
1435 		if (src0[0] != src2[0] && src1[-1] != src1[1]) {
1436 			dst0[0] = src1[-1] == src0[0] ? src1[-1] : src1[0];
1437 			dst0[1] = (src1[-1] == src0[0] && src1[0] != src0[1]) || (src1[1] == src0[0] && src1[0] != src0[-1]) ? src0[0] : src1[0];
1438 			dst0[2] = src1[1] == src0[0] ? src1[1] : src1[0];
1439 			dst1[0] = (src1[-1] == src0[0] && src1[0] != src2[-1]) || (src1[-1] == src2[0] && src1[0] != src0[-1]) ? src1[-1] : src1[0];
1440 			dst1[1] = src1[0];
1441 			dst1[2] = (src1[1] == src0[0] && src1[0] != src2[1]) || (src1[1] == src2[0] && src1[0] != src0[1]) ? src1[1] : src1[0];
1442 			dst2[0] = src1[-1] == src2[0] ? src1[-1] : src1[0];
1443 			dst2[1] = (src1[-1] == src2[0] && src1[0] != src2[1]) || (src1[1] == src2[0] && src1[0] != src2[-1]) ? src2[0] : src1[0];
1444 			dst2[2] = src1[1] == src2[0] ? src1[1] : src1[0];
1445 		} else {
1446 			dst0[0] = src1[0];
1447 			dst0[1] = src1[0];
1448 			dst0[2] = src1[0];
1449 			dst1[0] = src1[0];
1450 			dst1[1] = src1[0];
1451 			dst1[2] = src1[0];
1452 			dst2[0] = src1[0];
1453 			dst2[1] = src1[0];
1454 			dst2[2] = src1[0];
1455 		}
1456 
1457 		++src0;
1458 		++src1;
1459 		++src2;
1460 		dst0 += 3;
1461 		dst1 += 3;
1462 		dst2 += 3;
1463 		--count;
1464 	}
1465 
1466 	/* last pixel */
1467 	if (src0[0] != src2[0] && src1[-1] != src1[0]) {
1468 		dst0[0] = src1[-1] == src0[0] ? src1[-1] : src1[0];
1469 		dst0[1] = (src1[-1] == src0[0] && src1[0] != src0[0]) || (src1[0] == src0[0] && src1[0] != src0[-1]) ? src0[0] : src1[0];
1470 		dst0[2] = src1[0];
1471 		dst1[0] = (src1[-1] == src0[0] && src1[0] != src2[-1]) || (src1[-1] == src2[0] && src1[0] != src0[-1]) ? src1[-1] : src1[0];
1472 		dst1[1] = src1[0];
1473 		dst1[2] = (src1[0] == src0[0] && src1[0] != src2[0]) || (src1[0] == src2[0] && src1[0] != src0[0]) ? src1[0] : src1[0];
1474 		dst2[0] = src1[-1] == src2[0] ? src1[-1] : src1[0];
1475 		dst2[1] = (src1[-1] == src2[0] && src1[0] != src2[0]) || (src1[0] == src2[0] && src1[0] != src2[-1]) ? src2[0] : src1[0];
1476 		dst2[2] = src1[0];
1477 	} else {
1478 		dst0[0] = src1[0];
1479 		dst0[1] = src1[0];
1480 		dst0[2] = src1[0];
1481 		dst1[0] = src1[0];
1482 		dst1[1] = src1[0];
1483 		dst1[2] = src1[0];
1484 		dst2[0] = src1[0];
1485 		dst2[1] = src1[0];
1486 		dst2[2] = src1[0];
1487 	}
1488 }
1489 
1490 
1491 
Scale3x_ex6_5(unsigned char * srcPtr,DWORD srcPitch,unsigned char * dstPtr,int width,int height)1492 void Scale3x_ex6_5(unsigned char *srcPtr, DWORD srcPitch,
1493 				   unsigned char  *dstPtr, int width, int height)
1494 {
1495 	int count = height;
1496 	int dstPitch = srcPitch;
1497 
1498 	unsigned short  *dst0 = (unsigned short  *)dstPtr;
1499 	unsigned short  *dst1 = dst0 + dstPitch;
1500 	unsigned short  *dst2 = dst1 + dstPitch;
1501 
1502 	unsigned short  *src0 = (unsigned short  *)srcPtr;
1503 	unsigned short *src1 = src0 + (srcPitch >> 1);
1504 	unsigned short *src2 = src1 + (srcPitch >> 1);
1505 	scale3x_16_def_whole(dst0, dst1, dst2, src0, src1, src2, count);
1506 
1507 	count -= 2;
1508 	while(count) {
1509 
1510 		dst0 += dstPitch * 3;
1511 		dst1 += dstPitch * 3;
1512 		dst2 += dstPitch * 3;
1513 
1514 		scale3x_16_def_whole(dst0, dst1, dst2, src0, src1, src2, width);
1515 		src0 = src1;
1516 		src1 = src2;
1517 		src2 += srcPitch >> 1;
1518 		--count;
1519 	}
1520 	dst0 += dstPitch * 3;
1521 	dst1 += dstPitch * 3;
1522 	dst2 += dstPitch * 3;
1523 
1524 	scale3x_16_def_whole(dst0, dst1, dst2, src0, src1, src1, width);
1525 }
1526 
1527 ////////////////////////////////////////////////////////////////////////
1528 
1529 /*
1530 #define colorMask5     0x0000F7DE
1531 #define lowPixelMask5  0x00000821
1532 #define qcolorMask5    0x0000E79c
1533 #define qlowpixelMask5 0x00001863
1534 */
1535 
1536 #define colorMask5     0x00007BDE
1537 #define lowPixelMask5  0x00000421
1538 #define qcolorMask5    0x0000739c
1539 #define qlowpixelMask5 0x00000C63
1540 
1541 #define INTERPOLATE5(A, B) ((((A & colorMask5) >> 1) + ((B & colorMask5) >> 1) + (A & B & lowPixelMask5)))
1542 #define Q_INTERPOLATE5(A, B, C, D) (((((A & qcolorMask5) >> 2) + ((B & qcolorMask5) >> 2) + ((C & qcolorMask5) >> 2) + ((D & qcolorMask5) >> 2) \
1543 	+ ((((A & qlowpixelMask5) + (B & qlowpixelMask5) + (C & qlowpixelMask5) + (D & qlowpixelMask5)) >> 2) & qlowpixelMask5))))
1544 
Super2xSaI_ex5(unsigned char * srcPtr,DWORD srcPitch,unsigned char * dstBitmap,int width,int height)1545 void Super2xSaI_ex5(unsigned char *srcPtr, DWORD srcPitch,
1546 	            unsigned char  *dstBitmap, int width, int height)
1547 {
1548  DWORD dstPitch        = srcPitch<<1;
1549  int   finWidth        = srcPitch>>1;
1550  DWORD line;
1551  unsigned short *dP;
1552  unsigned short *bP;
1553  int iXA,iXB,iXC,iYA,iYB,iYC,finish;
1554  DWORD color4, color5, color6;
1555  DWORD color1, color2, color3;
1556  DWORD colorA0, colorA1, colorA2, colorA3,
1557        colorB0, colorB1, colorB2, colorB3,
1558        colorS1, colorS2;
1559  DWORD product1a, product1b,
1560        product2a, product2b;
1561 
1562  line = 0;
1563 
1564   {
1565    for (; height; height-=1)
1566 	{
1567      bP = (unsigned short *)srcPtr;
1568 	 dP = (unsigned short *)(dstBitmap + line*dstPitch);
1569      for (finish = width; finish; finish -= 1 )
1570       {
1571 //---------------------------------------    B1 B2
1572 //                                         4  5  6 S2
1573 //                                         1  2  3 S1
1574 //                                           A1 A2
1575        if(finish==finWidth) iXA=0;
1576        else                 iXA=1;
1577        if(finish>4) {iXB=1;iXC=2;}
1578        else
1579        if(finish>3) {iXB=1;iXC=1;}
1580        else         {iXB=0;iXC=0;}
1581        if(line==0) iYA=0;
1582        else        iYA=finWidth;
1583        if(height>4) {iYB=finWidth;iYC=srcPitch;}
1584        else
1585        if(height>3) {iYB=finWidth;iYC=finWidth;}
1586        else         {iYB=0;iYC=0;}
1587 
1588 
1589        colorB0 = *(bP- iYA - iXA);
1590        colorB1 = *(bP- iYA);
1591        colorB2 = *(bP- iYA + iXB);
1592        colorB3 = *(bP- iYA + iXC);
1593 
1594        color4 = *(bP  - iXA);
1595        color5 = *(bP);
1596        color6 = *(bP  + iXB);
1597        colorS2 = *(bP + iXC);
1598 
1599        color1 = *(bP  + iYB  - iXA);
1600        color2 = *(bP  + iYB);
1601        color3 = *(bP  + iYB  + iXB);
1602        colorS1= *(bP  + iYB  + iXC);
1603 
1604        colorA0 = *(bP + iYC - iXA);
1605        colorA1 = *(bP + iYC);
1606        colorA2 = *(bP + iYC + iXB);
1607        colorA3 = *(bP + iYC + iXC);
1608 
1609 //--------------------------------------
1610        if (color2 == color6 && color5 != color3)
1611         {
1612          product2b = product1b = color2;
1613         }
1614        else
1615        if (color5 == color3 && color2 != color6)
1616         {
1617          product2b = product1b = color5;
1618         }
1619        else
1620        if (color5 == color3 && color2 == color6)
1621         {
1622          register int r = 0;
1623 
1624          r += GET_RESULT ((color6), (color5), (color1),  (colorA1));
1625          r += GET_RESULT ((color6), (color5), (color4),  (colorB1));
1626          r += GET_RESULT ((color6), (color5), (colorA2), (colorS1));
1627          r += GET_RESULT ((color6), (color5), (colorB2), (colorS2));
1628 
1629          if (r > 0)
1630           product2b = product1b = color6;
1631          else
1632          if (r < 0)
1633           product2b = product1b = color5;
1634          else
1635           {
1636            product2b = product1b = INTERPOLATE5 (color5, color6);
1637           }
1638         }
1639        else
1640         {
1641          if (color6 == color3 && color3 == colorA1 && color2 != colorA2 && color3 != colorA0)
1642              product2b = Q_INTERPOLATE5 (color3, color3, color3, color2);
1643          else
1644          if (color5 == color2 && color2 == colorA2 && colorA1 != color3 && color2 != colorA3)
1645              product2b = Q_INTERPOLATE5 (color2, color2, color2, color3);
1646          else
1647              product2b = INTERPOLATE5 (color2, color3);
1648 
1649          if (color6 == color3 && color6 == colorB1 && color5 != colorB2 && color6 != colorB0)
1650              product1b = Q_INTERPOLATE5 (color6, color6, color6, color5);
1651          else
1652          if (color5 == color2 && color5 == colorB2 && colorB1 != color6 && color5 != colorB3)
1653              product1b = Q_INTERPOLATE5 (color6, color5, color5, color5);
1654          else
1655              product1b = INTERPOLATE5 (color5, color6);
1656         }
1657 
1658        if (color5 == color3 && color2 != color6 && color4 == color5 && color5 != colorA2)
1659         product2a = INTERPOLATE5 (color2, color5);
1660        else
1661        if (color5 == color1 && color6 == color5 && color4 != color2 && color5 != colorA0)
1662         product2a = INTERPOLATE5(color2, color5);
1663        else
1664         product2a = color2;
1665 
1666        if (color2 == color6 && color5 != color3 && color1 == color2 && color2 != colorB2)
1667         product1a = INTERPOLATE5(color2, color5);
1668        else
1669        if (color4 == color2 && color3 == color2 && color1 != color5 && color2 != colorB0)
1670         product1a = INTERPOLATE5(color2, color5);
1671        else
1672         product1a = color5;
1673 
1674        *dP=(unsigned short)product1a;
1675        *(dP+1)=(unsigned short)product1b;
1676        *(dP+(srcPitch))=(unsigned short)product2a;
1677        *(dP+1+(srcPitch))=(unsigned short)product2b;
1678 
1679        bP += 1;
1680        dP += 2;
1681       }//end of for ( finish= width etc..)
1682 
1683      line += 2;
1684      srcPtr += srcPitch;
1685 	}; //endof: for (; height; height--)
1686   }
1687 }
1688 
1689 ////////////////////////////////////////////////////////////////////////
1690 
Std2xSaI_ex5(unsigned char * srcPtr,DWORD srcPitch,unsigned char * dstBitmap,int width,int height)1691 void Std2xSaI_ex5(unsigned char *srcPtr, DWORD srcPitch,
1692 	              unsigned char  *dstBitmap, int width, int height)
1693 {
1694  DWORD dstPitch        = srcPitch<<1;
1695  int   finWidth        = srcPitch>>1;
1696  DWORD line;
1697  unsigned short *dP;
1698  unsigned short *bP;
1699  int iXA,iXB,iXC,iYA,iYB,iYC,finish;
1700  DWORD colorA, colorB;
1701  DWORD colorC, colorD,
1702        colorE, colorF, colorG, colorH,
1703        colorI, colorJ, colorK, colorL,
1704        colorM, colorN, colorO, colorP;
1705  DWORD product, product1, product2;
1706 
1707  line = 0;
1708 
1709   {
1710    for (; height; height-=1)
1711 	{
1712      bP = (unsigned short *)srcPtr;
1713 	 dP = (unsigned short *)(dstBitmap + line*dstPitch);
1714      for (finish = width; finish; finish -= 1 )
1715       {
1716 //---------------------------------------
1717 // Map of the pixels:                    I|E F|J
1718 //                                       G|A B|K
1719 //                                       H|C D|L
1720 //                                       M|N O|P
1721        if(finish==finWidth) iXA=0;
1722        else                 iXA=1;
1723        if(finish>4) {iXB=1;iXC=2;}
1724        else
1725        if(finish>3) {iXB=1;iXC=1;}
1726        else         {iXB=0;iXC=0;}
1727        if(line==0) iYA=0;
1728        else        iYA=finWidth;
1729        if(height>4) {iYB=finWidth;iYC=srcPitch;}
1730        else
1731        if(height>3) {iYB=finWidth;iYC=finWidth;}
1732        else         {iYB=0;iYC=0;}
1733 
1734        colorI = *(bP- iYA - iXA);
1735        colorE = *(bP- iYA);
1736        colorF = *(bP- iYA + iXB);
1737        colorJ = *(bP- iYA + iXC);
1738 
1739        colorG = *(bP  - iXA);
1740        colorA = *(bP);
1741        colorB = *(bP  + iXB);
1742        colorK = *(bP + iXC);
1743 
1744        colorH = *(bP  + iYB  - iXA);
1745        colorC = *(bP  + iYB);
1746        colorD = *(bP  + iYB  + iXB);
1747        colorL = *(bP  + iYB  + iXC);
1748 
1749        colorM = *(bP + iYC - iXA);
1750        colorN = *(bP + iYC);
1751        colorO = *(bP + iYC + iXB);
1752        colorP = *(bP + iYC + iXC);
1753 
1754        if((colorA == colorD) && (colorB != colorC))
1755         {
1756          if(((colorA == colorE) && (colorB == colorL)) ||
1757             ((colorA == colorC) && (colorA == colorF) &&
1758              (colorB != colorE) && (colorB == colorJ)))
1759           {
1760            product = colorA;
1761           }
1762          else
1763           {
1764            product = INTERPOLATE5(colorA, colorB);
1765           }
1766 
1767          if(((colorA == colorG) && (colorC == colorO)) ||
1768             ((colorA == colorB) && (colorA == colorH) &&
1769              (colorG != colorC) && (colorC == colorM)))
1770           {
1771            product1 = colorA;
1772           }
1773          else
1774           {
1775            product1 = INTERPOLATE5(colorA, colorC);
1776           }
1777          product2 = colorA;
1778         }
1779        else
1780        if((colorB == colorC) && (colorA != colorD))
1781         {
1782          if(((colorB == colorF) && (colorA == colorH)) ||
1783             ((colorB == colorE) && (colorB == colorD) &&
1784              (colorA != colorF) && (colorA == colorI)))
1785           {
1786            product = colorB;
1787           }
1788          else
1789           {
1790            product = INTERPOLATE5(colorA, colorB);
1791           }
1792 
1793          if(((colorC == colorH) && (colorA == colorF)) ||
1794             ((colorC == colorG) && (colorC == colorD) &&
1795              (colorA != colorH) && (colorA == colorI)))
1796           {
1797            product1 = colorC;
1798           }
1799          else
1800           {
1801            product1=INTERPOLATE5(colorA, colorC);
1802           }
1803          product2 = colorB;
1804         }
1805        else
1806        if((colorA == colorD) && (colorB == colorC))
1807         {
1808          if (colorA == colorB)
1809           {
1810            product = colorA;
1811            product1 = colorA;
1812            product2 = colorA;
1813           }
1814          else
1815           {
1816            register int r = 0;
1817            product1 = INTERPOLATE5(colorA, colorC);
1818            product = INTERPOLATE5(colorA, colorB);
1819 
1820            r += GetResult1 (colorA, colorB, colorG, colorE, colorI);
1821            r += GetResult2 (colorB, colorA, colorK, colorF, colorJ);
1822            r += GetResult2 (colorB, colorA, colorH, colorN, colorM);
1823            r += GetResult1 (colorA, colorB, colorL, colorO, colorP);
1824 
1825            if (r > 0)
1826             product2 = colorA;
1827            else
1828            if (r < 0)
1829             product2 = colorB;
1830            else
1831             {
1832              product2 = Q_INTERPOLATE5(colorA, colorB, colorC, colorD);
1833             }
1834           }
1835         }
1836        else
1837         {
1838          product2 = Q_INTERPOLATE5(colorA, colorB, colorC, colorD);
1839 
1840          if ((colorA == colorC) && (colorA == colorF) &&
1841              (colorB != colorE) && (colorB == colorJ))
1842           {
1843            product = colorA;
1844           }
1845          else
1846          if ((colorB == colorE) && (colorB == colorD) && (colorA != colorF) && (colorA == colorI))
1847           {
1848            product = colorB;
1849           }
1850          else
1851           {
1852            product = INTERPOLATE5(colorA, colorB);
1853           }
1854 
1855          if ((colorA == colorB) && (colorA == colorH) &&
1856              (colorG != colorC) && (colorC == colorM))
1857           {
1858            product1 = colorA;
1859           }
1860          else
1861          if ((colorC == colorG) && (colorC == colorD) &&
1862              (colorA != colorH) && (colorA == colorI))
1863           {
1864            product1 = colorC;
1865           }
1866          else
1867           {
1868            product1 = INTERPOLATE5(colorA, colorC);
1869           }
1870         }
1871 
1872        *dP=(unsigned short)colorA;
1873        *(dP+1)=(unsigned short)product;
1874        *(dP+(srcPitch))=(unsigned short)product1;
1875        *(dP+1+(srcPitch))=(unsigned short)product2;
1876 
1877        bP += 1;
1878        dP += 2;
1879       }//end of for ( finish= width etc..)
1880 
1881      line += 2;
1882      srcPtr += srcPitch;
1883 	}; //endof: for (; height; height--)
1884   }
1885 }
1886 
1887 ////////////////////////////////////////////////////////////////////////
1888 
SuperEagle_ex5(unsigned char * srcPtr,DWORD srcPitch,unsigned char * dstBitmap,int width,int height)1889 void SuperEagle_ex5(unsigned char *srcPtr, DWORD srcPitch,
1890 	            unsigned char  *dstBitmap, int width, int height)
1891 {
1892  DWORD dstPitch        = srcPitch<<1;
1893  int   finWidth        = srcPitch>>1;
1894  DWORD line;
1895  unsigned short *dP;
1896  unsigned short *bP;
1897  int iXA,iXB,iXC,iYA,iYB,iYC,finish;
1898  DWORD color4, color5, color6;
1899  DWORD color1, color2, color3;
1900  DWORD colorA1, colorA2,
1901        colorB1, colorB2,
1902        colorS1, colorS2;
1903  DWORD product1a, product1b,
1904        product2a, product2b;
1905 
1906  line = 0;
1907 
1908   {
1909    for (; height; height-=1)
1910 	{
1911      bP = (unsigned short *)srcPtr;
1912 	 dP = (unsigned short *)(dstBitmap + line*dstPitch);
1913      for (finish = width; finish; finish -= 1 )
1914       {
1915        if(finish==finWidth) iXA=0;
1916        else                 iXA=1;
1917        if(finish>4) {iXB=1;iXC=2;}
1918        else
1919        if(finish>3) {iXB=1;iXC=1;}
1920        else         {iXB=0;iXC=0;}
1921        if(line==0) iYA=0;
1922        else        iYA=finWidth;
1923        if(height>4) {iYB=finWidth;iYC=srcPitch;}
1924        else
1925        if(height>3) {iYB=finWidth;iYC=finWidth;}
1926        else         {iYB=0;iYC=0;}
1927 
1928        colorB1 = *(bP- iYA);
1929        colorB2 = *(bP- iYA + iXB);
1930 
1931        color4 = *(bP  - iXA);
1932        color5 = *(bP);
1933        color6 = *(bP  + iXB);
1934        colorS2 = *(bP + iXC);
1935 
1936        color1 = *(bP  + iYB  - iXA);
1937        color2 = *(bP  + iYB);
1938        color3 = *(bP  + iYB  + iXB);
1939        colorS1= *(bP  + iYB  + iXC);
1940 
1941        colorA1 = *(bP + iYC);
1942        colorA2 = *(bP + iYC + iXB);
1943 
1944        if(color2 == color6 && color5 != color3)
1945         {
1946          product1b = product2a = color2;
1947          if((color1 == color2) ||
1948             (color6 == colorB2))
1949           {
1950            product1a = INTERPOLATE5(color2, color5);
1951            product1a = INTERPOLATE5(color2, product1a);
1952           }
1953          else
1954           {
1955            product1a = INTERPOLATE5(color5, color6);
1956           }
1957 
1958          if((color6 == colorS2) ||
1959             (color2 == colorA1))
1960           {
1961            product2b = INTERPOLATE5(color2, color3);
1962            product2b = INTERPOLATE5(color2, product2b);
1963           }
1964          else
1965           {
1966            product2b = INTERPOLATE5(color2, color3);
1967           }
1968         }
1969        else
1970        if (color5 == color3 && color2 != color6)
1971         {
1972          product2b = product1a = color5;
1973 
1974          if ((colorB1 == color5) ||
1975              (color3 == colorS1))
1976           {
1977            product1b = INTERPOLATE5(color5, color6);
1978            product1b = INTERPOLATE5(color5, product1b);
1979           }
1980          else
1981           {
1982            product1b = INTERPOLATE5(color5, color6);
1983           }
1984 
1985          if ((color3 == colorA2) ||
1986              (color4 == color5))
1987           {
1988            product2a = INTERPOLATE5(color5, color2);
1989            product2a = INTERPOLATE5(color5, product2a);
1990           }
1991          else
1992           {
1993            product2a = INTERPOLATE5(color2, color3);
1994           }
1995         }
1996        else
1997        if (color5 == color3 && color2 == color6)
1998         {
1999          register int r = 0;
2000 
2001          r += GET_RESULT ((color6), (color5), (color1),  (colorA1));
2002          r += GET_RESULT ((color6), (color5), (color4),  (colorB1));
2003          r += GET_RESULT ((color6), (color5), (colorA2), (colorS1));
2004          r += GET_RESULT ((color6), (color5), (colorB2), (colorS2));
2005 
2006          if (r > 0)
2007           {
2008            product1b = product2a = color2;
2009            product1a = product2b = INTERPOLATE5(color5, color6);
2010           }
2011          else
2012          if (r < 0)
2013           {
2014            product2b = product1a = color5;
2015            product1b = product2a = INTERPOLATE5(color5, color6);
2016           }
2017          else
2018           {
2019            product2b = product1a = color5;
2020            product1b = product2a = color2;
2021           }
2022         }
2023        else
2024         {
2025          product2b = product1a = INTERPOLATE5(color2, color6);
2026          product2b = Q_INTERPOLATE5(color3, color3, color3, product2b);
2027          product1a = Q_INTERPOLATE5(color5, color5, color5, product1a);
2028 
2029          product2a = product1b = INTERPOLATE5(color5, color3);
2030          product2a = Q_INTERPOLATE5(color2, color2, color2, product2a);
2031          product1b = Q_INTERPOLATE5(color6, color6, color6, product1b);
2032         }
2033 
2034        *dP=(unsigned short)product1a;
2035        *(dP+1)=(unsigned short)product1b;
2036        *(dP+(srcPitch))=(unsigned short)product2a;
2037        *(dP+1+(srcPitch))=(unsigned short)product2b;
2038 
2039        bP += 1;
2040        dP += 2;
2041       }//end of for ( finish= width etc..)
2042 
2043      line += 2;
2044      srcPtr += srcPitch;
2045 	}; //endof: for (; height; height--)
2046   }
2047 }
2048 
2049 ////////////////////////////////////////////////////////////////////////
2050 // own swap buffer func (window/fullscreen)
2051 ////////////////////////////////////////////////////////////////////////
2052 
2053 sDX            DX;
2054 static DDSURFACEDESC       ddsd;
2055 GUID           guiDev;
2056 BOOL           bDeviceOK;
2057 HWND           hWGPU;
2058 int			   iSysMemory=0;
2059 int            iFPSEInterface=0;
2060 int			   iRefreshRate;
2061 BOOL		   bVsync=FALSE;
2062 BOOL		   bVsync_Key=FALSE;
2063 
2064 void (*BlitScreen) (unsigned char *,long,long);
2065 void (*pExtraBltFunc) (void);
2066 void (*p2XSaIFunc) (unsigned char *,DWORD,unsigned char *,int,int);
2067 
2068 ////////////////////////////////////////////////////////////////////////
2069 
WaitVBlank(void)2070 static __inline void WaitVBlank(void)
2071 {
2072  if(bVsync_Key)
2073   {
2074    IDirectDraw2_WaitForVerticalBlank(DX.DD,DDWAITVB_BLOCKBEGIN,0);
2075   }
2076 }
2077 
2078 ////////////////////////////////////////////////////////////////////////
2079 
BlitScreen32(unsigned char * surf,long x,long y)2080 void BlitScreen32(unsigned char * surf,long x,long y)  // BLIT IN 32bit COLOR MODE
2081 {
2082  unsigned char * pD;unsigned long lu;unsigned short s;
2083  unsigned int startxy;
2084  short row,column;
2085  short dx=(short)PreviousPSXDisplay.Range.x1;
2086  short dy=(short)PreviousPSXDisplay.DisplayMode.y;
2087 
2088  if(iDebugMode && iFVDisplay)
2089   {
2090    dx=1024;
2091    dy=iGPUHeight;
2092    x=0;y=0;
2093 
2094    for(column=0;column<dy;column++)
2095     {
2096      startxy=((1024)*(column+y))+x;
2097      for(row=0;row<dx;row++)
2098       {
2099        s=psxVuw[startxy++];
2100        *((unsigned long *)((surf)+(column*ddsd.lPitch)+row*4))=
2101         ((((s<<19)&0xf80000)|((s<<6)&0xf800)|((s>>7)&0xf8))&0xffffff)|0xff000000;
2102       }
2103     }
2104    return;
2105   }
2106 
2107 
2108  if(PreviousPSXDisplay.Range.y0)                       // centering needed?
2109   {
2110    surf+=PreviousPSXDisplay.Range.y0*ddsd.lPitch;
2111    dy-=PreviousPSXDisplay.Range.y0;
2112   }
2113 
2114  surf+=PreviousPSXDisplay.Range.x0<<2;
2115 
2116  if(PSXDisplay.RGB24)
2117   {
2118    if(iFPSEInterface)
2119     {
2120      for(column=0;column<dy;column++)
2121       {
2122        startxy=((1024)*(column+y))+x;
2123        pD=(unsigned char *)&psxVuw[startxy];
2124 
2125        for(row=0;row<dx;row++)
2126         {
2127          lu=*((unsigned long *)pD);
2128          *((unsigned long *)((surf)+(column*ddsd.lPitch)+row*4))=
2129             0xff000000|(BLUE(lu)<<16)|(GREEN(lu)<<8)|(RED(lu));
2130          pD+=3;
2131         }
2132       }
2133     }
2134    else
2135     {
2136      for(column=0;column<dy;column++)
2137       {
2138        startxy=((1024)*(column+y))+x;
2139        pD=(unsigned char *)&psxVuw[startxy];
2140 
2141        for(row=0;row<dx;row++)
2142         {
2143          lu=*((unsigned long *)pD);
2144          *((unsigned long *)((surf)+(column*ddsd.lPitch)+row*4))=
2145             0xff000000|(RED(lu)<<16)|(GREEN(lu)<<8)|(BLUE(lu));
2146          pD+=3;
2147         }
2148       }
2149     }
2150   }
2151  else
2152   {
2153    for(column=0;column<dy;column++)
2154     {
2155      startxy=((1024)*(column+y))+x;
2156      for(row=0;row<dx;row++)
2157       {
2158        s=psxVuw[startxy++];
2159        *((unsigned long *)((surf)+(column*ddsd.lPitch)+row*4))=
2160         ((((s<<19)&0xf80000)|((s<<6)&0xf800)|((s>>7)&0xf8))&0xffffff)|0xff000000;
2161       }
2162     }
2163   }
2164 }
2165 
2166 ////////////////////////////////////////////////////////////////////////
2167 
BlitScreen32_2xSaI(unsigned char * surf,long x,long y)2168 void BlitScreen32_2xSaI(unsigned char * surf,long x,long y)  // BLIT IN 32bit COLOR MODE
2169 {
2170  unsigned char * pD;unsigned long lu;unsigned short s;
2171  unsigned int startxy,off1,off2;
2172  short row,column;
2173  short dx=(short)PreviousPSXDisplay.Range.x1;
2174  short dy=(short)PreviousPSXDisplay.DisplayMode.y;
2175  unsigned char * pS=(unsigned char *)pSaISmallBuff;
2176  unsigned long * pS1, * pS2;
2177 
2178  if(PreviousPSXDisplay.DisplayMode.x>512)
2179   {BlitScreen32(surf,x,y);return;}
2180 
2181  if(PreviousPSXDisplay.Range.y0)                       // centering needed?
2182   {
2183    pS+=PreviousPSXDisplay.Range.y0*2048;
2184    dy-=PreviousPSXDisplay.Range.y0;
2185   }
2186 
2187  pS+=PreviousPSXDisplay.Range.x0<<2;
2188 
2189  if(PSXDisplay.RGB24)
2190   {
2191    if(iFPSEInterface)
2192     {
2193      for(column=0;column<dy;column++)
2194       {
2195        startxy=((1024)*(column+y))+x;
2196        pD=(unsigned char *)&psxVuw[startxy];
2197 
2198        for(row=0;row<dx;row++)
2199         {
2200          lu=*((unsigned long *)pD);
2201          *((unsigned long *)((pS)+(column*2048)+row*4))=
2202             0xff000000|(BLUE(lu)<<16)|(GREEN(lu)<<8)|(RED(lu));
2203          pD+=3;
2204         }
2205       }
2206     }
2207    else
2208     {
2209      for(column=0;column<dy;column++)
2210       {
2211        startxy=((1024)*(column+y))+x;
2212        pD=(unsigned char *)&psxVuw[startxy];
2213 
2214        for(row=0;row<dx;row++)
2215         {
2216          lu=*((unsigned long *)pD);
2217          *((unsigned long *)((pS)+(column*2048)+row*4))=
2218             0xff000000|(RED(lu)<<16)|(GREEN(lu)<<8)|(BLUE(lu));
2219          pD+=3;
2220         }
2221       }
2222     }
2223   }
2224  else
2225   {
2226    for(column=0;column<dy;column++)
2227     {
2228      startxy=((1024)*(column+y))+x;
2229      for(row=0;row<dx;row++)
2230       {
2231        s=psxVuw[startxy++];
2232        *((unsigned long *)((pS)+(column*2048)+row*4))=
2233         ((((s<<19)&0xf80000)|((s<<6)&0xf800)|((s>>7)&0xf8))&0xffffff)|0xff000000;
2234       }
2235     }
2236   }
2237 
2238  // ok, here we have filled pSaISmallBuff with PreviousPSXDisplay.DisplayMode.x * PreviousPSXDisplay.DisplayMode.y (*4) data
2239  // now do a 2xSai blit to pSaIBigBuff
2240 
2241  p2XSaIFunc((unsigned char *)pSaISmallBuff, 2048,
2242 	        (unsigned char *)pSaIBigBuff,
2243             PreviousPSXDisplay.DisplayMode.x,
2244             PreviousPSXDisplay.DisplayMode.y);
2245 
2246  // ok, here we have pSaIBigBuff filled with the 2xSai image...
2247  // now transfer it to the surface
2248 
2249  dx=(short)PreviousPSXDisplay.DisplayMode.x<<1;
2250  dy=(short)PreviousPSXDisplay.DisplayMode.y<<1;
2251  off1=(ddsd.lPitch>>2)-dx;
2252  off2=1024-dx;
2253 
2254  pS1=(unsigned long *)surf;
2255  pS2=(unsigned long *)pSaIBigBuff;
2256 
2257  for(column=0;column<dy;column++)
2258   {
2259    for(row=0;row<dx;row++)
2260     {
2261      *(pS1++)=*(pS2++);
2262     }
2263    pS1+=off1;
2264    pS2+=off2;
2265   }
2266 }
2267 
2268 ////////////////////////////////////////////////////////////////////////
2269 
2270 ///////////////////////////////////////////////////////////////////////
BlitScreen32_3xSaI(unsigned char * surf,long x,long y)2271 void BlitScreen32_3xSaI(unsigned char * surf,long x,long y)  // BLIT IN 32bit COLOR MODE
2272 {
2273 	unsigned char * pD;unsigned long lu;unsigned short s;
2274 	unsigned int startxy,off1,off2;
2275 	short row,column;
2276 	short dx=(short)PreviousPSXDisplay.Range.x1;
2277 	short dy=(short)PreviousPSXDisplay.DisplayMode.y;
2278 	unsigned char * pS=(unsigned char *)pSaISmallBuff;
2279 	unsigned long * pS1, * pS2;
2280 
2281 	if(PreviousPSXDisplay.DisplayMode.x>512)
2282 	{BlitScreen32(surf,x,y);return;}
2283 
2284 	if(PreviousPSXDisplay.Range.y0)                       // centering needed?
2285 	{
2286 		pS+=PreviousPSXDisplay.Range.y0*2048;
2287 		dy-=PreviousPSXDisplay.Range.y0;
2288 	}
2289 
2290 	pS+=PreviousPSXDisplay.Range.x0<<2;
2291 
2292 	if(PSXDisplay.RGB24)
2293 	{
2294 		if(iFPSEInterface)
2295 		{
2296 			for(column=0;column<dy;column++)
2297 			{
2298 				startxy=((1024)*(column+y))+x;
2299 				pD=(unsigned char *)&psxVuw[startxy];
2300 
2301 				for(row=0;row<dx;row++)
2302 				{
2303 					lu=*((unsigned long *)pD);
2304 					*((unsigned long *)((pS)+(column*2048)+row*4))=
2305 						0xff000000|(BLUE(lu)<<16)|(GREEN(lu)<<8)|(RED(lu));
2306 					pD+=3;
2307 				}
2308 			}
2309 		}
2310 		else
2311 		{
2312 			for(column=0;column<dy;column++)
2313 			{
2314 				startxy=((1024)*(column+y))+x;
2315 				pD=(unsigned char *)&psxVuw[startxy];
2316 
2317 				for(row=0;row<dx;row++)
2318 				{
2319 					lu=*((unsigned long *)pD);
2320 					*((unsigned long *)((pS)+(column*2048)+row*4))=
2321 						0xff000000|(RED(lu)<<16)|(GREEN(lu)<<8)|(BLUE(lu));
2322 					pD+=3;
2323 				}
2324 			}
2325 		}
2326 	}
2327 	else
2328 	{
2329 		for(column=0;column<dy;column++)
2330 		{
2331 			startxy=((1024)*(column+y))+x;
2332 			for(row=0;row<dx;row++)
2333 			{
2334 				s=psxVuw[startxy++];
2335 				*((unsigned long *)((pS)+(column*2048)+row*4))=
2336 					((((s<<19)&0xf80000)|((s<<6)&0xf800)|((s>>7)&0xf8))&0xffffff)|0xff000000;
2337 			}
2338 		}
2339 	}
2340 
2341 	// ok, here we have filled pSaISmallBuff with PreviousPSXDisplay.DisplayMode.x * PreviousPSXDisplay.DisplayMode.y (*4) data
2342 	// now do a 2xSai blit to pSaIBigBuff
2343 
2344 	p2XSaIFunc((unsigned char *)pSaISmallBuff, 2048,
2345 		(unsigned char *)pSaIBigBuff,
2346 		PreviousPSXDisplay.DisplayMode.x,
2347 		PreviousPSXDisplay.DisplayMode.y);
2348 
2349 	// ok, here we have pSaIBigBuff filled with the 2xSai image...
2350 	// now transfer it to the surface
2351 	//CHANGED << 1 to * 3
2352 
2353 	dx=(short)PreviousPSXDisplay.DisplayMode.x * 3;
2354 	dy=(short)PreviousPSXDisplay.DisplayMode.y * 3;
2355 
2356 	off1=(ddsd.lPitch>>2)-dx;
2357 	off2=1024-dx;
2358 
2359 	pS1=(unsigned long *)surf;
2360 	pS2=(unsigned long *)pSaIBigBuff;
2361 
2362 	for(column=0;column<dy;column++)
2363 	{
2364 		for(row=0;row<dx;row++)
2365 		{
2366 			*(pS1++)=*(pS2++);
2367 		}
2368 		pS1+=off1;
2369 		pS2+=off2;
2370 	}
2371 }
2372 //////////////////////////////////////////////////////////////////////
BlitScreen16(unsigned char * surf,long x,long y)2373 void BlitScreen16(unsigned char * surf,long x,long y)  // BLIT IN 16bit COLOR MODE
2374 {
2375  unsigned long lu;
2376  unsigned short row,column;
2377  unsigned short dx=(unsigned short)PreviousPSXDisplay.Range.x1;
2378  unsigned short dy=(unsigned short)PreviousPSXDisplay.DisplayMode.y;
2379 
2380  if(iDebugMode && iFVDisplay)
2381   {
2382    unsigned short LineOffset,SurfOffset;
2383    unsigned long * SRCPtr;
2384    unsigned long * DSTPtr;
2385 
2386    dx=1024;
2387    dy=iGPUHeight;
2388    x=0;y=0;
2389 
2390    SRCPtr = (unsigned long *)(psxVuw);
2391    DSTPtr = ((unsigned long *)surf);
2392 
2393    dx>>=1;
2394 
2395    LineOffset = 512 - dx;
2396    SurfOffset = (ddsd.lPitch>>2) - dx;
2397 
2398    for(column=0;column<dy;column++)
2399     {
2400      for(row=0;row<dx;row++)
2401       {
2402        lu=*SRCPtr++;
2403 
2404        *DSTPtr++=
2405         ((lu<<11)&0xf800f800)|((lu<<1)&0x7c007c0)|((lu>>10)&0x1f001f);
2406       }
2407      SRCPtr += LineOffset;
2408      DSTPtr += SurfOffset;
2409     }
2410    return;
2411   }
2412 
2413  if(PreviousPSXDisplay.Range.y0)                       // centering needed?
2414   {
2415    surf+=PreviousPSXDisplay.Range.y0*ddsd.lPitch;
2416    dy-=PreviousPSXDisplay.Range.y0;
2417   }
2418 
2419  if(PSXDisplay.RGB24)
2420   {
2421    unsigned char * pD;unsigned int startxy;
2422 
2423    surf+=PreviousPSXDisplay.Range.x0<<1;
2424 
2425    if(iFPSEInterface)
2426     {
2427      for(column=0;column<dy;column++)
2428       {
2429        startxy=((1024)*(column+y))+x;
2430 
2431        pD=(unsigned char *)&psxVuw[startxy];
2432 
2433        for(row=0;row<dx;row++)
2434         {
2435          lu=*((unsigned long *)pD);
2436          *((unsigned short *)((surf)+(column*ddsd.lPitch)+(row<<1)))=
2437            (unsigned short)(((BLUE(lu)<<8)&0xf800)|((GREEN(lu)<<3)&0x7e0)|(RED(lu)>>3));
2438           pD+=3;
2439         }
2440       }
2441     }
2442    else
2443     {
2444      for(column=0;column<dy;column++)
2445       {
2446        startxy=((1024)*(column+y))+x;
2447 
2448        pD=(unsigned char *)&psxVuw[startxy];
2449 
2450        for(row=0;row<dx;row++)
2451         {
2452          lu=*((unsigned long *)pD);
2453          *((unsigned short *)((surf)+(column*ddsd.lPitch)+(row<<1)))=
2454            (unsigned short)(((RED(lu)<<8)&0xf800)|((GREEN(lu)<<3)&0x7e0)|(BLUE(lu)>>3));
2455           pD+=3;
2456         }
2457       }
2458     }
2459   }
2460  else
2461   {
2462    unsigned short LineOffset,SurfOffset;
2463    unsigned long * SRCPtr = (unsigned long *)(psxVuw +
2464                              (y<<10) + x);
2465    unsigned long * DSTPtr =
2466     ((unsigned long *)surf)+(PreviousPSXDisplay.Range.x0>>1);
2467 
2468    dx>>=1;
2469 
2470    LineOffset = 512 - dx;
2471    SurfOffset = (ddsd.lPitch>>2) - dx;
2472 
2473    for(column=0;column<dy;column++)
2474     {
2475      for(row=0;row<dx;row++)
2476       {
2477        lu=*SRCPtr++;
2478 
2479        *DSTPtr++=
2480         ((lu<<11)&0xf800f800)|((lu<<1)&0x7c007c0)|((lu>>10)&0x1f001f);
2481       }
2482      SRCPtr += LineOffset;
2483      DSTPtr += SurfOffset;
2484     }
2485   }
2486 }
2487 
2488 ////////////////////////////////////////////////////////////////////////
2489 
BlitScreen16_2xSaI(unsigned char * surf,long x,long y)2490 void BlitScreen16_2xSaI(unsigned char * surf,long x,long y)  // BLIT IN 16bit COLOR MODE
2491 {
2492  unsigned long lu;
2493  unsigned short row,column,off1,off2;
2494  unsigned short dx=(unsigned short)PreviousPSXDisplay.Range.x1;
2495  unsigned short dy=(unsigned short)PreviousPSXDisplay.DisplayMode.y;
2496  unsigned char * pS=(unsigned char *)pSaISmallBuff;
2497  unsigned long * pS1, * pS2;
2498 
2499  if(PreviousPSXDisplay.DisplayMode.x>512)
2500   {BlitScreen16(surf,x,y);return;}
2501 
2502  if(PreviousPSXDisplay.Range.y0)                       // centering needed?
2503   {
2504    pS+=PreviousPSXDisplay.Range.y0*1024;
2505    dy-=PreviousPSXDisplay.Range.y0;
2506   }
2507 
2508  if(PSXDisplay.RGB24)
2509   {
2510    unsigned char * pD;unsigned int startxy;
2511 
2512    pS+=PreviousPSXDisplay.Range.x0<<1;
2513 
2514    if(iFPSEInterface)
2515     {
2516      for(column=0;column<dy;column++)
2517       {
2518        startxy=((1024)*(column+y))+x;
2519 
2520        pD=(unsigned char *)&psxVuw[startxy];
2521 
2522        for(row=0;row<dx;row++)
2523         {
2524          lu=*((unsigned long *)pD);
2525          *((unsigned short *)((pS)+(column*1024)+(row<<1)))=
2526            (unsigned short)(((BLUE(lu)<<8)&0xf800)|((GREEN(lu)<<3)&0x7e0)|(RED(lu)>>3));
2527           pD+=3;
2528         }
2529       }
2530     }
2531    else
2532     {
2533      for(column=0;column<dy;column++)
2534       {
2535        startxy=((1024)*(column+y))+x;
2536 
2537        pD=(unsigned char *)&psxVuw[startxy];
2538 
2539        for(row=0;row<dx;row++)
2540         {
2541          lu=*((unsigned long *)pD);
2542          *((unsigned short *)((pS)+(column*1024)+(row<<1)))=
2543            (unsigned short)(((RED(lu)<<8)&0xf800)|((GREEN(lu)<<3)&0x7e0)|(BLUE(lu)>>3));
2544           pD+=3;
2545         }
2546       }
2547     }
2548   }
2549  else
2550   {
2551    unsigned short LineOffset,SurfOffset;
2552    unsigned long * SRCPtr = (unsigned long *)(psxVuw +
2553                              (y<<10) + x);
2554    unsigned long * DSTPtr =
2555     ((unsigned long *)pS)+(PreviousPSXDisplay.Range.x0>>1);
2556 
2557    dx>>=1;
2558 
2559    LineOffset = 512 - dx;
2560    SurfOffset = 256 - dx;
2561 
2562    for(column=0;column<dy;column++)
2563     {
2564      for(row=0;row<dx;row++)
2565       {
2566        lu=*SRCPtr++;
2567 
2568        *DSTPtr++=
2569         ((lu<<11)&0xf800f800)|((lu<<1)&0x7c007c0)|((lu>>10)&0x1f001f);
2570       }
2571      SRCPtr += LineOffset;
2572      DSTPtr += SurfOffset;
2573     }
2574   }
2575 
2576  // ok, here we have filled pSaISmallBuff with PreviousPSXDisplay.DisplayMode.x * PreviousPSXDisplay.DisplayMode.y (*4) data
2577  // now do a 2xSai blit to pSaIBigBuff
2578 
2579  p2XSaIFunc((unsigned char *)pSaISmallBuff, 1024,
2580 	        (unsigned char *)pSaIBigBuff,
2581             PreviousPSXDisplay.DisplayMode.x,
2582             PreviousPSXDisplay.DisplayMode.y);
2583 
2584  // ok, here we have pSaIBigBuff filled with the 2xSai image...
2585  // now transfer it to the surface
2586 
2587  dx=(short)PreviousPSXDisplay.DisplayMode.x;
2588  dy=(short)PreviousPSXDisplay.DisplayMode.y<<1;
2589  off1=(ddsd.lPitch>>2)-dx;
2590  off2=512-dx;
2591 
2592  pS1=(unsigned long *)surf;
2593  pS2=(unsigned long *)pSaIBigBuff;
2594 
2595  for(column=0;column<dy;column++)
2596   {
2597    for(row=0;row<dx;row++)
2598     {
2599      *(pS1++)=*(pS2++);
2600     }
2601    pS1+=off1;
2602    pS2+=off2;
2603   }
2604 }
2605 
BlitScreen16_3xSaI(unsigned char * surf,long x,long y)2606 void BlitScreen16_3xSaI(unsigned char * surf,long x,long y)  // BLIT IN 16bit COLOR MODE
2607 {
2608 	unsigned long lu;
2609 	unsigned short row,column,off1,off2;
2610 	unsigned short dx=(unsigned short)PreviousPSXDisplay.Range.x1;
2611 	unsigned short dy=(unsigned short)PreviousPSXDisplay.DisplayMode.y;
2612 	unsigned char * pS=(unsigned char *)pSaISmallBuff;
2613 	unsigned long * pS1, * pS2;
2614 
2615 	if(PreviousPSXDisplay.DisplayMode.x>512)
2616 	{BlitScreen16(surf,x,y);return;}
2617 
2618 	if(PreviousPSXDisplay.Range.y0)                       // centering needed?
2619 	{
2620 		pS+=PreviousPSXDisplay.Range.y0*1024;
2621 		dy-=PreviousPSXDisplay.Range.y0;
2622 	}
2623 
2624 	if(PSXDisplay.RGB24)
2625 	{
2626 		unsigned char * pD;unsigned int startxy;
2627 
2628 		pS+=PreviousPSXDisplay.Range.x0<<1;
2629 
2630 		if(iFPSEInterface)
2631 		{
2632 			for(column=0;column<dy;column++)
2633 			{
2634 				startxy=((1024)*(column+y))+x;
2635 
2636 				pD=(unsigned char *)&psxVuw[startxy];
2637 
2638 				for(row=0;row<dx;row++)
2639 				{
2640 					lu=*((unsigned long *)pD);
2641 					*((unsigned short *)((pS)+(column*1024)+(row<<1)))=
2642 						(unsigned short)(((BLUE(lu)<<8)&0xf800)|((GREEN(lu)<<3)&0x7e0)|(RED(lu)>>3));
2643 					pD+=3;
2644 				}
2645 			}
2646 		}
2647 		else
2648 		{
2649 			for(column=0;column<dy;column++)
2650 			{
2651 				startxy=((1024)*(column+y))+x;
2652 
2653 				pD=(unsigned char *)&psxVuw[startxy];
2654 
2655 				for(row=0;row<dx;row++)
2656 				{
2657 					lu=*((unsigned long *)pD);
2658 					*((unsigned short *)((pS)+(column*1024)+(row<<1)))=
2659 						(unsigned short)(((RED(lu)<<8)&0xf800)|((GREEN(lu)<<3)&0x7e0)|(BLUE(lu)>>3));
2660 					pD+=3;
2661 				}
2662 			}
2663 		}
2664 	}
2665 	else
2666 	{
2667 		unsigned short LineOffset,SurfOffset;
2668 		unsigned long * SRCPtr = (unsigned long *)(psxVuw +
2669 			(y<<10) + x);
2670 		unsigned long * DSTPtr =
2671 			((unsigned long *)pS)+(PreviousPSXDisplay.Range.x0>>1);
2672 
2673 		dx>>=1;
2674 
2675 		LineOffset = 512 - dx;
2676 		SurfOffset = 256 - dx;
2677 
2678 		for(column=0;column<dy;column++)
2679 		{
2680 			for(row=0;row<dx;row++)
2681 			{
2682 				lu=*SRCPtr++;
2683 
2684 				*DSTPtr++=
2685 					((lu<<11)&0xf800f800)|((lu<<1)&0x7c007c0)|((lu>>10)&0x1f001f);
2686 			}
2687 			SRCPtr += LineOffset;
2688 			DSTPtr += SurfOffset;
2689 		}
2690 	}
2691 
2692 	// ok, here we have filled pSaISmallBuff with PreviousPSXDisplay.DisplayMode.x * PreviousPSXDisplay.DisplayMode.y (*4) data
2693 	// now do a 2xSai blit to pSaIBigBuff
2694 
2695 	p2XSaIFunc((unsigned char *)pSaISmallBuff, 1024,
2696 		(unsigned char *)pSaIBigBuff,
2697 		PreviousPSXDisplay.DisplayMode.x,
2698 		PreviousPSXDisplay.DisplayMode.y);
2699 
2700 	// ok, here we have pSaIBigBuff filled with the 2xSai image...
2701 	// now transfer it to the surface
2702 
2703 	dx=(short)(PreviousPSXDisplay.DisplayMode.x * 1.5);
2704 	dy=(short)PreviousPSXDisplay.DisplayMode.y*3;
2705 	off1=(ddsd.lPitch>>2)-dx;
2706 	off2=512-dx;
2707 
2708 	pS1=(unsigned long *)surf;
2709 	pS2=(unsigned long *)pSaIBigBuff;
2710 
2711 	for(column=0;column<dy;column++)
2712 	{
2713 		for(row=0;row<dx;row++)
2714 		{
2715 			*(pS1++)=*(pS2++);
2716 		}
2717 		pS1+=off1;
2718 		pS2+=off2;
2719 	}
2720 }
2721 
2722 ////////////////////////////////////////////////////////////////////////
2723 
BlitScreen15(unsigned char * surf,long x,long y)2724 void BlitScreen15(unsigned char * surf,long x,long y)  // BLIT IN 16bit COLOR MODE
2725 {
2726  unsigned long lu;
2727  unsigned short row,column;
2728  unsigned short dx=(unsigned short)PreviousPSXDisplay.Range.x1;
2729  unsigned short dy=(unsigned short)PreviousPSXDisplay.DisplayMode.y;
2730 
2731  if(PreviousPSXDisplay.Range.y0)                       // centering needed?
2732   {
2733    surf+=PreviousPSXDisplay.Range.y0*ddsd.lPitch;
2734    dy-=PreviousPSXDisplay.Range.y0;
2735   }
2736 
2737  if(PSXDisplay.RGB24)
2738   {
2739    unsigned char * pD;unsigned int startxy;
2740 
2741    surf+=PreviousPSXDisplay.Range.x0<<1;
2742 
2743    if(iFPSEInterface)
2744     {
2745      for(column=0;column<dy;column++)
2746       {
2747        startxy=((1024)*(column+y))+x;
2748 
2749        pD=(unsigned char *)&psxVuw[startxy];
2750 
2751        for(row=0;row<dx;row++)
2752         {
2753          lu=*((unsigned long *)pD);
2754          *((unsigned short *)((surf)+(column*ddsd.lPitch)+(row<<1)))=
2755           (unsigned short)
2756            (((BLUE(lu)<<7)&0x7c00)|
2757             ((GREEN(lu)<<2)&0x3e0)|
2758             (RED(lu)>>3));
2759          pD+=3;
2760         }
2761       }
2762     }
2763    else
2764     {
2765      for(column=0;column<dy;column++)
2766       {
2767        startxy=((1024)*(column+y))+x;
2768 
2769        pD=(unsigned char *)&psxVuw[startxy];
2770 
2771        for(row=0;row<dx;row++)
2772         {
2773          lu=*((unsigned long *)pD);
2774          *((unsigned short *)((surf)+(column*ddsd.lPitch)+(row<<1)))=
2775           (unsigned short)
2776            (((RED(lu)<<7)&0x7c00)|
2777             ((GREEN(lu)<<2)&0x3e0)|
2778             (BLUE(lu)>>3));
2779          pD+=3;
2780         }
2781       }
2782     }
2783   }
2784  else
2785   {
2786    unsigned short LineOffset,SurfOffset;
2787    unsigned long * SRCPtr = (unsigned long *)(psxVuw +
2788                              (y<<10) + x);
2789 
2790    unsigned long * DSTPtr =
2791     ((unsigned long *)surf)+(PreviousPSXDisplay.Range.x0>>1);
2792 
2793    dx>>=1;
2794 
2795    LineOffset = 512 - dx;
2796    SurfOffset = (ddsd.lPitch>>2) - dx;
2797 
2798    for(column=0;column<dy;column++)
2799     {
2800      for(row=0;row<dx;row++)
2801       {
2802        lu=*SRCPtr++;
2803 
2804        *DSTPtr++=
2805         ((lu<<10)&0x7c007c00)|
2806         ((lu)&0x3e003e0)|
2807         ((lu>>10)&0x1f001f);
2808       }
2809      SRCPtr += LineOffset;
2810      DSTPtr += SurfOffset;
2811     }
2812   }
2813 }
2814 
2815 ////////////////////////////////////////////////////////////////////////
2816 
BlitScreen15_2xSaI(unsigned char * surf,long x,long y)2817 void BlitScreen15_2xSaI(unsigned char * surf,long x,long y)  // BLIT IN 16bit COLOR MODE
2818 {
2819  unsigned long lu;
2820  unsigned short row,column,off1,off2;
2821  unsigned short dx=(unsigned short)PreviousPSXDisplay.Range.x1;
2822  unsigned short dy=(unsigned short)PreviousPSXDisplay.DisplayMode.y;
2823  unsigned char * pS=(unsigned char *)pSaISmallBuff;
2824  unsigned long * pS1, * pS2;
2825 
2826  if(PreviousPSXDisplay.DisplayMode.x>512)
2827   {BlitScreen15(surf,x,y);return;}
2828 
2829  if(PreviousPSXDisplay.Range.y0)                       // centering needed?
2830   {
2831    pS+=PreviousPSXDisplay.Range.y0*1024;
2832    dy-=PreviousPSXDisplay.Range.y0;
2833   }
2834 
2835  if(PSXDisplay.RGB24)
2836   {
2837    unsigned char * pD;unsigned int startxy;
2838 
2839    pS+=PreviousPSXDisplay.Range.x0<<1;
2840 
2841    if(iFPSEInterface)
2842     {
2843      for(column=0;column<dy;column++)
2844       {
2845        startxy=((1024)*(column+y))+x;
2846 
2847        pD=(unsigned char *)&psxVuw[startxy];
2848 
2849        for(row=0;row<dx;row++)
2850         {
2851          lu=*((unsigned long *)pD);
2852          *((unsigned short *)((pS)+(column*1024)+(row<<1)))=
2853           (unsigned short)
2854            (((BLUE(lu)<<7)&0x7c00)|
2855             ((GREEN(lu)<<2)&0x3e0)|
2856             (RED(lu)>>3));
2857          pD+=3;
2858         }
2859       }
2860     }
2861    else
2862     {
2863      for(column=0;column<dy;column++)
2864       {
2865        startxy=((1024)*(column+y))+x;
2866 
2867        pD=(unsigned char *)&psxVuw[startxy];
2868 
2869        for(row=0;row<dx;row++)
2870         {
2871          lu=*((unsigned long *)pD);
2872          *((unsigned short *)((pS)+(column*1024)+(row<<1)))=
2873           (unsigned short)
2874            (((RED(lu)<<7)&0x7c00)|
2875             ((GREEN(lu)<<2)&0x3e0)|
2876             (BLUE(lu)>>3));
2877          pD+=3;
2878         }
2879       }
2880     }
2881   }
2882  else
2883   {
2884    unsigned short LineOffset,SurfOffset;
2885    unsigned long * SRCPtr = (unsigned long *)(psxVuw +
2886                              (y<<10) + x);
2887    unsigned long * DSTPtr =
2888     ((unsigned long *)pS)+(PreviousPSXDisplay.Range.x0>>1);
2889 
2890    dx>>=1;
2891 
2892    LineOffset = 512 - dx;
2893    SurfOffset = 256 - dx;
2894 
2895    for(column=0;column<dy;column++)
2896     {
2897      for(row=0;row<dx;row++)
2898       {
2899        lu=*SRCPtr++;
2900 
2901        *DSTPtr++=
2902         ((lu<<10)&0x7c007c00)|
2903         ((lu)&0x3e003e0)|
2904         ((lu>>10)&0x1f001f);
2905       }
2906      SRCPtr += LineOffset;
2907      DSTPtr += SurfOffset;
2908     }
2909   }
2910 
2911  // ok, here we have filled pSaISmallBuff with PreviousPSXDisplay.DisplayMode.x * PreviousPSXDisplay.DisplayMode.y (*4) data
2912  // now do a 2xSai blit to pSaIBigBuff
2913 
2914  p2XSaIFunc((unsigned char *)pSaISmallBuff, 1024,
2915 	        (unsigned char *)pSaIBigBuff,
2916             PreviousPSXDisplay.DisplayMode.x,
2917             PreviousPSXDisplay.DisplayMode.y);
2918 
2919  // ok, here we have pSaIBigBuff filled with the 2xSai image...
2920  // now transfer it to the surface
2921 
2922  dx=(short)PreviousPSXDisplay.DisplayMode.x;
2923  dy=(short)PreviousPSXDisplay.DisplayMode.y<<1;
2924  off1=(ddsd.lPitch>>2)-dx;
2925  off2=512-dx;
2926 
2927  pS1=(unsigned long *)surf;
2928  pS2=(unsigned long *)pSaIBigBuff;
2929 
2930  for(column=0;column<dy;column++)
2931   {
2932    for(row=0;row<dx;row++)
2933     {
2934      *(pS1++)=*(pS2++);
2935     }
2936    pS1+=off1;
2937    pS2+=off2;
2938   }
2939 }
2940 
2941 ////////////////////////////////////////////////////////////////////////
2942 
DoClearScreenBuffer(void)2943 void DoClearScreenBuffer(void)                         // CLEAR DX BUFFER
2944 {
2945  DDBLTFX     ddbltfx;
2946 
2947  ddbltfx.dwSize = sizeof(ddbltfx);
2948  ddbltfx.dwFillColor = 0x00000000;
2949 
2950  IDirectDrawSurface_Blt(DX.DDSRender,NULL,NULL,NULL,DDBLT_COLORFILL,&ddbltfx);
2951 
2952  if(iUseNoStretchBlt>=3)
2953   {
2954    if(pSaISmallBuff) memset(pSaISmallBuff,0,512*512*4);
2955   }
2956 }
2957 
2958 ////////////////////////////////////////////////////////////////////////
2959 
DoClearFrontBuffer(void)2960 void DoClearFrontBuffer(void)                         // CLEAR PRIMARY BUFFER
2961 {
2962  DDBLTFX     ddbltfx;
2963 
2964  ddbltfx.dwSize = sizeof(ddbltfx);
2965  ddbltfx.dwFillColor = 0x00000000;
2966 
2967  IDirectDrawSurface_Blt(DX.DDSPrimary,NULL,NULL,NULL,DDBLT_COLORFILL,&ddbltfx);
2968 }
2969 
2970 ////////////////////////////////////////////////////////////////////////
2971 
NoStretchedBlit(void)2972 void NoStretchedBlit(void)
2973 {
2974  static int iOldDX=0;
2975  static int iOldDY=0;
2976 
2977  int iDX,iDY;
2978  int iX=iResX-PreviousPSXDisplay.DisplayMode.x;
2979  int iY=iResY-PreviousPSXDisplay.DisplayMode.y;
2980 
2981 /*
2982 float fXS,fYS,fS;
2983 fXS=(float)iResX/(float)PreviousPSXDisplay.DisplayMode.x;
2984 fYS=(float)iResY/(float)PreviousPSXDisplay.DisplayMode.y;
2985 if(fXS<fYS) fS=fXS; else fS=fYS;
2986 */
2987 
2988  if(iX<0) {iX=0;iDX=iResX;}
2989  else     {iX=iX/2;iDX=PreviousPSXDisplay.DisplayMode.x;}
2990 
2991  if(iY<0) {iY=0;iDY=iResY;}
2992  else     {iY=iY/2;iDY=PreviousPSXDisplay.DisplayMode.y;}
2993 
2994  if(iOldDX!=iDX || iOldDY!=iDY)
2995   {
2996    DDBLTFX     ddbltfx;
2997    ddbltfx.dwSize = sizeof(ddbltfx);
2998    ddbltfx.dwFillColor = 0x00000000;
2999    IDirectDrawSurface_Blt(DX.DDSPrimary,NULL,NULL,NULL,DDBLT_COLORFILL,&ddbltfx);
3000    iOldDX=iDX;iOldDY=iDY;
3001   }
3002 
3003  if(iWindowMode)
3004   {
3005    RECT ScreenRect,ViewportRect;
3006    POINT Point={0,0};
3007    ClientToScreen(DX.hWnd,&Point);
3008    Point.x+=iX;Point.y+=iY;
3009 
3010    ScreenRect.left     = Point.x;
3011    ScreenRect.top      = Point.y;
3012    ScreenRect.right    = iDX+Point.x;
3013    ScreenRect.bottom   = iDY+Point.y;
3014 
3015    ViewportRect.left   = 0;
3016    ViewportRect.top    = 0;
3017    ViewportRect.right  = iDX;
3018    ViewportRect.bottom = iDY;
3019 
3020    WaitVBlank();
3021    IDirectDrawSurface_Blt(DX.DDSPrimary,&ScreenRect,DX.DDSRender,&ViewportRect,
3022                           DDBLT_WAIT,NULL);
3023   }
3024  else
3025   {
3026    RECT ScreenRect,ViewportRect;
3027 
3028    ScreenRect.left     = iX;
3029    ScreenRect.top      = iY;
3030    ScreenRect.right    = iDX+iX;
3031    ScreenRect.bottom   = iDY+iY;
3032 
3033    ViewportRect.left   = 0;
3034    ViewportRect.top    = 0;
3035    ViewportRect.right  = iDX;
3036    ViewportRect.bottom = iDY;
3037 
3038    WaitVBlank();
3039    IDirectDrawSurface_Blt(DX.DDSPrimary,&ScreenRect,DX.DDSRender,&ViewportRect,
3040                           DDBLT_WAIT,NULL);
3041   }
3042  if(DX.DDSScreenPic) DisplayPic();
3043 }
3044 
3045 ////////////////////////////////////////////////////////////////////////
3046 
NoStretchedBlitEx(void)3047 void NoStretchedBlitEx(void)
3048 {
3049  static int iOldDX=0;
3050  static int iOldDY=0;
3051 
3052  int iDX,iDY,iX,iY;float fXS,fYS,fS;
3053 
3054  if(!PreviousPSXDisplay.DisplayMode.x) return;
3055  if(!PreviousPSXDisplay.DisplayMode.y) return;
3056 
3057  fXS=(float)iResX/(float)PreviousPSXDisplay.DisplayMode.x;
3058  fYS=(float)iResY/(float)PreviousPSXDisplay.DisplayMode.y;
3059  if(fXS<fYS) fS=fXS; else fS=fYS;
3060 
3061  iDX=(int)(PreviousPSXDisplay.DisplayMode.x*fS);
3062  iDY=(int)(PreviousPSXDisplay.DisplayMode.y*fS);
3063 
3064  iX=iResX-iDX;
3065  iY=iResY-iDY;
3066 
3067  if(iX<0) iX=0;
3068  else     iX=iX/2;
3069 
3070  if(iY<0) iY=0;
3071  else     iY=iY/2;
3072 
3073  if(iOldDX!=iDX || iOldDY!=iDY)
3074   {
3075    DDBLTFX     ddbltfx;
3076    ddbltfx.dwSize = sizeof(ddbltfx);
3077    ddbltfx.dwFillColor = 0x00000000;
3078    IDirectDrawSurface_Blt(DX.DDSPrimary,NULL,NULL,NULL,DDBLT_COLORFILL,&ddbltfx);
3079    iOldDX=iDX;iOldDY=iDY;
3080   }
3081 
3082  if(iWindowMode)
3083   {
3084    RECT ScreenRect,ViewportRect;
3085    POINT Point={0,0};
3086    ClientToScreen(DX.hWnd,&Point);
3087    Point.x+=iX;Point.y+=iY;
3088 
3089    ScreenRect.left     = Point.x;
3090    ScreenRect.top      = Point.y;
3091    ScreenRect.right    = iDX+Point.x;
3092    ScreenRect.bottom   = iDY+Point.y;
3093 
3094    ViewportRect.left   = 0;
3095    ViewportRect.top    = 0;
3096    ViewportRect.right  = PreviousPSXDisplay.DisplayMode.x;
3097    ViewportRect.bottom = PreviousPSXDisplay.DisplayMode.y;
3098 
3099    WaitVBlank();
3100    IDirectDrawSurface_Blt(DX.DDSPrimary,&ScreenRect,DX.DDSRender,&ViewportRect,
3101                           DDBLT_WAIT,NULL);
3102   }
3103  else
3104   {
3105    RECT ScreenRect,ViewportRect;
3106 
3107    ScreenRect.left     = iX;
3108    ScreenRect.top      = iY;
3109    ScreenRect.right    = iDX+iX;
3110    ScreenRect.bottom   = iDY+iY;
3111 
3112    ViewportRect.left   = 0;
3113    ViewportRect.top    = 0;
3114    ViewportRect.right  = PreviousPSXDisplay.DisplayMode.x;
3115    ViewportRect.bottom = PreviousPSXDisplay.DisplayMode.y;
3116 
3117    WaitVBlank();
3118    IDirectDrawSurface_Blt(DX.DDSPrimary,&ScreenRect,DX.DDSRender,&ViewportRect,
3119                           DDBLT_WAIT,NULL);
3120   }
3121  if(DX.DDSScreenPic) DisplayPic();
3122 }
3123 
3124 ////////////////////////////////////////////////////////////////////////
3125 
StretchedBlit2x(void)3126 void StretchedBlit2x(void)
3127 {
3128  if(iWindowMode)
3129   {
3130    RECT ScreenRect,ViewportRect;
3131    POINT Point={0,0};
3132    ClientToScreen(DX.hWnd,&Point);
3133 
3134    ScreenRect.left     = Point.x;
3135    ScreenRect.top      = Point.y;
3136    ScreenRect.right    = iResX+Point.x;
3137    ScreenRect.bottom   = iResY+Point.y;
3138 
3139    ViewportRect.left   = 0;
3140    ViewportRect.top    = 0;
3141    ViewportRect.right  = PreviousPSXDisplay.DisplayMode.x;
3142    ViewportRect.bottom = PreviousPSXDisplay.DisplayMode.y;
3143 
3144    if(ViewportRect.right<=512)
3145     {
3146      ViewportRect.right+=ViewportRect.right;
3147      ViewportRect.bottom+=ViewportRect.bottom;
3148     }
3149 
3150    if(iUseScanLines==2)                                // stupid nvidia scanline mode
3151     {
3152      RECT HelperRect={0,0,iResX,iResY};
3153 
3154      WaitVBlank();
3155 
3156      IDirectDrawSurface_Blt(DX.DDSHelper,&HelperRect,DX.DDSRender,&ViewportRect,
3157                             DDBLT_WAIT,NULL);
3158      IDirectDrawSurface_Blt(DX.DDSPrimary,&ScreenRect,DX.DDSHelper,&HelperRect,
3159                             DDBLT_WAIT,NULL);
3160     }
3161    else
3162     {
3163      WaitVBlank();
3164      IDirectDrawSurface_Blt(DX.DDSPrimary,&ScreenRect,DX.DDSRender,&ViewportRect,
3165                            DDBLT_WAIT,NULL);
3166     }
3167   }
3168  else
3169   {
3170    RECT ScreenRect={0,0,iResX,iResY},
3171         ViewportRect={0,0,PreviousPSXDisplay.DisplayMode.x,
3172                           PreviousPSXDisplay.DisplayMode.y};
3173 
3174    if(ViewportRect.right<=512)
3175     {
3176      ViewportRect.right+=ViewportRect.right;
3177      ViewportRect.bottom+=ViewportRect.bottom;
3178     }
3179 
3180    if(iUseScanLines==2)                                // stupid nvidia scanline mode
3181     {
3182      WaitVBlank();
3183 
3184      IDirectDrawSurface_Blt(DX.DDSHelper,&ScreenRect,DX.DDSRender,&ViewportRect,
3185                             DDBLT_WAIT,NULL);
3186      IDirectDrawSurface_Blt(DX.DDSPrimary,&ScreenRect,DX.DDSHelper,&ScreenRect,
3187                             DDBLT_WAIT,NULL);
3188     }
3189    else
3190     {
3191      WaitVBlank();
3192      IDirectDrawSurface_Blt(DX.DDSPrimary,&ScreenRect,DX.DDSRender,&ViewportRect,
3193                             DDBLT_WAIT,NULL );
3194     }
3195   }
3196 
3197  if(DX.DDSScreenPic) DisplayPic();
3198 
3199 }
3200 
3201 ////////////////////////////////////////////////////////////////////////
3202 
NoStretchedBlit2x(void)3203 void NoStretchedBlit2x(void)
3204 {
3205  static int iOldDX=0;
3206  static int iOldDY=0;
3207 
3208  int iX,iY,iDX,iDY;
3209  int iDX2=PreviousPSXDisplay.DisplayMode.x;
3210  int iDY2=PreviousPSXDisplay.DisplayMode.y;
3211  if(PreviousPSXDisplay.DisplayMode.x<=512)
3212   {
3213    iDX2<<=1;
3214    iDY2<<=1;
3215   }
3216 
3217  iX=iResX-iDX2;
3218  iY=iResY-iDY2;
3219 
3220  if(iX<0) {iX=0;iDX=iResX;}
3221  else     {iX=iX/2;iDX=iDX2;}
3222 
3223  if(iY<0) {iY=0;iDY=iResY;}
3224  else     {iY=iY/2;iDY=iDY2;}
3225 
3226  if(iOldDX!=iDX || iOldDY!=iDY)
3227   {
3228    DDBLTFX     ddbltfx;
3229    ddbltfx.dwSize = sizeof(ddbltfx);
3230    ddbltfx.dwFillColor = 0x00000000;
3231    IDirectDrawSurface_Blt(DX.DDSPrimary,NULL,NULL,NULL,DDBLT_COLORFILL,&ddbltfx);
3232    iOldDX=iDX;iOldDY=iDY;
3233   }
3234 
3235  if(iWindowMode)
3236   {
3237    RECT ScreenRect,ViewportRect;
3238    POINT Point={0,0};
3239    ClientToScreen(DX.hWnd,&Point);
3240    Point.x+=iX;Point.y+=iY;
3241 
3242    ScreenRect.left     = Point.x;
3243    ScreenRect.top      = Point.y;
3244    ScreenRect.right    = iDX+Point.x;
3245    ScreenRect.bottom   = iDY+Point.y;
3246 
3247    ViewportRect.left   = 0;
3248    ViewportRect.top    = 0;
3249    ViewportRect.right  = iDX;
3250    ViewportRect.bottom = iDY;
3251 
3252    WaitVBlank();
3253    IDirectDrawSurface_Blt(DX.DDSPrimary,&ScreenRect,DX.DDSRender,&ViewportRect,
3254                           DDBLT_WAIT,NULL);
3255   }
3256  else
3257   {
3258    RECT ScreenRect,ViewportRect;
3259 
3260    ScreenRect.left     = iX;
3261    ScreenRect.top      = iY;
3262    ScreenRect.right    = iDX+iX;
3263    ScreenRect.bottom   = iDY+iY;
3264 
3265    ViewportRect.left   = 0;
3266    ViewportRect.top    = 0;
3267    ViewportRect.right  = iDX;
3268    ViewportRect.bottom = iDY;
3269 
3270    WaitVBlank();
3271    IDirectDrawSurface_Blt(DX.DDSPrimary,&ScreenRect,DX.DDSRender,&ViewportRect,
3272                           DDBLT_WAIT,NULL);
3273   }
3274  if(DX.DDSScreenPic) DisplayPic();
3275 }
3276 
3277 ////////////////////////////////////////////////////////////////////////
NoStretchedBlit3x(void)3278 void NoStretchedBlit3x(void)
3279 {
3280 	static int iOldDX=0;
3281 	static int iOldDY=0;
3282 
3283 	int iX,iY,iDX,iDY;
3284 	int iDX2=PreviousPSXDisplay.DisplayMode.x;
3285 	int iDY2=PreviousPSXDisplay.DisplayMode.y;
3286 
3287 	if(PreviousPSXDisplay.DisplayMode.x<=512)
3288 	{
3289 		iDX2*=3;
3290 		iDY2*=3;
3291 	}
3292 
3293 	iX=iResX-iDX2;
3294 	iY=iResY-iDY2;
3295 
3296 	if(iX<0) {iX=0;iDX=iResX;}
3297 	else     {iX=iX/2;iDX=iDX2;}
3298 
3299 	if(iY<0) {iY=0;iDY=iResY;}
3300 	else     {iY=iY/2;iDY=iDY2;}
3301 
3302 	if(iOldDX!=iDX || iOldDY!=iDY)
3303 	{
3304 		DDBLTFX     ddbltfx;
3305 		ddbltfx.dwSize = sizeof(ddbltfx);
3306 		ddbltfx.dwFillColor = 0x00000000;
3307 		IDirectDrawSurface_Blt(DX.DDSPrimary,NULL,NULL,NULL,DDBLT_COLORFILL,&ddbltfx);
3308 		iOldDX=iDX;iOldDY=iDY;
3309 	}
3310 
3311 	if(iWindowMode)
3312 	{
3313 		RECT ScreenRect,ViewportRect;
3314 		POINT Point={0,0};
3315 		ClientToScreen(DX.hWnd,&Point);
3316 		Point.x+=iX;Point.y+=iY;
3317 
3318 		ScreenRect.left     = Point.x;
3319 		ScreenRect.top      = Point.y;
3320 		ScreenRect.right    = iDX+Point.x;
3321 		ScreenRect.bottom   = iDY+Point.y;
3322 
3323 		ViewportRect.left   = 0;
3324 		ViewportRect.top    = 0;
3325 		ViewportRect.right  = iDX;
3326 		ViewportRect.bottom = iDY;
3327 
3328 		WaitVBlank();
3329 		IDirectDrawSurface_Blt(DX.DDSPrimary,&ScreenRect,DX.DDSRender,&ViewportRect,
3330 			DDBLT_WAIT,NULL);
3331 	}
3332 	else
3333 	{
3334 		RECT ScreenRect,ViewportRect;
3335 
3336 		ScreenRect.left     = iX;
3337 		ScreenRect.top      = iY;
3338 		ScreenRect.right	   = iDX+iX;
3339 		ScreenRect.bottom   = iDY+iY;
3340 
3341 		ViewportRect.left   = 0;
3342 		ViewportRect.top    = 0;
3343 		ViewportRect.right  = iDX;
3344 		ViewportRect.bottom = iDY;
3345 
3346 		WaitVBlank();
3347 		IDirectDrawSurface_Blt(DX.DDSPrimary,&ScreenRect,DX.DDSRender,&ViewportRect,
3348 			DDBLT_WAIT,NULL);
3349 	}
3350 	if(DX.DDSScreenPic) DisplayPic();
3351 }
3352 
3353 
3354 ////////////////////////////////////////////////////////////////////////
3355 ////////////////////////////////////////////////////////////////////////
3356 
ShowGunCursor(unsigned char * surf)3357 void ShowGunCursor(unsigned char * surf)
3358 {
3359  unsigned short dx=(unsigned short)PreviousPSXDisplay.Range.x1;
3360  unsigned short dy=(unsigned short)PreviousPSXDisplay.DisplayMode.y;
3361  int x,y,iPlayer,sx,ex,sy,ey;
3362 
3363  if(PreviousPSXDisplay.Range.y0)                       // centering needed?
3364   {
3365    surf+=PreviousPSXDisplay.Range.y0*ddsd.lPitch;
3366    dy-=PreviousPSXDisplay.Range.y0;
3367   }
3368 
3369  if(iUseNoStretchBlt>=3 &&iUseNoStretchBlt < 13)                               // 2xsai is twice as big, of course
3370   {dx*=2;dy*=2;}
3371  else if(iUseNoStretchBlt >= 13)
3372   {dx*=3;dy*=3;}
3373 
3374  if(iDesktopCol==32)                                   // 32 bit color depth
3375   {
3376    const unsigned long crCursorColor32[8]={0xffff0000,0xff00ff00,0xff0000ff,0xffff00ff,0xffffff00,0xff00ffff,0xffffffff,0xff7f7f7f};
3377 
3378    surf+=PreviousPSXDisplay.Range.x0<<2;               // -> add x left border
3379 
3380    for(iPlayer=0;iPlayer<8;iPlayer++)                  // -> loop all possible players
3381     {
3382      if(usCursorActive&(1<<iPlayer))                   // -> player active?
3383       {
3384        const int ty=(ptCursorPoint[iPlayer].y*dy)/256;  // -> calculate the cursor pos in the current display
3385        const int tx=(ptCursorPoint[iPlayer].x*dx)/512;
3386        sx=tx-5;if(sx<0) {if(sx&1) sx=1; else sx=0;}
3387        sy=ty-5;if(sy<0) {if(sy&1) sy=1; else sy=0;}
3388        ex=tx+6;if(ex>dx) ex=dx;
3389        ey=ty+6;if(ey>dy) ey=dy;
3390 
3391        for(x=tx,y=sy;y<ey;y+=2)                    // -> do dotted y line
3392         *((unsigned long *)((surf)+(y*ddsd.lPitch)+x*4))=crCursorColor32[iPlayer];
3393        for(y=ty,x=sx;x<ex;x+=2)                    // -> do dotted x line
3394         *((unsigned long *)((surf)+(y*ddsd.lPitch)+x*4))=crCursorColor32[iPlayer];
3395       }
3396     }
3397   }
3398  else                                                  // 16 bit color depth
3399   {
3400    const unsigned short crCursorColor16[8]={0xf800,0x07c0,0x001f,0xf81f,0xffc0,0x07ff,0xffff,0x7bdf};
3401 
3402    surf+=PreviousPSXDisplay.Range.x0<<1;               // -> same stuff as above
3403 
3404    for(iPlayer=0;iPlayer<8;iPlayer++)
3405     {
3406      if(usCursorActive&(1<<iPlayer))
3407       {
3408        const int ty=(ptCursorPoint[iPlayer].y*dy)/256;
3409        const int tx=(ptCursorPoint[iPlayer].x*dx)/512;
3410        sx=tx-5;if(sx<0) {if(sx&1) sx=1; else sx=0;}
3411        sy=ty-5;if(sy<0) {if(sy&1) sy=1; else sy=0;}
3412        ex=tx+6;if(ex>dx) ex=dx;
3413        ey=ty+6;if(ey>dy) ey=dy;
3414 
3415        for(x=tx,y=sy;y<ey;y+=2)
3416         *((unsigned short *)((surf)+(y*ddsd.lPitch)+x*2))=crCursorColor16[iPlayer];
3417        for(y=ty,x=sx;x<ex;x+=2)
3418         *((unsigned short *)((surf)+(y*ddsd.lPitch)+x*2))=crCursorColor16[iPlayer];
3419       }
3420     }
3421   }
3422 }
3423 
3424 ////////////////////////////////////////////////////////////////////////
3425 
DoBufferSwap(void)3426 void DoBufferSwap(void)                                // SWAP BUFFERS
3427 {                                                      // (we don't swap... we blit only)
3428  HRESULT ddrval;long x,y;
3429 
3430  ddrval=IDirectDrawSurface_Lock(DX.DDSRender,NULL, &ddsd, DDLOCK_WAIT|DDLOCK_WRITEONLY, NULL);
3431 
3432  if(ddrval==DDERR_SURFACELOST)
3433   {
3434    IDirectDrawSurface_Restore(DX.DDSRender);
3435   }
3436 
3437  if(ddrval!=DD_OK)
3438   {
3439    IDirectDrawSurface_Unlock(DX.DDSRender,&ddsd);
3440    return;
3441   }
3442 
3443  //----------------------------------------------------//
3444 
3445  x=PSXDisplay.DisplayPosition.x;
3446  y=PSXDisplay.DisplayPosition.y;
3447 
3448  //----------------------------------------------------//
3449 
3450  BlitScreen((unsigned char *)ddsd.lpSurface,x,y);      // fill DDSRender surface
3451 
3452  if(usCursorActive) ShowGunCursor((unsigned char *)ddsd.lpSurface);
3453 
3454  IDirectDrawSurface_Unlock(DX.DDSRender,&ddsd);
3455 
3456  if(ulKeybits&KEY_SHOWFPS) DisplayText();              // paint menu text
3457 
3458  if(pExtraBltFunc) {pExtraBltFunc();return;}
3459 
3460  if(iWindowMode)
3461   {
3462    RECT ScreenRect,ViewportRect;
3463    POINT Point={0,0};
3464    ClientToScreen(DX.hWnd,&Point);
3465 
3466    ScreenRect.left     = Point.x;
3467    ScreenRect.top      = Point.y;
3468    ScreenRect.right    = iResX+Point.x;
3469    ScreenRect.bottom   = iResY+Point.y;
3470 
3471    ViewportRect.left   = 0;
3472    ViewportRect.top    = 0;
3473 
3474    if(iDebugMode)
3475     {
3476      if(iFVDisplay)
3477       {
3478        ViewportRect.right  = 1024;
3479        ViewportRect.bottom = iGPUHeight;
3480       }
3481      else
3482       {
3483        ViewportRect.right  = PreviousPSXDisplay.DisplayMode.x;
3484        ViewportRect.bottom = PreviousPSXDisplay.DisplayMode.y;
3485       }
3486     }
3487    else
3488     {
3489      ViewportRect.right  = PreviousPSXDisplay.DisplayMode.x;
3490      ViewportRect.bottom = PreviousPSXDisplay.DisplayMode.y;
3491 
3492      if(iRumbleTime)
3493       {
3494        ScreenRect.left+=((rand()*iRumbleVal)/RAND_MAX)-(iRumbleVal/2);
3495        ScreenRect.right+=((rand()*iRumbleVal)/RAND_MAX)-(iRumbleVal/2);
3496        ScreenRect.top+=((rand()*iRumbleVal)/RAND_MAX)-(iRumbleVal/2);
3497        ScreenRect.bottom+=((rand()*iRumbleVal)/RAND_MAX)-(iRumbleVal/2);
3498        iRumbleTime--;
3499       }
3500     }
3501 
3502    if(iUseScanLines==2)                                // stupid nvidia scanline mode
3503     {
3504      RECT HelperRect={0,0,iResX,iResY};
3505 
3506      WaitVBlank();
3507 
3508      IDirectDrawSurface_Blt(DX.DDSHelper,&HelperRect,DX.DDSRender,&ViewportRect,
3509                             DDBLT_WAIT,NULL);
3510      IDirectDrawSurface_Blt(DX.DDSPrimary,&ScreenRect,DX.DDSHelper,&HelperRect,
3511                             DDBLT_WAIT,NULL);
3512     }
3513    else
3514     {
3515      WaitVBlank();
3516      IDirectDrawSurface_Blt(DX.DDSPrimary,&ScreenRect,DX.DDSRender,&ViewportRect,
3517                            DDBLT_WAIT,NULL);
3518     }
3519   }
3520  else
3521   {
3522    RECT ScreenRect={0,0,iResX,iResY},
3523         ViewportRect={0,0,PreviousPSXDisplay.DisplayMode.x,
3524                           PreviousPSXDisplay.DisplayMode.y};
3525 
3526    if(iDebugMode && iFVDisplay)
3527     {
3528      ViewportRect.right=1024;
3529      ViewportRect.bottom=iGPUHeight;
3530     }
3531    else
3532     {
3533      if(iRumbleTime)
3534       {
3535        ScreenRect.left+=((rand()*iRumbleVal)/RAND_MAX)-(iRumbleVal/2);
3536        ScreenRect.right+=((rand()*iRumbleVal)/RAND_MAX)-(iRumbleVal/2);
3537        ScreenRect.top+=((rand()*iRumbleVal)/RAND_MAX)-(iRumbleVal/2);
3538        ScreenRect.bottom+=((rand()*iRumbleVal)/RAND_MAX)-(iRumbleVal/2);
3539        iRumbleTime--;
3540       }
3541     }
3542 
3543    if(iUseScanLines==2)                                // stupid nvidia scanline mode
3544     {
3545      WaitVBlank();
3546 
3547      IDirectDrawSurface_Blt(DX.DDSHelper,&ScreenRect,DX.DDSRender,&ViewportRect,
3548                             DDBLT_WAIT,NULL);
3549      IDirectDrawSurface_Blt(DX.DDSPrimary,&ScreenRect,DX.DDSHelper,&ScreenRect,
3550                             DDBLT_WAIT,NULL);
3551     }
3552    else
3553     {
3554      WaitVBlank();
3555      IDirectDrawSurface_Blt(DX.DDSPrimary,&ScreenRect,DX.DDSRender,&ViewportRect,
3556                             DDBLT_WAIT,NULL );
3557     }
3558   }
3559 
3560  if(DX.DDSScreenPic) DisplayPic();
3561 }
3562 
3563 ////////////////////////////////////////////////////////////////////////
3564 // GAMMA
3565 ////////////////////////////////////////////////////////////////////////
3566 
3567 int iUseGammaVal=2048;
3568 
DXSetGamma(void)3569 void DXSetGamma(void)
3570 {
3571  float g;
3572  if(iUseGammaVal==2048) return;
3573 
3574  g=(float)iUseGammaVal;
3575  if(g>512) g=((g-512)*2)+512;
3576  g=0.5f+((g)/1024.0f);
3577 
3578 // some cards will cheat... so we don't trust the caps here
3579 // if (DD_Caps.dwCaps2 & DDCAPS2_PRIMARYGAMMA)
3580   {
3581    float f;DDGAMMARAMP ramp;int i;
3582    LPDIRECTDRAWGAMMACONTROL DD_Gamma = NULL;
3583 
3584    if FAILED(IDirectDrawSurface_QueryInterface(DX.DDSPrimary,&IID_IDirectDrawGammaControl,(void**)&DD_Gamma))
3585     return;
3586 
3587    for (i=0;i<256;i++)
3588     {
3589      f=(((float)(i*256))*g);
3590      if(f>65535) f=65535;
3591      ramp.red[i]=ramp.green[i]=ramp.blue[i]=(WORD)f;
3592     }
3593 
3594    IDirectDrawGammaControl_SetGammaRamp(DD_Gamma,0,&ramp);
3595    IDirectDrawGammaControl_Release(DD_Gamma);
3596   }
3597 }
3598 
3599 ////////////////////////////////////////////////////////////////////////
3600 // SCAN LINE STUFF
3601 ////////////////////////////////////////////////////////////////////////
3602 
SetScanLineList(LPDIRECTDRAWCLIPPER Clipper)3603 void SetScanLineList(LPDIRECTDRAWCLIPPER Clipper)
3604 {
3605  LPRGNDATA lpCL;RECT * pr;int y;POINT Point={0,0};
3606 
3607  IDirectDrawClipper_SetClipList(Clipper,NULL,0);
3608 
3609  lpCL=(LPRGNDATA)malloc(sizeof(RGNDATAHEADER)+((iResY/2)+1)*sizeof(RECT));
3610  if(iWindowMode) ClientToScreen(DX.hWnd,&Point);
3611 
3612  lpCL->rdh.dwSize=sizeof(RGNDATAHEADER);
3613  lpCL->rdh.iType=RDH_RECTANGLES;
3614  lpCL->rdh.nCount=iResY/2;
3615  lpCL->rdh.nRgnSize=0;
3616  lpCL->rdh.rcBound.left=Point.x;
3617  lpCL->rdh.rcBound.top=Point.y;
3618  lpCL->rdh.rcBound.bottom=Point.y+iResY;
3619  lpCL->rdh.rcBound.right=Point.x+iResX;
3620 
3621  pr=(RECT *)lpCL->Buffer;
3622  for(y=0;y<iResY;y+=2)
3623   {
3624    pr->left=Point.x;
3625    pr->top=Point.y+y;
3626    pr->right=Point.x+iResX;
3627    pr->bottom=Point.y+y+1;
3628    pr++;
3629   }
3630 
3631  IDirectDrawClipper_SetClipList(Clipper,lpCL,0);
3632 
3633  free(lpCL);
3634 }
3635 
3636 ////////////////////////////////////////////////////////////////////////
3637 
MoveScanLineArea(HWND hwnd)3638 void MoveScanLineArea(HWND hwnd)
3639 {
3640  LPDIRECTDRAWCLIPPER Clipper;HRESULT h;
3641  DDBLTFX ddbltfx;RECT r;
3642 
3643  if(FAILED(h=IDirectDraw_CreateClipper(DX.DD,0,&Clipper,NULL)))
3644   return;
3645 
3646  IDirectDrawSurface_SetClipper(DX.DDSPrimary,NULL);
3647 
3648  ddbltfx.dwSize = sizeof(ddbltfx);
3649  ddbltfx.dwFillColor = 0x00000000;
3650 
3651  GetClientRect(hwnd,&r);
3652  ClientToScreen(hwnd,(LPPOINT)&r.left);
3653  r.right+=r.left;
3654  r.bottom+=r.top;
3655 
3656  IDirectDrawSurface_Blt(DX.DDSPrimary,&r,NULL,NULL,DDBLT_COLORFILL,&ddbltfx);
3657 
3658  SetScanLineList(Clipper);
3659 
3660  IDirectDrawSurface_SetClipper(DX.DDSPrimary,Clipper);
3661  IDirectDrawClipper_Release(Clipper);
3662 }
3663 
3664 ////////////////////////////////////////////////////////////////////////
3665 // MAIN DIRECT DRAW INIT
3666 ////////////////////////////////////////////////////////////////////////
3667 
3668 BOOL ReStart=FALSE;
3669 
DXinitialize()3670 int DXinitialize()
3671 {
3672  LPDIRECTDRAW DD;int i;
3673  LPDIRECTDRAWCLIPPER Clipper;HRESULT h;
3674  GUID FAR * guid=0;
3675  unsigned char * c;
3676  DDSCAPS ddscaps;
3677  DDBLTFX ddbltfx;
3678  DDPIXELFORMAT dd;
3679  HRESULT (WINAPI *pDDrawCreateFn)(GUID *,LPDIRECTDRAW *,IUnknown *);
3680 
3681  // init some DX vars
3682  DX.hWnd = (HWND)hWGPU;
3683  DX.DDSHelper=0;
3684  DX.DDSScreenPic=0;
3685 
3686  // make guid !
3687  c=(unsigned char *)&guiDev;
3688  for(i=0;i<sizeof(GUID);i++,c++)
3689   {if(*c) {guid=&guiDev;break;}}
3690 
3691  pDDrawCreateFn = (LPVOID)GetProcAddress( hDDrawDLL, "DirectDrawCreate" );
3692 
3693  // create dd
3694  if(pDDrawCreateFn == NULL || pDDrawCreateFn(guid,&DD,0))
3695   {
3696    MessageBox(NULL, "This GPU requires DirectX!", "Error", MB_OK);
3697    return 0;
3698   }
3699 
3700  DX.DD=DD;
3701 
3702  //////////////////////////////////////////////////////// co-op level
3703 
3704  if(iWindowMode)                                       // win mode?
3705   {
3706    if(IDirectDraw_SetCooperativeLevel(DX.DD,DX.hWnd,DDSCL_NORMAL))
3707     return 0;
3708   }
3709  else
3710   {
3711    if(ReStart)
3712     {
3713      if(IDirectDraw_SetCooperativeLevel(DX.DD,DX.hWnd, DDSCL_NORMAL | DDSCL_FULLSCREEN | DDSCL_FPUSETUP))
3714       return 0;
3715     }
3716    else
3717     {
3718      if(IDirectDraw_SetCooperativeLevel(DX.DD,DX.hWnd, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN | DDSCL_FPUSETUP))
3719       return 0;
3720     }
3721 
3722    if(iRefreshRate)
3723     {
3724      LPDIRECTDRAW2 DD2;
3725      IDirectDraw_QueryInterface(DX.DD,&IID_IDirectDraw2,(LPVOID *)&DD2);
3726      if(IDirectDraw2_SetDisplayMode(DD2,iResX,iResY,iColDepth,iRefreshRate,0))
3727       return 0;
3728     }
3729    else
3730     {
3731      if(IDirectDraw_SetDisplayMode(DX.DD,iResX,iResY,iColDepth))
3732       return 0;
3733     }
3734   }
3735 
3736  //////////////////////////////////////////////////////// main surfaces
3737 
3738  memset(&ddsd, 0, sizeof(DDSURFACEDESC));
3739  memset(&ddscaps, 0, sizeof(DDSCAPS));
3740  ddsd.dwSize = sizeof(DDSURFACEDESC);
3741 
3742  ddsd.dwFlags = DDSD_CAPS;                             // front buffer
3743 
3744  if(iSysMemory)
3745   ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_SYSTEMMEMORY;
3746  else
3747   ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_VIDEOMEMORY;
3748 
3749  //ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;//|DDSCAPS_VIDEOMEMORY;
3750  if(IDirectDraw_CreateSurface(DX.DD,&ddsd, &DX.DDSPrimary, NULL))
3751   return 0;
3752 
3753  //----------------------------------------------------//
3754  if(iSysMemory && iUseScanLines==2) iUseScanLines=1;   // pete: nvidia hack not needed on system mem
3755 
3756  if(iUseScanLines==2)                                  // special nvidia hack
3757   {
3758    memset(&ddsd, 0, sizeof(DDSURFACEDESC));
3759    ddsd.dwSize = sizeof(DDSURFACEDESC);
3760    ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS;
3761    ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
3762    ddsd.dwWidth        = iResX;
3763    ddsd.dwHeight       = iResY;
3764 
3765    if(IDirectDraw_CreateSurface(DX.DD,&ddsd, &DX.DDSHelper, NULL))
3766     return 0;
3767   }
3768  //----------------------------------------------------//
3769 
3770  memset(&ddsd, 0, sizeof(DDSURFACEDESC));              // back buffer
3771  ddsd.dwSize = sizeof(DDSURFACEDESC);
3772  ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS;
3773 // ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;//|DDSCAPS_VIDEOMEMORY;
3774  if(iSysMemory)
3775   ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;
3776  else
3777   ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY;
3778 
3779  if(iDebugMode || iUseNoStretchBlt>=3)
3780       ddsd.dwWidth        = 1024;
3781  else ddsd.dwWidth        = 640;
3782 
3783  if(iUseNoStretchBlt>=3)
3784       ddsd.dwHeight       = 1024;
3785  else
3786   {
3787    if(iDebugMode) ddsd.dwHeight = iGPUHeight;
3788    else           ddsd.dwHeight = 512;
3789   }
3790 
3791  if(IDirectDraw_CreateSurface(DX.DD,&ddsd, &DX.DDSRender, NULL))
3792   return 0;
3793 
3794  // check for desktop color depth
3795  dd.dwSize=sizeof(DDPIXELFORMAT);
3796  IDirectDrawSurface_GetPixelFormat(DX.DDSRender,&dd);
3797 
3798  if(dd.dwRBitMask==0x00007c00 &&
3799     dd.dwGBitMask==0x000003e0 &&
3800     dd.dwBBitMask==0x0000001f)
3801   {
3802    if(iUseNoStretchBlt>=3)
3803         BlitScreen=BlitScreen15_2xSaI;
3804    else BlitScreen=BlitScreen15;
3805    iDesktopCol=15;
3806   }
3807  else
3808  if(dd.dwRBitMask==0x0000f800 &&
3809     dd.dwGBitMask==0x000007e0 &&
3810     dd.dwBBitMask==0x0000001f)
3811   {
3812    if(iUseNoStretchBlt < 4)
3813   		BlitScreen = BlitScreen16;
3814    else if(iUseNoStretchBlt < 13)
3815         BlitScreen = BlitScreen16_2xSaI;
3816    else
3817         BlitScreen = BlitScreen16_3xSaI;
3818    iDesktopCol=16;
3819   }
3820  else
3821   {
3822    if(iUseNoStretchBlt < 4)
3823 	BlitScreen = BlitScreen32;
3824    else if(iUseNoStretchBlt < 13)
3825     BlitScreen = BlitScreen32_2xSaI;
3826    else
3827     BlitScreen = BlitScreen32_3xSaI;
3828    iDesktopCol=32;
3829   }
3830 
3831  //////////////////////////////////////////////////////// extra blts
3832 
3833  switch(iUseNoStretchBlt)
3834   {
3835    case 1:
3836     pExtraBltFunc=NoStretchedBlit;
3837     p2XSaIFunc=NULL;
3838     break;
3839    case 2:
3840     pExtraBltFunc=NoStretchedBlitEx;
3841     p2XSaIFunc=NULL;
3842     break;
3843    case 3:
3844     pExtraBltFunc=StretchedBlit2x;
3845     if     (iDesktopCol==15) p2XSaIFunc=Std2xSaI_ex5;
3846     else if(iDesktopCol==16) p2XSaIFunc=Std2xSaI_ex6;
3847     else                     p2XSaIFunc=Std2xSaI_ex8;
3848     break;
3849    case 4:
3850     pExtraBltFunc=NoStretchedBlit2x;
3851     if     (iDesktopCol==15) p2XSaIFunc=Std2xSaI_ex5;
3852     else if(iDesktopCol==16) p2XSaIFunc=Std2xSaI_ex6;
3853     else                     p2XSaIFunc=Std2xSaI_ex8;
3854     break;
3855    case 5:
3856     pExtraBltFunc=StretchedBlit2x;
3857     if     (iDesktopCol==15) p2XSaIFunc=Super2xSaI_ex5;
3858     else if(iDesktopCol==16) p2XSaIFunc=Super2xSaI_ex6;
3859     else                     p2XSaIFunc=Super2xSaI_ex8;
3860     break;
3861    case 6:
3862     pExtraBltFunc=NoStretchedBlit2x;
3863     if     (iDesktopCol==15) p2XSaIFunc=Super2xSaI_ex5;
3864     else if(iDesktopCol==16) p2XSaIFunc=Super2xSaI_ex6;
3865     else                     p2XSaIFunc=Super2xSaI_ex8;
3866     break;
3867    case 7:
3868     pExtraBltFunc=StretchedBlit2x;
3869     if     (iDesktopCol==15) p2XSaIFunc=SuperEagle_ex5;
3870     else if(iDesktopCol==16) p2XSaIFunc=SuperEagle_ex6;
3871     else                     p2XSaIFunc=SuperEagle_ex8;
3872     break;
3873    case 8:
3874     pExtraBltFunc=NoStretchedBlit2x;
3875     if     (iDesktopCol==15) p2XSaIFunc=SuperEagle_ex5;
3876     else if(iDesktopCol==16) p2XSaIFunc=SuperEagle_ex6;
3877     else                     p2XSaIFunc=SuperEagle_ex8;
3878     break;
3879    case 9:
3880     pExtraBltFunc=StretchedBlit2x;
3881     if     (iDesktopCol==15) p2XSaIFunc=Scale2x_ex6_5;
3882     else if(iDesktopCol==16) p2XSaIFunc=Scale2x_ex6_5;
3883     else                     p2XSaIFunc=Scale2x_ex8;
3884     break;
3885    case 10:
3886     pExtraBltFunc=NoStretchedBlit2x;
3887     if     (iDesktopCol==15) p2XSaIFunc=Scale2x_ex6_5;
3888     else if(iDesktopCol==16) p2XSaIFunc=Scale2x_ex6_5;
3889     else                     p2XSaIFunc=Scale2x_ex8;
3890     break;
3891    case 11:
3892     pExtraBltFunc=NoStretchedBlit2x;
3893 	if(iDesktopCol==15)      p2XSaIFunc=hq2x;
3894     else if(iDesktopCol==16) p2XSaIFunc=hq2x;
3895     else p2XSaIFunc=hq2x_32;
3896 	break;
3897    case 12:
3898     pExtraBltFunc=StretchedBlit2x;
3899     if(iDesktopCol==15)      p2XSaIFunc=hq2x;
3900 	else if(iDesktopCol==16) p2XSaIFunc=hq2x;
3901 	else p2XSaIFunc=hq2x_32;
3902 	break;
3903    case 13:
3904 	pExtraBltFunc=StretchedBlit2x;
3905 	if(iDesktopCol==15)      p2XSaIFunc=Scale3x_ex6_5;
3906 	else if(iDesktopCol==16) p2XSaIFunc=Scale3x_ex6_5;
3907 	else                     p2XSaIFunc=Scale3x_ex8;
3908 	break;
3909    case 14:
3910 	pExtraBltFunc=NoStretchedBlit3x;
3911 	if(iDesktopCol==15)      p2XSaIFunc=Scale3x_ex6_5;
3912     else if(iDesktopCol==16) p2XSaIFunc=Scale3x_ex6_5;
3913 	else                     p2XSaIFunc=Scale3x_ex8;
3914 	break;
3915    case 15:
3916 	pExtraBltFunc=NoStretchedBlit3x;
3917 	if     (iDesktopCol==15) p2XSaIFunc=hq3x_16;
3918 	else if(iDesktopCol==16) p2XSaIFunc=hq3x_16;
3919 	else p2XSaIFunc=hq3x_32;
3920 	break;
3921    default:
3922     pExtraBltFunc=NULL;
3923     p2XSaIFunc=NULL;
3924     break;
3925   }
3926 
3927  //////////////////////////////////////////////////////// clipper init
3928 
3929  if(FAILED(h=IDirectDraw_CreateClipper(DX.DD,0,&Clipper,NULL)))
3930    return 0;
3931 
3932  if(iUseScanLines)
3933       SetScanLineList(Clipper);
3934  else IDirectDrawClipper_SetHWnd(Clipper,0,DX.hWnd);
3935 
3936  IDirectDrawSurface_SetClipper(DX.DDSPrimary,Clipper);
3937  IDirectDrawClipper_Release(Clipper);
3938 
3939  //////////////////////////////////////////////////////// small screen clean up
3940 
3941  DXSetGamma();
3942 
3943  ddbltfx.dwSize = sizeof(ddbltfx);
3944  ddbltfx.dwFillColor = 0x00000000;
3945 
3946  IDirectDrawSurface_Blt(DX.DDSPrimary,NULL,NULL,NULL,DDBLT_COLORFILL,&ddbltfx);
3947  IDirectDrawSurface_Blt(DX.DDSRender,NULL,NULL,NULL,DDBLT_COLORFILL,&ddbltfx);
3948 
3949  //////////////////////////////////////////////////////// finish init
3950 
3951  if(iUseNoStretchBlt>=3)
3952   {
3953    pSaISmallBuff=malloc(512*512*4);
3954    memset(pSaISmallBuff,0,512*512*4);
3955    pSaIBigBuff=malloc(1024*1024*4);
3956    memset(pSaIBigBuff,0,1024*1024*4);
3957   }
3958 
3959  bUsingTWin=FALSE;
3960 
3961  InitMenu();                                           // menu init
3962 
3963  if(iShowFPS)                                          // fps on startup
3964   {
3965    ulKeybits|=KEY_SHOWFPS;
3966    szDispBuf[0]=0;
3967    BuildDispMenu(0);
3968   }
3969 
3970  bIsFirstFrame = FALSE;                                // done
3971 
3972  return 0;
3973 }
3974 
3975 ////////////////////////////////////////////////////////////////////////
3976 // clean up DX stuff
3977 ////////////////////////////////////////////////////////////////////////
3978 
DXcleanup()3979 void DXcleanup()                                       // DX CLEANUP
3980 {
3981  CloseMenu();                                          // bye display lists
3982 
3983  if(iUseNoStretchBlt>=3)
3984   {
3985    if(pSaISmallBuff) free(pSaISmallBuff);
3986    pSaISmallBuff=NULL;
3987    if(pSaIBigBuff) free(pSaIBigBuff);
3988    pSaIBigBuff=NULL;
3989   }
3990 
3991  if(!bIsFirstFrame)
3992   {
3993    if(DX.DDSHelper) IDirectDrawSurface_Release(DX.DDSHelper);
3994    DX.DDSHelper=0;
3995    if(DX.DDSScreenPic) IDirectDrawSurface_Release(DX.DDSScreenPic);
3996    DX.DDSScreenPic=0;
3997    IDirectDrawSurface_Release(DX.DDSRender);
3998    IDirectDrawSurface_Release(DX.DDSPrimary);
3999    IDirectDraw_SetCooperativeLevel(DX.DD,DX.hWnd, DDSCL_NORMAL);
4000    IDirectDraw_RestoreDisplayMode(DX.DD);
4001    IDirectDraw_Release(DX.DD);
4002 
4003    ReStart=TRUE;
4004    bIsFirstFrame = TRUE;
4005   }
4006 }
4007 
4008 ////////////////////////////////////////////////////////////////////////
4009 ////////////////////////////////////////////////////////////////////////
4010 ////////////////////////////////////////////////////////////////////////
4011 
4012 DWORD  dwGPUStyle=0;                                   // vars to store some wimdows stuff
4013 HANDLE hGPUMenu=NULL;
4014 
ulInitDisplay(void)4015 unsigned long ulInitDisplay(void)
4016 {
4017  HDC hdc;RECT r;
4018 
4019  if(iWindowMode)                                       // win mode?
4020   {
4021    DWORD dw=GetWindowLong(hWGPU, GWL_STYLE);    // -> adjust wnd style
4022    dwGPUStyle=dw;
4023    dw&=~WS_THICKFRAME;
4024    dw|=WS_BORDER|WS_CAPTION;
4025    SetWindowLong(hWGPU, GWL_STYLE, dw);
4026 
4027    iResX=LOWORD(iWinSize);iResY=HIWORD(iWinSize);
4028    ShowWindow(hWGPU,SW_SHOWNORMAL);
4029 
4030    if(iUseScanLines)
4031     SetWindowPos(hWGPU,HWND_TOPMOST,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE);
4032 
4033    MoveWindow(hWGPU,                            // -> move wnd
4034       GetSystemMetrics(SM_CXFULLSCREEN)/2-iResX/2,
4035       GetSystemMetrics(SM_CYFULLSCREEN)/2-iResY/2,
4036       iResX+GetSystemMetrics(SM_CXFIXEDFRAME)+3,
4037       iResY+GetSystemMetrics(SM_CYFIXEDFRAME)+GetSystemMetrics(SM_CYCAPTION)+3,
4038       TRUE);
4039    UpdateWindow(hWGPU);                         // -> let windows do some update
4040   }
4041  else                                                  // no window mode:
4042   {
4043    DWORD dw=GetWindowLong(hWGPU, GWL_STYLE);    // -> adjust wnd style
4044    dwGPUStyle=dw;
4045    hGPUMenu=GetMenu(hWGPU);
4046 
4047    dw&=~(WS_THICKFRAME|WS_BORDER|WS_CAPTION);
4048    SetWindowLong(hWGPU, GWL_STYLE, dw);
4049    SetMenu(hWGPU,NULL);
4050 
4051    ShowWindow(hWGPU,SW_SHOWMAXIMIZED);          // -> max mode
4052   }
4053 
4054  r.left=r.top=0;r.right=iResX;r.bottom=iResY;          // init bkg with black
4055  hdc = GetDC(hWGPU);
4056  FillRect(hdc,&r,(HBRUSH)GetStockObject(BLACK_BRUSH));
4057  ReleaseDC(hWGPU, hdc);
4058 
4059  DXinitialize();                                       // init direct draw (not D3D... oh, well)
4060 
4061  if(!iWindowMode)                                      // fullscreen mode?
4062   ShowWindow(hWGPU,SW_SHOWMAXIMIZED);           // -> maximize again (fixes strange DX behavior)
4063 
4064  return 1;
4065 }
4066 
4067 ////////////////////////////////////////////////////////////////////////
4068 
CloseDisplay(void)4069 void CloseDisplay(void)
4070 {
4071  DXcleanup();                                          // cleanup dx
4072 
4073  SetWindowLong(hWGPU, GWL_STYLE,dwGPUStyle);    // repair window
4074  if(hGPUMenu) SetMenu(hWGPU,(HMENU)hGPUMenu);
4075 }
4076 
4077 ////////////////////////////////////////////////////////////////////////
4078 
CreatePic(unsigned char * pMem)4079 void CreatePic(unsigned char * pMem)
4080 {
4081  DDSURFACEDESC xddsd;HRESULT ddrval;
4082  unsigned char * ps;int x,y;
4083 
4084  memset(&xddsd, 0, sizeof(DDSURFACEDESC));
4085  xddsd.dwSize = sizeof(DDSURFACEDESC);
4086  xddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS;
4087 // xddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
4088 
4089  if(iSysMemory)
4090   xddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;
4091  else
4092   xddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY;
4093 
4094  xddsd.dwWidth        = 128;
4095  xddsd.dwHeight       = 96;
4096 
4097  if(IDirectDraw_CreateSurface(DX.DD,&xddsd, &DX.DDSScreenPic, NULL))
4098   {DX.DDSScreenPic=0;return;}
4099 
4100  ddrval=IDirectDrawSurface_Lock(DX.DDSScreenPic,NULL, &xddsd, DDLOCK_WAIT|DDLOCK_WRITEONLY, NULL);
4101 
4102  if(ddrval==DDERR_SURFACELOST)
4103   {
4104    IDirectDrawSurface_Restore(DX.DDSScreenPic);
4105   }
4106 
4107  if(ddrval!=DD_OK)
4108   {
4109    IDirectDrawSurface_Unlock(DX.DDSScreenPic,&xddsd);
4110    return;
4111   }
4112 
4113  ps=(unsigned char *)xddsd.lpSurface;
4114 
4115  if(iDesktopCol==16)
4116   {
4117    unsigned short s;
4118    for(y=0;y<96;y++)
4119     {
4120      for(x=0;x<128;x++)
4121       {
4122        s=(*(pMem+0))>>3;
4123        s|=((*(pMem+1))&0xfc)<<3;
4124        s|=((*(pMem+2))&0xf8)<<8;
4125        pMem+=3;
4126        *((unsigned short *)(ps+y*xddsd.lPitch+x*2))=s;
4127       }
4128     }
4129   }
4130  else
4131  if(iDesktopCol==15)
4132   {
4133    unsigned short s;
4134    for(y=0;y<96;y++)
4135     {
4136      for(x=0;x<128;x++)
4137       {
4138        s=(*(pMem+0))>>3;
4139        s|=((*(pMem+1))&0xfc)<<2;
4140        s|=((*(pMem+2))&0xf8)<<7;
4141        pMem+=3;
4142        *((unsigned short *)(ps+y*xddsd.lPitch+x*2))=s;
4143       }
4144     }
4145   }
4146  else
4147  if(iDesktopCol==32)
4148   {
4149    unsigned long l;
4150    for(y=0;y<96;y++)
4151     {
4152      for(x=0;x<128;x++)
4153       {
4154        l=  *(pMem+0);
4155        l|=(*(pMem+1))<<8;
4156        l|=(*(pMem+2))<<16;
4157        pMem+=3;
4158        *((unsigned long *)(ps+y*xddsd.lPitch+x*4))=l;
4159       }
4160     }
4161   }
4162 
4163  IDirectDrawSurface_Unlock(DX.DDSScreenPic,&xddsd);
4164 }
4165 
4166 ///////////////////////////////////////////////////////////////////////////////////////
4167 
DestroyPic(void)4168 void DestroyPic(void)
4169 {
4170  if(DX.DDSScreenPic)
4171   {
4172    RECT ScreenRect={iResX-128,0,iResX,96};
4173    DDBLTFX     ddbltfx;
4174 
4175    if(iWindowMode)
4176     {
4177      POINT Point={0,0};
4178      ClientToScreen(DX.hWnd,&Point);
4179      ScreenRect.left+=Point.x;
4180      ScreenRect.right+=Point.x;
4181      ScreenRect.top+=Point.y;
4182      ScreenRect.bottom+=Point.y;
4183     }
4184 
4185    ddbltfx.dwSize = sizeof(ddbltfx);
4186    ddbltfx.dwFillColor = 0x00000000;
4187    IDirectDrawSurface_Blt(DX.DDSPrimary,&ScreenRect,NULL,NULL,DDBLT_COLORFILL,&ddbltfx);
4188 
4189    IDirectDrawSurface_Release(DX.DDSScreenPic);
4190    DX.DDSScreenPic=0;
4191   }
4192 }
4193 
4194 ///////////////////////////////////////////////////////////////////////////////////////
4195 
DisplayPic(void)4196 void DisplayPic(void)
4197 {
4198  RECT ScreenRect={iResX-128,0,iResX,96},
4199       HelperRect={0,0,128,96};
4200  if(iWindowMode)
4201   {
4202    POINT Point={0,0};
4203    ClientToScreen(DX.hWnd,&Point);
4204    ScreenRect.left+=Point.x;
4205    ScreenRect.right+=Point.x;
4206    ScreenRect.top+=Point.y;
4207    ScreenRect.bottom+=Point.y;
4208   }
4209 
4210 // ??? eh... no need to wait here!
4211 // WaitVBlank();
4212 
4213  IDirectDrawSurface_Blt(DX.DDSPrimary,&ScreenRect,DX.DDSScreenPic,&HelperRect,
4214                         DDBLT_WAIT,NULL);
4215 }
4216 
4217 ///////////////////////////////////////////////////////////////////////////////////////
4218 
ShowGpuPic(void)4219 void ShowGpuPic(void)
4220 {
4221  HRSRC hR;HGLOBAL hG;unsigned long * pRMem;
4222  unsigned char * pMem;int x,y;unsigned long * pDMem;
4223 
4224  // turn off any screen pic, if it does already exist
4225  if(DX.DDSScreenPic) {DestroyPic();return;}
4226 
4227  if(ulKeybits&KEY_SHOWFPS) {ShowTextGpuPic();return;}
4228 
4229  // load and lock the bitmap (lock is kinda obsolete in win32)
4230  hR=FindResource(hInst,MAKEINTRESOURCE(IDB_GPU),RT_BITMAP);
4231  hG=LoadResource(hInst,hR);
4232 
4233  // get long ptr to bmp data
4234  pRMem=((unsigned long *)LockResource(hG))+10;
4235 
4236  // change the data upside-down
4237  pMem=(unsigned char *)malloc(128*96*3);
4238 
4239  for(y=0;y<96;y++)
4240   {
4241    pDMem=(unsigned long *)(pMem+(95-y)*128*3);
4242    for(x=0;x<96;x++) *pDMem++=*pRMem++;
4243   }
4244 
4245  // show the pic
4246  CreatePic(pMem);
4247 
4248  // clean up
4249  free(pMem);
4250  DeleteObject(hG);
4251 }
4252 
4253 ////////////////////////////////////////////////////////////////////////
4254 
ShowTextGpuPic(void)4255 void ShowTextGpuPic(void)                              // CREATE TEXT SCREEN PIC
4256 {                                                      // gets an Text and paints
4257  unsigned char * pMem;BITMAPINFO bmi;                  // it into a rgb24 bitmap
4258  HDC hdc,hdcMem;HBITMAP hBmp,hBmpMem;HFONT hFontMem;   // to display it in the gpu
4259  HBRUSH hBrush,hBrushMem;HPEN hPen,hPenMem;
4260  char szB[256];
4261  RECT r={0,0,128,96};                                  // size of bmp... don't change that
4262  COLORREF crFrame = RGB(128,255,128);                  // some example color inits
4263  COLORREF crBkg   = RGB(0,0,0);
4264  COLORREF crText  = RGB(0,255,0);
4265 
4266  if(DX.DDSScreenPic) DestroyPic();
4267 
4268  //----------------------------------------------------// creation of the dc & bitmap
4269 
4270  hdc   =GetDC(NULL);                                   // create a dc
4271  hdcMem=CreateCompatibleDC(hdc);
4272  ReleaseDC(NULL,hdc);
4273 
4274  memset(&bmi,0,sizeof(BITMAPINFO));                    // create a 24bit dib
4275  bmi.bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
4276  bmi.bmiHeader.biWidth=128;
4277  bmi.bmiHeader.biHeight=-96;
4278  bmi.bmiHeader.biPlanes=1;
4279  bmi.bmiHeader.biBitCount=24;
4280  bmi.bmiHeader.biCompression=BI_RGB;
4281  hBmp=CreateDIBSection(hdcMem,&bmi,DIB_RGB_COLORS,
4282                        (void **)&pMem,NULL,0);         // pMem will point to 128x96x3 bitmap data
4283 
4284  hBmpMem   = (HBITMAP)SelectObject(hdcMem,hBmp);       // sel the bmp into the dc
4285 
4286  //----------------------------------------------------// ok, the following is just a drawing example... change it...
4287                                                        // create & select an additional font... whatever you want to paint, paint it in the dc :)
4288  hBrush=CreateSolidBrush(crBkg);
4289  hPen=CreatePen(PS_SOLID,0,crFrame);
4290 
4291  hBrushMem = (HBRUSH)SelectObject(hdcMem,hBrush);
4292  hPenMem   = (HPEN)SelectObject(hdcMem,hPen);
4293  hFontMem  = (HFONT)SelectObject(hdcMem,hGFont);
4294 
4295  SetTextColor(hdcMem,crText);
4296  SetBkColor(hdcMem,crBkg);
4297 
4298  Rectangle(hdcMem,r.left,r.top,r.right,r.bottom);      // our example: fill rect and paint border
4299  InflateRect(&r,-3,-2);                                // reduce the text area
4300 
4301  LoadString(hInst,IDS_INFO0+iMPos,szB,255);
4302  DrawText(hdcMem,szB,strlen(szB),&r,                   // paint the text (including clipping and word break)
4303           DT_LEFT|DT_WORDBREAK);
4304 
4305  //----------------------------------------------------// ok, now store the pMem data, or just call the gpu func
4306 
4307  CreatePic(pMem);
4308 
4309  //----------------------------------------------------// finished, now we clean up... needed, or you will get resource leaks :)
4310 
4311  SelectObject(hdcMem,hBmpMem);                         // sel old mem dc objects
4312  SelectObject(hdcMem,hBrushMem);
4313  SelectObject(hdcMem,hPenMem);
4314  SelectObject(hdcMem,hFontMem);
4315  DeleteDC(hdcMem);                                     // delete mem dcs
4316  DeleteObject(hBmp);
4317  DeleteObject(hBrush);                                 // delete created objects
4318  DeleteObject(hPen);
4319 }
4320 
4321 ///////////////////////////////////////////////////////////////////////
4322 
hqx_init(unsigned bits_per_pixel)4323 static void hqx_init(unsigned bits_per_pixel)
4324 {
4325   interp_set(bits_per_pixel);
4326 }
4327 
hq2x_16_def(unsigned short * dst0,unsigned short * dst1,const unsigned short * src0,const unsigned short * src1,const unsigned short * src2,unsigned count)4328 static void hq2x_16_def(unsigned short* dst0, unsigned short* dst1, const unsigned short* src0, const unsigned short* src1, const unsigned short* src2, unsigned count)
4329 {
4330 	unsigned i;
4331 
4332 	for(i=0;i<count;++i) {
4333 		unsigned char mask;
4334 
4335 		unsigned short c[9];
4336 
4337 		c[1] = src0[0];
4338 		c[4] = src1[0];
4339 		c[7] = src2[0];
4340 
4341 		if (i>0) {
4342 			c[0] = src0[-1];
4343 			c[3] = src1[-1];
4344 			c[6] = src2[-1];
4345 		} else {
4346 			c[0] = c[1];
4347 			c[3] = c[4];
4348 			c[6] = c[7];
4349 		}
4350 
4351 		if (i<count-1) {
4352 			c[2] = src0[1];
4353 			c[5] = src1[1];
4354 			c[8] = src2[1];
4355 		} else {
4356 			c[2] = c[1];
4357 			c[5] = c[4];
4358 			c[8] = c[7];
4359 		}
4360 
4361 		mask = 0;
4362 
4363 		if (interp_16_diff(c[0], c[4]))
4364 			mask |= 1 << 0;
4365 		if (interp_16_diff(c[1], c[4]))
4366 			mask |= 1 << 1;
4367 		if (interp_16_diff(c[2], c[4]))
4368 			mask |= 1 << 2;
4369 		if (interp_16_diff(c[3], c[4]))
4370 			mask |= 1 << 3;
4371 		if (interp_16_diff(c[5], c[4]))
4372 			mask |= 1 << 4;
4373 		if (interp_16_diff(c[6], c[4]))
4374 			mask |= 1 << 5;
4375 		if (interp_16_diff(c[7], c[4]))
4376 			mask |= 1 << 6;
4377 		if (interp_16_diff(c[8], c[4]))
4378 			mask |= 1 << 7;
4379 
4380 #define P0 dst0[0]
4381 #define P1 dst0[1]
4382 #define P2 dst1[0]
4383 #define P3 dst1[1]
4384 #define MUR interp_16_diff(c[1], c[5])
4385 #define MDR interp_16_diff(c[5], c[7])
4386 #define MDL interp_16_diff(c[7], c[3])
4387 #define MUL interp_16_diff(c[3], c[1])
4388 #define IC(p0) c[p0]
4389 #define I11(p0,p1) interp_16_11(c[p0], c[p1])
4390 #define I211(p0,p1,p2) interp_16_211(c[p0], c[p1], c[p2])
4391 #define I31(p0,p1) interp_16_31(c[p0], c[p1])
4392 #define I332(p0,p1,p2) interp_16_332(c[p0], c[p1], c[p2])
4393 #define I431(p0,p1,p2) interp_16_431(c[p0], c[p1], c[p2])
4394 #define I521(p0,p1,p2) interp_16_521(c[p0], c[p1], c[p2])
4395 #define I53(p0,p1) interp_16_53(c[p0], c[p1])
4396 #define I611(p0,p1,p2) interp_16_611(c[p0], c[p1], c[p2])
4397 #define I71(p0,p1) interp_16_71(c[p0], c[p1])
4398 #define I772(p0,p1,p2) interp_16_772(c[p0], c[p1], c[p2])
4399 #define I97(p0,p1) interp_16_97(c[p0], c[p1])
4400 #define I1411(p0,p1,p2) interp_16_1411(c[p0], c[p1], c[p2])
4401 #define I151(p0,p1) interp_16_151(c[p0], c[p1])
4402 
4403 		switch (mask) {
4404 #include "hq2x.h"
4405 		}
4406 
4407 #undef P0
4408 #undef P1
4409 #undef P2
4410 #undef P3
4411 #undef MUR
4412 #undef MDR
4413 #undef MDL
4414 #undef MUL
4415 #undef IC
4416 #undef I11
4417 #undef I211
4418 #undef I31
4419 #undef I332
4420 #undef I431
4421 #undef I521
4422 #undef I53
4423 #undef I611
4424 #undef I71
4425 #undef I772
4426 #undef I97
4427 #undef I1411
4428 #undef I151
4429 
4430 		src0 += 1;
4431 		src1 += 1;
4432 		src2 += 1;
4433 		dst0 += 2;
4434 		dst1 += 2;
4435 	}
4436 }
4437 
hq2x(unsigned char * srcPtr,DWORD srcPitch,unsigned char * dstPtr,int width,int height)4438 void hq2x( unsigned char * srcPtr,  DWORD srcPitch, unsigned char * dstPtr, int width, int height)
4439 {
4440 	const int dstPitch = srcPitch;
4441 
4442 	int count = height;
4443 
4444 	unsigned short  *dst0 = (unsigned short  *)dstPtr;
4445 	unsigned short  *dst1 = dst0 + dstPitch;
4446 
4447 	unsigned short *src0 = (unsigned short  *)srcPtr;
4448 	unsigned short *src1 = src0 + (srcPitch >> 1);
4449 	unsigned short *src2 = src1 + (srcPitch >> 1);
4450 	hqx_init(16);
4451 	hq2x_16_def(dst0, dst1, src0, src0, src1, width);
4452 
4453 	count -= 2;
4454 	while(count) {
4455 		dst0 += dstPitch << 1;
4456 		dst1 += dstPitch << 1;
4457 		hq2x_16_def(dst0, dst1, src0, src1, src2, width);
4458 		src0 = src1;
4459 		src1 = src2;
4460 		src2 += srcPitch >> 1;
4461 		--count;
4462 	}
4463 	dst0 += dstPitch << 1;
4464 	dst1 += dstPitch << 1;
4465 	hq2x_16_def(dst0, dst1, src0, src1, src1, width);
4466 }
4467 
4468 ///////////////////////////////////////////////////////////////////
4469 
hq2x_32_def(unsigned long * dst0,unsigned long * dst1,const unsigned long * src0,const unsigned long * src1,const unsigned long * src2,unsigned count)4470 static void hq2x_32_def(unsigned long * dst0, unsigned long * dst1, const unsigned long * src0, const unsigned long * src1, const unsigned long * src2, unsigned count)
4471 {
4472 	unsigned i;
4473 
4474 	for(i=0;i<count;++i) {
4475 		unsigned char mask;
4476 
4477 		unsigned long  c[9];
4478 
4479 		c[1] = src0[0];
4480 		c[4] = src1[0];
4481 		c[7] = src2[0];
4482 
4483 		if (i>0) {
4484 			c[0] = src0[-1];
4485 			c[3] = src1[-1];
4486 			c[6] = src2[-1];
4487 		} else {
4488 			c[0] = c[1];
4489 			c[3] = c[4];
4490 			c[6] = c[7];
4491 		}
4492 
4493 		if (i<count-1) {
4494 			c[2] = src0[1];
4495 			c[5] = src1[1];
4496 			c[8] = src2[1];
4497 		} else {
4498 			c[2] = c[1];
4499 			c[5] = c[4];
4500 			c[8] = c[7];
4501 		}
4502 
4503 		mask = 0;
4504 
4505 		if (interp_32_diff(c[0], c[4]))
4506 			mask |= 1 << 0;
4507 		if (interp_32_diff(c[1], c[4]))
4508 			mask |= 1 << 1;
4509 		if (interp_32_diff(c[2], c[4]))
4510 			mask |= 1 << 2;
4511 		if (interp_32_diff(c[3], c[4]))
4512 			mask |= 1 << 3;
4513 		if (interp_32_diff(c[5], c[4]))
4514 			mask |= 1 << 4;
4515 		if (interp_32_diff(c[6], c[4]))
4516 			mask |= 1 << 5;
4517 		if (interp_32_diff(c[7], c[4]))
4518 			mask |= 1 << 6;
4519 		if (interp_32_diff(c[8], c[4]))
4520 			mask |= 1 << 7;
4521 
4522 #define P0 dst0[0]
4523 #define P1 dst0[1]
4524 #define P2 dst1[0]
4525 #define P3 dst1[1]
4526 #define MUR interp_32_diff(c[1], c[5])
4527 #define MDR interp_32_diff(c[5], c[7])
4528 #define MDL interp_32_diff(c[7], c[3])
4529 #define MUL interp_32_diff(c[3], c[1])
4530 #define IC(p0) c[p0]
4531 #define I11(p0,p1) interp_32_11(c[p0], c[p1])
4532 #define I211(p0,p1,p2) interp_32_211(c[p0], c[p1], c[p2])
4533 #define I31(p0,p1) interp_32_31(c[p0], c[p1])
4534 #define I332(p0,p1,p2) interp_32_332(c[p0], c[p1], c[p2])
4535 #define I431(p0,p1,p2) interp_32_431(c[p0], c[p1], c[p2])
4536 #define I521(p0,p1,p2) interp_32_521(c[p0], c[p1], c[p2])
4537 #define I53(p0,p1) interp_32_53(c[p0], c[p1])
4538 #define I611(p0,p1,p2) interp_32_611(c[p0], c[p1], c[p2])
4539 #define I71(p0,p1) interp_32_71(c[p0], c[p1])
4540 #define I772(p0,p1,p2) interp_32_772(c[p0], c[p1], c[p2])
4541 #define I97(p0,p1) interp_32_97(c[p0], c[p1])
4542 #define I1411(p0,p1,p2) interp_32_1411(c[p0], c[p1], c[p2])
4543 #define I151(p0,p1) interp_32_151(c[p0], c[p1])
4544 
4545 		switch (mask) {
4546 #include "hq2x.h"
4547 		}
4548 
4549 #undef P0
4550 #undef P1
4551 #undef P2
4552 #undef P3
4553 #undef MUR
4554 #undef MDR
4555 #undef MDL
4556 #undef MUL
4557 #undef IC
4558 #undef I11
4559 #undef I211
4560 #undef I31
4561 #undef I332
4562 #undef I431
4563 #undef I521
4564 #undef I53
4565 #undef I611
4566 #undef I71
4567 #undef I772
4568 #undef I97
4569 #undef I1411
4570 #undef I151
4571 
4572 		src0 += 1;
4573 		src1 += 1;
4574 		src2 += 1;
4575 		dst0 += 2;
4576 		dst1 += 2;
4577 	}
4578 }
4579 
4580 
4581 
hq2x_32(unsigned char * srcPtr,DWORD srcPitch,unsigned char * dstPtr,int width,int height)4582 void hq2x_32( unsigned char * srcPtr,  DWORD srcPitch, unsigned char * dstPtr, int width, int height)
4583 {
4584 	const int dstPitch = srcPitch<<1;
4585 
4586 	int count = height;
4587 
4588 	unsigned long  *dst0 = (unsigned long  *)dstPtr;
4589 	unsigned long  *dst1 = dst0 + (dstPitch >> 2);
4590 
4591 	unsigned long  *src0 = (unsigned long  *)srcPtr;
4592 	unsigned long  *src1 = src0 + (srcPitch >> 2);
4593 	unsigned long  *src2 = src1 + (srcPitch >> 2);
4594 	hq2x_32_def(dst0, dst1, src0, src0, src1, width);
4595 
4596 
4597 
4598 	count -= 2;
4599 	while(count) {
4600 		dst0 += dstPitch >> 1;
4601 		dst1 += dstPitch >> 1;
4602 		hq2x_32_def(dst0, dst1, src0, src1, src2, width);
4603 		src0 = src1;
4604 		src1 = src2;
4605 		src2 += srcPitch >> 2;
4606 		--count;
4607 	}
4608 	dst0 += dstPitch >> 1;
4609 	dst1 += dstPitch >> 1;
4610 	hq2x_32_def(dst0, dst1, src0, src1, src1, width);
4611 }
4612 
hq3x_32_def(unsigned long * dst0,unsigned long * dst1,unsigned long * dst2,const unsigned long * src0,const unsigned long * src1,const unsigned long * src2,unsigned count)4613 static void hq3x_32_def(unsigned long*  dst0, unsigned long*  dst1, unsigned long*  dst2, const unsigned long* src0, const unsigned long* src1, const unsigned long* src2, unsigned count)
4614 {
4615 	unsigned i;
4616 
4617 	for(i=0;i<count;++i) {
4618 		unsigned char mask;
4619 
4620 		unsigned long c[9];
4621 
4622 		c[1] = src0[0];
4623 		c[4] = src1[0];
4624 		c[7] = src2[0];
4625 
4626 		if (i>0) {
4627 			c[0] = src0[-1];
4628 			c[3] = src1[-1];
4629 			c[6] = src2[-1];
4630 		} else {
4631 			c[0] = c[1];
4632 			c[3] = c[4];
4633 			c[6] = c[7];
4634 		}
4635 
4636 		if (i<count-1) {
4637 			c[2] = src0[1];
4638 			c[5] = src1[1];
4639 			c[8] = src2[1];
4640 		} else {
4641 			c[2] = c[1];
4642 			c[5] = c[4];
4643 			c[8] = c[7];
4644 		}
4645 
4646 		mask = 0;
4647 
4648 		if (interp_32_diff(c[0], c[4]))
4649 			mask |= 1 << 0;
4650 		if (interp_32_diff(c[1], c[4]))
4651 			mask |= 1 << 1;
4652 		if (interp_32_diff(c[2], c[4]))
4653 			mask |= 1 << 2;
4654 		if (interp_32_diff(c[3], c[4]))
4655 			mask |= 1 << 3;
4656 		if (interp_32_diff(c[5], c[4]))
4657 			mask |= 1 << 4;
4658 		if (interp_32_diff(c[6], c[4]))
4659 			mask |= 1 << 5;
4660 		if (interp_32_diff(c[7], c[4]))
4661 			mask |= 1 << 6;
4662 		if (interp_32_diff(c[8], c[4]))
4663 			mask |= 1 << 7;
4664 
4665 #define P0 dst0[0]
4666 #define P1 dst0[1]
4667 #define P2 dst0[2]
4668 #define P3 dst1[0]
4669 #define P4 dst1[1]
4670 #define P5 dst1[2]
4671 #define P6 dst2[0]
4672 #define P7 dst2[1]
4673 #define P8 dst2[2]
4674 #define MUR interp_32_diff(c[1], c[5])
4675 #define MDR interp_32_diff(c[5], c[7])
4676 #define MDL interp_32_diff(c[7], c[3])
4677 #define MUL interp_32_diff(c[3], c[1])
4678 #define IC(p0) c[p0]
4679 #define I11(p0,p1) interp_32_11(c[p0], c[p1])
4680 #define I211(p0,p1,p2) interp_32_211(c[p0], c[p1], c[p2])
4681 #define I31(p0,p1) interp_32_31(c[p0], c[p1])
4682 #define I332(p0,p1,p2) interp_32_332(c[p0], c[p1], c[p2])
4683 #define I431(p0,p1,p2) interp_32_431(c[p0], c[p1], c[p2])
4684 #define I521(p0,p1,p2) interp_32_521(c[p0], c[p1], c[p2])
4685 #define I53(p0,p1) interp_32_53(c[p0], c[p1])
4686 #define I611(p0,p1,p2) interp_32_611(c[p0], c[p1], c[p2])
4687 #define I71(p0,p1) interp_32_71(c[p0], c[p1])
4688 #define I772(p0,p1,p2) interp_32_772(c[p0], c[p1], c[p2])
4689 #define I97(p0,p1) interp_32_97(c[p0], c[p1])
4690 #define I1411(p0,p1,p2) interp_32_1411(c[p0], c[p1], c[p2])
4691 #define I151(p0,p1) interp_32_151(c[p0], c[p1])
4692 
4693 		switch (mask) {
4694 #include "hq3x.h"
4695 		}
4696 
4697 #undef P0
4698 #undef P1
4699 #undef P2
4700 #undef P3
4701 #undef P4
4702 #undef P5
4703 #undef P6
4704 #undef P7
4705 #undef P8
4706 #undef MUR
4707 #undef MDR
4708 #undef MDL
4709 #undef MUL
4710 #undef IC
4711 #undef I11
4712 #undef I211
4713 #undef I31
4714 #undef I332
4715 #undef I431
4716 #undef I521
4717 #undef I53
4718 #undef I611
4719 #undef I71
4720 #undef I772
4721 #undef I97
4722 #undef I1411
4723 #undef I151
4724 
4725 		src0 += 1;
4726 		src1 += 1;
4727 		src2 += 1;
4728 		dst0 += 3;
4729 		dst1 += 3;
4730 		dst2 += 3;
4731 	}
4732 }
4733 
hq3x_32(unsigned char * srcPtr,DWORD srcPitch,unsigned char * dstPtr,int width,int height)4734 void hq3x_32( unsigned char * srcPtr,  DWORD srcPitch, unsigned char * dstPtr, int width, int height)
4735 {
4736 
4737 
4738 
4739 	int count = height;
4740 
4741 	int dstPitch = srcPitch >> 1;
4742 
4743 	unsigned long  *dst0 = (unsigned long  *)dstPtr;
4744 	unsigned long  *dst1 = dst0 + dstPitch;
4745 	unsigned long  *dst2 = dst1 + dstPitch;
4746 
4747 	unsigned long  *src0 = (unsigned long  *)srcPtr;
4748 	unsigned long  *src1 = src0 + (srcPitch >> 2);
4749 	unsigned long  *src2 = src1 + (srcPitch >> 2);
4750 	hq3x_32_def(dst0, dst1, dst2, src0, src0, src2, width);
4751 
4752 	count -= 2;
4753 	while(count) {
4754 
4755 		dst0 += dstPitch * 3;
4756 		dst1 += dstPitch * 3;
4757 		dst2 += dstPitch * 3;
4758 
4759 		hq3x_32_def(dst0, dst1, dst2, src0, src1, src2, width);
4760 		src0 = src1;
4761 		src1 = src2;
4762 		src2 += srcPitch >> 2;
4763 		--count;
4764 	}
4765 	dst0 += dstPitch * 3;
4766 	dst1 += dstPitch * 3;
4767 	dst2 += dstPitch * 3;
4768 
4769 
4770 	hq3x_32_def(dst0, dst1, dst2, src0, src1, src1, width);
4771 
4772 }
4773 
hq3x_16_def(unsigned short * dst0,unsigned short * dst1,unsigned short * dst2,const unsigned short * src0,const unsigned short * src1,const unsigned short * src2,unsigned count)4774 static void hq3x_16_def(unsigned short* dst0, unsigned short* dst1, unsigned short* dst2, const unsigned short* src0, const unsigned short* src1, const unsigned short* src2, unsigned count)
4775 {
4776 	unsigned i;
4777 
4778 	for(i=0;i<count;++i) {
4779 		unsigned char mask;
4780 
4781 		unsigned short c[9];
4782 
4783 		c[1] = src0[0];
4784 		c[4] = src1[0];
4785 		c[7] = src2[0];
4786 
4787 		if (i>0) {
4788 			c[0] = src0[-1];
4789 			c[3] = src1[-1];
4790 			c[6] = src2[-1];
4791 		} else {
4792 			c[0] = c[1];
4793 			c[3] = c[4];
4794 			c[6] = c[7];
4795 		}
4796 
4797 		if (i<count-1) {
4798 			c[2] = src0[1];
4799 			c[5] = src1[1];
4800 			c[8] = src2[1];
4801 		} else {
4802 			c[2] = c[1];
4803 			c[5] = c[4];
4804 			c[8] = c[7];
4805 		}
4806 
4807 		mask = 0;
4808 
4809 		if (interp_16_diff(c[0], c[4]))
4810 			mask |= 1 << 0;
4811 		if (interp_16_diff(c[1], c[4]))
4812 			mask |= 1 << 1;
4813 		if (interp_16_diff(c[2], c[4]))
4814 			mask |= 1 << 2;
4815 		if (interp_16_diff(c[3], c[4]))
4816 			mask |= 1 << 3;
4817 		if (interp_16_diff(c[5], c[4]))
4818 			mask |= 1 << 4;
4819 		if (interp_16_diff(c[6], c[4]))
4820 			mask |= 1 << 5;
4821 		if (interp_16_diff(c[7], c[4]))
4822 			mask |= 1 << 6;
4823 		if (interp_16_diff(c[8], c[4]))
4824 			mask |= 1 << 7;
4825 
4826 #define P0 dst0[0]
4827 #define P1 dst0[1]
4828 #define P2 dst0[2]
4829 #define P3 dst1[0]
4830 #define P4 dst1[1]
4831 #define P5 dst1[2]
4832 #define P6 dst2[0]
4833 #define P7 dst2[1]
4834 #define P8 dst2[2]
4835 #define MUR interp_16_diff(c[1], c[5])
4836 #define MDR interp_16_diff(c[5], c[7])
4837 #define MDL interp_16_diff(c[7], c[3])
4838 #define MUL interp_16_diff(c[3], c[1])
4839 #define IC(p0) c[p0]
4840 #define I11(p0,p1) interp_16_11(c[p0], c[p1])
4841 #define I211(p0,p1,p2) interp_16_211(c[p0], c[p1], c[p2])
4842 #define I31(p0,p1) interp_16_31(c[p0], c[p1])
4843 #define I332(p0,p1,p2) interp_16_332(c[p0], c[p1], c[p2])
4844 #define I431(p0,p1,p2) interp_16_431(c[p0], c[p1], c[p2])
4845 #define I521(p0,p1,p2) interp_16_521(c[p0], c[p1], c[p2])
4846 #define I53(p0,p1) interp_16_53(c[p0], c[p1])
4847 #define I611(p0,p1,p2) interp_16_611(c[p0], c[p1], c[p2])
4848 #define I71(p0,p1) interp_16_71(c[p0], c[p1])
4849 #define I772(p0,p1,p2) interp_16_772(c[p0], c[p1], c[p2])
4850 #define I97(p0,p1) interp_16_97(c[p0], c[p1])
4851 #define I1411(p0,p1,p2) interp_16_1411(c[p0], c[p1], c[p2])
4852 #define I151(p0,p1) interp_16_151(c[p0], c[p1])
4853 
4854 		switch (mask) {
4855 #include "hq3x.h"
4856 		}
4857 
4858 #undef P0
4859 #undef P1
4860 #undef P2
4861 #undef P3
4862 #undef P4
4863 #undef P5
4864 #undef P6
4865 #undef P7
4866 #undef P8
4867 #undef MUR
4868 #undef MDR
4869 #undef MDL
4870 #undef MUL
4871 #undef IC
4872 #undef I11
4873 #undef I211
4874 #undef I31
4875 #undef I332
4876 #undef I431
4877 #undef I521
4878 #undef I53
4879 #undef I611
4880 #undef I71
4881 #undef I772
4882 #undef I97
4883 #undef I1411
4884 #undef I151
4885 
4886 		src0 += 1;
4887 		src1 += 1;
4888 		src2 += 1;
4889 		dst0 += 3;
4890 		dst1 += 3;
4891 		dst2 += 3;
4892 	}
4893 }
4894 
hq3x_16(unsigned char * srcPtr,DWORD srcPitch,unsigned char * dstPtr,int width,int height)4895 void hq3x_16( unsigned char * srcPtr,  DWORD srcPitch, unsigned char * dstPtr, int width, int height)
4896 {
4897 	int count = height;
4898 	int dstPitch = srcPitch;
4899 
4900 	unsigned short  *dst0 = (unsigned short  *)dstPtr;
4901 	unsigned short  *dst1 = dst0 + dstPitch;
4902 	unsigned short  *dst2 = dst1 + dstPitch;
4903 
4904 	unsigned short  *src0 = (unsigned short  *)srcPtr;
4905 	unsigned short *src1 = src0 + (srcPitch >> 1);
4906 	unsigned short *src2 = src1 + (srcPitch >> 1);
4907 	hqx_init(16);
4908 	hq3x_16_def(dst0, dst1, dst2, src0, src0, src2, width);
4909 
4910 	count -= 2;
4911 	while(count) {
4912 
4913 		dst0 += dstPitch * 3;
4914 		dst1 += dstPitch * 3;
4915 		dst2 += dstPitch * 3;
4916 
4917 		hq3x_16_def(dst0, dst1, dst2, src0, src1, src2, width);
4918 		src0 = src1;
4919 		src1 = src2;
4920 		src2 += srcPitch >> 1;
4921 		--count;
4922 	}
4923 	dst0 += dstPitch * 3;
4924 	dst1 += dstPitch * 3;
4925 	dst2 += dstPitch * 3;
4926 
4927 	hq3x_16_def(dst0, dst1, dst2, src0, src1, src1, width);
4928 }
4929 
4930