diff options
Diffstat (limited to 'src/r_drawcolumn.inl')
-rw-r--r-- | src/r_drawcolumn.inl | 378 |
1 files changed, 378 insertions, 0 deletions
diff --git a/src/r_drawcolumn.inl b/src/r_drawcolumn.inl new file mode 100644 index 0000000..199a24e --- /dev/null +++ b/src/r_drawcolumn.inl | |||
@@ -0,0 +1,378 @@ | |||
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 | |||
32 | #if (R_DRAWCOLUMN_PIPELINE_BITS == 8) | ||
33 | #define SCREENTYPE byte | ||
34 | #define TEMPBUF byte_tempbuf | ||
35 | #elif (R_DRAWCOLUMN_PIPELINE_BITS == 15) | ||
36 | #define SCREENTYPE unsigned short | ||
37 | #define TEMPBUF short_tempbuf | ||
38 | #elif (R_DRAWCOLUMN_PIPELINE_BITS == 16) | ||
39 | #define SCREENTYPE unsigned short | ||
40 | #define TEMPBUF short_tempbuf | ||
41 | #elif (R_DRAWCOLUMN_PIPELINE_BITS == 32) | ||
42 | #define SCREENTYPE unsigned int | ||
43 | #define TEMPBUF int_tempbuf | ||
44 | #endif | ||
45 | |||
46 | #define GETDESTCOLOR8(col) (col) | ||
47 | #define GETDESTCOLOR15(col) (col) | ||
48 | #define GETDESTCOLOR16(col) (col) | ||
49 | #define GETDESTCOLOR32(col) (col) | ||
50 | |||
51 | #if (R_DRAWCOLUMN_PIPELINE & RDC_TRANSLATED) | ||
52 | #define GETCOL8_MAPPED(col) (translation[(col)]) | ||
53 | #else | ||
54 | #define GETCOL8_MAPPED(col) (col) | ||
55 | #endif | ||
56 | |||
57 | #if (R_DRAWCOLUMN_PIPELINE & RDC_NOCOLMAP) | ||
58 | #define GETCOL8_DEPTH(col) GETCOL8_MAPPED(col) | ||
59 | #else | ||
60 | #if (R_DRAWCOLUMN_PIPELINE & RDC_DITHERZ) | ||
61 | #define GETCOL8_DEPTH(col) (dither_colormaps[filter_getDitheredPixelLevel(x, y, fracz)][GETCOL8_MAPPED(col)]) | ||
62 | #else | ||
63 | #define GETCOL8_DEPTH(col) colormap[GETCOL8_MAPPED(col)] | ||
64 | #endif | ||
65 | #endif | ||
66 | |||
67 | #if (R_DRAWCOLUMN_PIPELINE & RDC_BILINEAR) | ||
68 | #define GETCOL8(frac, nextfrac) GETCOL8_DEPTH(filter_getDitheredForColumn(x,y,frac,nextfrac)) | ||
69 | #define GETCOL15(frac, nextfrac) filter_getFilteredForColumn15(GETCOL8_DEPTH,frac,nextfrac) | ||
70 | #define GETCOL16(frac, nextfrac) filter_getFilteredForColumn16(GETCOL8_DEPTH,frac,nextfrac) | ||
71 | #define GETCOL32(frac, nextfrac) filter_getFilteredForColumn32(GETCOL8_DEPTH,frac,nextfrac) | ||
72 | #elif (R_DRAWCOLUMN_PIPELINE & RDC_ROUNDED) | ||
73 | #define GETCOL8(frac, nextfrac) GETCOL8_DEPTH(filter_getRoundedForColumn(frac,nextfrac)) | ||
74 | #define GETCOL15(frac, nextfrac) VID_PAL15(GETCOL8_DEPTH(filter_getRoundedForColumn(frac,nextfrac)), VID_COLORWEIGHTMASK) | ||
75 | #define GETCOL16(frac, nextfrac) VID_PAL16(GETCOL8_DEPTH(filter_getRoundedForColumn(frac,nextfrac)), VID_COLORWEIGHTMASK) | ||
76 | #define GETCOL32(frac, nextfrac) VID_PAL32(GETCOL8_DEPTH(filter_getRoundedForColumn(frac,nextfrac)), VID_COLORWEIGHTMASK) | ||
77 | #else | ||
78 | #define GETCOL8(frac, nextfrac) GETCOL8_DEPTH(source[(frac)>>FRACBITS]) | ||
79 | #define GETCOL15(frac, nextfrac) VID_PAL15(GETCOL8_DEPTH(source[(frac)>>FRACBITS]), VID_COLORWEIGHTMASK) | ||
80 | #define GETCOL16(frac, nextfrac) VID_PAL16(GETCOL8_DEPTH(source[(frac)>>FRACBITS]), VID_COLORWEIGHTMASK) | ||
81 | #define GETCOL32(frac, nextfrac) VID_PAL32(GETCOL8_DEPTH(source[(frac)>>FRACBITS]), VID_COLORWEIGHTMASK) | ||
82 | #endif | ||
83 | |||
84 | #if (R_DRAWCOLUMN_PIPELINE & (RDC_BILINEAR|RDC_ROUNDED|RDC_DITHERZ)) | ||
85 | #define INCY(y) (y++) | ||
86 | #else | ||
87 | #define INCY(y) | ||
88 | #endif | ||
89 | |||
90 | #if (R_DRAWCOLUMN_PIPELINE & RDC_TRANSLUCENT) | ||
91 | #define COLTYPE (COL_TRANS) | ||
92 | #elif (R_DRAWCOLUMN_PIPELINE & RDC_FUZZ) | ||
93 | #define COLTYPE (COL_FUZZ) | ||
94 | #else | ||
95 | #define COLTYPE (COL_OPAQUE) | ||
96 | #endif | ||
97 | |||
98 | #if (R_DRAWCOLUMN_PIPELINE_BITS == 8) | ||
99 | #define GETCOL(frac, nextfrac) GETCOL8(frac, nextfrac) | ||
100 | #define GETDESTCOLOR(col) GETDESTCOLOR8(col) | ||
101 | #elif (R_DRAWCOLUMN_PIPELINE_BITS == 15) | ||
102 | #define GETCOL(frac, nextfrac) GETCOL15(frac, nextfrac) | ||
103 | #define GETDESTCOLOR(col) GETDESTCOLOR15(col) | ||
104 | #elif (R_DRAWCOLUMN_PIPELINE_BITS == 16) | ||
105 | #define GETCOL(frac, nextfrac) GETCOL16(frac, nextfrac) | ||
106 | #define GETDESTCOLOR(col) GETDESTCOLOR16(col) | ||
107 | #elif (R_DRAWCOLUMN_PIPELINE_BITS == 32) | ||
108 | #define GETCOL(frac, nextfrac) GETCOL32(frac, nextfrac) | ||
109 | #define GETDESTCOLOR(col) GETDESTCOLOR32(col) | ||
110 | #endif | ||
111 | |||
112 | static void R_DRAWCOLUMN_FUNCNAME(draw_column_vars_t *dcvars) | ||
113 | { | ||
114 | int count; | ||
115 | SCREENTYPE *dest; // killough | ||
116 | fixed_t frac; | ||
117 | const fixed_t fracstep = dcvars->iscale; | ||
118 | #if ((R_DRAWCOLUMN_PIPELINE & RDC_BILINEAR) && (R_DRAWCOLUMN_PIPELINE_BITS != 8)) | ||
119 | const fixed_t slope_texu = (dcvars->source == dcvars->nextsource) ? 0 : dcvars->texu & 0xffff; | ||
120 | #else | ||
121 | const fixed_t slope_texu = dcvars->texu; | ||
122 | #endif | ||
123 | |||
124 | // drop back to point filtering if we're minifying | ||
125 | #if (R_DRAWCOLUMN_PIPELINE & (RDC_BILINEAR|RDC_ROUNDED)) | ||
126 | if (dcvars->iscale > drawvars.mag_threshold) { | ||
127 | R_GetDrawColumnFunc(R_DRAWCOLUMN_PIPELINE_TYPE, | ||
128 | RDRAW_FILTER_POINT, | ||
129 | drawvars.filterz)(dcvars); | ||
130 | return; | ||
131 | } | ||
132 | #endif | ||
133 | |||
134 | #if (R_DRAWCOLUMN_PIPELINE & RDC_FUZZ) | ||
135 | // Adjust borders. Low... | ||
136 | if (!dcvars->yl) | ||
137 | dcvars->yl = 1; | ||
138 | |||
139 | // .. and high. | ||
140 | if (dcvars->yh == viewheight-1) | ||
141 | dcvars->yh = viewheight - 2; | ||
142 | #endif | ||
143 | |||
144 | // leban 1/17/99: | ||
145 | // removed the + 1 here, adjusted the if test, and added an increment | ||
146 | // later. this helps a compiler pipeline a bit better. the x86 | ||
147 | // assembler also does this. | ||
148 | |||
149 | count = dcvars->yh - dcvars->yl; | ||
150 | |||
151 | // leban 1/17/99: | ||
152 | // this case isn't executed too often. depending on how many instructions | ||
153 | // there are between here and the second if test below, this case could | ||
154 | // be moved down and might save instructions overall. since there are | ||
155 | // probably different wads that favor one way or the other, i'll leave | ||
156 | // this alone for now. | ||
157 | if (count < 0) // Zero length, column does not exceed a pixel. | ||
158 | return; | ||
159 | |||
160 | #ifdef RANGECHECK | ||
161 | if (dcvars->x >= SCREENWIDTH | ||
162 | || dcvars->yl < 0 | ||
163 | || dcvars->yh >= SCREENHEIGHT) | ||
164 | I_Error("R_DrawColumn: %i to %i at %i", dcvars->yl, dcvars->yh, dcvars->x); | ||
165 | #endif | ||
166 | |||
167 | // Determine scaling, which is the only mapping to be done. | ||
168 | #if (R_DRAWCOLUMN_PIPELINE & RDC_BILINEAR) | ||
169 | frac = dcvars->texturemid - (FRACUNIT>>1) + (dcvars->yl-centery)*fracstep; | ||
170 | #else | ||
171 | frac = dcvars->texturemid + (dcvars->yl-centery)*fracstep; | ||
172 | #endif | ||
173 | |||
174 | if (dcvars->drawingmasked && dcvars->edgetype == RDRAW_MASKEDCOLUMNEDGE_SLOPED) { | ||
175 | // slope the top and bottom column edge based on the fractional u coordinate | ||
176 | // and dcvars->edgeslope, which were set in R_DrawMaskedColumn | ||
177 | // in r_things.c | ||
178 | if (dcvars->yl != 0) { | ||
179 | if (dcvars->edgeslope & RDRAW_EDGESLOPE_TOP_UP) { | ||
180 | // [/#] | ||
181 | int shift = ((0xffff-(slope_texu & 0xffff))/dcvars->iscale); | ||
182 | dcvars->yl += shift; | ||
183 | count -= shift; | ||
184 | frac += 0xffff-(slope_texu & 0xffff); | ||
185 | } | ||
186 | else if (dcvars->edgeslope & RDRAW_EDGESLOPE_TOP_DOWN) { | ||
187 | // [#\] | ||
188 | int shift = ((slope_texu & 0xffff)/dcvars->iscale); | ||
189 | dcvars->yl += shift; | ||
190 | count -= shift; | ||
191 | frac += slope_texu & 0xffff; | ||
192 | } | ||
193 | } | ||
194 | if (dcvars->yh != viewheight-1) { | ||
195 | if (dcvars->edgeslope & RDRAW_EDGESLOPE_BOT_UP) { | ||
196 | // [#/] | ||
197 | int shift = ((0xffff-(slope_texu & 0xffff))/dcvars->iscale); | ||
198 | dcvars->yh -= shift; | ||
199 | count -= shift; | ||
200 | } | ||
201 | else if (dcvars->edgeslope & RDRAW_EDGESLOPE_BOT_DOWN) { | ||
202 | // [\#] | ||
203 | int shift = ((slope_texu & 0xffff)/dcvars->iscale); | ||
204 | dcvars->yh -= shift; | ||
205 | count -= shift; | ||
206 | } | ||
207 | } | ||
208 | if (count <= 0) return; | ||
209 | } | ||
210 | |||
211 | // Framebuffer destination address. | ||
212 | // SoM: MAGIC | ||
213 | { | ||
214 | // haleyjd: reordered predicates | ||
215 | if(temp_x == 4 || | ||
216 | (temp_x && (temptype != COLTYPE || temp_x + startx != dcvars->x))) | ||
217 | R_FlushColumns(); | ||
218 | |||
219 | if(!temp_x) | ||
220 | { | ||
221 | startx = dcvars->x; | ||
222 | tempyl[0] = commontop = dcvars->yl; | ||
223 | tempyh[0] = commonbot = dcvars->yh; | ||
224 | temptype = COLTYPE; | ||
225 | #if (R_DRAWCOLUMN_PIPELINE & RDC_TRANSLUCENT) | ||
226 | temptranmap = tranmap; | ||
227 | #elif (R_DRAWCOLUMN_PIPELINE & RDC_FUZZ) | ||
228 | tempfuzzmap = fullcolormap; // SoM 7-28-04: Fix the fuzz problem. | ||
229 | #endif | ||
230 | R_FlushWholeColumns = R_FLUSHWHOLE_FUNCNAME; | ||
231 | R_FlushHTColumns = R_FLUSHHEADTAIL_FUNCNAME; | ||
232 | R_FlushQuadColumn = R_FLUSHQUAD_FUNCNAME; | ||
233 | dest = &TEMPBUF[dcvars->yl << 2]; | ||
234 | } else { | ||
235 | tempyl[temp_x] = dcvars->yl; | ||
236 | tempyh[temp_x] = dcvars->yh; | ||
237 | |||
238 | if(dcvars->yl > commontop) | ||
239 | commontop = dcvars->yl; | ||
240 | if(dcvars->yh < commonbot) | ||
241 | commonbot = dcvars->yh; | ||
242 | |||
243 | dest = &TEMPBUF[(dcvars->yl << 2) + temp_x]; | ||
244 | } | ||
245 | temp_x += 1; | ||
246 | } | ||
247 | |||
248 | // do nothing else when drawin fuzz columns | ||
249 | #if (!(R_DRAWCOLUMN_PIPELINE & RDC_FUZZ)) | ||
250 | { | ||
251 | const byte *source = dcvars->source; | ||
252 | const lighttable_t *colormap = dcvars->colormap; | ||
253 | const byte *translation = dcvars->translation; | ||
254 | #if (R_DRAWCOLUMN_PIPELINE & (RDC_BILINEAR|RDC_ROUNDED|RDC_DITHERZ)) | ||
255 | int y = dcvars->yl; | ||
256 | const int x = dcvars->x; | ||
257 | #endif | ||
258 | #if (R_DRAWCOLUMN_PIPELINE & RDC_DITHERZ) | ||
259 | const int fracz = (dcvars->z >> 6) & 255; | ||
260 | const byte *dither_colormaps[2] = { dcvars->colormap, dcvars->nextcolormap }; | ||
261 | #endif | ||
262 | #if (R_DRAWCOLUMN_PIPELINE & RDC_BILINEAR) | ||
263 | #if (R_DRAWCOLUMN_PIPELINE_BITS == 8) | ||
264 | const int yl = dcvars->yl; | ||
265 | const byte *dither_sources[2] = { dcvars->source, dcvars->nextsource }; | ||
266 | const unsigned int filter_fracu = (dcvars->source == dcvars->nextsource) ? 0 : (dcvars->texu>>8) & 0xff; | ||
267 | #else | ||
268 | const byte *nextsource = dcvars->nextsource; | ||
269 | const unsigned int filter_fracu = (dcvars->source == dcvars->nextsource) ? 0 : dcvars->texu & 0xffff; | ||
270 | #endif | ||
271 | #endif | ||
272 | #if (R_DRAWCOLUMN_PIPELINE & RDC_ROUNDED) | ||
273 | const byte *prevsource = dcvars->prevsource; | ||
274 | const byte *nextsource = dcvars->nextsource; | ||
275 | const unsigned int filter_fracu = (dcvars->source == dcvars->nextsource) ? 0 : (dcvars->texu>>8) & 0xff; | ||
276 | #endif | ||
277 | |||
278 | count++; | ||
279 | |||
280 | // Inner loop that does the actual texture mapping, | ||
281 | // e.g. a DDA-lile scaling. | ||
282 | // This is as fast as it gets. (Yeah, right!!! -- killough) | ||
283 | // | ||
284 | // killough 2/1/98: more performance tuning | ||
285 | |||
286 | if (dcvars->texheight == 128) { | ||
287 | #define FIXEDT_128MASK ((127<<FRACBITS)|0xffff) | ||
288 | while(count--) { | ||
289 | *dest = GETDESTCOLOR(GETCOL(frac & FIXEDT_128MASK, (frac+FRACUNIT) & FIXEDT_128MASK)); | ||
290 | INCY(y); | ||
291 | dest += 4; | ||
292 | frac += fracstep; | ||
293 | } | ||
294 | } else if (dcvars->texheight == 0) { | ||
295 | /* cph - another special case */ | ||
296 | while (count--) { | ||
297 | *dest = GETDESTCOLOR(GETCOL(frac, (frac+FRACUNIT))); | ||
298 | INCY(y); | ||
299 | dest += 4; | ||
300 | frac += fracstep; | ||
301 | } | ||
302 | } else { | ||
303 | unsigned heightmask = dcvars->texheight-1; // CPhipps - specify type | ||
304 | if (! (dcvars->texheight & heightmask) ) { // power of 2 -- killough | ||
305 | fixed_t fixedt_heightmask = (heightmask<<FRACBITS)|0xffff; | ||
306 | while ((count-=2)>=0) { // texture height is a power of 2 -- killough | ||
307 | *dest = GETDESTCOLOR(GETCOL(frac & fixedt_heightmask, (frac+FRACUNIT) & fixedt_heightmask)); | ||
308 | INCY(y); | ||
309 | dest += 4; | ||
310 | frac += fracstep; | ||
311 | *dest = GETDESTCOLOR(GETCOL(frac & fixedt_heightmask, (frac+FRACUNIT) & fixedt_heightmask)); | ||
312 | INCY(y); | ||
313 | dest += 4; | ||
314 | frac += fracstep; | ||
315 | } | ||
316 | if (count & 1) | ||
317 | *dest = GETDESTCOLOR(GETCOL(frac & fixedt_heightmask, (frac+FRACUNIT) & fixedt_heightmask)); | ||
318 | INCY(y); | ||
319 | } else { | ||
320 | fixed_t nextfrac = 0; | ||
321 | |||
322 | heightmask++; | ||
323 | heightmask <<= FRACBITS; | ||
324 | |||
325 | if (frac < 0) | ||
326 | while ((frac += heightmask) < 0); | ||
327 | else | ||
328 | while (frac >= (int)heightmask) | ||
329 | frac -= heightmask; | ||
330 | |||
331 | #if (R_DRAWCOLUMN_PIPELINE & (RDC_BILINEAR|RDC_ROUNDED)) | ||
332 | nextfrac = frac + FRACUNIT; | ||
333 | while (nextfrac >= (int)heightmask) | ||
334 | nextfrac -= heightmask; | ||
335 | #endif | ||
336 | |||
337 | #define INCFRAC(f) if ((f += fracstep) >= (int)heightmask) f -= heightmask; | ||
338 | |||
339 | while (count--) { | ||
340 | // Re-map color indices from wall texture column | ||
341 | // using a lighting/special effects LUT. | ||
342 | |||
343 | // heightmask is the Tutti-Frutti fix -- killough | ||
344 | |||
345 | *dest = GETDESTCOLOR(GETCOL(frac, nextfrac)); | ||
346 | INCY(y); | ||
347 | dest += 4; | ||
348 | INCFRAC(frac); | ||
349 | #if (R_DRAWCOLUMN_PIPELINE & (RDC_BILINEAR|RDC_ROUNDED)) | ||
350 | INCFRAC(nextfrac); | ||
351 | #endif | ||
352 | } | ||
353 | } | ||
354 | } | ||
355 | } | ||
356 | #endif // (!(R_DRAWCOLUMN_PIPELINE & RDC_FUZZ)) | ||
357 | } | ||
358 | |||
359 | #undef GETDESTCOLOR32 | ||
360 | #undef GETDESTCOLOR16 | ||
361 | #undef GETDESTCOLOR15 | ||
362 | #undef GETDESTCOLOR8 | ||
363 | #undef GETDESTCOLOR | ||
364 | #undef GETCOL8_MAPPED | ||
365 | #undef GETCOL8_DEPTH | ||
366 | #undef GETCOL32 | ||
367 | #undef GETCOL16 | ||
368 | #undef GETCOL15 | ||
369 | #undef GETCOL8 | ||
370 | #undef GETCOL | ||
371 | #undef INCY | ||
372 | #undef INCFRAC | ||
373 | #undef COLTYPE | ||
374 | #undef TEMPBUF | ||
375 | #undef SCREENTYPE | ||
376 | |||
377 | #undef R_DRAWCOLUMN_FUNCNAME | ||
378 | #undef R_DRAWCOLUMN_PIPELINE | ||