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