more 0.98.15-like timing, but sound glitches
[fceu.git] / drivers / common / vidblit.c
CommitLineData
c62d2810 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
25static uint32 CBM[3];
26static uint32 *palettetranslate=0;
27static int Bpp; // BYTES per pixel
28
29
30int InitBlitToHigh(int b, uint32 rmask, uint32 gmask, uint32 bmask)
31{
32 Bpp=b;
4fdfab07 33
c62d2810 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
50void KillBlitToHigh(void)
51{
52 free(palettetranslate);
53}
54
55void SetPaletteBlitToHigh(uint8 *src)
4fdfab07 56{
c62d2810 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
108void 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 {
4fdfab07 118 for(y=yr;y;y--,/*dest+=pinc,*/src+=320-xr)
c62d2810 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 {
4fdfab07 144 for(y=yr;y;y--,/*dest+=pinc,*/src+=320-xr)
c62d2810 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 }
4fdfab07 164
c62d2810 165 }
166 else
167 {
4fdfab07 168 for(y=yr;y;y--,dest+=pinc,src+=320-xr)
c62d2810 169 for(x=xr;x;x-=4,dest+=4,src+=4)
170 *(uint32 *)dest=*(uint32 *)src;
171 }
172}
173
174void 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}