1
/* FCE Ultra - NES/Famicom Emulator
3
* Copyright notice for this file:
4
* Copyright (C) 2002 Xodnizel
6
* This program is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation; either version 2 of the License, or
9
* (at your option) any later version.
11
* This program is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU General Public License for more details.
16
* You should have received a copy of the GNU General Public License
17
* along with this program; if not, write to the Free Software
18
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26
#include "../../types.h"
29
static uint32 *palettetranslate=0;
31
static uint16 *specbuf=NULL; // 8bpp -> 16bpp, pre hq2x/hq3x
32
static uint32 *specbuf32bpp = NULL; // Buffer to hold output
33
// of hq2x/hq3x when converting
35
static int backBpp, backshiftr[3], backshiftl[3];
36
//static uint32 backmask[3];
38
static uint8 *specbuf8bpp = NULL; // For 2xscale, 3xscale.
43
static int Bpp; // BYTES per pixel
50
#define FVB_SCANLINES 1
52
/* The blur effect is only available for bpp>=16. It could be easily modified
53
to look like what happens on the real NES and TV, but lack of decent
54
synchronization to the vertical retrace period makes it look rather
59
static void CalculateShift(uint32 *CBM, int *cshiftr, int *cshiftl)
62
cshiftl[0]=cshiftl[1]=cshiftl[2]=-1;
65
for(x=0,y=-1,z=0;x<32;x++)
69
if(cshiftl[a]==-1) cshiftl[a]=x;
78
int InitBlitToHigh(int b, uint32 rmask, uint32 gmask, uint32 bmask, int efx, int specfilt)
80
if(specfilt == 2 || specfilt == 4) // scale2x and scale3x
82
int multi = ((specfilt == 2) ? 2 * 2 : 3 * 3);
84
specbuf8bpp = (uint8*)malloc(256*240*multi); //mbg merge 7/17/06 added cast
87
else if(specfilt == 1 || specfilt == 3) // hq2x and hq3x
92
if(b == 2 || b == 3) // 8->16->(hq2x)->32-> 24 or 16. YARGH.
100
CalculateShift(tmpCBM, backshiftr, backshiftl);
109
// Begin iffy code(requires 16bpp and 32bpp to have same RGB order)
110
//backmask[0] = (rmask>>backshiftl[0]) << (backshiftr[0]);
111
//backmask[1] = (gmask>>backshiftl[1]) << (backshiftr[1]);
112
//backmask[2] = (bmask>>backshiftl[2]) << (backshiftr[2]);
116
// backshiftr[x] -= backshiftl[x];
119
if(specfilt == 1) specbuf32bpp = (uint32*)malloc(256*240*4*sizeof(uint32)); //mbg merge 7/17/06 added cast
120
else if(specfilt == 3) specbuf32bpp = (uint32*)malloc(256*240*9*sizeof(uint32)); //mbg merge 7/17/06 added cast
134
specbuf=(uint16*)malloc(256*240*sizeof(uint16)); //mbg merge 7/17/06 added cast
149
palettetranslate=(uint32 *)malloc(65536*4);
151
palettetranslate=(uint32 *)malloc(65536*4);
156
palettetranslate=(uint32*)malloc(65536*4);
158
palettetranslate=(uint32*)malloc(256*4);
161
if(!palettetranslate)
171
void KillBlitToHigh(void)
175
free(palettetranslate);
176
palettetranslate=NULL;
200
void SetPaletteBlitToHigh(uint8 *src)
206
CalculateShift(CBM, cshiftr, cshiftl);
218
r=src[x<<2]*(100-BLUR_RED);
219
g=src[(x<<2)+1]*(100-BLUR_GREEN);
220
b=src[(x<<2)+2]*(100-BLUR_BLUE);
222
r+=src[y<<2]*BLUR_RED;
223
g+=src[(y<<2)+1]*BLUR_GREEN;
224
b+=src[(y<<2)+2]*BLUR_BLUE;
229
if(r>255) r=255; if(g>255) g=255; if(b>255) b=255;
230
palettetranslate[x|(y<<8)]=((r>>cshiftr[0])<<cshiftl[0])|
231
((g>>cshiftr[1])<<cshiftl[1])|
232
((b>>cshiftr[2])<<cshiftl[2]);
241
lower=(src[((x&255)<<2)]>>cshiftr[0])<<cshiftl[0];
242
lower|=(src[((x&255)<<2)+1]>>cshiftr[1])<<cshiftl[1];
243
lower|=(src[((x&255)<<2)+2]>>cshiftr[2])<<cshiftl[2];
244
upper=(src[((x>>8)<<2)]>>cshiftr[0])<<cshiftl[0];
245
upper|=(src[((x>>8)<<2)+1]>>cshiftr[1])<<cshiftl[1];
246
upper|=(src[((x>>8)<<2)+2]>>cshiftr[2])<<cshiftl[2];
248
palettetranslate[x]=lower|(upper<<16);
257
if(!(highefx&FVB_BLUR))
262
palettetranslate[x]=(r<<cshiftl[0])|(g<<cshiftl[1])|(b<<cshiftl[2]);
267
r=src[x<<2]*(100-BLUR_RED);
268
g=src[(x<<2)+1]*(100-BLUR_GREEN);
269
b=src[(x<<2)+2]*(100-BLUR_BLUE);
271
r+=src[y<<2]*BLUR_RED;
272
g+=src[(y<<2)+1]*BLUR_GREEN;
273
b+=src[(y<<2)+2]*BLUR_BLUE;
278
if(r>255) r=255; if(g>255) g=255; if(b>255) b=255;
280
palettetranslate[x|(y<<8)]=(r<<cshiftl[0])|(g<<cshiftl[1])|(b<<cshiftl[2]);
287
void Blit32to24(uint32 *src, uint8 *dest, int xr, int yr, int dpitch)
304
dest += dpitch / 3 - xr;
309
void Blit32to16(uint32 *src, uint16 *dest, int xr, int yr, int dpitch,
310
int shiftr[3], int shiftl[3])
313
//printf("%d\n",shiftl[1]);
322
//dtmp = (tmp & backmask[2]) >> shiftr[2];
323
//dtmp |= (tmp & backmask[1]) >> shiftr[1];
324
//dtmp |= (tmp & backmask[0]) >> shiftr[0];
327
// Begin non-iffy code
328
dtmp = ((tmp&0x0000FF) >> shiftr[2]) << shiftl[2];
329
dtmp |= ((tmp&0x00FF00) >> shiftr[1]) << shiftl[1];
330
dtmp |= ((tmp&0xFF0000) >> shiftr[0]) << shiftl[0];
333
//dtmp = ((tmp&0x0000FF) >> 3);
334
//dtmp |= ((tmp&0x00FC00) >>5);
335
//dtmp |= ((tmp&0xF80000) >>8);
341
dest += dpitch / 2 - xr;
346
void Blit8To8(uint8 *src, uint8 *dest, int xr, int yr, int pitch, int xscale, int yscale, int efx, int special)
353
if(xscale!=2 || yscale!=2) return;
355
scale(2,dest,pitch,src,256,1,xr,yr);
361
if(xscale!=3 || yscale!=3) return;
362
scale(3,dest,pitch,src,256,1,xr,yr);
366
pinc=pitch-(xr*xscale);
367
if(xscale!=1 || yscale!=1)
369
if(efx&FVB_SCANLINES)
371
for(y=yr;y;y--,src+=256-xr)
373
int doo=yscale-(yscale>>1);
376
for(x=xr;x;x--,src++)
381
*(uint8 *)dest=*(uint8 *)src;
388
//src-=xr*(yscale-(yscale>>1));
389
dest+=pitch*(yscale>>1);
397
for(y=yr;y;y--,src+=256-xr)
402
for(x=xr;x;x--,src++)
407
*(uint8 *)dest=*(uint8 *)src;
421
for(y=yr;y;y--,dest+=pinc,src+=256-xr)
422
for(x=xr;x;x-=4,dest+=4,src+=4)
423
*(uint32 *)dest=*(uint32 *)src;
427
/* Todo: Make sure 24bpp code works right with big-endian cpus */
429
void Blit8ToHigh(uint8 *src, uint8 *dest, int xr, int yr, int pitch,
430
int xscale, int yscale)
434
uint8 *destbackup = NULL; /* For hq2x */
437
//static int google=0;
440
if(specbuf8bpp) // 2xscale/3xscale
445
if(silt == 2) mult = 2;
448
Blit8To8(src, specbuf8bpp, xr, yr, 256*mult, xscale, yscale, 0, silt);
460
for(y=yr;y;y--,src+=base-xr)
464
*(uint32 *)dest=palettetranslate[(uint32)*src];
472
pinc=pitch-(xr+xr+xr);
473
for(y=yr;y;y--,src+=base-xr)
477
uint32 tmp=palettetranslate[(uint32)*src];
479
*((uint8 *)dest+1)=tmp>>8;
480
*((uint8 *)dest+2)=tmp>>16;
491
for(y=yr;y;y--,src+=base-xr)
495
*(uint32 *)dest=palettetranslate[*(uint16 *)src];
508
dest=(uint8 *)specbuf;
511
pitch=xr*sizeof(uint16);
516
if(highefx&FVB_BLUR) // DONE
518
if(xscale!=1 || yscale!=1 || (highefx&FVB_SCANLINES)) // DONE
523
pinc=pitch-((xr*xscale)<<2);
524
for(y=yr;y;y--,src+=256-xr)
528
if(highefx&FVB_SCANLINES)
534
//if(doo == 1 && google) dest+=4;
535
for(x=xr;x;x--,src++)
540
*(uint32 *)dest=palettetranslate[*src|(last<<8)];
545
//if(doo == 1 && google) dest-=4;
550
if(highefx&FVB_SCANLINES)
551
dest+=pitch*(yscale>>1);
555
pinc=pitch-((xr*xscale)*3);
556
for(y=yr;y;y--,src+=256-xr)
560
if(highefx&FVB_SCANLINES)
565
for(x=xr;x;x--,src++)
570
*(uint32 *)dest=palettetranslate[*src|(last<<8)];
579
if(highefx&FVB_SCANLINES)
580
dest+=pitch*(yscale>>1);
585
pinc=pitch-((xr*xscale)<<1);
587
for(y=yr;y;y--,src+=256-xr)
591
if(highefx& FVB_SCANLINES)
596
for(x=xr;x;x--,src++)
601
*(uint16 *)dest=palettetranslate[*src|(last<<8)];
610
if(highefx&FVB_SCANLINES)
611
dest+=pitch*(yscale>>1);
616
else // No scaling, no scanlines, just blurring. - DONE
621
for(y=yr;y;y--,src+=256-xr)
626
*(uint32 *)dest=palettetranslate[*src|(last<<8)];
635
pinc=pitch-(xr+xr+xr);
636
for(y=yr;y;y--,src+=256-xr)
641
uint32 tmp=palettetranslate[*src|(last<<8)];
644
*((uint8 *)dest+1)=tmp>>8;
645
*((uint8 *)dest+2)=tmp>>16;
654
for(y=yr;y;y--,src+=256-xr)
659
*(uint16 *)dest=palettetranslate[*src|(last<<8)];
669
else // No blur effects.
671
if(xscale!=1 || yscale!=1 || (highefx&FVB_SCANLINES))
676
pinc=pitch-((xr*xscale)<<2);
677
for(y=yr;y;y--,src+=256-xr)
681
if(highefx& FVB_SCANLINES)
685
for(x=xr;x;x--,src++)
690
*(uint32 *)dest=palettetranslate[*src];
698
if(highefx&FVB_SCANLINES)
699
dest+=pitch*(yscale>>1);
704
pinc=pitch-((xr*xscale)*3);
705
for(y=yr;y;y--,src+=256-xr)
709
if(highefx& FVB_SCANLINES)
713
for(x=xr;x;x--,src++)
718
uint32 tmp=palettetranslate[(uint32)*src];
720
*((uint8 *)dest+1)=tmp>>8;
721
*((uint8 *)dest+2)=tmp>>16;
724
//*(uint32 *)dest=palettetranslate[*src];
732
if(highefx&FVB_SCANLINES)
733
dest+=pitch*(yscale>>1);
738
pinc=pitch-((xr*xscale)<<1);
740
for(y=yr;y;y--,src+=256-xr)
744
if(highefx& FVB_SCANLINES)
748
for(x=xr;x;x--,src++)
753
*(uint16 *)dest=palettetranslate[*src];
761
if(highefx&FVB_SCANLINES)
762
dest+=pitch*(yscale>>1);
772
for(y=yr;y;y--,src+=256-xr)
776
*(uint32 *)dest=palettetranslate[(uint32)*src];
784
pinc=pitch-(xr+xr+xr);
785
for(y=yr;y;y--,src+=256-xr)
789
uint32 tmp=palettetranslate[(uint32)*src];
791
*((uint8 *)dest+1)=tmp>>8;
792
*((uint8 *)dest+2)=tmp>>16;
802
for(y=yr;y;y--,src+=256-xr)
806
*(uint32 *)dest=palettetranslate[*(uint16 *)src];
820
int mult = (silt == 3)?3:2;
823
hq3x_32((uint8 *)specbuf,(uint8*)specbuf32bpp,xr,yr,xr*3*sizeof(uint32));
825
hq2x_32((uint8 *)specbuf,(uint8*)specbuf32bpp,xr,yr,xr*2*sizeof(uint32));
828
Blit32to16(specbuf32bpp, (uint16*)destbackup, xr*mult, yr*mult, pitchbackup, backshiftr,backshiftl);
830
Blit32to24(specbuf32bpp, (uint8*)destbackup, xr*mult, yr*mult, pitchbackup);
835
hq3x_32((uint8 *)specbuf,destbackup,xr,yr,pitchbackup);
837
hq2x_32((uint8 *)specbuf,destbackup,xr,yr,pitchbackup);