diff options
Diffstat (limited to 'src/r_filter.c')
-rw-r--r-- | src/r_filter.c | 119 |
1 files changed, 119 insertions, 0 deletions
diff --git a/src/r_filter.c b/src/r_filter.c new file mode 100644 index 0000000..4b44f14 --- /dev/null +++ b/src/r_filter.c | |||
@@ -0,0 +1,119 @@ | |||
1 | /* Emacs style mode select -*- C++ -*- | ||
2 | *----------------------------------------------------------------------------- | ||
3 | * | ||
4 | * | ||
5 | * PrBoom: a Doom port merged with LxDoom and LSDLDoom | ||
6 | * based on BOOM, a modified and improved DOOM engine | ||
7 | * Copyright (C) 1999 by | ||
8 | * id Software, Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman | ||
9 | * Copyright (C) 1999-2000 by | ||
10 | * Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze | ||
11 | * Copyright 2005, 2006 by | ||
12 | * Florian Schulze, Colin Phipps, Neil Stevens, Andrey Budko | ||
13 | * | ||
14 | * This program is free software; you can redistribute it and/or | ||
15 | * modify it under the terms of the GNU General Public License | ||
16 | * as published by the Free Software Foundation; either version 2 | ||
17 | * of the License, or (at your option) any later version. | ||
18 | * | ||
19 | * This program is distributed in the hope that it will be useful, | ||
20 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
21 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
22 | * GNU General Public License for more details. | ||
23 | * | ||
24 | * You should have received a copy of the GNU General Public License | ||
25 | * along with this program; if not, write to the Free Software | ||
26 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA | ||
27 | * 02111-1307, USA. | ||
28 | * | ||
29 | *-----------------------------------------------------------------------------*/ | ||
30 | |||
31 | #include "doomtype.h" | ||
32 | #include "r_filter.h" | ||
33 | |||
34 | #define DMR 16 | ||
35 | byte filter_ditherMatrix[DITHER_DIM][DITHER_DIM] = { | ||
36 | 0*DMR, 14*DMR, 3*DMR, 13*DMR, 11*DMR, 5*DMR, 8*DMR, 6*DMR, | ||
37 | 12*DMR, 2*DMR, 15*DMR, 1*DMR, 7*DMR, 9*DMR, 4*DMR, 10*DMR | ||
38 | }; | ||
39 | |||
40 | byte filter_roundedUVMap[FILTER_UVDIM*FILTER_UVDIM]; | ||
41 | byte filter_roundedRowMap[4*16]; | ||
42 | |||
43 | void R_FilterInit(void) { | ||
44 | int i,j,s,t; | ||
45 | |||
46 | // scale2x takes the following source: | ||
47 | // A B C | ||
48 | // D E F | ||
49 | // G H I | ||
50 | // | ||
51 | // and doubles the size of E to produce: | ||
52 | // E0 E1 | ||
53 | // E2 E3 | ||
54 | // | ||
55 | // E0 = D == B && B != F && D != H ? D : E; | ||
56 | // E1 = B == F && B != D && F != H ? F : E; | ||
57 | // E2 = D == H && D != B && H != F ? D : E; | ||
58 | // E3 = H == F && D != H && B != F ? F : E; | ||
59 | // | ||
60 | // to make this comparison regimen faster, we encode source color | ||
61 | // equivalency into a single byte with the getCode() macro | ||
62 | // | ||
63 | // #define getCode(b,f,h,d) ( (b == f)<<0 | (f == h)<<1 | (h == d)<<2 | (d == b)<<3 ) | ||
64 | |||
65 | // encode the scale2x conditionals into a lookup code | ||
66 | for (i=0; i<16; i++) { | ||
67 | // E0 = D == B && B != F && D != H ? D : E; // 10-0 => 1000 or 1010 => 8 or A | ||
68 | filter_roundedRowMap[0*16+i] = (i == 0x8 || i == 0xA) ? 0 : 1; | ||
69 | // E1 = B == F && B != D && F != H ? F : E; // 0-01 => 0101 or 0001 => 5 or 1 | ||
70 | filter_roundedRowMap[1*16+i] = (i == 0x5 || i == 0x1) ? 2 : 1; | ||
71 | // E2 = D == H && D != B && H != F ? D : E; // 010- => 0101 or 0100 => 5 or 4 | ||
72 | filter_roundedRowMap[2*16+i] = (i == 0x4 || i == 0x5) ? 0 : 1; | ||
73 | // E3 = H == F && D != H && B != F ? F : E; // -010 => 1010 or 0010 => A or 2 | ||
74 | filter_roundedRowMap[3*16+i] = (i == 0xA || i == 0x2) ? 2 : 1; | ||
75 | } | ||
76 | |||
77 | // fill the uvMap. this will return: | ||
78 | // 0/\1 | ||
79 | // /4 \ | ||
80 | // \ / | ||
81 | // 2\/3 | ||
82 | // .. based on the uv coordinates | ||
83 | for (i=0; i<FILTER_UVDIM; i++) { | ||
84 | for (j=0; j<FILTER_UVDIM; j++) { | ||
85 | s = (FILTER_UVDIM/2) - i; | ||
86 | t = (FILTER_UVDIM/2) - j; | ||
87 | if (s>=0 && t>=0) filter_roundedUVMap[i*FILTER_UVDIM+j] = (s+t > FILTER_UVDIM/2) ? 0 : 4; | ||
88 | else if (s>=0 && t<=0) filter_roundedUVMap[i*FILTER_UVDIM+j] = (s-t > FILTER_UVDIM/2) ? 2 : 4; | ||
89 | else if (s<=0 && t>=0) filter_roundedUVMap[i*FILTER_UVDIM+j] = (-s+t > FILTER_UVDIM/2) ? 1 : 4; | ||
90 | else if (s<=0 && t<=0) filter_roundedUVMap[i*FILTER_UVDIM+j] = (-s-t > FILTER_UVDIM/2) ? 3 : 4; | ||
91 | else filter_roundedUVMap[i*FILTER_UVDIM+j] = 4; | ||
92 | } | ||
93 | } | ||
94 | } | ||
95 | |||
96 | byte *filter_getScale2xQuadColors(byte e, byte b, byte f, byte h, byte d) { | ||
97 | // A B C | ||
98 | // D E F | ||
99 | // G H I | ||
100 | // perform the Scale2x algorithm (quickly) to get the new quad to represent E | ||
101 | static byte quad[5]; | ||
102 | static byte rowColors[3]; | ||
103 | int code; | ||
104 | |||
105 | rowColors[0] = d; | ||
106 | rowColors[1] = e; | ||
107 | rowColors[2] = f; | ||
108 | |||
109 | #define getCode(b,f,h,d) ( (b == f)<<0 | (f == h)<<1 | (h == d)<<2 | (d == b)<<3 ) | ||
110 | |||
111 | code = getCode(b,f,h,d); | ||
112 | quad[0] = rowColors[filter_roundedRowMap[0*16+code]]; | ||
113 | quad[1] = rowColors[filter_roundedRowMap[1*16+code]]; | ||
114 | quad[2] = rowColors[filter_roundedRowMap[2*16+code]]; | ||
115 | quad[3] = rowColors[filter_roundedRowMap[3*16+code]]; | ||
116 | quad[4] = e; | ||
117 | |||
118 | return quad; | ||
119 | } | ||