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