1 // VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
2 // Copyright (C) 1999-2003 Forgotten
3 // Copyright (C) 2005 Forgotten and the VBA development team
4 
5 // This program is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation; either version 2, or(at your option)
8 // any later version.
9 //
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 // GNU General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software Foundation,
17 // Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 
19 #include "hq_shared32.h"
20 #include "interp.h"
21 
22 #define SIZE_PIXEL 2 // 16bit = 2 bytes
23 #define PIXELTYPE unsigned short
24 #define Interp1 Interp1_16
25 #define Interp2 Interp2_16
26 #define Interp3 Interp3_16
27 #define Interp4 Interp4_16
28 #define Interp5 Interp5_16
29 
hq3xS(unsigned char * pIn,unsigned int srcPitch,unsigned char *,unsigned char * pOut,unsigned int dstPitch,int Xres,int Yres)30 void hq3xS(unsigned char * pIn,  unsigned int srcPitch,
31 			unsigned char *,
32 			unsigned char * pOut, unsigned int dstPitch,
33 			int Xres, int Yres)
34 {
35 	int i, j;
36 	PIXELTYPE c[10];
37 
38 	// +----+----+----+
39 	// |    |    |    |
40 	// | c1 | c2 | c3 |
41 	// +----+----+----+
42 	// |    |    |    |
43 	// | c4 | c5 | c6 |
44 	// +----+----+----+
45 	// |    |    |    |
46 	// | c7 | c8 | c9 |
47 	// +----+----+----+
48 
49 	for (j=0; j<Yres; j++)
50 	{
51 		for (i=0; i<Xres; i++)
52 		{
53 			c[2] = *((PIXELTYPE*)(pIn - srcPitch));
54 			c[5] = *((PIXELTYPE*)(pIn        ));
55 			c[8] = *((PIXELTYPE*)(pIn + srcPitch));
56 
57 			c[1] = *((PIXELTYPE*)(pIn - srcPitch - SIZE_PIXEL));
58 			c[4] = *((PIXELTYPE*)(pIn        - SIZE_PIXEL));
59 			c[7] = *((PIXELTYPE*)(pIn + srcPitch - SIZE_PIXEL));
60 
61 			c[3] = *((PIXELTYPE*)(pIn - srcPitch + SIZE_PIXEL));
62 			c[6] = *((PIXELTYPE*)(pIn        + SIZE_PIXEL));
63 			c[9] = *((PIXELTYPE*)(pIn + srcPitch + SIZE_PIXEL));
64 
65 
66 			int pattern = 0;
67 
68 			// hq3xS dynamic edge detection:
69 			// simply comparing the center color against its surroundings will give bad results in many cases,
70 			// so, instead, compare the center color relative to the max difference in brightness of this 3x3 block
71 			int brightArray[10];
72 			int maxBright = 0, minBright = 999999;
73 			for(int j = 1 ; j < 10 ; j++)
74 			{
75 				int r,g,b;
76 				if (interp_bits_per_pixel == 16) {
77 					b = (int)((c[j] & 0x1F)) << 3;
78 					g = (int)((c[j] & 0x7E0)) >> 3;
79 					r = (int)((c[j] & 0xF800)) >> 8;
80 				} else {
81 					b = (int)((c[j] & 0x1F)) << 3;
82 					g = (int)((c[j] & 0x3E0)) >> 2;
83 					r = (int)((c[j] & 0x7C00)) >> 7;
84 				}
85 				const int bright = r+r+r + g+g+g + b+b;
86 				if(bright > maxBright) maxBright = bright;
87 				if(bright < minBright) minBright = bright;
88 
89 				brightArray[j] = bright;
90 			}
91 			const int diffBright = ((maxBright - minBright) * 7) >> 4;
92 			if(diffBright > 7)
93 			{
94 				#define ABS(x) ((x) < 0 ? -(x) : (x))
95 
96 				const int centerBright = brightArray[5];
97 				if(ABS(brightArray[1] - centerBright) > diffBright)
98 					pattern |= 1 << 0;
99 				if(ABS(brightArray[2] - centerBright) > diffBright)
100 					pattern |= 1 << 1;
101 				if(ABS(brightArray[3] - centerBright) > diffBright)
102 					pattern |= 1 << 2;
103 				if(ABS(brightArray[4] - centerBright) > diffBright)
104 					pattern |= 1 << 3;
105 				if(ABS(brightArray[6] - centerBright) > diffBright)
106 					pattern |= 1 << 4;
107 				if(ABS(brightArray[7] - centerBright) > diffBright)
108 					pattern |= 1 << 5;
109 				if(ABS(brightArray[8] - centerBright) > diffBright)
110 					pattern |= 1 << 6;
111 				if(ABS(brightArray[9] - centerBright) > diffBright)
112 					pattern |= 1 << 7;
113 			}
114 
115 #define Diff(x,y) false//(ABS((x) - (y)) > diffBright)
116 #undef cget
117 #define cget(x) brightArray[x]
118 #include "hq3xs.h"
119 #undef cget
120 #undef Diff
121 			pIn+=SIZE_PIXEL;
122 			pOut+=3<<1;
123 		}
124 		pIn+=srcPitch-(Xres<<1);
125 		pOut+=dstPitch-(3*Xres<<1);
126 		pOut+=dstPitch<<1;
127 		//	pIn+=SIZE_PIXEL;
128 		//	pOut+=3*SIZE_PIXEL;
129 		//}
130 		//pIn+=srcPitch-(4*Xres);
131 		//pOut+=dstPitch-(3*Xres*SIZE_PIXEL);
132 		//pOut+=2*dstPitch;
133 	}
134 }
135 
136 #undef Interp1
137 #undef Interp2
138 #undef Interp3
139 #undef Interp4
140 #undef Interp5
141 #undef SIZE_PIXEL
142 #undef PIXELTYPE
143 #define SIZE_PIXEL 4 // 32bit = 4 bytes
144 #define PIXELTYPE unsigned int
145 
hq3xS32(unsigned char * pIn,unsigned int srcPitch,unsigned char *,unsigned char * pOut,unsigned int dstPitch,int Xres,int Yres)146 void hq3xS32(unsigned char * pIn,  unsigned int srcPitch,
147 			unsigned char *,
148 			unsigned char * pOut, unsigned int dstPitch,
149 			int Xres, int Yres)
150 {
151 	int i, j;
152 	unsigned int line;
153 	PIXELTYPE c[10];
154 
155 	// +----+----+----+
156 	// |    |    |    |
157 	// | c1 | c2 | c3 |
158 	// +----+----+----+
159 	// |    |    |    |
160 	// | c4 | c5 | c6 |
161 	// +----+----+----+
162 	// |    |    |    |
163 	// | c7 | c8 | c9 |
164 	// +----+----+----+
165 
166 	for (j=0; j<Yres; j++)
167 	{
168 		if ( (j>0) && (j<Yres-1) )
169 			line = srcPitch;
170 		else
171 			line = 0;
172 
173 		for (i=0; i<Xres; i++)
174 		{
175 			c[2] = *((PIXELTYPE*)(pIn - line));
176 			c[5] = *((PIXELTYPE*)(pIn        ));
177 			c[8] = *((PIXELTYPE*)(pIn + line));
178 
179 			if (i>0)
180 			{
181 				c[1] = *((PIXELTYPE*)(pIn - line - SIZE_PIXEL));
182 				c[4] = *((PIXELTYPE*)(pIn        - SIZE_PIXEL));
183 				c[7] = *((PIXELTYPE*)(pIn + line - SIZE_PIXEL));
184 			}
185 			else
186 			{
187 				c[1] = c[2];
188 				c[4] = c[5];
189 				c[7] = c[8];
190 			}
191 
192 			if (i<Xres-1)
193 			{
194 				c[3] = *((PIXELTYPE*)(pIn - line + SIZE_PIXEL));
195 				c[6] = *((PIXELTYPE*)(pIn        + SIZE_PIXEL));
196 				c[9] = *((PIXELTYPE*)(pIn + line + SIZE_PIXEL));
197 			}
198 			else
199 			{
200 				c[3] = c[2];
201 				c[6] = c[5];
202 				c[9] = c[8];
203 			}
204 
205 			int pattern = 0;
206 
207 			// hq3xS dynamic edge detection:
208 			// simply comparing the center color against its surroundings will give bad results in many cases,
209 			// so, instead, compare the center color relative to the max difference in brightness of this 3x3 block
210 			int brightArray[10];
211 			int maxBright = 0, minBright = 999999;
212 			for(int j = 1 ; j < 10 ; j++)
213 			{
214 				const int b = (int)((c[j] & 0xF8));
215 				const int g = (int)((c[j] & 0xF800)) >> 8;
216 				const int r = (int)((c[j] & 0xF80000)) >> 16;
217 				const int bright = r+r+r + g+g+g + b+b;
218 				if(bright > maxBright) maxBright = bright;
219 				if(bright < minBright) minBright = bright;
220 
221 				brightArray[j] = bright;
222 			}
223 			int diffBright = ((maxBright - minBright) * 7) >> 4;
224 			if(diffBright > 7)
225 			{
226 				#define ABS(x) ((x) < 0 ? -(x) : (x))
227 
228 				const int centerBright = brightArray[5];
229 				if(ABS(brightArray[1] - centerBright) > diffBright)
230 					pattern |= 1 << 0;
231 				if(ABS(brightArray[2] - centerBright) > diffBright)
232 					pattern |= 1 << 1;
233 				if(ABS(brightArray[3] - centerBright) > diffBright)
234 					pattern |= 1 << 2;
235 				if(ABS(brightArray[4] - centerBright) > diffBright)
236 					pattern |= 1 << 3;
237 				if(ABS(brightArray[6] - centerBright) > diffBright)
238 					pattern |= 1 << 4;
239 				if(ABS(brightArray[7] - centerBright) > diffBright)
240 					pattern |= 1 << 5;
241 				if(ABS(brightArray[8] - centerBright) > diffBright)
242 					pattern |= 1 << 6;
243 				if(ABS(brightArray[9] - centerBright) > diffBright)
244 					pattern |= 1 << 7;
245 			}
246 
247 #define Diff(x,y) false//(ABS((x) - (y)) > diffBright)
248 #undef cget
249 #define cget(x) brightArray[x]
250 #include "hq3xs.h"
251 #undef cget
252 #undef Diff
253 			pIn+=SIZE_PIXEL;
254 			pOut+=3<<2;
255 		}
256 		pIn+=srcPitch-(Xres<<2);
257 		pOut+=dstPitch-(3*Xres<<2);
258 		pOut+=dstPitch<<1;
259 		//	pIn+=SIZE_PIXEL;
260 		//	pOut+=3*SIZE_PIXEL;
261 		//}
262 		//pIn+=srcPitch-(4*Xres);
263 		//pOut+=dstPitch-(3*Xres*SIZE_PIXEL);
264 		//pOut+=2*dstPitch;
265 	}
266 }
267