Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
9169 | turbocat | 1 | /* |
2 | * OpenTyrian: A modern cross-platform port of Tyrian |
||
3 | * Copyright (C) 2007-2010 The OpenTyrian Development Team |
||
4 | * |
||
5 | * Scale2x, Scale3x |
||
6 | * Copyright (C) 2001, 2002, 2003, 2004 Andrea Mazzoleni |
||
7 | * |
||
8 | * This program is free software; you can redistribute it and/or |
||
9 | * modify it under the terms of the GNU General Public License |
||
10 | * as published by the Free Software Foundation; either version 2 |
||
11 | * of the License, or (at your option) any later version. |
||
12 | * |
||
13 | * This program is distributed in the hope that it will be useful, |
||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||
16 | * GNU General Public License for more details. |
||
17 | * |
||
18 | * You should have received a copy of the GNU General Public License |
||
19 | * along with this program; if not, write to the Free Software |
||
20 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
||
21 | */ |
||
22 | #include "video_scale.h" |
||
23 | |||
24 | #include "palette.h" |
||
25 | #include "video.h" |
||
26 | |||
27 | #include |
||
28 | |||
29 | static void no_scale( SDL_Surface *src_surface, SDL_Surface *dst_surface ); |
||
30 | static void nn_32( SDL_Surface *src_surface, SDL_Surface *dst_surface ); |
||
31 | static void nn_16( SDL_Surface *src_surface, SDL_Surface *dst_surface ); |
||
32 | |||
33 | static void scale2x_32( SDL_Surface *src_surface, SDL_Surface *dst_surface ); |
||
34 | static void scale2x_16( SDL_Surface *src_surface, SDL_Surface *dst_surface ); |
||
35 | static void scale3x_32( SDL_Surface *src_surface, SDL_Surface *dst_surface ); |
||
36 | static void scale3x_16( SDL_Surface *src_surface, SDL_Surface *dst_surface ); |
||
37 | |||
38 | void hq2x_32( SDL_Surface *src_surface, SDL_Surface *dst_surface ); |
||
39 | void hq3x_32( SDL_Surface *src_surface, SDL_Surface *dst_surface ); |
||
40 | void hq4x_32( SDL_Surface *src_surface, SDL_Surface *dst_surface ); |
||
41 | |||
42 | uint scaler; |
||
43 | |||
44 | const struct Scalers scalers[] = |
||
45 | { |
||
46 | #if defined(TARGET_GP2X) || defined(TARGET_DINGUX) |
||
47 | { 320, 240, no_scale, nn_16, nn_32, "None" }, |
||
48 | #else |
||
49 | { 1 * vga_width, 1 * vga_height, no_scale, nn_16, nn_32, "None" }, |
||
50 | { 2 * vga_width, 2 * vga_height, NULL, nn_16, nn_32, "2x" }, |
||
51 | { 2 * vga_width, 2 * vga_height, NULL, scale2x_16, scale2x_32, "Scale2x" }, |
||
52 | { 2 * vga_width, 2 * vga_height, NULL, NULL, hq2x_32, "hq2x" }, |
||
53 | { 3 * vga_width, 3 * vga_height, NULL, nn_16, nn_32, "3x" }, |
||
54 | { 3 * vga_width, 3 * vga_height, NULL, scale3x_16, scale3x_32, "Scale3x" }, |
||
55 | { 3 * vga_width, 3 * vga_height, NULL, NULL, hq3x_32, "hq3x" }, |
||
56 | { 4 * vga_width, 4 * vga_height, NULL, nn_16, nn_32, "4x" }, |
||
57 | { 4 * vga_width, 4 * vga_height, NULL, NULL, hq4x_32, "hq4x" }, |
||
58 | #endif |
||
59 | }; |
||
60 | const uint scalers_count = COUNTOF(scalers); |
||
61 | |||
62 | void set_scaler_by_name( const char *name ) |
||
63 | { |
||
64 | for (uint i = 0; i < scalers_count; ++i) |
||
65 | { |
||
66 | if (strcmp(name, scalers[i].name) == 0) |
||
67 | { |
||
68 | scaler = i; |
||
69 | break; |
||
70 | } |
||
71 | } |
||
72 | } |
||
73 | |||
74 | #if defined(TARGET_GP2X) || defined(TARGET_DINGUX) |
||
75 | #define VGA_CENTERED |
||
76 | #endif |
||
77 | |||
78 | void no_scale( SDL_Surface *src_surface, SDL_Surface *dst_surface ) |
||
79 | { |
||
80 | Uint8 *src = src_surface->pixels, |
||
81 | *dst = dst_surface->pixels; |
||
82 | |||
83 | #ifdef VGA_CENTERED |
||
84 | size_t blank = (dst_surface->h - src_surface->h) / 2 * dst_surface->pitch; |
||
85 | memset(dst, 0, blank); |
||
86 | dst += blank; |
||
87 | #endif |
||
88 | |||
89 | memcpy(dst, src, src_surface->pitch * src_surface->h); |
||
90 | |||
91 | #ifdef VGA_CENTERED |
||
92 | dst += src_surface->pitch * src_surface->h; |
||
93 | memset(dst, 0, blank); |
||
94 | #endif |
||
95 | } |
||
96 | |||
97 | |||
98 | void nn_32( SDL_Surface *src_surface, SDL_Surface *dst_surface ) |
||
99 | { |
||
100 | Uint8 *src = src_surface->pixels, *src_temp, |
||
101 | *dst = dst_surface->pixels, *dst_temp; |
||
102 | int src_pitch = src_surface->pitch, |
||
103 | dst_pitch = dst_surface->pitch; |
||
104 | const int dst_Bpp = 4; // dst_surface->format->BytesPerPixel |
||
105 | |||
106 | const int height = vga_height, // src_surface->h |
||
107 | width = vga_width, // src_surface->w |
||
108 | scale = dst_surface->w / width; |
||
109 | assert(scale == dst_surface->h / height); |
||
110 | |||
111 | #ifdef VGA_CENTERED |
||
112 | size_t blank = (dst_surface->h - src_surface->h) / 2 * dst_surface->pitch; |
||
113 | memset(dst, 0, blank); |
||
114 | dst += blank; |
||
115 | #endif |
||
116 | |||
117 | for (int y = height; y > 0; y--) |
||
118 | { |
||
119 | src_temp = src; |
||
120 | dst_temp = dst; |
||
121 | |||
122 | for (int x = width; x > 0; x--) |
||
123 | { |
||
124 | for (int z = scale; z > 0; z--) |
||
125 | { |
||
126 | *(Uint32 *)dst = rgb_palette[*src]; |
||
127 | dst += dst_Bpp; |
||
128 | } |
||
129 | src++; |
||
130 | } |
||
131 | |||
132 | src = src_temp + src_pitch; |
||
133 | dst = dst_temp + dst_pitch; |
||
134 | |||
135 | for (int z = scale; z > 1; z--) |
||
136 | { |
||
137 | memcpy(dst, dst_temp, dst_pitch); |
||
138 | dst += dst_pitch; |
||
139 | } |
||
140 | } |
||
141 | |||
142 | #ifdef VGA_CENTERED |
||
143 | memset(dst, 0, blank); |
||
144 | #endif |
||
145 | } |
||
146 | |||
147 | void nn_16( SDL_Surface *src_surface, SDL_Surface *dst_surface ) |
||
148 | { |
||
149 | Uint8 *src = src_surface->pixels, *src_temp, |
||
150 | *dst = dst_surface->pixels, *dst_temp; |
||
151 | int src_pitch = src_surface->pitch, |
||
152 | dst_pitch = dst_surface->pitch; |
||
153 | const int dst_Bpp = 2; // dst_surface->format->BytesPerPixel |
||
154 | |||
155 | const int height = vga_height, // src_surface->h |
||
156 | width = vga_width, // src_surface->w |
||
157 | scale = dst_surface->w / width; |
||
158 | assert(scale == dst_surface->h / height); |
||
159 | |||
160 | #ifdef VGA_CENTERED |
||
161 | size_t blank = (dst_surface->h - src_surface->h) / 2 * dst_surface->pitch; |
||
162 | memset(dst, 0, blank); |
||
163 | dst += blank; |
||
164 | #endif |
||
165 | |||
166 | for (int y = height; y > 0; y--) |
||
167 | { |
||
168 | src_temp = src; |
||
169 | dst_temp = dst; |
||
170 | |||
171 | for (int x = width; x > 0; x--) |
||
172 | { |
||
173 | for (int z = scale; z > 0; z--) |
||
174 | { |
||
175 | *(Uint16 *)dst = rgb_palette[*src]; |
||
176 | dst += dst_Bpp; |
||
177 | } |
||
178 | src++; |
||
179 | } |
||
180 | |||
181 | src = src_temp + src_pitch; |
||
182 | dst = dst_temp + dst_pitch; |
||
183 | |||
184 | for (int z = scale; z > 1; z--) |
||
185 | { |
||
186 | memcpy(dst, dst_temp, dst_pitch); |
||
187 | dst += dst_pitch; |
||
188 | } |
||
189 | } |
||
190 | |||
191 | #ifdef VGA_CENTERED |
||
192 | memset(dst, 0, blank); |
||
193 | #endif |
||
194 | } |
||
195 | |||
196 | |||
197 | void scale2x_32( SDL_Surface *src_surface, SDL_Surface *dst_surface ) |
||
198 | { |
||
199 | Uint8 *src = src_surface->pixels, *src_temp, |
||
200 | *dst = dst_surface->pixels, *dst_temp; |
||
201 | int src_pitch = src_surface->pitch, |
||
202 | dst_pitch = dst_surface->pitch; |
||
203 | const int dst_Bpp = 4; // dst_surface->format->BytesPerPixel |
||
204 | |||
205 | const int height = vga_height, // src_surface->h |
||
206 | width = vga_width; // src_surface->w |
||
207 | |||
208 | int prevline, nextline; |
||
209 | |||
210 | Uint32 E0, E1, E2, E3, B, D, E, F, H; |
||
211 | for (int y = 0; y < height; y++) |
||
212 | { |
||
213 | src_temp = src; |
||
214 | dst_temp = dst; |
||
215 | |||
216 | prevline = (y > 0) ? -src_pitch : 0; |
||
217 | nextline = (y < height - 1) ? src_pitch : 0; |
||
218 | |||
219 | for (int x = 0; x < width; x++) |
||
220 | { |
||
221 | B = rgb_palette[*(src + prevline)]; |
||
222 | D = rgb_palette[*(x > 0 ? src - 1 : src)]; |
||
223 | E = rgb_palette[*src]; |
||
224 | F = rgb_palette[*(x < width - 1 ? src + 1 : src)]; |
||
225 | H = rgb_palette[*(src + nextline)]; |
||
226 | |||
227 | if (B != H && D != F) { |
||
228 | E0 = D == B ? D : E; |
||
229 | E1 = B == F ? F : E; |
||
230 | E2 = D == H ? D : E; |
||
231 | E3 = H == F ? F : E; |
||
232 | } else { |
||
233 | E0 = E1 = E2 = E3 = E; |
||
234 | } |
||
235 | |||
236 | *(Uint32 *)dst = E0; |
||
237 | *(Uint32 *)(dst + dst_Bpp) = E1; |
||
238 | *(Uint32 *)(dst + dst_pitch) = E2; |
||
239 | *(Uint32 *)(dst + dst_pitch + dst_Bpp) = E3; |
||
240 | |||
241 | src++; |
||
242 | dst += 2 * dst_Bpp; |
||
243 | } |
||
244 | |||
245 | src = src_temp + src_pitch; |
||
246 | dst = dst_temp + 2 * dst_pitch; |
||
247 | } |
||
248 | } |
||
249 | |||
250 | void scale2x_16( SDL_Surface *src_surface, SDL_Surface *dst_surface ) |
||
251 | { |
||
252 | Uint8 *src = src_surface->pixels, *src_temp, |
||
253 | *dst = dst_surface->pixels, *dst_temp; |
||
254 | int src_pitch = src_surface->pitch, |
||
255 | dst_pitch = dst_surface->pitch; |
||
256 | const int dst_Bpp = 2; // dst_surface->format->BytesPerPixel |
||
257 | |||
258 | const int height = vga_height, // src_surface->h |
||
259 | width = vga_width; // src_surface->w |
||
260 | |||
261 | int prevline, nextline; |
||
262 | |||
263 | Uint16 E0, E1, E2, E3, B, D, E, F, H; |
||
264 | for (int y = 0; y < height; y++) |
||
265 | { |
||
266 | src_temp = src; |
||
267 | dst_temp = dst; |
||
268 | |||
269 | prevline = (y > 0) ? -src_pitch : 0; |
||
270 | nextline = (y < height - 1) ? src_pitch : 0; |
||
271 | |||
272 | for (int x = 0; x < width; x++) |
||
273 | { |
||
274 | B = rgb_palette[*(src + prevline)]; |
||
275 | D = rgb_palette[*(x > 0 ? src - 1 : src)]; |
||
276 | E = rgb_palette[*src]; |
||
277 | F = rgb_palette[*(x < width - 1 ? src + 1 : src)]; |
||
278 | H = rgb_palette[*(src + nextline)]; |
||
279 | |||
280 | if (B != H && D != F) { |
||
281 | E0 = D == B ? D : E; |
||
282 | E1 = B == F ? F : E; |
||
283 | E2 = D == H ? D : E; |
||
284 | E3 = H == F ? F : E; |
||
285 | } else { |
||
286 | E0 = E1 = E2 = E3 = E; |
||
287 | } |
||
288 | |||
289 | *(Uint16 *)dst = E0; |
||
290 | *(Uint16 *)(dst + dst_Bpp) = E1; |
||
291 | *(Uint16 *)(dst + dst_pitch) = E2; |
||
292 | *(Uint16 *)(dst + dst_pitch + dst_Bpp) = E3; |
||
293 | |||
294 | src++; |
||
295 | dst += 2 * dst_Bpp; |
||
296 | } |
||
297 | |||
298 | src = src_temp + src_pitch; |
||
299 | dst = dst_temp + 2 * dst_pitch; |
||
300 | } |
||
301 | } |
||
302 | |||
303 | |||
304 | void scale3x_32( SDL_Surface *src_surface, SDL_Surface *dst_surface ) |
||
305 | { |
||
306 | Uint8 *src = src_surface->pixels, *src_temp, |
||
307 | *dst = dst_surface->pixels, *dst_temp; |
||
308 | int src_pitch = src_surface->pitch, |
||
309 | dst_pitch = dst_surface->pitch; |
||
310 | const int dst_Bpp = 4; // dst_surface->format->BytesPerPixel |
||
311 | |||
312 | const int height = vga_height, // src_surface->h |
||
313 | width = vga_width; // src_surface->w |
||
314 | |||
315 | int prevline, nextline; |
||
316 | |||
317 | Uint32 E0, E1, E2, E3, E4, E5, E6, E7, E8, A, B, C, D, E, F, G, H, I; |
||
318 | for (int y = 0; y < height; y++) |
||
319 | { |
||
320 | src_temp = src; |
||
321 | dst_temp = dst; |
||
322 | |||
323 | prevline = (y > 0) ? -src_pitch : 0; |
||
324 | nextline = (y < height - 1) ? src_pitch : 0; |
||
325 | |||
326 | for (int x = 0; x < width; x++) |
||
327 | { |
||
328 | A = rgb_palette[*(src + prevline - (x > 0 ? 1 : 0))]; |
||
329 | B = rgb_palette[*(src + prevline)]; |
||
330 | C = rgb_palette[*(src + prevline + (x < width - 1 ? 1 : 0))]; |
||
331 | D = rgb_palette[*(src - (x > 0 ? 1 : 0))]; |
||
332 | E = rgb_palette[*src]; |
||
333 | F = rgb_palette[*(src + (x < width - 1 ? 1 : 0))]; |
||
334 | G = rgb_palette[*(src + nextline - (x > 0 ? 1 : 0))]; |
||
335 | H = rgb_palette[*(src + nextline)]; |
||
336 | I = rgb_palette[*(src + nextline + (x < width - 1 ? 1 : 0))]; |
||
337 | |||
338 | if (B != H && D != F) { |
||
339 | E0 = D == B ? D : E; |
||
340 | E1 = (D == B && E != C) || (B == F && E != A) ? B : E; |
||
341 | E2 = B == F ? F : E; |
||
342 | E3 = (D == B && E != G) || (D == H && E != A) ? D : E; |
||
343 | E4 = E; |
||
344 | E5 = (B == F && E != I) || (H == F && E != C) ? F : E; |
||
345 | E6 = D == H ? D : E; |
||
346 | E7 = (D == H && E != I) || (H == F && E != G) ? H : E; |
||
347 | E8 = H == F ? F : E; |
||
348 | } else { |
||
349 | E0 = E1 = E2 = E3 = E4 = E5 = E6 = E7 = E8 = E; |
||
350 | } |
||
351 | |||
352 | *(Uint32 *)dst = E0; |
||
353 | *(Uint32 *)(dst + dst_Bpp) = E1; |
||
354 | *(Uint32 *)(dst + 2 * dst_Bpp) = E2; |
||
355 | *(Uint32 *)(dst + dst_pitch) = E3; |
||
356 | *(Uint32 *)(dst + dst_pitch + dst_Bpp) = E4; |
||
357 | *(Uint32 *)(dst + dst_pitch + 2 * dst_Bpp) = E5; |
||
358 | *(Uint32 *)(dst + 2 * dst_pitch) = E6; |
||
359 | *(Uint32 *)(dst + 2 * dst_pitch + dst_Bpp) = E7; |
||
360 | *(Uint32 *)(dst + 2 * dst_pitch + 2 * dst_Bpp) = E8; |
||
361 | |||
362 | src++; |
||
363 | dst += 3 * dst_Bpp; |
||
364 | } |
||
365 | |||
366 | src = src_temp + src_pitch; |
||
367 | dst = dst_temp + 3 * dst_pitch; |
||
368 | } |
||
369 | } |
||
370 | |||
371 | void scale3x_16( SDL_Surface *src_surface, SDL_Surface *dst_surface ) |
||
372 | { |
||
373 | Uint8 *src = src_surface->pixels, *src_temp, |
||
374 | *dst = dst_surface->pixels, *dst_temp; |
||
375 | int src_pitch = src_surface->pitch, |
||
376 | dst_pitch = dst_surface->pitch; |
||
377 | const int dst_Bpp = 2; // dst_surface->format->BytesPerPixel |
||
378 | |||
379 | const int height = vga_height, // src_surface->h |
||
380 | width = vga_width; // src_surface->w |
||
381 | |||
382 | int prevline, nextline; |
||
383 | |||
384 | Uint16 E0, E1, E2, E3, E4, E5, E6, E7, E8, A, B, C, D, E, F, G, H, I; |
||
385 | for (int y = 0; y < height; y++) |
||
386 | { |
||
387 | src_temp = src; |
||
388 | dst_temp = dst; |
||
389 | |||
390 | prevline = (y > 0) ? -src_pitch : 0; |
||
391 | nextline = (y < height - 1) ? src_pitch : 0; |
||
392 | |||
393 | for (int x = 0; x < width; x++) |
||
394 | { |
||
395 | A = rgb_palette[*(src + prevline - (x > 0 ? 1 : 0))]; |
||
396 | B = rgb_palette[*(src + prevline)]; |
||
397 | C = rgb_palette[*(src + prevline + (x < width - 1 ? 1 : 0))]; |
||
398 | D = rgb_palette[*(src - (x > 0 ? 1 : 0))]; |
||
399 | E = rgb_palette[*src]; |
||
400 | F = rgb_palette[*(src + (x < width - 1 ? 1 : 0))]; |
||
401 | G = rgb_palette[*(src + nextline - (x > 0 ? 1 : 0))]; |
||
402 | H = rgb_palette[*(src + nextline)]; |
||
403 | I = rgb_palette[*(src + nextline + (x < width - 1 ? 1 : 0))]; |
||
404 | |||
405 | if (B != H && D != F) { |
||
406 | E0 = D == B ? D : E; |
||
407 | E1 = (D == B && E != C) || (B == F && E != A) ? B : E; |
||
408 | E2 = B == F ? F : E; |
||
409 | E3 = (D == B && E != G) || (D == H && E != A) ? D : E; |
||
410 | E4 = E; |
||
411 | E5 = (B == F && E != I) || (H == F && E != C) ? F : E; |
||
412 | E6 = D == H ? D : E; |
||
413 | E7 = (D == H && E != I) || (H == F && E != G) ? H : E; |
||
414 | E8 = H == F ? F : E; |
||
415 | } else { |
||
416 | E0 = E1 = E2 = E3 = E4 = E5 = E6 = E7 = E8 = E; |
||
417 | } |
||
418 | |||
419 | *(Uint16 *)dst = E0; |
||
420 | *(Uint16 *)(dst + dst_Bpp) = E1; |
||
421 | *(Uint16 *)(dst + 2 * dst_Bpp) = E2; |
||
422 | *(Uint16 *)(dst + dst_pitch) = E3; |
||
423 | *(Uint16 *)(dst + dst_pitch + dst_Bpp) = E4; |
||
424 | *(Uint16 *)(dst + dst_pitch + 2 * dst_Bpp) = E5; |
||
425 | *(Uint16 *)(dst + 2 * dst_pitch) = E6; |
||
426 | *(Uint16 *)(dst + 2 * dst_pitch + dst_Bpp) = E7; |
||
427 | *(Uint16 *)(dst + 2 * dst_pitch + 2 * dst_Bpp) = E8; |
||
428 | |||
429 | src++; |
||
430 | dst += 3 * dst_Bpp; |
||
431 | } |
||
432 | |||
433 | src = src_temp + src_pitch; |
||
434 | dst = dst_temp + 3 * dst_pitch; |
||
435 | } |
||
436 | }>>>>>>>>>>>>>>>>>>>>> |
||
437 |