Pickle's port for this emu
[pcsx_rearmed.git] / plugins / dfxvideo / interp.h
1 /*
2  * This file is part of the Advance project.
3  *
4  * Copyright (C) 2003 Andrea Mazzoleni
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., 675 Mass Ave, Cambridge, MA 02139, USA.
19  *
20  * In addition, as a special exception, Andrea Mazzoleni
21  * gives permission to link the code of this program with
22  * the MAME library (or with modified versions of MAME that use the
23  * same license as MAME), and distribute linked combinations including
24  * the two.  You must obey the GNU General Public License in all
25  * respects for all of the code used other than MAME.  If you modify
26  * this file, you may extend this exception to your version of the
27  * file, but you are not obligated to do so.  If you do not wish to
28  * do so, delete this exception statement from your version.
29  */
30
31 #ifndef __INTERP_H
32 #define __INTERP_H
33
34 /***************************************************************************/
35 /* Basic types */
36
37 /***************************************************************************/
38 /* interpolation */
39
40 static unsigned interp_mask[2];
41 static unsigned interp_bits_per_pixel;
42
43 #define INTERP_16_MASK_1(v) (v & interp_mask[0])
44 #define INTERP_16_MASK_2(v) (v & interp_mask[1])
45
46 static __inline unsigned short interp_16_521(unsigned short p1, unsigned short p2, unsigned short p3)
47 {
48   return INTERP_16_MASK_1((INTERP_16_MASK_1(p1)*5 + INTERP_16_MASK_1(p2)*2 + INTERP_16_MASK_1(p3)*1) / 8)
49     | INTERP_16_MASK_2((INTERP_16_MASK_2(p1)*5 + INTERP_16_MASK_2(p2)*2 + INTERP_16_MASK_2(p3)*1) / 8);
50 }
51
52 static __inline unsigned short interp_16_332(unsigned short p1, unsigned short p2, unsigned short p3)
53 {
54   return INTERP_16_MASK_1((INTERP_16_MASK_1(p1)*3 + INTERP_16_MASK_1(p2)*3 + INTERP_16_MASK_1(p3)*2) / 8)
55     | INTERP_16_MASK_2((INTERP_16_MASK_2(p1)*3 + INTERP_16_MASK_2(p2)*3 + INTERP_16_MASK_2(p3)*2) / 8);
56 }
57
58 static __inline unsigned short interp_16_611(unsigned short p1, unsigned short p2, unsigned short p3)
59 {
60   return INTERP_16_MASK_1((INTERP_16_MASK_1(p1)*6 + INTERP_16_MASK_1(p2) + INTERP_16_MASK_1(p3)) / 8)
61     | INTERP_16_MASK_2((INTERP_16_MASK_2(p1)*6 + INTERP_16_MASK_2(p2) + INTERP_16_MASK_2(p3)) / 8);
62 }
63
64 static __inline unsigned short interp_16_71(unsigned short p1, unsigned short p2)
65 {
66   return INTERP_16_MASK_1((INTERP_16_MASK_1(p1)*7 + INTERP_16_MASK_1(p2)) / 8)
67     | INTERP_16_MASK_2((INTERP_16_MASK_2(p1)*7 + INTERP_16_MASK_2(p2)) / 8);
68 }
69
70 static __inline unsigned short interp_16_211(unsigned short p1, unsigned short p2, unsigned short p3)
71 {
72   return INTERP_16_MASK_1((INTERP_16_MASK_1(p1)*2 + INTERP_16_MASK_1(p2) + INTERP_16_MASK_1(p3)) / 4)
73     | INTERP_16_MASK_2((INTERP_16_MASK_2(p1)*2 + INTERP_16_MASK_2(p2) + INTERP_16_MASK_2(p3)) / 4);
74 }
75
76 static __inline unsigned short interp_16_772(unsigned short p1, unsigned short p2, unsigned short p3)
77 {
78   return INTERP_16_MASK_1(((INTERP_16_MASK_1(p1) + INTERP_16_MASK_1(p2))*7 + INTERP_16_MASK_1(p3)*2) / 16)
79     | INTERP_16_MASK_2(((INTERP_16_MASK_2(p1) + INTERP_16_MASK_2(p2))*7 + INTERP_16_MASK_2(p3)*2) / 16);
80 }
81
82 static __inline unsigned short interp_16_11(unsigned short p1, unsigned short p2)
83 {
84   return INTERP_16_MASK_1((INTERP_16_MASK_1(p1) + INTERP_16_MASK_1(p2)) / 2)
85     | INTERP_16_MASK_2((INTERP_16_MASK_2(p1) + INTERP_16_MASK_2(p2)) / 2);
86 }
87
88 static __inline unsigned short interp_16_31(unsigned short p1, unsigned short p2)
89 {
90   return INTERP_16_MASK_1((INTERP_16_MASK_1(p1)*3 + INTERP_16_MASK_1(p2)) / 4)
91     | INTERP_16_MASK_2((INTERP_16_MASK_2(p1)*3 + INTERP_16_MASK_2(p2)) / 4);
92 }
93
94 static __inline unsigned short interp_16_1411(unsigned short p1, unsigned short p2, unsigned short p3)
95 {
96   return INTERP_16_MASK_1((INTERP_16_MASK_1(p1)*14 + INTERP_16_MASK_1(p2) + INTERP_16_MASK_1(p3)) / 16)
97     | INTERP_16_MASK_2((INTERP_16_MASK_2(p1)*14 + INTERP_16_MASK_2(p2) + INTERP_16_MASK_2(p3)) / 16);
98 }
99
100 static __inline unsigned short interp_16_431(unsigned short p1, unsigned short p2, unsigned short p3)
101 {
102   return INTERP_16_MASK_1((INTERP_16_MASK_1(p1)*4 + INTERP_16_MASK_1(p2)*3 + INTERP_16_MASK_1(p3)) / 8)
103     | INTERP_16_MASK_2((INTERP_16_MASK_2(p1)*4 + INTERP_16_MASK_2(p2)*3 + INTERP_16_MASK_2(p3)) / 8);
104 }
105
106 static __inline unsigned short interp_16_53(unsigned short p1, unsigned short p2)
107 {
108   return INTERP_16_MASK_1((INTERP_16_MASK_1(p1)*5 + INTERP_16_MASK_1(p2)*3) / 8)
109     | INTERP_16_MASK_2((INTERP_16_MASK_2(p1)*5 + INTERP_16_MASK_2(p2)*3) / 8);
110 }
111
112 static __inline unsigned short interp_16_151(unsigned short p1, unsigned short p2)
113 {
114   return INTERP_16_MASK_1((INTERP_16_MASK_1(p1)*15 + INTERP_16_MASK_1(p2)) / 16)
115     | INTERP_16_MASK_2((INTERP_16_MASK_2(p1)*15 + INTERP_16_MASK_2(p2)) / 16);
116 }
117
118 static __inline unsigned short interp_16_97(unsigned short p1, unsigned short p2)
119 {
120   return INTERP_16_MASK_1((INTERP_16_MASK_1(p1)*9 + INTERP_16_MASK_1(p2)*7) / 16)
121     | INTERP_16_MASK_2((INTERP_16_MASK_2(p1)*9 + INTERP_16_MASK_2(p2)*7) / 16);
122 }
123
124 #define INTERP_32_MASK_1(v) (v & 0xFF00FF)
125 #define INTERP_32_MASK_2(v) (v & 0x00FF00)
126
127 static __inline unsigned int  interp_32_521(unsigned int  p1, unsigned int  p2, unsigned int  p3)
128 {
129   return INTERP_32_MASK_1((INTERP_32_MASK_1(p1)*5 + INTERP_32_MASK_1(p2)*2 + INTERP_32_MASK_1(p3)*1) / 8)
130     | INTERP_32_MASK_2((INTERP_32_MASK_2(p1)*5 + INTERP_32_MASK_2(p2)*2 + INTERP_32_MASK_2(p3)*1) / 8);
131 }
132
133 static __inline unsigned int  interp_32_332(unsigned int  p1, unsigned int  p2, unsigned int  p3)
134 {
135   return INTERP_32_MASK_1((INTERP_32_MASK_1(p1)*3 + INTERP_32_MASK_1(p2)*3 + INTERP_32_MASK_1(p3)*2) / 8)
136     | INTERP_32_MASK_2((INTERP_32_MASK_2(p1)*3 + INTERP_32_MASK_2(p2)*3 + INTERP_32_MASK_2(p3)*2) / 8);
137 }
138
139 static __inline unsigned int  interp_32_211(unsigned int  p1, unsigned int  p2, unsigned int  p3)
140 {
141   return INTERP_32_MASK_1((INTERP_32_MASK_1(p1)*2 + INTERP_32_MASK_1(p2) + INTERP_32_MASK_1(p3)) / 4)
142     | INTERP_32_MASK_2((INTERP_32_MASK_2(p1)*2 + INTERP_32_MASK_2(p2) + INTERP_32_MASK_2(p3)) / 4);
143 }
144
145 static __inline unsigned int  interp_32_611(unsigned int  p1, unsigned int  p2, unsigned int  p3)
146 {
147   return INTERP_32_MASK_1((INTERP_32_MASK_1(p1)*6 + INTERP_32_MASK_1(p2) + INTERP_32_MASK_1(p3)) / 8)
148     | INTERP_32_MASK_2((INTERP_32_MASK_2(p1)*6 + INTERP_32_MASK_2(p2) + INTERP_32_MASK_2(p3)) / 8);
149 }
150
151 static __inline unsigned int  interp_32_71(unsigned int  p1, unsigned int  p2)
152 {
153   return INTERP_32_MASK_1((INTERP_32_MASK_1(p1)*7 + INTERP_32_MASK_1(p2)) / 8)
154     | INTERP_32_MASK_2((INTERP_32_MASK_2(p1)*7 + INTERP_32_MASK_2(p2)) / 8);
155 }
156
157 static __inline unsigned int  interp_32_772(unsigned int  p1, unsigned int  p2, unsigned int  p3)
158 {
159   return INTERP_32_MASK_1(((INTERP_32_MASK_1(p1) + INTERP_32_MASK_1(p2))*7 + INTERP_32_MASK_1(p3)*2) / 16)
160     | INTERP_32_MASK_2(((INTERP_32_MASK_2(p1) + INTERP_32_MASK_2(p2))*7 + INTERP_32_MASK_2(p3)*2) / 16);
161 }
162
163 static __inline unsigned int  interp_32_11(unsigned int  p1, unsigned int  p2)
164 {
165   return INTERP_32_MASK_1((INTERP_32_MASK_1(p1) + INTERP_32_MASK_1(p2)) / 2)
166     | INTERP_32_MASK_2((INTERP_32_MASK_2(p1) + INTERP_32_MASK_2(p2)) / 2);
167 }
168
169 static __inline unsigned int  interp_32_31(unsigned int  p1, unsigned int  p2)
170 {
171   return INTERP_32_MASK_1((INTERP_32_MASK_1(p1)*3 + INTERP_32_MASK_1(p2)) / 4)
172     | INTERP_32_MASK_2((INTERP_32_MASK_2(p1)*3 + INTERP_32_MASK_2(p2)) / 4);
173 }
174
175 static __inline unsigned int  interp_32_1411(unsigned int  p1, unsigned int  p2, unsigned int  p3)
176 {
177   return INTERP_32_MASK_1((INTERP_32_MASK_1(p1)*14 + INTERP_32_MASK_1(p2) + INTERP_32_MASK_1(p3)) / 16)
178     | INTERP_32_MASK_2((INTERP_32_MASK_2(p1)*14 + INTERP_32_MASK_2(p2) + INTERP_32_MASK_2(p3)) / 16);
179 }
180
181 static __inline unsigned int  interp_32_431(unsigned int  p1, unsigned int  p2, unsigned int  p3)
182 {
183   return INTERP_32_MASK_1((INTERP_32_MASK_1(p1)*4 + INTERP_32_MASK_1(p2)*3 + INTERP_32_MASK_1(p3)) / 8)
184     | INTERP_32_MASK_2((INTERP_32_MASK_2(p1)*4 + INTERP_32_MASK_2(p2)*3 + INTERP_32_MASK_2(p3)) / 8);
185 }
186
187 static __inline unsigned int  interp_32_53(unsigned int  p1, unsigned int  p2)
188 {
189   return INTERP_32_MASK_1((INTERP_32_MASK_1(p1)*5 + INTERP_32_MASK_1(p2)*3) / 8)
190     | INTERP_32_MASK_2((INTERP_32_MASK_2(p1)*5 + INTERP_32_MASK_2(p2)*3) / 8);
191 }
192
193 static __inline unsigned int  interp_32_151(unsigned int  p1, unsigned int  p2)
194 {
195   return INTERP_32_MASK_1((INTERP_32_MASK_1(p1)*15 + INTERP_32_MASK_1(p2)) / 16)
196     | INTERP_32_MASK_2((INTERP_32_MASK_2(p1)*15 + INTERP_32_MASK_2(p2)) / 16);
197 }
198
199 static __inline unsigned int  interp_32_97(unsigned int  p1, unsigned int  p2)
200 {
201   return INTERP_32_MASK_1((INTERP_32_MASK_1(p1)*9 + INTERP_32_MASK_1(p2)*7) / 16)
202     | INTERP_32_MASK_2((INTERP_32_MASK_2(p1)*9 + INTERP_32_MASK_2(p2)*7) / 16);
203 }
204
205 /***************************************************************************/
206 /* diff */
207
208 #define INTERP_Y_LIMIT (0x30*4)
209 #define INTERP_U_LIMIT (0x07*4)
210 #define INTERP_V_LIMIT (0x06*8)
211
212 inline static int interp_16_diff(unsigned short p1, unsigned short p2)
213 {
214   int r, g, b;
215   int y, u, v;
216
217   if (p1 == p2)
218     return 0;
219
220   if (interp_bits_per_pixel == 16) {
221     b = (int)((p1 & 0x1F) - (p2 & 0x1F)) << 3;
222     g = (int)((p1 & 0x7E0) - (p2 & 0x7E0)) >> 3;
223     r = (int)((p1 & 0xF800) - (p2 & 0xF800)) >> 8;
224   } else {
225     b = (int)((p1 & 0x1F) - (p2 & 0x1F)) << 3;
226     g = (int)((p1 & 0x3E0) - (p2 & 0x3E0)) >> 2;
227     r = (int)((p1 & 0x7C00) - (p2 & 0x7C00)) >> 7;
228   }
229
230   y = r + g + b;
231   u = r - b;
232   v = -r + 2*g - b;
233
234   if (y < -INTERP_Y_LIMIT || y > INTERP_Y_LIMIT)
235     return 1;
236
237   if (u < -INTERP_U_LIMIT || u > INTERP_U_LIMIT)
238     return 1;
239
240   if (v < -INTERP_V_LIMIT || v > INTERP_V_LIMIT)
241     return 1;
242
243   return 0;
244 }
245
246 inline static int interp_32_diff(unsigned int  p1, unsigned int  p2)
247 {
248   int r, g, b;
249   int y, u, v;
250
251   if ((p1 & 0xF8F8F8) == (p2 & 0xF8F8F8))
252     return 0;
253
254   b = (int)((p1 & 0xFF) - (p2 & 0xFF));
255   g = (int)((p1 & 0xFF00) - (p2 & 0xFF00)) >> 8;
256   r = (int)((p1 & 0xFF0000) - (p2 & 0xFF0000)) >> 16;
257
258   y = r + g + b;
259   u = r - b;
260   v = -r + 2*g - b;
261
262   if (y < -INTERP_Y_LIMIT || y > INTERP_Y_LIMIT)
263     return 1;
264
265   if (u < -INTERP_U_LIMIT || u > INTERP_U_LIMIT)
266     return 1;
267
268   if (v < -INTERP_V_LIMIT || v > INTERP_V_LIMIT)
269     return 1;
270
271   return 0;
272 }
273
274 #if 0
275
276 static void interp_set(unsigned bits_per_pixel)
277 {
278   interp_bits_per_pixel = bits_per_pixel;
279
280   switch (bits_per_pixel) {
281   case 15 :
282     interp_mask[0] = 0x7C1F;
283     interp_mask[1] = 0x03E0;
284     break;
285   case 16 :
286     interp_mask[0] = 0xF81F;
287     interp_mask[1] = 0x07E0;
288     break;
289   case 32 :
290     interp_mask[0] = 0xFF00FF;
291     interp_mask[1] = 0x00FF00;
292     break;
293   }
294 }
295
296 #endif
297
298 #endif