more 0.98.15-like timing, but sound glitches
[fceu.git] / drivers / common / vidblit.c
1 /* FCE Ultra - NES/Famicom Emulator
2  *
3  * Copyright notice for this file:
4  *  Copyright (C) 2002 Ben Parnell
5  *
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.
10  *
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.
15  *
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
19  */
20
21 #include <stdlib.h>
22
23 #include "../../types.h"
24
25 static uint32 CBM[3];
26 static uint32 *palettetranslate=0;
27 static int Bpp; // BYTES per pixel
28
29
30 int InitBlitToHigh(int b, uint32 rmask, uint32 gmask, uint32 bmask)
31 {
32  Bpp=b;
33
34  if(Bpp<=1 || Bpp>4)
35   return(0);
36
37  if(Bpp==2)
38   palettetranslate=malloc(65536*4);
39  else if(Bpp>=3)
40   palettetranslate=malloc(256*4);
41  if(!palettetranslate)
42   return(0);
43
44  CBM[0]=rmask;
45  CBM[1]=gmask;
46  CBM[2]=bmask;
47  return(1);
48 }
49
50 void KillBlitToHigh(void)
51 {
52   free(palettetranslate);
53 }
54
55 void SetPaletteBlitToHigh(uint8 *src)
56 {
57              int cshiftr[3];
58              int cshiftl[3];
59              int a,x,z,y;
60
61              cshiftl[0]=cshiftl[1]=cshiftl[2]=-1;
62              for(a=0;a<3;a++)
63              {
64               for(x=0,y=-1,z=0;x<32;x++)
65               {
66                if(CBM[a]&(1<<x))
67                {
68                 if(cshiftl[a]==-1) cshiftl[a]=x;
69                 z++;
70                }
71               }
72               cshiftr[a]=(8-z);
73              }
74
75  switch(Bpp)
76  {
77     case 2:
78              for(x=0;x<65536;x++)
79              {
80               uint16 lower,upper;
81
82               lower=(src[((x&255)<<2)]>>cshiftr[0])<<cshiftl[0];
83               lower|=(src[((x&255)<<2)+1]>>cshiftr[1])<<cshiftl[1];
84               lower|=(src[((x&255)<<2)+2]>>cshiftr[2])<<cshiftl[2];
85               upper=(src[((x>>8)<<2)]>>cshiftr[0])<<cshiftl[0];
86               upper|=(src[((x>>8)<<2)+1]>>cshiftr[1])<<cshiftl[1];
87               upper|=(src[((x>>8)<<2)+2]>>cshiftr[2])<<cshiftl[2];
88
89               palettetranslate[x]=lower|(upper<<16);
90              }
91             break;
92     case 3:
93     case 4:
94             for(x=0;x<256;x++)
95             {
96              uint32 t;
97
98              t=src[(x<<2)]<<cshiftl[0];
99              t|=src[(x<<2)+1]<<cshiftl[1];
100              t|=src[(x<<2)+2]<<cshiftl[2];
101
102              palettetranslate[x]=t;
103             }
104             break;
105  }
106 }
107
108 void Blit8To8(uint8 *src, uint8 *dest, int xr, int yr, int pitch, int xscale, int yscale, int efx)
109 {
110  int x,y;
111  int pinc;
112
113  pinc=pitch-(xr*xscale);
114  if(xscale!=1 || yscale!=1)
115  {
116   if(efx)
117   {
118    for(y=yr;y;y--,/*dest+=pinc,*/src+=320-xr)
119    {
120     int doo=yscale-(yscale>>1);
121     do
122     {
123      for(x=xr;x;x--,src++)
124      {
125       int too=xscale;
126       do
127       {
128        *(uint8 *)dest=*(uint8 *)src;
129        dest++;
130       } while(--too);
131      }
132      src-=xr;
133      dest+=pinc;
134     } while(--doo);
135     //src-=xr*(yscale-(yscale>>1));
136     dest+=pitch*(yscale>>1);
137
138     src+=xr;
139    }
140
141   }
142   else
143   {
144    for(y=yr;y;y--,/*dest+=pinc,*/src+=320-xr)
145    {
146     int doo=yscale;
147     do
148     {
149      for(x=xr;x;x--,src++)
150      {
151       int too=xscale;
152       do
153       {
154        *(uint8 *)dest=*(uint8 *)src;
155        dest++;
156       } while(--too);
157      }
158      src-=xr;
159      dest+=pinc;
160     } while(--doo);
161     src+=xr;
162    }
163  }
164
165  }
166  else
167  {
168   for(y=yr;y;y--,dest+=pinc,src+=320-xr)
169    for(x=xr;x;x-=4,dest+=4,src+=4)
170     *(uint32 *)dest=*(uint32 *)src;
171  }
172 }
173
174 void Blit8ToHigh(uint8 *src, uint8 *dest, int xr, int yr, int pitch)
175 {
176  int x,y;
177  int pinc;
178
179  switch(Bpp)
180  {
181   case 4:
182    pinc=pitch-(xr<<2);
183    for(y=yr;y;y--)
184    {
185     for(x=xr;x;x--)
186     {
187      *(uint32 *)dest=palettetranslate[(uint32)*src];
188      dest+=4;
189      src++;
190     }
191     dest+=pinc;
192     src+=16;
193    }
194   break;
195
196   case 3:
197    pinc=pitch-(xr+xr+xr);
198    for(y=yr;y;y--)
199    {
200     for(x=xr;x;x--)
201     {
202      uint32 tmp;
203      tmp=palettetranslate[(uint32)*src];
204      *(uint16*)dest=(uint16)tmp;
205      *&dest[2]=(uint8)(tmp>>16);
206      dest+=3;
207      src++;
208     }
209     dest+=pinc;
210     src+=16;
211    }
212    break;
213
214   case 2:
215    pinc=pitch-(xr<<1);
216    for(y=yr;y;y--)
217    {
218     for(x=xr>>1;x;x--)
219     {
220      *(uint32 *)dest=palettetranslate[*(uint16 *)src];
221      dest+=4;
222      src+=2;
223     }
224     dest+=pinc;
225     src+=16;
226    }
227    break;
228  }
229 }