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