remove more unportable ASM, obsoleting C_CORE define
[rofl0r-VisualBoyAdvance.git] / src / hq2x.c
blob77b62a914ab203f44e663c2cfdecb04c16a7b9a9
1 /*
2 * This file is part of the Advance project.
4 * Copyright (C) 2003 Andrea Mazzoleni
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., 675 Mass Ave, Cambridge, MA 02139, USA.
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.
30 #include "System.h"
31 #include "interp.h"
33 /***************************************************************************/
34 /* HQ2x C implementation */
37 * This effect is a rewritten implementation of the hq2x effect made by Maxim Stepin
40 static void hq2x_16_def(u16* dst0, u16* dst1, const u16* src0, const u16* src1, const u16* src2, unsigned count)
42 unsigned i;
44 for(i=0;i<count;++i) {
45 unsigned char mask;
47 u16 c[9];
49 c[1] = src0[0];
50 c[4] = src1[0];
51 c[7] = src2[0];
53 if (i>0) {
54 c[0] = src0[-1];
55 c[3] = src1[-1];
56 c[6] = src2[-1];
57 } else {
58 c[0] = c[1];
59 c[3] = c[4];
60 c[6] = c[7];
63 if (i<count-1) {
64 c[2] = src0[1];
65 c[5] = src1[1];
66 c[8] = src2[1];
67 } else {
68 c[2] = c[1];
69 c[5] = c[4];
70 c[8] = c[7];
73 mask = 0;
75 if (interp_16_diff(c[0], c[4]))
76 mask |= 1 << 0;
77 if (interp_16_diff(c[1], c[4]))
78 mask |= 1 << 1;
79 if (interp_16_diff(c[2], c[4]))
80 mask |= 1 << 2;
81 if (interp_16_diff(c[3], c[4]))
82 mask |= 1 << 3;
83 if (interp_16_diff(c[5], c[4]))
84 mask |= 1 << 4;
85 if (interp_16_diff(c[6], c[4]))
86 mask |= 1 << 5;
87 if (interp_16_diff(c[7], c[4]))
88 mask |= 1 << 6;
89 if (interp_16_diff(c[8], c[4]))
90 mask |= 1 << 7;
92 #define P0 dst0[0]
93 #define P1 dst0[1]
94 #define P2 dst1[0]
95 #define P3 dst1[1]
96 #define MUR interp_16_diff(c[1], c[5])
97 #define MDR interp_16_diff(c[5], c[7])
98 #define MDL interp_16_diff(c[7], c[3])
99 #define MUL interp_16_diff(c[3], c[1])
100 #define IC(p0) c[p0]
101 #define I11(p0,p1) interp_16_11(c[p0], c[p1])
102 #define I211(p0,p1,p2) interp_16_211(c[p0], c[p1], c[p2])
103 #define I31(p0,p1) interp_16_31(c[p0], c[p1])
104 #define I332(p0,p1,p2) interp_16_332(c[p0], c[p1], c[p2])
105 #define I431(p0,p1,p2) interp_16_431(c[p0], c[p1], c[p2])
106 #define I521(p0,p1,p2) interp_16_521(c[p0], c[p1], c[p2])
107 #define I53(p0,p1) interp_16_53(c[p0], c[p1])
108 #define I611(p0,p1,p2) interp_16_611(c[p0], c[p1], c[p2])
109 #define I71(p0,p1) interp_16_71(c[p0], c[p1])
110 #define I772(p0,p1,p2) interp_16_772(c[p0], c[p1], c[p2])
111 #define I97(p0,p1) interp_16_97(c[p0], c[p1])
112 #define I1411(p0,p1,p2) interp_16_1411(c[p0], c[p1], c[p2])
113 #define I151(p0,p1) interp_16_151(c[p0], c[p1])
115 switch (mask) {
116 #include "hq2x.h"
119 #undef P0
120 #undef P1
121 #undef P2
122 #undef P3
123 #undef MUR
124 #undef MDR
125 #undef MDL
126 #undef MUL
127 #undef IC
128 #undef I11
129 #undef I211
130 #undef I31
131 #undef I332
132 #undef I431
133 #undef I521
134 #undef I53
135 #undef I611
136 #undef I71
137 #undef I772
138 #undef I97
139 #undef I1411
140 #undef I151
142 src0 += 1;
143 src1 += 1;
144 src2 += 1;
145 dst0 += 2;
146 dst1 += 2;
150 static void hq2x_32_def(u32* dst0, u32* dst1, const u32* src0, const u32* src1, const u32* src2, unsigned count)
152 unsigned i;
154 for(i=0;i<count;++i) {
155 unsigned char mask;
157 u32 c[9];
159 c[1] = src0[0];
160 c[4] = src1[0];
161 c[7] = src2[0];
163 if (i>0) {
164 c[0] = src0[-1];
165 c[3] = src1[-1];
166 c[6] = src2[-1];
167 } else {
168 c[0] = c[1];
169 c[3] = c[4];
170 c[6] = c[7];
173 if (i<count-1) {
174 c[2] = src0[1];
175 c[5] = src1[1];
176 c[8] = src2[1];
177 } else {
178 c[2] = c[1];
179 c[5] = c[4];
180 c[8] = c[7];
183 mask = 0;
185 if (interp_32_diff(c[0], c[4]))
186 mask |= 1 << 0;
187 if (interp_32_diff(c[1], c[4]))
188 mask |= 1 << 1;
189 if (interp_32_diff(c[2], c[4]))
190 mask |= 1 << 2;
191 if (interp_32_diff(c[3], c[4]))
192 mask |= 1 << 3;
193 if (interp_32_diff(c[5], c[4]))
194 mask |= 1 << 4;
195 if (interp_32_diff(c[6], c[4]))
196 mask |= 1 << 5;
197 if (interp_32_diff(c[7], c[4]))
198 mask |= 1 << 6;
199 if (interp_32_diff(c[8], c[4]))
200 mask |= 1 << 7;
202 #define P0 dst0[0]
203 #define P1 dst0[1]
204 #define P2 dst1[0]
205 #define P3 dst1[1]
206 #define MUR interp_32_diff(c[1], c[5])
207 #define MDR interp_32_diff(c[5], c[7])
208 #define MDL interp_32_diff(c[7], c[3])
209 #define MUL interp_32_diff(c[3], c[1])
210 #define IC(p0) c[p0]
211 #define I11(p0,p1) interp_32_11(c[p0], c[p1])
212 #define I211(p0,p1,p2) interp_32_211(c[p0], c[p1], c[p2])
213 #define I31(p0,p1) interp_32_31(c[p0], c[p1])
214 #define I332(p0,p1,p2) interp_32_332(c[p0], c[p1], c[p2])
215 #define I431(p0,p1,p2) interp_32_431(c[p0], c[p1], c[p2])
216 #define I521(p0,p1,p2) interp_32_521(c[p0], c[p1], c[p2])
217 #define I53(p0,p1) interp_32_53(c[p0], c[p1])
218 #define I611(p0,p1,p2) interp_32_611(c[p0], c[p1], c[p2])
219 #define I71(p0,p1) interp_32_71(c[p0], c[p1])
220 #define I772(p0,p1,p2) interp_32_772(c[p0], c[p1], c[p2])
221 #define I97(p0,p1) interp_32_97(c[p0], c[p1])
222 #define I1411(p0,p1,p2) interp_32_1411(c[p0], c[p1], c[p2])
223 #define I151(p0,p1) interp_32_151(c[p0], c[p1])
225 switch (mask) {
226 #include "hq2x.h"
229 #undef P0
230 #undef P1
231 #undef P2
232 #undef P3
233 #undef MUR
234 #undef MDR
235 #undef MDL
236 #undef MUL
237 #undef IC
238 #undef I11
239 #undef I211
240 #undef I31
241 #undef I332
242 #undef I431
243 #undef I521
244 #undef I53
245 #undef I611
246 #undef I71
247 #undef I772
248 #undef I97
249 #undef I1411
250 #undef I151
252 src0 += 1;
253 src1 += 1;
254 src2 += 1;
255 dst0 += 2;
256 dst1 += 2;
260 /***************************************************************************/
261 /* LQ2x C implementation */
264 * This effect is derived from the hq2x effect made by Maxim Stepin
267 static void lq2x_16_def(u16* dst0, u16* dst1, const u16* src0, const u16* src1, const u16* src2, unsigned count)
269 unsigned i;
271 for(i=0;i<count;++i) {
272 unsigned char mask;
274 u16 c[9];
276 c[1] = src0[0];
277 c[4] = src1[0];
278 c[7] = src2[0];
280 if (i>0) {
281 c[0] = src0[-1];
282 c[3] = src1[-1];
283 c[6] = src2[-1];
284 } else {
285 c[0] = c[1];
286 c[3] = c[4];
287 c[6] = c[7];
290 if (i<count-1) {
291 c[2] = src0[1];
292 c[5] = src1[1];
293 c[8] = src2[1];
294 } else {
295 c[2] = c[1];
296 c[5] = c[4];
297 c[8] = c[7];
300 mask = 0;
302 if (c[0] != c[4])
303 mask |= 1 << 0;
304 if (c[1] != c[4])
305 mask |= 1 << 1;
306 if (c[2] != c[4])
307 mask |= 1 << 2;
308 if (c[3] != c[4])
309 mask |= 1 << 3;
310 if (c[5] != c[4])
311 mask |= 1 << 4;
312 if (c[6] != c[4])
313 mask |= 1 << 5;
314 if (c[7] != c[4])
315 mask |= 1 << 6;
316 if (c[8] != c[4])
317 mask |= 1 << 7;
319 #define P0 dst0[0]
320 #define P1 dst0[1]
321 #define P2 dst1[0]
322 #define P3 dst1[1]
323 #define MUR (c[1] != c[5])
324 #define MDR (c[5] != c[7])
325 #define MDL (c[7] != c[3])
326 #define MUL (c[3] != c[1])
327 #define IC(p0) c[p0]
328 #define I11(p0,p1) interp_16_11(c[p0], c[p1])
329 #define I211(p0,p1,p2) interp_16_211(c[p0], c[p1], c[p2])
330 #define I31(p0,p1) interp_16_31(c[p0], c[p1])
331 #define I332(p0,p1,p2) interp_16_332(c[p0], c[p1], c[p2])
332 #define I431(p0,p1,p2) interp_16_431(c[p0], c[p1], c[p2])
333 #define I521(p0,p1,p2) interp_16_521(c[p0], c[p1], c[p2])
334 #define I53(p0,p1) interp_16_53(c[p0], c[p1])
335 #define I611(p0,p1,p2) interp_16_611(c[p0], c[p1], c[p2])
336 #define I71(p0,p1) interp_16_71(c[p0], c[p1])
337 #define I772(p0,p1,p2) interp_16_772(c[p0], c[p1], c[p2])
338 #define I97(p0,p1) interp_16_97(c[p0], c[p1])
339 #define I1411(p0,p1,p2) interp_16_1411(c[p0], c[p1], c[p2])
340 #define I151(p0,p1) interp_16_151(c[p0], c[p1])
342 switch (mask) {
343 #include "lq2x.h"
346 #undef P0
347 #undef P1
348 #undef P2
349 #undef P3
350 #undef MUR
351 #undef MDR
352 #undef MDL
353 #undef MUL
354 #undef IC
355 #undef I11
356 #undef I211
357 #undef I31
358 #undef I332
359 #undef I431
360 #undef I521
361 #undef I53
362 #undef I611
363 #undef I71
364 #undef I772
365 #undef I97
366 #undef I1411
367 #undef I151
369 src0 += 1;
370 src1 += 1;
371 src2 += 1;
372 dst0 += 2;
373 dst1 += 2;
377 static void lq2x_32_def(u32* dst0, u32* dst1, const u32* src0, const u32* src1, const u32* src2, unsigned count)
379 unsigned i;
381 for(i=0;i<count;++i) {
382 unsigned char mask;
384 u32 c[9];
386 c[1] = src0[0];
387 c[4] = src1[0];
388 c[7] = src2[0];
390 if (i>0) {
391 c[0] = src0[-1];
392 c[3] = src1[-1];
393 c[6] = src2[-1];
394 } else {
395 c[0] = c[1];
396 c[3] = c[4];
397 c[6] = c[7];
400 if (i<count-1) {
401 c[2] = src0[1];
402 c[5] = src1[1];
403 c[8] = src2[1];
404 } else {
405 c[2] = c[1];
406 c[5] = c[4];
407 c[8] = c[7];
410 mask = 0;
412 if (c[0] != c[4])
413 mask |= 1 << 0;
414 if (c[1] != c[4])
415 mask |= 1 << 1;
416 if (c[2] != c[4])
417 mask |= 1 << 2;
418 if (c[3] != c[4])
419 mask |= 1 << 3;
420 if (c[5] != c[4])
421 mask |= 1 << 4;
422 if (c[6] != c[4])
423 mask |= 1 << 5;
424 if (c[7] != c[4])
425 mask |= 1 << 6;
426 if (c[8] != c[4])
427 mask |= 1 << 7;
429 #define P0 dst0[0]
430 #define P1 dst0[1]
431 #define P2 dst1[0]
432 #define P3 dst1[1]
433 #define MUR (c[1] != c[5])
434 #define MDR (c[5] != c[7])
435 #define MDL (c[7] != c[3])
436 #define MUL (c[3] != c[1])
437 #define IC(p0) c[p0]
438 #define I11(p0,p1) interp_32_11(c[p0], c[p1])
439 #define I211(p0,p1,p2) interp_32_211(c[p0], c[p1], c[p2])
440 #define I31(p0,p1) interp_32_31(c[p0], c[p1])
441 #define I332(p0,p1,p2) interp_32_332(c[p0], c[p1], c[p2])
442 #define I431(p0,p1,p2) interp_32_431(c[p0], c[p1], c[p2])
443 #define I521(p0,p1,p2) interp_32_521(c[p0], c[p1], c[p2])
444 #define I53(p0,p1) interp_32_53(c[p0], c[p1])
445 #define I611(p0,p1,p2) interp_32_611(c[p0], c[p1], c[p2])
446 #define I71(p0,p1) interp_32_71(c[p0], c[p1])
447 #define I772(p0,p1,p2) interp_32_772(c[p0], c[p1], c[p2])
448 #define I97(p0,p1) interp_32_97(c[p0], c[p1])
449 #define I1411(p0,p1,p2) interp_32_1411(c[p0], c[p1], c[p2])
450 #define I151(p0,p1) interp_32_151(c[p0], c[p1])
452 switch (mask) {
453 #include "lq2x.h"
456 #undef P0
457 #undef P1
458 #undef P2
459 #undef P3
460 #undef MUR
461 #undef MDR
462 #undef MDL
463 #undef MUL
464 #undef IC
465 #undef I11
466 #undef I211
467 #undef I31
468 #undef I332
469 #undef I431
470 #undef I521
471 #undef I53
472 #undef I611
473 #undef I71
474 #undef I772
475 #undef I97
476 #undef I1411
477 #undef I151
479 src0 += 1;
480 src1 += 1;
481 src2 += 1;
482 dst0 += 2;
483 dst1 += 2;
487 void hq2x(u8 *srcPtr, u32 srcPitch, u8 * unused/* deltaPtr */,
488 u8 *dstPtr, u32 dstPitch, int width, int height)
490 u16 *dst0 = (u16 *)dstPtr;
491 u16 *dst1 = dst0 + (dstPitch >> 1);
493 u16 *src0 = (u16 *)srcPtr;
494 u16 *src1 = src0 + (srcPitch >> 1);
495 u16 *src2 = src1 + (srcPitch >> 1);
497 hq2x_16_def(dst0, dst1, src0, src0, src1, width);
499 int count = height;
501 count -= 2;
502 while(count) {
503 dst0 += dstPitch;
504 dst1 += dstPitch;
505 hq2x_16_def(dst0, dst1, src0, src1, src2, width);
506 src0 = src1;
507 src1 = src2;
508 src2 += srcPitch >> 1;
509 --count;
511 dst0 += dstPitch;
512 dst1 += dstPitch;
513 hq2x_16_def(dst0, dst1, src0, src1, src1, width);
516 void hq2x32(u8 *srcPtr, u32 srcPitch, u8 *unused /* deltaPtr */,
517 u8 *dstPtr, u32 dstPitch, int width, int height)
519 u32 *dst0 = (u32 *)dstPtr;
520 u32 *dst1 = dst0 + (dstPitch >> 2);
522 u32 *src0 = (u32 *)srcPtr;
523 u32 *src1 = src0 + (srcPitch >> 2);
524 u32 *src2 = src1 + (srcPitch >> 2);
525 hq2x_32_def(dst0, dst1, src0, src0, src1, width);
527 int count = height;
529 count -= 2;
530 while(count) {
531 dst0 += dstPitch >> 1;
532 dst1 += dstPitch >> 1;
533 hq2x_32_def(dst0, dst1, src0, src1, src2, width);
534 src0 = src1;
535 src1 = src2;
536 src2 += srcPitch >> 2;
537 --count;
539 dst0 += dstPitch >> 1;
540 dst1 += dstPitch >> 1;
541 hq2x_32_def(dst0, dst1, src0, src1, src1, width);
544 void lq2x(u8 *srcPtr, u32 srcPitch, u8 * unused/* deltaPtr */,
545 u8 *dstPtr, u32 dstPitch, int width, int height)
547 u16 *dst0 = (u16 *)dstPtr;
548 u16 *dst1 = dst0 + (dstPitch >> 1);
550 u16 *src0 = (u16 *)srcPtr;
551 u16 *src1 = src0 + (srcPitch >> 1);
552 u16 *src2 = src1 + (srcPitch >> 1);
554 lq2x_16_def(dst0, dst1, src0, src0, src1, width);
556 int count = height;
558 count -= 2;
559 while(count) {
560 dst0 += dstPitch;
561 dst1 += dstPitch;
562 lq2x_16_def(dst0, dst1, src0, src1, src2, width);
563 src0 = src1;
564 src1 = src2;
565 src2 += srcPitch >> 1;
566 --count;
568 dst0 += dstPitch;
569 dst1 += dstPitch;
570 lq2x_16_def(dst0, dst1, src0, src1, src1, width);
573 void lq2x32(u8 *srcPtr, u32 srcPitch, u8 * unused /* deltaPtr */,
574 u8 *dstPtr, u32 dstPitch, int width, int height)
576 u32 *dst0 = (u32 *)dstPtr;
577 u32 *dst1 = dst0 + (dstPitch >> 2);
579 u32 *src0 = (u32 *)srcPtr;
580 u32 *src1 = src0 + (srcPitch >> 2);
581 u32 *src2 = src1 + (srcPitch >> 2);
582 lq2x_32_def(dst0, dst1, src0, src0, src1, width);
584 int count = height;
586 count -= 2;
587 while(count) {
588 dst0 += dstPitch >> 1;
589 dst1 += dstPitch >> 1;
590 lq2x_32_def(dst0, dst1, src0, src1, src2, width);
591 src0 = src1;
592 src1 = src2;
593 src2 += srcPitch >> 2;
594 --count;
596 dst0 += dstPitch >> 1;
597 dst1 += dstPitch >> 1;
598 lq2x_32_def(dst0, dst1, src0, src1, src1, width);
601 void hq2x_init(unsigned bits_per_pixel)
603 interp_set(bits_per_pixel);