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