Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
1 | pmbaty | 1 | /* |
2 | * Portions of this file are copyright Rebirth contributors and licensed as |
||
3 | * described in COPYING.txt. |
||
4 | * Portions of this file are copyright Parallax Software and licensed |
||
5 | * according to the Parallax license below. |
||
6 | * See COPYING.txt for license details. |
||
7 | |||
8 | THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX |
||
9 | SOFTWARE CORPORATION ("PARALLAX"). PARALLAX, IN DISTRIBUTING THE CODE TO |
||
10 | END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A |
||
11 | ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS |
||
12 | IN USING, DISPLAYING, AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS |
||
13 | SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE |
||
14 | FREE PURPOSES. IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE |
||
15 | CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES. THE END-USER UNDERSTANDS |
||
16 | AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE. |
||
17 | COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. |
||
18 | */ |
||
19 | |||
20 | /* |
||
21 | * |
||
22 | * Routines to draw the texture mapped scanlines. |
||
23 | * |
||
24 | */ |
||
25 | |||
26 | #include <math.h> |
||
27 | #include <limits.h> |
||
28 | #include <stdio.h> |
||
29 | #include <stdlib.h> |
||
30 | #include <stdint.h> |
||
31 | #include <string.h> |
||
32 | #include "maths.h" |
||
33 | #include "gr.h" |
||
34 | #include "grdef.h" |
||
35 | #include "texmap.h" |
||
36 | #include "texmapl.h" |
||
37 | #include "scanline.h" |
||
38 | #include "strutil.h" |
||
39 | #include "dxxerror.h" |
||
40 | |||
41 | namespace dcx { |
||
42 | |||
43 | tmap_scanline_function_table tmap_scanline_functions; |
||
44 | |||
45 | void c_tmap_scanline_flat() |
||
46 | { |
||
47 | uint8_t *dest; |
||
48 | int x, index = fx_xleft + (bytes_per_row * fx_y ); |
||
49 | |||
50 | dest = (write_buffer + fx_xleft + (bytes_per_row * fx_y )); |
||
51 | |||
52 | for (x= fx_xright-fx_xleft+1 ; x > 0; --x ) { |
||
53 | if (++index >= SWIDTH*SHEIGHT) return; |
||
54 | *dest++ = tmap_flat_color; |
||
55 | } |
||
56 | // memset(dest,tmap_flat_color,fx_xright-fx_xleft+1); |
||
57 | } |
||
58 | |||
59 | void c_tmap_scanline_shaded(const uint_fast32_t fade) |
||
60 | { |
||
61 | uint8_t tmp; |
||
62 | int x, index = fx_xleft + (bytes_per_row * fx_y ); |
||
63 | |||
64 | auto dest = &write_buffer[fx_xleft + (bytes_per_row * fx_y)]; |
||
65 | for (x= fx_xright-fx_xleft+1 ; x > 0; --x ) { |
||
66 | if (++index >= SWIDTH*SHEIGHT) return; |
||
67 | tmp = *dest; |
||
68 | *dest++ = gr_fade_table[fade][tmp]; |
||
69 | } |
||
70 | } |
||
71 | |||
72 | void c_tmap_scanline_lin_nolight() |
||
73 | { |
||
74 | uint c; |
||
75 | int x, index = fx_xleft + (bytes_per_row * fx_y ); |
||
76 | fix u,v,dudx, dvdx; |
||
77 | |||
78 | u = fx_u; |
||
79 | v = fx_v*64; |
||
80 | dudx = fx_du_dx; |
||
81 | dvdx = fx_dv_dx*64; |
||
82 | |||
83 | auto dest = &write_buffer[fx_xleft + (bytes_per_row * fx_y)]; |
||
84 | |||
85 | if (!Transparency_on) { |
||
86 | for (x= fx_xright-fx_xleft+1 ; x > 0; --x ) { |
||
87 | if (++index >= SWIDTH*SHEIGHT) return; |
||
88 | *dest++ = static_cast<uint32_t>(pixptr[ (f2i(v)&(64*63)) + (f2i(u)&63) ]); |
||
89 | u += dudx; |
||
90 | v += dvdx; |
||
91 | } |
||
92 | } else { |
||
93 | for (x= fx_xright-fx_xleft+1 ; x > 0; --x ) { |
||
94 | if (++index >= SWIDTH*SHEIGHT) return; |
||
95 | c = static_cast<uint32_t>(pixptr[ (f2i(v)&(64*63)) + (f2i(u)&63) ]); |
||
96 | if ( c!=255) |
||
97 | *dest = c; |
||
98 | dest++; |
||
99 | u += dudx; |
||
100 | v += dvdx; |
||
101 | } |
||
102 | } |
||
103 | } |
||
104 | |||
105 | void c_tmap_scanline_lin() |
||
106 | { |
||
107 | uint c; |
||
108 | int x, j, index = fx_xleft + (bytes_per_row * fx_y); |
||
109 | fix u,v,l,dudx, dvdx, dldx; |
||
110 | |||
111 | u = fx_u; |
||
112 | v = fx_v*64; |
||
113 | dudx = fx_du_dx; |
||
114 | dvdx = fx_dv_dx*64; |
||
115 | |||
116 | l = fx_l>>8; |
||
117 | dldx = fx_dl_dx/256; |
||
118 | auto dest = &write_buffer[fx_xleft + (bytes_per_row * fx_y)]; |
||
119 | |||
120 | if (!Transparency_on) { |
||
121 | const auto pixPtrLocalCopy = pixptr; |
||
122 | auto &fadeTableLocalCopy = gr_fade_table; |
||
123 | |||
124 | x = fx_xright-fx_xleft+1; |
||
125 | |||
126 | if ((j = reinterpret_cast<uintptr_t>(dest) & 3) != 0) |
||
127 | { |
||
128 | j = 4 - j; |
||
129 | |||
130 | if (j > x) |
||
131 | j = x; |
||
132 | |||
133 | while (j > 0) |
||
134 | { |
||
135 | if (++index >= SWIDTH*SHEIGHT) return; |
||
136 | //edited 05/18/99 Matt Mueller - changed from 0xff00 to 0x7f00 to fix glitches |
||
137 | *dest++ = fadeTableLocalCopy[(l>>8)&0x7f][pixPtrLocalCopy[ (f2i(v)&(64*63)) + (f2i(u)&63) ] ]; |
||
138 | //end edit -MM |
||
139 | l += dldx; |
||
140 | u += dudx; |
||
141 | v += dvdx; |
||
142 | x--; |
||
143 | j--; |
||
144 | } |
||
145 | } |
||
146 | |||
147 | j &= ~3; |
||
148 | while (j > 0) |
||
149 | { |
||
150 | uint32_t destlong; |
||
151 | //edited 05/18/99 Matt Mueller - changed from 0xff00 to 0x7f00 to fix glitches |
||
152 | destlong = fadeTableLocalCopy[(l>>8)&0x7f][pixPtrLocalCopy[ (f2i(v)&(64*63)) + (f2i(u)&63) ] ] << 24; |
||
153 | //end edit -MM |
||
154 | l += dldx; |
||
155 | u += dudx; |
||
156 | v += dvdx; |
||
157 | //edited 05/18/99 Matt Mueller - changed from 0xff00 to 0x7f00 to fix glitches |
||
158 | destlong |= fadeTableLocalCopy[(l>>8)&0x7f][pixPtrLocalCopy[ (f2i(v)&(64*63)) + (f2i(u)&63) ] ] << 16; |
||
159 | //end edit -MM |
||
160 | l += dldx; |
||
161 | u += dudx; |
||
162 | v += dvdx; |
||
163 | //edited 05/18/99 Matt Mueller - changed from 0xff00 to 0x7f00 to fix glitches |
||
164 | destlong |= fadeTableLocalCopy[(l>>8)&0x7f][pixPtrLocalCopy[ (f2i(v)&(64*63)) + (f2i(u)&63) ] ] << 8; |
||
165 | //end edit -MM |
||
166 | l += dldx; |
||
167 | u += dudx; |
||
168 | v += dvdx; |
||
169 | //edited 05/18/99 Matt Mueller - changed from 0xff00 to 0x7f00 to fix glitches |
||
170 | destlong |= fadeTableLocalCopy[(l>>8)&0x7f][pixPtrLocalCopy[ (f2i(v)&(64*63)) + (f2i(u)&63) ] ]; |
||
171 | //end edit -MM |
||
172 | l += dldx; |
||
173 | u += dudx; |
||
174 | v += dvdx; |
||
175 | *reinterpret_cast<uint32_t *>(dest) = destlong; |
||
176 | dest += 4; |
||
177 | x -= 4; |
||
178 | j -= 4; |
||
179 | index += 4; |
||
180 | if (index+4 >= SWIDTH*SHEIGHT) return; |
||
181 | } |
||
182 | |||
183 | while (x-- > 0) |
||
184 | { |
||
185 | if (++index >= SWIDTH*SHEIGHT) return; |
||
186 | //edited 05/18/99 Matt Mueller - changed from 0xff00 to 0x7f00 to fix glitches |
||
187 | *dest++ = fadeTableLocalCopy[(l>>8)&0x7f][pixPtrLocalCopy[ (f2i(v)&(64*63)) + (f2i(u)&63) ] ]; |
||
188 | //end edit -MM |
||
189 | l += dldx; |
||
190 | u += dudx; |
||
191 | v += dvdx; |
||
192 | } |
||
193 | |||
194 | } else { |
||
195 | for (x= fx_xright-fx_xleft+1 ; x > 0; --x ) { |
||
196 | if (++index >= SWIDTH*SHEIGHT) return; |
||
197 | c = static_cast<uint32_t>(pixptr[ (f2i(v)&(64*63)) + (f2i(u)&63) ]); |
||
198 | if ( c!=TRANSPARENCY_COLOR) |
||
199 | //edited 05/18/99 Matt Mueller - changed from 0xff00 to 0x7f00 to fix glitches |
||
200 | *dest = gr_fade_table[(l >> 8)&0x7f][c]; |
||
201 | //end edit -MM |
||
202 | dest++; |
||
203 | l += dldx; |
||
204 | u += dudx; |
||
205 | v += dvdx; |
||
206 | } |
||
207 | } |
||
208 | } |
||
209 | |||
210 | // This texture mapper uses floating point extensively and writes 8 pixels at once, so it likely works |
||
211 | // best on 64 bit RISC processors. |
||
212 | // WARNING: it is not endian clean. For big endian, reverse the shift counts in the unrolled loops. I |
||
213 | // have no means to test that, so I didn't try it. Please tell me if you get this to work on a big |
||
214 | // endian machine. |
||
215 | // If you're using an Alpha, use the Compaq compiler for this file for quite some fps more. |
||
216 | // Unfortunately, it won't compile the whole source, so simply compile everything, change the |
||
217 | // compiler to ccc, remove scanline.o and compile again. |
||
218 | // Please send comments/suggestions to falk.hueffner@student.uni-tuebingen.de. |
||
219 | static void c_fp_tmap_scanline_per() |
||
220 | { |
||
221 | uint c; |
||
222 | int x, j, index = fx_xleft + (bytes_per_row * fx_y); |
||
223 | double u, v, z, l, dudx, dvdx, dzdx, dldx, rec_z; |
||
224 | |||
225 | u = f2db(fx_u); |
||
226 | v = f2db(fx_v) * 64.0; |
||
227 | z = f2db(fx_z); |
||
228 | l = f2db(fx_l); |
||
229 | dudx = f2db(fx_du_dx); |
||
230 | dvdx = f2db(fx_dv_dx) * 64.0; |
||
231 | dzdx = f2db(fx_dz_dx); |
||
232 | dldx = f2db(fx_dl_dx); |
||
233 | |||
234 | rec_z = 1.0 / z; // gcc 2.95.2 is won't do this optimization itself |
||
235 | |||
236 | auto dest = &write_buffer[fx_xleft + (bytes_per_row * fx_y)]; |
||
237 | x = fx_xright - fx_xleft + 1; |
||
238 | |||
239 | if (!Transparency_on) { |
||
240 | if (x >= 8) { |
||
241 | if ((j = reinterpret_cast<uintptr_t>(dest) & 7) != 0) { |
||
242 | j = 8 - j; |
||
243 | |||
244 | while (j > 0) { |
||
245 | if (++index >= SWIDTH*SHEIGHT) return; |
||
246 | *dest++ = |
||
247 | gr_fade_table[static_cast<int>(fabs(l))][ |
||
248 | pixptr[((static_cast<int>(v * rec_z)) & (64 * 63)) + |
||
249 | ((static_cast<int>(u * rec_z)) & 63)]]; |
||
250 | l += dldx; |
||
251 | u += dudx; |
||
252 | v += dvdx; |
||
253 | z += dzdx; |
||
254 | rec_z = 1.0 / z; |
||
255 | x--; |
||
256 | j--; |
||
257 | } |
||
258 | } |
||
259 | |||
260 | j = x; |
||
261 | while (j >= 8) { |
||
262 | uint64_t destlong = |
||
263 | gr_fade_table[static_cast<int>(fabs(l))][ |
||
264 | pixptr[((static_cast<int>(v * rec_z)) & (64 * 63)) + |
||
265 | ((static_cast<int>(u * rec_z)) & 63)]]; |
||
266 | l += dldx; |
||
267 | u += dudx; |
||
268 | v += dvdx; |
||
269 | z += dzdx; |
||
270 | rec_z = 1.0 / z; |
||
271 | destlong |= |
||
272 | static_cast<uint64_t>(gr_fade_table[static_cast<int>(fabs(l))][ |
||
273 | pixptr[((static_cast<int>(v * rec_z)) & (64 * 63)) + |
||
274 | ((static_cast<int>(u * rec_z)) & 63)]]) << 8; |
||
275 | l += dldx; |
||
276 | u += dudx; |
||
277 | v += dvdx; |
||
278 | z += dzdx; |
||
279 | rec_z = 1.0 / z; |
||
280 | destlong |= |
||
281 | static_cast<uint64_t>(gr_fade_table[static_cast<int>(fabs(l))][ |
||
282 | pixptr[((static_cast<int>(v * rec_z)) & (64 * 63)) + |
||
283 | ((static_cast<int>(u * rec_z)) & 63)]]) << 16; |
||
284 | l += dldx; |
||
285 | u += dudx; |
||
286 | v += dvdx; |
||
287 | z += dzdx; |
||
288 | rec_z = 1.0 / z; |
||
289 | destlong |= |
||
290 | static_cast<uint64_t>(gr_fade_table[static_cast<int>(fabs(l))][ |
||
291 | pixptr[((static_cast<int>(v * rec_z)) & (64 * 63)) + |
||
292 | ((static_cast<int>(u * rec_z)) & 63)]]) << 24; |
||
293 | l += dldx; |
||
294 | u += dudx; |
||
295 | v += dvdx; |
||
296 | z += dzdx; |
||
297 | rec_z = 1.0 / z; |
||
298 | destlong |= |
||
299 | static_cast<uint64_t>(gr_fade_table[static_cast<int>(fabs(l))][ |
||
300 | pixptr[((static_cast<int>(v * rec_z)) & (64 * 63)) + |
||
301 | ((static_cast<int>(u * rec_z)) & 63)]]) << 32; |
||
302 | l += dldx; |
||
303 | u += dudx; |
||
304 | v += dvdx; |
||
305 | z += dzdx; |
||
306 | rec_z = 1.0 / z; |
||
307 | destlong |= |
||
308 | static_cast<uint64_t>(gr_fade_table[static_cast<int>(fabs(l))][ |
||
309 | pixptr[((static_cast<int>(v * rec_z)) & (64 * 63)) + |
||
310 | ((static_cast<int>(u * rec_z)) & 63)]]) << 40; |
||
311 | l += dldx; |
||
312 | u += dudx; |
||
313 | v += dvdx; |
||
314 | z += dzdx; |
||
315 | rec_z = 1.0 / z; |
||
316 | destlong |= |
||
317 | static_cast<uint64_t>(gr_fade_table[static_cast<int>(fabs(l))][ |
||
318 | pixptr[((static_cast<int>(v * rec_z)) & (64 * 63)) + |
||
319 | ((static_cast<int>(u * rec_z)) & 63)]]) << 48; |
||
320 | l += dldx; |
||
321 | u += dudx; |
||
322 | v += dvdx; |
||
323 | z += dzdx; |
||
324 | rec_z = 1.0 / z; |
||
325 | destlong |= |
||
326 | static_cast<uint64_t>(gr_fade_table[static_cast<int>(fabs(l))][ |
||
327 | pixptr[((static_cast<int>(v * rec_z)) & (64 * 63)) + |
||
328 | ((static_cast<int>(u * rec_z)) & 63)]]) << 56; |
||
329 | l += dldx; |
||
330 | u += dudx; |
||
331 | v += dvdx; |
||
332 | z += dzdx; |
||
333 | rec_z = 1.0 / z; |
||
334 | |||
335 | *(reinterpret_cast<uint64_t *>(dest)) = destlong; |
||
336 | dest += 8; |
||
337 | x -= 8; |
||
338 | j -= 8; |
||
339 | index += 8; |
||
340 | if (index+8 >= SWIDTH*SHEIGHT) return; |
||
341 | } |
||
342 | } |
||
343 | while (x-- > 0) { |
||
344 | if (++index >= SWIDTH*SHEIGHT) return; |
||
345 | *dest++ = |
||
346 | gr_fade_table[static_cast<int>(fabs(l))][ |
||
347 | static_cast<uint32_t>(pixptr[((static_cast<int>(v * rec_z)) & (64 * 63)) + ((static_cast<int>(u * rec_z)) & 63)])]; |
||
348 | l += dldx; |
||
349 | u += dudx; |
||
350 | v += dvdx; |
||
351 | z += dzdx; |
||
352 | rec_z = 1.0 / z; |
||
353 | } |
||
354 | } else { |
||
355 | if (x >= 8) { |
||
356 | if ((j = reinterpret_cast<uintptr_t>(dest) & 7) != 0) { |
||
357 | j = 8 - j; |
||
358 | |||
359 | while (j > 0) { |
||
360 | if (++index >= SWIDTH*SHEIGHT) return; |
||
361 | c = static_cast<uint32_t>(pixptr[((static_cast<int>(v * rec_z)) & (64 * 63)) + ((static_cast<int>(u * rec_z)) & 63)]); |
||
362 | if (c != 255) |
||
363 | *dest = gr_fade_table[static_cast<int>(fabs(l))][c]; |
||
364 | dest++; |
||
365 | l += dldx; |
||
366 | u += dudx; |
||
367 | v += dvdx; |
||
368 | z += dzdx; |
||
369 | rec_z = 1.0 / z; |
||
370 | x--; |
||
371 | j--; |
||
372 | } |
||
373 | } |
||
374 | |||
375 | j = x; |
||
376 | while (j >= 8) { |
||
377 | uint64_t destlong; |
||
378 | destlong = *(reinterpret_cast<uint64_t *>(dest)); |
||
379 | c = static_cast<uint32_t>(pixptr[((static_cast<int>(v * rec_z)) & (64 * 63)) + ((static_cast<int>(u * rec_z)) & 63)]); |
||
380 | if (c != 255) { |
||
381 | destlong &= ~static_cast<uint64_t>(0xFF); |
||
382 | destlong |= static_cast<uint64_t>(gr_fade_table[static_cast<int>(fabs(l))][c]); |
||
383 | } |
||
384 | l += dldx; |
||
385 | u += dudx; |
||
386 | v += dvdx; |
||
387 | z += dzdx; |
||
388 | rec_z = 1.0 / z; |
||
389 | c = static_cast<uint32_t>(pixptr[((static_cast<int>(v * rec_z)) & (64 * 63)) + ((static_cast<int>(u * rec_z)) & 63)]); |
||
390 | if (c != 255) { |
||
391 | destlong &= ~(static_cast<uint64_t>(0xFF) << 8); |
||
392 | destlong |= static_cast<uint64_t>(gr_fade_table[static_cast<int>(fabs(l))][c]) << 8; |
||
393 | } |
||
394 | l += dldx; |
||
395 | u += dudx; |
||
396 | v += dvdx; |
||
397 | z += dzdx; |
||
398 | rec_z = 1.0 / z; |
||
399 | c = static_cast<uint32_t>(pixptr[((static_cast<int>(v * rec_z)) & (64 * 63)) + ((static_cast<int>(u * rec_z)) & 63)]); |
||
400 | if (c != 255) { |
||
401 | destlong &= ~(static_cast<uint64_t>(0xFF) << 16); |
||
402 | destlong |= static_cast<uint64_t>(gr_fade_table[static_cast<int>(fabs(l))][c]) << 16; |
||
403 | } |
||
404 | l += dldx; |
||
405 | u += dudx; |
||
406 | v += dvdx; |
||
407 | z += dzdx; |
||
408 | rec_z = 1.0 / z; |
||
409 | c = static_cast<uint32_t>(pixptr[((static_cast<int>(v * rec_z)) & (64 * 63)) + ((static_cast<int>(u * rec_z)) & 63)]); |
||
410 | if (c != 255) { |
||
411 | destlong &= ~(static_cast<uint64_t>(0xFF) << 24); |
||
412 | destlong |= static_cast<uint64_t>(gr_fade_table[static_cast<int>(fabs(l))][c]) << 24; |
||
413 | } |
||
414 | l += dldx; |
||
415 | u += dudx; |
||
416 | v += dvdx; |
||
417 | z += dzdx; |
||
418 | rec_z = 1.0 / z; |
||
419 | c = static_cast<uint32_t>(pixptr[((static_cast<int>(v * rec_z)) & (64 * 63)) + ((static_cast<int>(u * rec_z)) & 63)]); |
||
420 | if (c != 255) { |
||
421 | destlong &= ~(static_cast<uint64_t>(0xFF) << 32); |
||
422 | destlong |= static_cast<uint64_t>(gr_fade_table[static_cast<int>(fabs(l))][c]) << 32; |
||
423 | } |
||
424 | l += dldx; |
||
425 | u += dudx; |
||
426 | v += dvdx; |
||
427 | z += dzdx; |
||
428 | rec_z = 1.0 / z; |
||
429 | c = static_cast<uint32_t>(pixptr[((static_cast<int>(v * rec_z)) & (64 * 63)) + ((static_cast<int>(u * rec_z)) & 63)]); |
||
430 | if (c != 255) { |
||
431 | destlong &= ~(static_cast<uint64_t>(0xFF) << 40); |
||
432 | destlong |= static_cast<uint64_t>(gr_fade_table[static_cast<int>(fabs(l))][c]) << 40; |
||
433 | } |
||
434 | l += dldx; |
||
435 | u += dudx; |
||
436 | v += dvdx; |
||
437 | z += dzdx; |
||
438 | rec_z = 1.0 / z; |
||
439 | c = static_cast<uint32_t>(pixptr[((static_cast<int>(v * rec_z)) & (64 * 63)) + ((static_cast<int>(u * rec_z)) & 63)]); |
||
440 | if (c != 255) { |
||
441 | destlong &= ~(static_cast<uint64_t>(0xFF) << 48); |
||
442 | destlong |= static_cast<uint64_t>(gr_fade_table[static_cast<int>(fabs(l))][c]) << 48; |
||
443 | } |
||
444 | l += dldx; |
||
445 | u += dudx; |
||
446 | v += dvdx; |
||
447 | z += dzdx; |
||
448 | rec_z = 1.0 / z; |
||
449 | c = static_cast<uint32_t>(pixptr[((static_cast<int>(v * rec_z)) & (64 * 63)) + ((static_cast<int>(u * rec_z)) & 63)]); |
||
450 | if (c != 255) { |
||
451 | destlong &= ~(static_cast<uint64_t>(0xFF) << 56); |
||
452 | destlong |= static_cast<uint64_t>(gr_fade_table[static_cast<int>(fabs(l))][c]) << 56; |
||
453 | } |
||
454 | l += dldx; |
||
455 | u += dudx; |
||
456 | v += dvdx; |
||
457 | z += dzdx; |
||
458 | rec_z = 1.0 / z; |
||
459 | |||
460 | *(reinterpret_cast<uint64_t *>(dest)) = destlong; |
||
461 | dest += 8; |
||
462 | x -= 8; |
||
463 | j -= 8; |
||
464 | index += 8; |
||
465 | if (index+8 >= SWIDTH*SHEIGHT) return; |
||
466 | } |
||
467 | } |
||
468 | while (x-- > 0) { |
||
469 | if (++index >= SWIDTH*SHEIGHT) return; |
||
470 | c = static_cast<uint32_t>(pixptr[((static_cast<int>(v * rec_z)) & (64 * 63)) + ((static_cast<int>(u * rec_z)) & 63)]); |
||
471 | if (c != 255) |
||
472 | *dest = gr_fade_table[static_cast<int>(fabs(l))][c]; |
||
473 | dest++; |
||
474 | l += dldx; |
||
475 | u += dudx; |
||
476 | v += dvdx; |
||
477 | z += dzdx; |
||
478 | rec_z = 1.0 / z; |
||
479 | } |
||
480 | } |
||
481 | } |
||
482 | |||
483 | // note the unrolling loop is broken. It is never called, and uses big endian. -- FH |
||
484 | static void c_tmap_scanline_per() |
||
485 | { |
||
486 | uint c; |
||
487 | int x, j, index = fx_xleft + (bytes_per_row * fx_y); |
||
488 | fix l,u,v,z; |
||
489 | fix dudx, dvdx, dzdx, dldx; |
||
490 | |||
491 | u = fx_u; |
||
492 | v = fx_v*64; |
||
493 | z = fx_z; |
||
494 | dudx = fx_du_dx; |
||
495 | dvdx = fx_dv_dx*64; |
||
496 | dzdx = fx_dz_dx; |
||
497 | |||
498 | l = fx_l>>8; |
||
499 | dldx = fx_dl_dx/256; |
||
500 | auto dest = &write_buffer[fx_xleft + (bytes_per_row * fx_y)]; |
||
501 | |||
502 | if (!Transparency_on) { |
||
503 | const auto pixPtrLocalCopy = pixptr; |
||
504 | auto &fadeTableLocalCopy = gr_fade_table; |
||
505 | |||
506 | x = fx_xright-fx_xleft+1; // x = number of pixels in scanline |
||
507 | |||
508 | if ((j = reinterpret_cast<uintptr_t>(dest) & 3) != 0) |
||
509 | { |
||
510 | j = 4 - j; |
||
511 | |||
512 | if (j > x) |
||
513 | j = x; |
||
514 | |||
515 | while (j > 0) |
||
516 | { |
||
517 | if (++index >= SWIDTH*SHEIGHT) return; |
||
518 | //edited 05/18/99 Matt Mueller - changed from 0xff00 to 0x7f00 to fix glitches |
||
519 | *dest++ = fadeTableLocalCopy[(l>>8)&0x7f][static_cast<uint32_t>(pixPtrLocalCopy[ ( (v/z)&(64*63) ) + ((u/z)&63) ]) ]; |
||
520 | //end edit -MM |
||
521 | l += dldx; |
||
522 | u += dudx; |
||
523 | v += dvdx; |
||
524 | z += dzdx; |
||
525 | x--; |
||
526 | j--; |
||
527 | } |
||
528 | } |
||
529 | |||
530 | j &= ~3; |
||
531 | while (j > 0) |
||
532 | { |
||
533 | uint32_t destlong; |
||
534 | //edited 05/18/99 Matt Mueller - changed from 0xff00 to 0x7f00 to fix glitches |
||
535 | destlong = fadeTableLocalCopy[(l>>8)&0x7f][pixPtrLocalCopy[ ( (v/z)&(64*63) ) + ((u/z)&63) ] ] << 24; |
||
536 | //end edit -MM |
||
537 | l += dldx; |
||
538 | u += dudx; |
||
539 | v += dvdx; |
||
540 | z += dzdx; |
||
541 | //edited 05/18/99 Matt Mueller - changed from 0xff00 to 0x7f00 to fix glitches |
||
542 | destlong |= fadeTableLocalCopy[(l>>8)&0x7f][pixPtrLocalCopy[ ( (v/z)&(64*63) ) + ((u/z)&63) ] ] << 16; |
||
543 | //end edit -MM |
||
544 | l += dldx; |
||
545 | u += dudx; |
||
546 | v += dvdx; |
||
547 | z += dzdx; |
||
548 | //edited 05/18/99 Matt Mueller - changed from 0xff00 to 0x7f00 to fix glitches |
||
549 | destlong |= fadeTableLocalCopy[(l>>8)&0x7f][pixPtrLocalCopy[ ( (v/z)&(64*63) ) + ((u/z)&63) ] ] << 8; |
||
550 | //end edit -MM |
||
551 | l += dldx; |
||
552 | u += dudx; |
||
553 | v += dvdx; |
||
554 | z += dzdx; |
||
555 | //edited 05/18/99 Matt Mueller - changed from 0xff00 to 0x7f00 to fix glitches |
||
556 | destlong |= fadeTableLocalCopy[(l>>8)&0x7f][pixPtrLocalCopy[ ( (v/z)&(64*63) ) + ((u/z)&63) ] ]; |
||
557 | //end edit -MM |
||
558 | l += dldx; |
||
559 | u += dudx; |
||
560 | v += dvdx; |
||
561 | z += dzdx; |
||
562 | *reinterpret_cast<uint32_t *>(dest) = destlong; |
||
563 | dest += 4; |
||
564 | x -= 4; |
||
565 | j -= 4; |
||
566 | index += 4; |
||
567 | if (index+4 >= SWIDTH*SHEIGHT) return; |
||
568 | } |
||
569 | |||
570 | while (x-- > 0) |
||
571 | { |
||
572 | if (++index >= SWIDTH*SHEIGHT) return; |
||
573 | //edited 05/18/99 Matt Mueller - changed from 0xff00 to 0x7f00 to fix glitches |
||
574 | *dest++ = fadeTableLocalCopy[(l>>8)&0x7f][pixPtrLocalCopy[ ( (v/z)&(64*63) ) + ((u/z)&63) ] ]; |
||
575 | //end edit -MM |
||
576 | l += dldx; |
||
577 | u += dudx; |
||
578 | v += dvdx; |
||
579 | z += dzdx; |
||
580 | } |
||
581 | |||
582 | } else { |
||
583 | for (x= fx_xright-fx_xleft+1 ; x > 0; --x ) { |
||
584 | if (++index >= SWIDTH*SHEIGHT) return; |
||
585 | c = static_cast<uint32_t>(pixptr[ ( (v/z)&(64*63) ) + ((u/z)&63) ]); |
||
586 | if ( c!=TRANSPARENCY_COLOR) |
||
587 | *dest = gr_fade_table[(l >> 8) &0x7f][c ]; |
||
588 | dest++; |
||
589 | l += dldx; |
||
590 | u += dudx; |
||
591 | v += dvdx; |
||
592 | z += dzdx; |
||
593 | } |
||
594 | } |
||
595 | } |
||
596 | |||
597 | static void c_tmap_scanline_quad() |
||
598 | { |
||
599 | uint c; |
||
600 | int x, index = fx_xleft + (bytes_per_row * fx_y); |
||
601 | fix u,v,l,dudx, dvdx, dldx; |
||
602 | |||
603 | // Quadratic setup stuff: |
||
604 | fix a1, a2, b1, b2, dudx1, dvdx1; |
||
605 | fix u0 = fx_u; |
||
606 | fix u2 = fx_u + fx_du_dx*(fx_xright-fx_xleft+1); // This just needs to be uright from outer loop |
||
607 | fix v0 = fx_v; |
||
608 | fix v2 = fx_v + fx_dv_dx*(fx_xright-fx_xleft+1); // This just needs to be vright from outer loop |
||
609 | fix w0 = fx_z; |
||
610 | fix w2 = fx_z + fx_dz_dx*(fx_xright-fx_xleft+1); // This just needs to be zright from outer loop |
||
611 | fix u1 = fixdiv((u0+u2),(w0+w2)); |
||
612 | fix v1 = fixdiv((v0+v2),(w0+w2)); |
||
613 | int dx = fx_xright-fx_xleft+1; |
||
614 | u0 = fixdiv( u0, w0 ); // Divide Z out. This should be in outer loop |
||
615 | v0 = fixdiv( v0, w0 ); // Divide Z out. This should be in outer loop |
||
616 | u2 = fixdiv( u2, w2 ); // Divide Z out. This should be in outer loop |
||
617 | v2 = fixdiv( v2, w2 ); // Divide Z out. This should be in outer loop |
||
618 | a1 = (-3*u0+4*u1-u2)/dx; |
||
619 | b1 = (-3*v0+4*v1-v2)/dx; |
||
620 | a2 = (2*(u0-2*u1+u2))/(dx*dx); |
||
621 | b2 = (2*(v0-2*v1+v2))/(dx*dx); |
||
622 | dudx = a1 + a2; |
||
623 | dvdx = b1 + b2; |
||
624 | dudx1 = 2*a2; |
||
625 | dvdx1 = 2*b2; |
||
626 | u = u0; |
||
627 | v = v0; |
||
628 | |||
629 | // Normal lighting setup |
||
630 | l = fx_l>>8; |
||
631 | dldx = fx_dl_dx>>8; |
||
632 | |||
633 | // Normal destination pointer setup |
||
634 | auto dest = &write_buffer[fx_xleft + (bytes_per_row * fx_y)]; |
||
635 | |||
636 | if (!Transparency_on) { |
||
637 | for (x= fx_xright-fx_xleft+1 ; x > 0; --x ) { |
||
638 | if (++index >= SWIDTH*SHEIGHT) return; |
||
639 | *dest++ = gr_fade_table[(l>>8)&0xff][pixptr[ (f2i(v)&63)*64 + (f2i(u)&63) ] ]; |
||
640 | l += dldx; |
||
641 | u += dudx; |
||
642 | v += dvdx; |
||
643 | dudx += dudx1; // Extra add for quadratic! |
||
644 | dvdx += dvdx1; // Extra add for quadratic! |
||
645 | } |
||
646 | } else { |
||
647 | for (x= fx_xright-fx_xleft+1 ; x > 0; --x ) { |
||
648 | if (++index >= SWIDTH*SHEIGHT) return; |
||
649 | c = static_cast<uint32_t>(pixptr[ (f2i(v)&63)*64 + (f2i(u)&63) ]); |
||
650 | if ( c!=255) |
||
651 | *dest = gr_fade_table[(l>>8)&0xff][c]; |
||
652 | dest++; |
||
653 | l += dldx; |
||
654 | u += dudx; |
||
655 | v += dvdx; |
||
656 | dudx += dudx1; // Extra add for quadratic! |
||
657 | dvdx += dvdx1; // Extra add for quadratic! |
||
658 | } |
||
659 | } |
||
660 | } |
||
661 | |||
662 | //runtime selection of optimized tmappers. 12/07/99 Matthew Mueller |
||
663 | //the reason I did it this way rather than having a *tmap_funcs that then points to a c_tmap or fp_tmap struct thats already filled in, is to avoid a second pointer dereference. |
||
664 | void select_tmap(const std::string &type) |
||
665 | { |
||
666 | if (type == "fp") |
||
667 | { |
||
668 | cur_tmap_scanline_per=c_fp_tmap_scanline_per; |
||
669 | } |
||
670 | else if (type == "quad") |
||
671 | { |
||
672 | cur_tmap_scanline_per=c_tmap_scanline_quad; |
||
673 | } |
||
674 | else { |
||
675 | cur_tmap_scanline_per=c_tmap_scanline_per; |
||
676 | } |
||
677 | } |
||
678 | |||
679 | } |