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
32
33 #ifdef HAVE_CONFIG_H
34 #include <config.h>
35 #endif
36
37 #include "SDL.h"
38 #include "../screen.h"
39 #include "../video.h"
40
41 #include "hqx_common.h"
42 #include "hq3x.h"
43
44 /***************************************************************************/
45 /* HQ3x C implementation */
46
47 /*
48 * This effect is a rewritten implementation of the hq3x effect made by Maxim Stepin
49 */
50 static Uint16 *dst0, *dst1, *dst2, *src0, *src1, *src2;
51 static Uint16 height;
52
53 #ifdef I386_ASM
54 void hq3x_16_i386(Uint8*, Uint8*, int, int, int);
55 #endif
56
effect_hq3x_init(void)57 SDL_bool effect_hq3x_init(void)
58 {
59 #ifdef I386_ASM
60 /* init LUT & RGB2YUV table*/
61 InitLUTs();
62 tmps= SDL_CreateRGBSurface(SDL_SWSURFACE,visible_area.w, visible_area.h, 16, 0xF800, 0x7E0, 0x1F, 0);
63 #endif
64 return SDL_TRUE;
65 }
66
67 #ifndef I386_ASM
hq3x_16_def(Uint16 * dst0,Uint16 * dst1,Uint16 * dst2,Uint16 * src0,Uint16 * src1,Uint16 * src2,unsigned count)68 void hq3x_16_def(Uint16 *dst0, Uint16 *dst1, Uint16 *dst2, Uint16 *src0, Uint16 *src1, Uint16 *src2, unsigned count)
69 {
70 unsigned i;
71
72 for(i=0;i<count;++i) {
73 unsigned char mask;
74
75 Uint16 c[9];
76
77 c[1] = src0[0];
78 c[4] = src1[0];
79 c[7] = src2[0];
80
81 if (i>0) {
82 c[0] = src0[-1];
83 c[3] = src1[-1];
84 c[6] = src2[-1];
85 } else {
86 c[0] = c[1];
87 c[3] = c[4];
88 c[6] = c[7];
89 }
90
91 if (i<count-1) {
92 c[2] = src0[1];
93 c[5] = src1[1];
94 c[8] = src2[1];
95 } else {
96 c[2] = c[1];
97 c[5] = c[4];
98 c[8] = c[7];
99 }
100
101 mask = 0;
102
103 if (interp_16_diff(c[0], c[4]))
104 mask |= 1 << 0;
105 if (interp_16_diff(c[1], c[4]))
106 mask |= 1 << 1;
107 if (interp_16_diff(c[2], c[4]))
108 mask |= 1 << 2;
109 if (interp_16_diff(c[3], c[4]))
110 mask |= 1 << 3;
111 if (interp_16_diff(c[5], c[4]))
112 mask |= 1 << 4;
113 if (interp_16_diff(c[6], c[4]))
114 mask |= 1 << 5;
115 if (interp_16_diff(c[7], c[4]))
116 mask |= 1 << 6;
117 if (interp_16_diff(c[8], c[4]))
118 mask |= 1 << 7;
119
120 #define P0 dst0[0]
121 #define P1 dst0[1]
122 #define P2 dst0[2]
123 #define P3 dst1[0]
124 #define P4 dst1[1]
125 #define P5 dst1[2]
126 #define P6 dst2[0]
127 #define P7 dst2[1]
128 #define P8 dst2[2]
129 #define MUR interp_16_diff(c[1], c[5])
130 #define MDR interp_16_diff(c[5], c[7])
131 #define MDL interp_16_diff(c[7], c[3])
132 #define MUL interp_16_diff(c[3], c[1])
133 #define IC(p0) c[p0]
134 #define I11(p0,p1) interp_16_11(c[p0], c[p1])
135 #define I211(p0,p1,p2) interp_16_211(c[p0], c[p1], c[p2])
136 #define I31(p0,p1) interp_16_31(c[p0], c[p1])
137 #define I332(p0,p1,p2) interp_16_332(c[p0], c[p1], c[p2])
138 #define I431(p0,p1,p2) interp_16_431(c[p0], c[p1], c[p2])
139 #define I521(p0,p1,p2) interp_16_521(c[p0], c[p1], c[p2])
140 #define I53(p0,p1) interp_16_53(c[p0], c[p1])
141 #define I611(p0,p1,p2) interp_16_611(c[p0], c[p1], c[p2])
142 #define I71(p0,p1) interp_16_71(c[p0], c[p1])
143 #define I772(p0,p1,p2) interp_16_772(c[p0], c[p1], c[p2])
144 #define I97(p0,p1) interp_16_97(c[p0], c[p1])
145 #define I1411(p0,p1,p2) interp_16_1411(c[p0], c[p1], c[p2])
146 #define I151(p0,p1) interp_16_151(c[p0], c[p1])
147
148 switch (mask) {
149 #include "hq3x.dat"
150 }
151
152 #undef P0
153 #undef P1
154 #undef P2
155 #undef P3
156 #undef P4
157 #undef P5
158 #undef P6
159 #undef P7
160 #undef P8
161 #undef MUR
162 #undef MDR
163 #undef MDL
164 #undef MUL
165 #undef IC
166 #undef I11
167 #undef I211
168 #undef I31
169 #undef I332
170 #undef I431
171 #undef I521
172 #undef I53
173 #undef I611
174 #undef I71
175 #undef I772
176 #undef I97
177 #undef I1411
178 #undef I151
179
180 src0 += 1;
181 src1 += 1;
182 src2 += 1;
183 dst0 += 3;
184 dst1 += 3;
185 dst2 += 3;
186 }
187 }
188
effect_hq3x_update()189 void effect_hq3x_update()
190 {
191 height = visible_area.h;
192
193 dst0 = (Uint16 *)screen->pixels + yscreenpadding;
194 dst1 = (Uint16 *)dst0 + visible_area.w*3;
195 dst2 = (Uint16 *)dst1 + visible_area.w*3;
196
197 src1 = (Uint16 *)buffer->pixels + 352 * visible_area.y + visible_area.x;
198 src0 = (Uint16 *)src1 - 352;
199 src2 = (Uint16 *)src1 + 352;
200 while(height--)
201 {
202
203 hq3x_16_def(dst0, dst1, dst2, src0, src1, src2, visible_area.w);
204
205 dst0 += (visible_area.w*9);
206 dst1 += (visible_area.w*9);
207 dst2 += (visible_area.w*9);
208
209 src0 += 352;
210 src1 += 352;
211 src2 += 352;
212 }
213 }
214
215
216 #else
effect_hq3x_update(void)217 void effect_hq3x_update(void)
218 {
219 SDL_BlitSurface(buffer, &visible_area, tmps, &tmps_rect);
220 dst0 = (Uint16 *)screen->pixels + yscreenpadding;
221 src0 = (Uint16 *)tmps->pixels;
222 //src0 = (Uint16 *)buffer->pixels + 352 * visible_area.y + visible_area.x;
223
224 hq3x_16_i386((Uint8*)src0, (Uint8*)dst0, visible_area.w, visible_area.h, visible_area.w*6);
225 }
226
227 #endif
228