2
* OpenTyrian: A modern cross-platform port of Tyrian
3
* Copyright (C) 2007-2010 The OpenTyrian Development Team
6
* Copyright (C) 2001, 2002, 2003, 2004 Andrea Mazzoleni
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.
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.
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.
23
#include "video_scale.h"
30
static void no_scale( SDL_Surface *src_surface, SDL_Surface *dst_surface );
31
static void nn_32( SDL_Surface *src_surface, SDL_Surface *dst_surface );
32
static void nn_16( SDL_Surface *src_surface, SDL_Surface *dst_surface );
34
static void scale2x_32( SDL_Surface *src_surface, SDL_Surface *dst_surface );
35
static void scale2x_16( SDL_Surface *src_surface, SDL_Surface *dst_surface );
36
static void scale3x_32( SDL_Surface *src_surface, SDL_Surface *dst_surface );
37
static void scale3x_16( SDL_Surface *src_surface, SDL_Surface *dst_surface );
39
void hq2x_32( SDL_Surface *src_surface, SDL_Surface *dst_surface );
40
void hq3x_32( SDL_Surface *src_surface, SDL_Surface *dst_surface );
41
void hq4x_32( SDL_Surface *src_surface, SDL_Surface *dst_surface );
45
const struct Scalers scalers[] =
47
#if defined(TARGET_GP2X) || defined(TARGET_DINGUX)
48
{ 320, 240, no_scale, nn_16, nn_32, "None" },
50
{ 1 * vga_width, 1 * vga_height, no_scale, nn_16, nn_32, "None" },
51
{ 2 * vga_width, 2 * vga_height, NULL, nn_16, nn_32, "2x" },
52
{ 2 * vga_width, 2 * vga_height, NULL, scale2x_16, scale2x_32, "Scale2x" },
53
{ 2 * vga_width, 2 * vga_height, NULL, NULL, hq2x_32, "hq2x" },
54
{ 3 * vga_width, 3 * vga_height, NULL, nn_16, nn_32, "3x" },
55
{ 3 * vga_width, 3 * vga_height, NULL, scale3x_16, scale3x_32, "Scale3x" },
56
{ 3 * vga_width, 3 * vga_height, NULL, NULL, hq3x_32, "hq3x" },
57
{ 4 * vga_width, 4 * vga_height, NULL, nn_16, nn_32, "4x" },
58
{ 4 * vga_width, 4 * vga_height, NULL, NULL, hq4x_32, "hq4x" },
61
const uint scalers_count = COUNTOF(scalers);
63
void set_scaler_by_name( const char *name )
65
for (uint i = 0; i < scalers_count; ++i)
67
if (strcmp(name, scalers[i].name) == 0)
75
#if defined(TARGET_GP2X) || defined(TARGET_DINGUX)
79
void no_scale( SDL_Surface *src_surface, SDL_Surface *dst_surface )
81
Uint8 *src = src_surface->pixels,
82
*dst = dst_surface->pixels;
85
size_t blank = (dst_surface->h - src_surface->h) / 2 * dst_surface->pitch;
86
memset(dst, 0, blank);
90
memcpy(dst, src, src_surface->pitch * src_surface->h);
93
dst += src_surface->pitch * src_surface->h;
94
memset(dst, 0, blank);
99
void nn_32( SDL_Surface *src_surface, SDL_Surface *dst_surface )
101
Uint8 *src = src_surface->pixels, *src_temp,
102
*dst = dst_surface->pixels, *dst_temp;
103
int src_pitch = src_surface->pitch,
104
dst_pitch = dst_surface->pitch;
105
const int dst_Bpp = 4; // dst_surface->format->BytesPerPixel
107
const int height = vga_height, // src_surface->h
108
width = vga_width, // src_surface->w
109
scale = dst_surface->w / width;
110
assert(scale == dst_surface->h / height);
113
size_t blank = (dst_surface->h - src_surface->h) / 2 * dst_surface->pitch;
114
memset(dst, 0, blank);
118
for (int y = height; y > 0; y--)
123
for (int x = width; x > 0; x--)
125
for (int z = scale; z > 0; z--)
127
*(Uint32 *)dst = rgb_palette[*src];
133
src = src_temp + src_pitch;
134
dst = dst_temp + dst_pitch;
136
for (int z = scale; z > 1; z--)
138
memcpy(dst, dst_temp, dst_pitch);
144
memset(dst, 0, blank);
148
void nn_16( SDL_Surface *src_surface, SDL_Surface *dst_surface )
150
Uint8 *src = src_surface->pixels, *src_temp,
151
*dst = dst_surface->pixels, *dst_temp;
152
int src_pitch = src_surface->pitch,
153
dst_pitch = dst_surface->pitch;
154
const int dst_Bpp = 2; // dst_surface->format->BytesPerPixel
156
const int height = vga_height, // src_surface->h
157
width = vga_width, // src_surface->w
158
scale = dst_surface->w / width;
159
assert(scale == dst_surface->h / height);
162
size_t blank = (dst_surface->h - src_surface->h) / 2 * dst_surface->pitch;
163
memset(dst, 0, blank);
167
for (int y = height; y > 0; y--)
172
for (int x = width; x > 0; x--)
174
for (int z = scale; z > 0; z--)
176
*(Uint16 *)dst = rgb_palette[*src];
182
src = src_temp + src_pitch;
183
dst = dst_temp + dst_pitch;
185
for (int z = scale; z > 1; z--)
187
memcpy(dst, dst_temp, dst_pitch);
193
memset(dst, 0, blank);
198
void scale2x_32( SDL_Surface *src_surface, SDL_Surface *dst_surface )
200
Uint8 *src = src_surface->pixels, *src_temp,
201
*dst = dst_surface->pixels, *dst_temp;
202
int src_pitch = src_surface->pitch,
203
dst_pitch = dst_surface->pitch;
204
const int dst_Bpp = 4; // dst_surface->format->BytesPerPixel
206
const int height = vga_height, // src_surface->h
207
width = vga_width; // src_surface->w
209
int prevline, nextline;
211
Uint32 E0, E1, E2, E3, B, D, E, F, H;
212
for (int y = 0; y < height; y++)
217
prevline = (y > 0) ? -src_pitch : 0;
218
nextline = (y < height - 1) ? src_pitch : 0;
220
for (int x = 0; x < width; x++)
222
B = rgb_palette[*(src + prevline)];
223
D = rgb_palette[*(x > 0 ? src - 1 : src)];
224
E = rgb_palette[*src];
225
F = rgb_palette[*(x < width - 1 ? src + 1 : src)];
226
H = rgb_palette[*(src + nextline)];
228
if (B != H && D != F) {
234
E0 = E1 = E2 = E3 = E;
238
*(Uint32 *)(dst + dst_Bpp) = E1;
239
*(Uint32 *)(dst + dst_pitch) = E2;
240
*(Uint32 *)(dst + dst_pitch + dst_Bpp) = E3;
246
src = src_temp + src_pitch;
247
dst = dst_temp + 2 * dst_pitch;
251
void scale2x_16( SDL_Surface *src_surface, SDL_Surface *dst_surface )
253
Uint8 *src = src_surface->pixels, *src_temp,
254
*dst = dst_surface->pixels, *dst_temp;
255
int src_pitch = src_surface->pitch,
256
dst_pitch = dst_surface->pitch;
257
const int dst_Bpp = 2; // dst_surface->format->BytesPerPixel
259
const int height = vga_height, // src_surface->h
260
width = vga_width; // src_surface->w
262
int prevline, nextline;
264
Uint16 E0, E1, E2, E3, B, D, E, F, H;
265
for (int y = 0; y < height; y++)
270
prevline = (y > 0) ? -src_pitch : 0;
271
nextline = (y < height - 1) ? src_pitch : 0;
273
for (int x = 0; x < width; x++)
275
B = rgb_palette[*(src + prevline)];
276
D = rgb_palette[*(x > 0 ? src - 1 : src)];
277
E = rgb_palette[*src];
278
F = rgb_palette[*(x < width - 1 ? src + 1 : src)];
279
H = rgb_palette[*(src + nextline)];
281
if (B != H && D != F) {
287
E0 = E1 = E2 = E3 = E;
291
*(Uint16 *)(dst + dst_Bpp) = E1;
292
*(Uint16 *)(dst + dst_pitch) = E2;
293
*(Uint16 *)(dst + dst_pitch + dst_Bpp) = E3;
299
src = src_temp + src_pitch;
300
dst = dst_temp + 2 * dst_pitch;
305
void scale3x_32( SDL_Surface *src_surface, SDL_Surface *dst_surface )
307
Uint8 *src = src_surface->pixels, *src_temp,
308
*dst = dst_surface->pixels, *dst_temp;
309
int src_pitch = src_surface->pitch,
310
dst_pitch = dst_surface->pitch;
311
const int dst_Bpp = 4; // dst_surface->format->BytesPerPixel
313
const int height = vga_height, // src_surface->h
314
width = vga_width; // src_surface->w
316
int prevline, nextline;
318
Uint32 E0, E1, E2, E3, E4, E5, E6, E7, E8, A, B, C, D, E, F, G, H, I;
319
for (int y = 0; y < height; y++)
324
prevline = (y > 0) ? -src_pitch : 0;
325
nextline = (y < height - 1) ? src_pitch : 0;
327
for (int x = 0; x < width; x++)
329
A = rgb_palette[*(src + prevline - (x > 0 ? 1 : 0))];
330
B = rgb_palette[*(src + prevline)];
331
C = rgb_palette[*(src + prevline + (x < width - 1 ? 1 : 0))];
332
D = rgb_palette[*(src - (x > 0 ? 1 : 0))];
333
E = rgb_palette[*src];
334
F = rgb_palette[*(src + (x < width - 1 ? 1 : 0))];
335
G = rgb_palette[*(src + nextline - (x > 0 ? 1 : 0))];
336
H = rgb_palette[*(src + nextline)];
337
I = rgb_palette[*(src + nextline + (x < width - 1 ? 1 : 0))];
339
if (B != H && D != F) {
341
E1 = (D == B && E != C) || (B == F && E != A) ? B : E;
343
E3 = (D == B && E != G) || (D == H && E != A) ? D : E;
345
E5 = (B == F && E != I) || (H == F && E != C) ? F : E;
347
E7 = (D == H && E != I) || (H == F && E != G) ? H : E;
350
E0 = E1 = E2 = E3 = E4 = E5 = E6 = E7 = E8 = E;
354
*(Uint32 *)(dst + dst_Bpp) = E1;
355
*(Uint32 *)(dst + 2 * dst_Bpp) = E2;
356
*(Uint32 *)(dst + dst_pitch) = E3;
357
*(Uint32 *)(dst + dst_pitch + dst_Bpp) = E4;
358
*(Uint32 *)(dst + dst_pitch + 2 * dst_Bpp) = E5;
359
*(Uint32 *)(dst + 2 * dst_pitch) = E6;
360
*(Uint32 *)(dst + 2 * dst_pitch + dst_Bpp) = E7;
361
*(Uint32 *)(dst + 2 * dst_pitch + 2 * dst_Bpp) = E8;
367
src = src_temp + src_pitch;
368
dst = dst_temp + 3 * dst_pitch;
372
void scale3x_16( SDL_Surface *src_surface, SDL_Surface *dst_surface )
374
Uint8 *src = src_surface->pixels, *src_temp,
375
*dst = dst_surface->pixels, *dst_temp;
376
int src_pitch = src_surface->pitch,
377
dst_pitch = dst_surface->pitch;
378
const int dst_Bpp = 2; // dst_surface->format->BytesPerPixel
380
const int height = vga_height, // src_surface->h
381
width = vga_width; // src_surface->w
383
int prevline, nextline;
385
Uint16 E0, E1, E2, E3, E4, E5, E6, E7, E8, A, B, C, D, E, F, G, H, I;
386
for (int y = 0; y < height; y++)
391
prevline = (y > 0) ? -src_pitch : 0;
392
nextline = (y < height - 1) ? src_pitch : 0;
394
for (int x = 0; x < width; x++)
396
A = rgb_palette[*(src + prevline - (x > 0 ? 1 : 0))];
397
B = rgb_palette[*(src + prevline)];
398
C = rgb_palette[*(src + prevline + (x < width - 1 ? 1 : 0))];
399
D = rgb_palette[*(src - (x > 0 ? 1 : 0))];
400
E = rgb_palette[*src];
401
F = rgb_palette[*(src + (x < width - 1 ? 1 : 0))];
402
G = rgb_palette[*(src + nextline - (x > 0 ? 1 : 0))];
403
H = rgb_palette[*(src + nextline)];
404
I = rgb_palette[*(src + nextline + (x < width - 1 ? 1 : 0))];
406
if (B != H && D != F) {
408
E1 = (D == B && E != C) || (B == F && E != A) ? B : E;
410
E3 = (D == B && E != G) || (D == H && E != A) ? D : E;
412
E5 = (B == F && E != I) || (H == F && E != C) ? F : E;
414
E7 = (D == H && E != I) || (H == F && E != G) ? H : E;
417
E0 = E1 = E2 = E3 = E4 = E5 = E6 = E7 = E8 = E;
421
*(Uint16 *)(dst + dst_Bpp) = E1;
422
*(Uint16 *)(dst + 2 * dst_Bpp) = E2;
423
*(Uint16 *)(dst + dst_pitch) = E3;
424
*(Uint16 *)(dst + dst_pitch + dst_Bpp) = E4;
425
*(Uint16 *)(dst + dst_pitch + 2 * dst_Bpp) = E5;
426
*(Uint16 *)(dst + 2 * dst_pitch) = E6;
427
*(Uint16 *)(dst + 2 * dst_pitch + dst_Bpp) = E7;
428
*(Uint16 *)(dst + 2 * dst_pitch + 2 * dst_Bpp) = E8;
434
src = src_temp + src_pitch;
435
dst = dst_temp + 3 * dst_pitch;