aboutsummaryrefslogtreecommitdiff
path: root/src/r_drawcolumn.inl
diff options
context:
space:
mode:
Diffstat (limited to 'src/r_drawcolumn.inl')
-rw-r--r--src/r_drawcolumn.inl378
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
112static 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