2006-03-20 17:12:09 +00:00
/*
2014-06-01 17:55:23 +00:00
* Portions of this file are copyright Rebirth contributors and licensed as
* described in COPYING . txt .
* Portions of this file are copyright Parallax Software and licensed
* according to the Parallax license below .
* See COPYING . txt for license details .
2006-03-20 17:12:09 +00:00
THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
SOFTWARE CORPORATION ( " PARALLAX " ) . PARALLAX , IN DISTRIBUTING THE CODE TO
END - USERS , AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN , GRANTS A
ROYALTY - FREE , PERPETUAL LICENSE TO SUCH END - USERS FOR USE BY SUCH END - USERS
IN USING , DISPLAYING , AND CREATING DERIVATIVE WORKS THEREOF , SO LONG AS
SUCH USE , DISPLAY OR CREATION IS FOR NON - COMMERCIAL , ROYALTY OR REVENUE
FREE PURPOSES . IN NO EVENT SHALL THE END - USER USE THE COMPUTER CODE
CONTAINED HEREIN FOR REVENUE - BEARING PURPOSES . THE END - USER UNDERSTANDS
AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE .
COPYRIGHT 1993 - 1998 PARALLAX SOFTWARE CORPORATION . ALL RIGHTS RESERVED .
*/
/*
*
* Routines to draw the texture mapped scanlines .
*
*/
# include <math.h>
# include <limits.h>
# include <stdio.h>
# include <stdlib.h>
2013-10-27 00:55:49 +00:00
# include <stdint.h>
2006-03-20 17:12:09 +00:00
# include <string.h>
# include "maths.h"
# include "gr.h"
# include "grdef.h"
# include "texmap.h"
# include "texmapl.h"
# include "scanline.h"
# include "strutil.h"
2012-07-07 18:35:06 +00:00
# include "dxxerror.h"
2006-03-20 17:12:09 +00:00
2015-12-13 18:00:49 +00:00
namespace dcx {
2015-12-05 22:57:24 +00:00
2015-07-25 23:10:47 +00:00
tmap_scanline_function_table tmap_scanline_functions ;
2015-07-25 23:10:47 +00:00
# ifndef OGL
2006-03-20 17:12:09 +00:00
void c_tmap_scanline_flat ( )
{
ubyte * dest ;
2011-01-17 20:00:52 +00:00
int x , index = fx_xleft + ( bytes_per_row * fx_y ) ;
2006-03-20 17:12:09 +00:00
2016-06-05 01:04:25 +00:00
dest = ( uint8_t * ) ( write_buffer + fx_xleft + ( bytes_per_row * fx_y ) ) ;
2006-03-20 17:12:09 +00:00
2011-01-17 20:00:52 +00:00
for ( x = fx_xright - fx_xleft + 1 ; x > 0 ; - - x ) {
if ( + + index > = SWIDTH * SHEIGHT ) return ;
2006-03-20 17:12:09 +00:00
* dest + + = tmap_flat_color ;
2011-01-17 20:00:52 +00:00
}
// memset(dest,tmap_flat_color,fx_xright-fx_xleft+1);
2006-03-20 17:12:09 +00:00
}
2015-07-25 23:10:47 +00:00
# endif
2006-03-20 17:12:09 +00:00
void c_tmap_scanline_shaded ( )
{
int fade ;
ubyte * dest , tmp ;
2011-01-17 20:00:52 +00:00
int x , index = fx_xleft + ( bytes_per_row * fx_y ) ;
2006-03-20 17:12:09 +00:00
2016-06-05 01:04:25 +00:00
dest = ( uint8_t * ) ( write_buffer + fx_xleft + ( bytes_per_row * fx_y ) ) ;
2006-03-20 17:12:09 +00:00
2014-08-08 02:44:27 +00:00
fade = tmap_flat_shade_value ;
2006-03-20 17:12:09 +00:00
for ( x = fx_xright - fx_xleft + 1 ; x > 0 ; - - x ) {
2011-01-17 20:00:52 +00:00
if ( + + index > = SWIDTH * SHEIGHT ) return ;
2006-03-20 17:12:09 +00:00
tmp = * dest ;
2014-08-08 02:44:27 +00:00
* dest + + = gr_fade_table [ fade ] [ tmp ] ;
2006-03-20 17:12:09 +00:00
}
}
void c_tmap_scanline_lin_nolight ( )
{
ubyte * dest ;
uint c ;
2011-01-17 20:00:52 +00:00
int x , index = fx_xleft + ( bytes_per_row * fx_y ) ;
2006-03-20 17:12:09 +00:00
fix u , v , dudx , dvdx ;
u = fx_u ;
v = fx_v * 64 ;
dudx = fx_du_dx ;
dvdx = fx_dv_dx * 64 ;
2016-06-05 01:04:25 +00:00
dest = ( uint8_t * ) ( write_buffer + fx_xleft + ( bytes_per_row * fx_y ) ) ;
2006-03-20 17:12:09 +00:00
if ( ! Transparency_on ) {
for ( x = fx_xright - fx_xleft + 1 ; x > 0 ; - - x ) {
2011-01-17 20:00:52 +00:00
if ( + + index > = SWIDTH * SHEIGHT ) return ;
2006-03-20 17:12:09 +00:00
* dest + + = ( uint ) pixptr [ ( f2i ( v ) & ( 64 * 63 ) ) + ( f2i ( u ) & 63 ) ] ;
u + = dudx ;
v + = dvdx ;
}
} else {
for ( x = fx_xright - fx_xleft + 1 ; x > 0 ; - - x ) {
2011-01-17 20:00:52 +00:00
if ( + + index > = SWIDTH * SHEIGHT ) return ;
2006-03-20 17:12:09 +00:00
c = ( uint ) pixptr [ ( f2i ( v ) & ( 64 * 63 ) ) + ( f2i ( u ) & 63 ) ] ;
if ( c ! = 255 )
* dest = c ;
dest + + ;
u + = dudx ;
v + = dvdx ;
}
}
}
# if 1
void c_tmap_scanline_lin ( )
{
ubyte * dest ;
uint c ;
2011-01-17 20:00:52 +00:00
int x , j , index = fx_xleft + ( bytes_per_row * fx_y ) ;
2006-03-20 17:12:09 +00:00
fix u , v , l , dudx , dvdx , dldx ;
u = fx_u ;
v = fx_v * 64 ;
dudx = fx_du_dx ;
dvdx = fx_dv_dx * 64 ;
l = fx_l > > 8 ;
2006-12-24 08:01:25 +00:00
dldx = fx_dl_dx / 256 ;
2016-06-05 01:04:25 +00:00
dest = ( uint8_t * ) ( write_buffer + fx_xleft + ( bytes_per_row * fx_y ) ) ;
2006-03-20 17:12:09 +00:00
if ( ! Transparency_on ) {
2014-11-30 22:09:18 +00:00
const auto pixPtrLocalCopy = pixptr ;
2014-08-08 02:07:47 +00:00
auto & fadeTableLocalCopy = gr_fade_table ;
2006-03-20 17:12:09 +00:00
unsigned long destlong ;
x = fx_xright - fx_xleft + 1 ;
2013-10-27 00:55:49 +00:00
if ( ( j = reinterpret_cast < uintptr_t > ( dest ) & 3 ) ! = 0 )
2006-03-20 17:12:09 +00:00
{
j = 4 - j ;
if ( j > x )
j = x ;
while ( j > 0 )
{
2011-01-17 20:00:52 +00:00
if ( + + index > = SWIDTH * SHEIGHT ) return ;
2006-03-20 17:12:09 +00:00
//edited 05/18/99 Matt Mueller - changed from 0xff00 to 0x7f00 to fix glitches
2014-08-08 02:44:27 +00:00
* dest + + = ( unsigned long ) fadeTableLocalCopy [ ( l > > 8 ) & 0x7f ] [ pixPtrLocalCopy [ ( f2i ( v ) & ( 64 * 63 ) ) + ( f2i ( u ) & 63 ) ] ] ;
2006-03-20 17:12:09 +00:00
//end edit -MM
l + = dldx ;
u + = dudx ;
v + = dvdx ;
x - - ;
j - - ;
}
}
j & = ~ 3 ;
while ( j > 0 )
{
//edited 05/18/99 Matt Mueller - changed from 0xff00 to 0x7f00 to fix glitches
2014-08-08 02:44:27 +00:00
destlong = ( unsigned long ) fadeTableLocalCopy [ ( l > > 8 ) & 0x7f ] [ pixPtrLocalCopy [ ( f2i ( v ) & ( 64 * 63 ) ) + ( f2i ( u ) & 63 ) ] ] < < 24 ;
2006-03-20 17:12:09 +00:00
//end edit -MM
l + = dldx ;
u + = dudx ;
v + = dvdx ;
//edited 05/18/99 Matt Mueller - changed from 0xff00 to 0x7f00 to fix glitches
2014-08-08 02:44:27 +00:00
destlong | = ( unsigned long ) fadeTableLocalCopy [ ( l > > 8 ) & 0x7f ] [ pixPtrLocalCopy [ ( f2i ( v ) & ( 64 * 63 ) ) + ( f2i ( u ) & 63 ) ] ] < < 16 ;
2006-03-20 17:12:09 +00:00
//end edit -MM
l + = dldx ;
u + = dudx ;
v + = dvdx ;
//edited 05/18/99 Matt Mueller - changed from 0xff00 to 0x7f00 to fix glitches
2014-08-08 02:44:27 +00:00
destlong | = ( unsigned long ) fadeTableLocalCopy [ ( l > > 8 ) & 0x7f ] [ pixPtrLocalCopy [ ( f2i ( v ) & ( 64 * 63 ) ) + ( f2i ( u ) & 63 ) ] ] < < 8 ;
2006-03-20 17:12:09 +00:00
//end edit -MM
l + = dldx ;
u + = dudx ;
v + = dvdx ;
//edited 05/18/99 Matt Mueller - changed from 0xff00 to 0x7f00 to fix glitches
2014-08-08 02:44:27 +00:00
destlong | = ( unsigned long ) fadeTableLocalCopy [ ( l > > 8 ) & 0x7f ] [ pixPtrLocalCopy [ ( f2i ( v ) & ( 64 * 63 ) ) + ( f2i ( u ) & 63 ) ] ] ;
2006-03-20 17:12:09 +00:00
//end edit -MM
l + = dldx ;
u + = dudx ;
v + = dvdx ;
* ( ( unsigned long * ) dest ) = destlong ;
dest + = 4 ;
x - = 4 ;
j - = 4 ;
2011-01-17 20:00:52 +00:00
index + = 4 ;
if ( index + 4 > = SWIDTH * SHEIGHT ) return ;
2006-03-20 17:12:09 +00:00
}
while ( x - - > 0 )
{
2011-01-17 20:00:52 +00:00
if ( + + index > = SWIDTH * SHEIGHT ) return ;
2006-03-20 17:12:09 +00:00
//edited 05/18/99 Matt Mueller - changed from 0xff00 to 0x7f00 to fix glitches
2014-08-08 02:44:27 +00:00
* dest + + = ( unsigned long ) fadeTableLocalCopy [ ( l > > 8 ) & 0x7f ] [ pixPtrLocalCopy [ ( f2i ( v ) & ( 64 * 63 ) ) + ( f2i ( u ) & 63 ) ] ] ;
2006-03-20 17:12:09 +00:00
//end edit -MM
l + = dldx ;
u + = dudx ;
v + = dvdx ;
}
} else {
for ( x = fx_xright - fx_xleft + 1 ; x > 0 ; - - x ) {
2011-01-17 20:00:52 +00:00
if ( + + index > = SWIDTH * SHEIGHT ) return ;
2006-03-20 17:12:09 +00:00
c = ( uint ) pixptr [ ( f2i ( v ) & ( 64 * 63 ) ) + ( f2i ( u ) & 63 ) ] ;
if ( c ! = TRANSPARENCY_COLOR )
//edited 05/18/99 Matt Mueller - changed from 0xff00 to 0x7f00 to fix glitches
2014-08-08 02:44:27 +00:00
* dest = gr_fade_table [ ( l > > 8 ) & 0x7f ] [ c ] ;
2006-03-20 17:12:09 +00:00
//end edit -MM
dest + + ;
l + = dldx ;
u + = dudx ;
v + = dvdx ;
}
}
}
# else
void c_tmap_scanline_lin ( )
{
ubyte * dest ;
uint c ;
fix u , v , l , dudx , dvdx , dldx ;
u = fx_u ;
v = fx_v * 64 ;
dudx = fx_du_dx ;
dvdx = fx_dv_dx * 64 ;
l = fx_l > > 8 ;
2006-12-24 08:01:25 +00:00
dldx = fx_dl_dx / 256 ;
2016-06-05 01:04:25 +00:00
dest = ( uint8_t * ) ( write_buffer + fx_xleft + ( bytes_per_row * fx_y ) ) ;
2006-03-20 17:12:09 +00:00
if ( ! Transparency_on ) {
2014-09-26 02:42:15 +00:00
for ( int x = fx_xright - fx_xleft + 1 ; x > 0 ; - - x ) {
2006-03-20 17:12:09 +00:00
//edited 05/18/99 Matt Mueller - changed from 0xff00 to 0x7f00 to fix glitches
* dest + + = gr_fade_table [ ( l & ( 0x7f00 ) ) + ( uint ) pixptr [ ( f2i ( v ) & ( 64 * 63 ) ) + ( f2i ( u ) & 63 ) ] ] ;
//end edit -MM
l + = dldx ;
u + = dudx ;
v + = dvdx ;
}
} else {
2014-09-26 02:42:15 +00:00
for ( int x = fx_xright - fx_xleft + 1 ; x > 0 ; - - x ) {
2006-03-20 17:12:09 +00:00
c = ( uint ) pixptr [ ( f2i ( v ) & ( 64 * 63 ) ) + ( f2i ( u ) & 63 ) ] ;
if ( c ! = 255 )
//edited 05/18/99 Matt Mueller - changed from 0xff00 to 0x7f00 to fix glitches
* dest = gr_fade_table [ ( l & ( 0x7f00 ) ) + c ] ;
//end edit -MM
dest + + ;
l + = dldx ;
u + = dudx ;
v + = dvdx ;
}
}
}
# endif
// This texture mapper uses floating point extensively and writes 8 pixels at once, so it likely works
// best on 64 bit RISC processors.
// WARNING: it is not endian clean. For big endian, reverse the shift counts in the unrolled loops. I
// have no means to test that, so I didn't try it. Please tell me if you get this to work on a big
// endian machine.
// If you're using an Alpha, use the Compaq compiler for this file for quite some fps more.
// Unfortunately, it won't compile the whole source, so simply compile everything, change the
// compiler to ccc, remove scanline.o and compile again.
// Please send comments/suggestions to falk.hueffner@student.uni-tuebingen.de.
2013-10-27 22:00:14 +00:00
static void c_fp_tmap_scanline_per ( )
2006-03-20 17:12:09 +00:00
{
ubyte * dest ;
uint c ;
2011-01-17 20:00:52 +00:00
int x , j , index = fx_xleft + ( bytes_per_row * fx_y ) ;
2006-03-20 17:12:09 +00:00
double u , v , z , l , dudx , dvdx , dzdx , dldx , rec_z ;
2015-01-03 06:34:13 +00:00
uint64_t destlong ;
2006-03-20 17:12:09 +00:00
u = f2db ( fx_u ) ;
v = f2db ( fx_v ) * 64.0 ;
z = f2db ( fx_z ) ;
l = f2db ( fx_l ) ;
dudx = f2db ( fx_du_dx ) ;
dvdx = f2db ( fx_dv_dx ) * 64.0 ;
dzdx = f2db ( fx_dz_dx ) ;
dldx = f2db ( fx_dl_dx ) ;
rec_z = 1.0 / z ; // gcc 2.95.2 is won't do this optimization itself
2016-06-05 01:04:25 +00:00
dest = ( uint8_t * ) ( write_buffer + fx_xleft + ( bytes_per_row * fx_y ) ) ;
2006-03-20 17:12:09 +00:00
x = fx_xright - fx_xleft + 1 ;
if ( ! Transparency_on ) {
if ( x > = 8 ) {
if ( ( j = ( size_t ) dest & 7 ) ! = 0 ) {
j = 8 - j ;
while ( j > 0 ) {
2011-01-17 20:00:52 +00:00
if ( + + index > = SWIDTH * SHEIGHT ) return ;
2006-03-20 17:12:09 +00:00
* dest + + =
2014-08-08 02:44:27 +00:00
gr_fade_table [ ( ( int ) fabs ( l ) ) ] [
2006-03-20 17:12:09 +00:00
( uint ) pixptr [ ( ( ( int ) ( v * rec_z ) ) & ( 64 * 63 ) ) +
( ( ( int ) ( u * rec_z ) ) & 63 ) ] ] ;
l + = dldx ;
u + = dudx ;
v + = dvdx ;
z + = dzdx ;
rec_z = 1.0 / z ;
x - - ;
j - - ;
}
}
j = x ;
while ( j > = 8 ) {
destlong =
2015-01-03 06:34:13 +00:00
( uint64_t ) gr_fade_table [ ( ( int ) fabs ( l ) ) ] [
2006-03-20 17:12:09 +00:00
( uint ) pixptr [ ( ( ( int ) ( v * rec_z ) ) & ( 64 * 63 ) ) +
( ( ( int ) ( u * rec_z ) ) & 63 ) ] ] ;
l + = dldx ;
u + = dudx ;
v + = dvdx ;
z + = dzdx ;
rec_z = 1.0 / z ;
destlong | =
2015-01-03 06:34:13 +00:00
( uint64_t ) gr_fade_table [ ( ( int ) fabs ( l ) ) ] [
2006-03-20 17:12:09 +00:00
( uint ) pixptr [ ( ( ( int ) ( v * rec_z ) ) & ( 64 * 63 ) ) +
( ( ( int ) ( u * rec_z ) ) & 63 ) ] ] < < 8 ;
l + = dldx ;
u + = dudx ;
v + = dvdx ;
z + = dzdx ;
rec_z = 1.0 / z ;
destlong | =
2015-01-03 06:34:13 +00:00
( uint64_t ) gr_fade_table [ ( ( int ) fabs ( l ) ) ] [
2006-03-20 17:12:09 +00:00
( uint ) pixptr [ ( ( ( int ) ( v * rec_z ) ) & ( 64 * 63 ) ) +
( ( ( int ) ( u * rec_z ) ) & 63 ) ] ] < < 16 ;
l + = dldx ;
u + = dudx ;
v + = dvdx ;
z + = dzdx ;
rec_z = 1.0 / z ;
destlong | =
2015-01-03 06:34:13 +00:00
( uint64_t ) gr_fade_table [ ( ( int ) fabs ( l ) ) ] [
2006-03-20 17:12:09 +00:00
( uint ) pixptr [ ( ( ( int ) ( v * rec_z ) ) & ( 64 * 63 ) ) +
( ( ( int ) ( u * rec_z ) ) & 63 ) ] ] < < 24 ;
l + = dldx ;
u + = dudx ;
v + = dvdx ;
z + = dzdx ;
rec_z = 1.0 / z ;
destlong | =
2015-01-03 06:34:13 +00:00
( uint64_t ) gr_fade_table [ ( ( int ) fabs ( l ) ) ] [
2006-03-20 17:12:09 +00:00
( uint ) pixptr [ ( ( ( int ) ( v * rec_z ) ) & ( 64 * 63 ) ) +
( ( ( int ) ( u * rec_z ) ) & 63 ) ] ] < < 32 ;
l + = dldx ;
u + = dudx ;
v + = dvdx ;
z + = dzdx ;
rec_z = 1.0 / z ;
destlong | =
2015-01-03 06:34:13 +00:00
( uint64_t ) gr_fade_table [ ( ( int ) fabs ( l ) ) ] [
2006-03-20 17:12:09 +00:00
( uint ) pixptr [ ( ( ( int ) ( v * rec_z ) ) & ( 64 * 63 ) ) +
( ( ( int ) ( u * rec_z ) ) & 63 ) ] ] < < 40 ;
l + = dldx ;
u + = dudx ;
v + = dvdx ;
z + = dzdx ;
rec_z = 1.0 / z ;
destlong | =
2015-01-03 06:34:13 +00:00
( uint64_t ) gr_fade_table [ ( ( int ) fabs ( l ) ) ] [
2006-03-20 17:12:09 +00:00
( uint ) pixptr [ ( ( ( int ) ( v * rec_z ) ) & ( 64 * 63 ) ) +
( ( ( int ) ( u * rec_z ) ) & 63 ) ] ] < < 48 ;
l + = dldx ;
u + = dudx ;
v + = dvdx ;
z + = dzdx ;
rec_z = 1.0 / z ;
destlong | =
2015-01-03 06:34:13 +00:00
( uint64_t ) gr_fade_table [ ( ( int ) fabs ( l ) ) ] [
2006-03-20 17:12:09 +00:00
( uint ) pixptr [ ( ( ( int ) ( v * rec_z ) ) & ( 64 * 63 ) ) +
( ( ( int ) ( u * rec_z ) ) & 63 ) ] ] < < 56 ;
l + = dldx ;
u + = dudx ;
v + = dvdx ;
z + = dzdx ;
rec_z = 1.0 / z ;
2015-01-03 06:34:13 +00:00
* ( ( uint64_t * ) dest ) = destlong ;
2006-03-20 17:12:09 +00:00
dest + = 8 ;
x - = 8 ;
j - = 8 ;
2011-01-17 20:00:52 +00:00
index + = 8 ;
if ( index + 8 > = SWIDTH * SHEIGHT ) return ;
2006-03-20 17:12:09 +00:00
}
}
while ( x - - > 0 ) {
2011-01-17 20:00:52 +00:00
if ( + + index > = SWIDTH * SHEIGHT ) return ;
2006-03-20 17:12:09 +00:00
* dest + + =
2014-08-08 02:44:27 +00:00
gr_fade_table [ ( ( int ) fabs ( l ) ) ] [
2006-03-20 17:12:09 +00:00
( uint ) pixptr [ ( ( ( int ) ( v * rec_z ) ) & ( 64 * 63 ) ) + ( ( ( int ) ( u * rec_z ) ) & 63 ) ] ] ;
l + = dldx ;
u + = dudx ;
v + = dvdx ;
z + = dzdx ;
rec_z = 1.0 / z ;
}
} else {
if ( x > = 8 ) {
if ( ( j = ( size_t ) dest & 7 ) ! = 0 ) {
j = 8 - j ;
while ( j > 0 ) {
2011-01-17 20:00:52 +00:00
if ( + + index > = SWIDTH * SHEIGHT ) return ;
2006-03-20 17:12:09 +00:00
c = ( uint ) pixptr [ ( ( ( int ) ( v * rec_z ) ) & ( 64 * 63 ) ) + ( ( ( int ) ( u * rec_z ) ) & 63 ) ] ;
if ( c ! = 255 )
2014-08-08 02:44:27 +00:00
* dest = gr_fade_table [ ( ( int ) fabs ( l ) ) ] [ c ] ;
2006-03-20 17:12:09 +00:00
dest + + ;
l + = dldx ;
u + = dudx ;
v + = dvdx ;
z + = dzdx ;
rec_z = 1.0 / z ;
x - - ;
j - - ;
}
}
j = x ;
while ( j > = 8 ) {
2015-01-03 06:34:13 +00:00
destlong = * ( ( uint64_t * ) dest ) ;
2006-03-20 17:12:09 +00:00
c = ( uint ) pixptr [ ( ( ( int ) ( v * rec_z ) ) & ( 64 * 63 ) ) + ( ( ( int ) ( u * rec_z ) ) & 63 ) ] ;
if ( c ! = 255 ) {
2015-01-03 06:34:13 +00:00
destlong & = ~ ( uint64_t ) 0xFF ;
destlong | = ( uint64_t ) gr_fade_table [ ( ( int ) fabs ( l ) ) ] [ c ] ;
2006-03-20 17:12:09 +00:00
}
l + = dldx ;
u + = dudx ;
v + = dvdx ;
z + = dzdx ;
rec_z = 1.0 / z ;
c = ( uint ) pixptr [ ( ( ( int ) ( v * rec_z ) ) & ( 64 * 63 ) ) + ( ( ( int ) ( u * rec_z ) ) & 63 ) ] ;
if ( c ! = 255 ) {
2015-01-03 06:34:13 +00:00
destlong & = ~ ( ( uint64_t ) 0xFF < < 8 ) ;
destlong | = ( uint64_t ) gr_fade_table [ ( ( int ) fabs ( l ) ) ] [ c ] < < 8 ;
2006-03-20 17:12:09 +00:00
}
l + = dldx ;
u + = dudx ;
v + = dvdx ;
z + = dzdx ;
rec_z = 1.0 / z ;
c = ( uint ) pixptr [ ( ( ( int ) ( v * rec_z ) ) & ( 64 * 63 ) ) + ( ( ( int ) ( u * rec_z ) ) & 63 ) ] ;
if ( c ! = 255 ) {
2015-01-03 06:34:13 +00:00
destlong & = ~ ( ( uint64_t ) 0xFF < < 16 ) ;
destlong | = ( uint64_t ) gr_fade_table [ ( ( int ) fabs ( l ) ) ] [ c ] < < 16 ;
2006-03-20 17:12:09 +00:00
}
l + = dldx ;
u + = dudx ;
v + = dvdx ;
z + = dzdx ;
rec_z = 1.0 / z ;
c = ( uint ) pixptr [ ( ( ( int ) ( v * rec_z ) ) & ( 64 * 63 ) ) + ( ( ( int ) ( u * rec_z ) ) & 63 ) ] ;
if ( c ! = 255 ) {
2015-01-03 06:34:13 +00:00
destlong & = ~ ( ( uint64_t ) 0xFF < < 24 ) ;
destlong | = ( uint64_t ) gr_fade_table [ ( ( int ) fabs ( l ) ) ] [ c ] < < 24 ;
2006-03-20 17:12:09 +00:00
}
l + = dldx ;
u + = dudx ;
v + = dvdx ;
z + = dzdx ;
rec_z = 1.0 / z ;
c = ( uint ) pixptr [ ( ( ( int ) ( v * rec_z ) ) & ( 64 * 63 ) ) + ( ( ( int ) ( u * rec_z ) ) & 63 ) ] ;
if ( c ! = 255 ) {
2015-01-03 06:34:13 +00:00
destlong & = ~ ( ( uint64_t ) 0xFF < < 32 ) ;
destlong | = ( uint64_t ) gr_fade_table [ ( ( int ) fabs ( l ) ) ] [ c ] < < 32 ;
2006-03-20 17:12:09 +00:00
}
l + = dldx ;
u + = dudx ;
v + = dvdx ;
z + = dzdx ;
rec_z = 1.0 / z ;
c = ( uint ) pixptr [ ( ( ( int ) ( v * rec_z ) ) & ( 64 * 63 ) ) + ( ( ( int ) ( u * rec_z ) ) & 63 ) ] ;
if ( c ! = 255 ) {
2015-01-03 06:34:13 +00:00
destlong & = ~ ( ( uint64_t ) 0xFF < < 40 ) ;
destlong | = ( uint64_t ) gr_fade_table [ ( ( int ) fabs ( l ) ) ] [ c ] < < 40 ;
2006-03-20 17:12:09 +00:00
}
l + = dldx ;
u + = dudx ;
v + = dvdx ;
z + = dzdx ;
rec_z = 1.0 / z ;
c = ( uint ) pixptr [ ( ( ( int ) ( v * rec_z ) ) & ( 64 * 63 ) ) + ( ( ( int ) ( u * rec_z ) ) & 63 ) ] ;
if ( c ! = 255 ) {
2015-01-03 06:34:13 +00:00
destlong & = ~ ( ( uint64_t ) 0xFF < < 48 ) ;
destlong | = ( uint64_t ) gr_fade_table [ ( ( int ) fabs ( l ) ) ] [ c ] < < 48 ;
2006-03-20 17:12:09 +00:00
}
l + = dldx ;
u + = dudx ;
v + = dvdx ;
z + = dzdx ;
rec_z = 1.0 / z ;
c = ( uint ) pixptr [ ( ( ( int ) ( v * rec_z ) ) & ( 64 * 63 ) ) + ( ( ( int ) ( u * rec_z ) ) & 63 ) ] ;
if ( c ! = 255 ) {
2015-01-03 06:34:13 +00:00
destlong & = ~ ( ( uint64_t ) 0xFF < < 56 ) ;
destlong | = ( uint64_t ) gr_fade_table [ ( ( int ) fabs ( l ) ) ] [ c ] < < 56 ;
2006-03-20 17:12:09 +00:00
}
l + = dldx ;
u + = dudx ;
v + = dvdx ;
z + = dzdx ;
rec_z = 1.0 / z ;
2015-01-03 06:34:13 +00:00
* ( ( uint64_t * ) dest ) = destlong ;
2006-03-20 17:12:09 +00:00
dest + = 8 ;
x - = 8 ;
j - = 8 ;
2011-01-17 20:00:52 +00:00
index + = 8 ;
if ( index + 8 > = SWIDTH * SHEIGHT ) return ;
2006-03-20 17:12:09 +00:00
}
}
while ( x - - > 0 ) {
2011-01-17 20:00:52 +00:00
if ( + + index > = SWIDTH * SHEIGHT ) return ;
2006-03-20 17:12:09 +00:00
c = ( uint ) pixptr [ ( ( ( int ) ( v * rec_z ) ) & ( 64 * 63 ) ) + ( ( ( int ) ( u * rec_z ) ) & 63 ) ] ;
if ( c ! = 255 )
2014-08-08 02:44:27 +00:00
* dest = gr_fade_table [ ( ( int ) fabs ( l ) ) ] [ c ] ;
2006-03-20 17:12:09 +00:00
dest + + ;
l + = dldx ;
u + = dudx ;
v + = dvdx ;
z + = dzdx ;
rec_z = 1.0 / z ;
}
}
}
# if 1
// note the unrolling loop is broken. It is never called, and uses big endian. -- FH
2015-07-25 23:10:47 +00:00
static void c_tmap_scanline_per ( )
2006-03-20 17:12:09 +00:00
{
ubyte * dest ;
uint c ;
2011-01-17 20:00:52 +00:00
int x , j , index = fx_xleft + ( bytes_per_row * fx_y ) ;
2006-03-20 17:12:09 +00:00
fix l , u , v , z ;
fix dudx , dvdx , dzdx , dldx ;
u = fx_u ;
v = fx_v * 64 ;
z = fx_z ;
dudx = fx_du_dx ;
dvdx = fx_dv_dx * 64 ;
dzdx = fx_dz_dx ;
l = fx_l > > 8 ;
2006-12-24 08:01:25 +00:00
dldx = fx_dl_dx / 256 ;
2016-06-05 01:04:25 +00:00
dest = ( uint8_t * ) ( write_buffer + fx_xleft + ( bytes_per_row * fx_y ) ) ;
2006-03-20 17:12:09 +00:00
if ( ! Transparency_on ) {
2014-11-30 22:09:18 +00:00
const auto pixPtrLocalCopy = pixptr ;
2014-08-08 02:07:47 +00:00
auto & fadeTableLocalCopy = gr_fade_table ;
2006-03-20 17:12:09 +00:00
unsigned long destlong ;
2006-12-24 08:01:25 +00:00
x = fx_xright - fx_xleft + 1 ; // x = number of pixels in scanline
2006-03-20 17:12:09 +00:00
2013-10-27 00:55:49 +00:00
if ( ( j = reinterpret_cast < uintptr_t > ( dest ) & 3 ) ! = 0 )
2006-03-20 17:12:09 +00:00
{
j = 4 - j ;
if ( j > x )
j = x ;
while ( j > 0 )
{
2011-01-17 20:00:52 +00:00
if ( + + index > = SWIDTH * SHEIGHT ) return ;
2006-03-20 17:12:09 +00:00
//edited 05/18/99 Matt Mueller - changed from 0xff00 to 0x7f00 to fix glitches
2014-08-08 02:44:27 +00:00
* dest + + = fadeTableLocalCopy [ ( l > > 8 ) & 0x7f ] [ ( uint ) pixPtrLocalCopy [ ( ( v / z ) & ( 64 * 63 ) ) + ( ( u / z ) & 63 ) ] ] ;
2006-03-20 17:12:09 +00:00
//end edit -MM
l + = dldx ;
u + = dudx ;
v + = dvdx ;
z + = dzdx ;
x - - ;
j - - ;
}
}
j & = ~ 3 ;
while ( j > 0 )
{
//edited 05/18/99 Matt Mueller - changed from 0xff00 to 0x7f00 to fix glitches
2014-08-08 02:44:27 +00:00
destlong = ( unsigned long ) fadeTableLocalCopy [ ( l > > 8 ) & 0x7f ] [ pixPtrLocalCopy [ ( ( v / z ) & ( 64 * 63 ) ) + ( ( u / z ) & 63 ) ] ] < < 24 ;
2006-03-20 17:12:09 +00:00
//end edit -MM
l + = dldx ;
u + = dudx ;
v + = dvdx ;
z + = dzdx ;
//edited 05/18/99 Matt Mueller - changed from 0xff00 to 0x7f00 to fix glitches
2014-08-08 02:44:27 +00:00
destlong | = ( unsigned long ) fadeTableLocalCopy [ ( l > > 8 ) & 0x7f ] [ pixPtrLocalCopy [ ( ( v / z ) & ( 64 * 63 ) ) + ( ( u / z ) & 63 ) ] ] < < 16 ;
2006-03-20 17:12:09 +00:00
//end edit -MM
l + = dldx ;
u + = dudx ;
v + = dvdx ;
z + = dzdx ;
//edited 05/18/99 Matt Mueller - changed from 0xff00 to 0x7f00 to fix glitches
2014-08-08 02:44:27 +00:00
destlong | = ( unsigned long ) fadeTableLocalCopy [ ( l > > 8 ) & 0x7f ] [ pixPtrLocalCopy [ ( ( v / z ) & ( 64 * 63 ) ) + ( ( u / z ) & 63 ) ] ] < < 8 ;
2006-03-20 17:12:09 +00:00
//end edit -MM
l + = dldx ;
u + = dudx ;
v + = dvdx ;
z + = dzdx ;
//edited 05/18/99 Matt Mueller - changed from 0xff00 to 0x7f00 to fix glitches
2014-08-08 02:44:27 +00:00
destlong | = ( unsigned long ) fadeTableLocalCopy [ ( l > > 8 ) & 0x7f ] [ pixPtrLocalCopy [ ( ( v / z ) & ( 64 * 63 ) ) + ( ( u / z ) & 63 ) ] ] ;
2006-03-20 17:12:09 +00:00
//end edit -MM
l + = dldx ;
u + = dudx ;
v + = dvdx ;
z + = dzdx ;
* ( ( unsigned long * ) dest ) = destlong ;
dest + = 4 ;
x - = 4 ;
j - = 4 ;
2011-01-17 20:00:52 +00:00
index + = 4 ;
if ( index + 4 > = SWIDTH * SHEIGHT ) return ;
2006-03-20 17:12:09 +00:00
}
while ( x - - > 0 )
{
2011-01-17 20:00:52 +00:00
if ( + + index > = SWIDTH * SHEIGHT ) return ;
2006-03-20 17:12:09 +00:00
//edited 05/18/99 Matt Mueller - changed from 0xff00 to 0x7f00 to fix glitches
2014-08-08 02:44:27 +00:00
* dest + + = ( unsigned long ) fadeTableLocalCopy [ ( l > > 8 ) & 0x7f ] [ pixPtrLocalCopy [ ( ( v / z ) & ( 64 * 63 ) ) + ( ( u / z ) & 63 ) ] ] ;
2006-03-20 17:12:09 +00:00
//end edit -MM
l + = dldx ;
u + = dudx ;
v + = dvdx ;
z + = dzdx ;
}
} else {
for ( x = fx_xright - fx_xleft + 1 ; x > 0 ; - - x ) {
2011-01-17 20:00:52 +00:00
if ( + + index > = SWIDTH * SHEIGHT ) return ;
2006-03-20 17:12:09 +00:00
c = ( uint ) pixptr [ ( ( v / z ) & ( 64 * 63 ) ) + ( ( u / z ) & 63 ) ] ;
if ( c ! = TRANSPARENCY_COLOR )
2014-08-08 02:44:27 +00:00
* dest = gr_fade_table [ ( l > > 8 ) & 0x7f ] [ c ] ;
2006-03-20 17:12:09 +00:00
dest + + ;
l + = dldx ;
u + = dudx ;
v + = dvdx ;
z + = dzdx ;
}
}
}
# else
void c_tmap_scanline_per ( )
{
ubyte * dest ;
uint c ;
fix u , v , z , l , dudx , dvdx , dzdx , dldx ;
u = fx_u ;
v = fx_v * 64 ;
z = fx_z ;
dudx = fx_du_dx ;
dvdx = fx_dv_dx * 64 ;
dzdx = fx_dz_dx ;
l = fx_l > > 8 ;
2006-12-24 08:01:25 +00:00
dldx = fx_dl_dx / 256 ;
2016-06-05 01:04:25 +00:00
dest = ( uint8_t * ) ( write_buffer + fx_xleft + ( bytes_per_row * fx_y ) ) ;
2006-03-20 17:12:09 +00:00
if ( ! Transparency_on ) {
2014-09-26 02:42:15 +00:00
for ( int x = fx_xright - fx_xleft + 1 ; x > 0 ; - - x ) {
2006-03-20 17:12:09 +00:00
//edited 05/18/99 Matt Mueller - changed from 0xff00 to 0x7f00 to fix glitches
* dest + + = gr_fade_table [ ( l & ( 0x7f00 ) ) + ( uint ) pixptr [ ( ( v / z ) & ( 64 * 63 ) ) + ( ( u / z ) & 63 ) ] ] ;
//end edit -MM
l + = dldx ;
u + = dudx ;
v + = dvdx ;
z + = dzdx ;
}
} else {
2014-09-26 02:42:15 +00:00
for ( int x = fx_xright - fx_xleft + 1 ; x > 0 ; - - x ) {
2006-03-20 17:12:09 +00:00
c = ( uint ) pixptr [ ( ( v / z ) & ( 64 * 63 ) ) + ( ( u / z ) & 63 ) ] ;
if ( c ! = 255 )
//edited 05/18/99 Matt Mueller - changed from 0xff00 to 0x7f00 to fix glitches
* dest = gr_fade_table [ ( l & ( 0x7f00 ) ) + c ] ;
//end edit -MM
dest + + ;
l + = dldx ;
u + = dudx ;
v + = dvdx ;
z + = dzdx ;
}
}
}
# endif
2013-10-27 22:00:14 +00:00
static void c_tmap_scanline_quad ( )
2006-12-19 02:25:50 +00:00
{
ubyte * dest ;
uint c ;
2011-01-17 20:00:52 +00:00
int x , index = fx_xleft + ( bytes_per_row * fx_y ) ;
2006-12-19 02:25:50 +00:00
fix u , v , l , dudx , dvdx , dldx ;
// Quadratic setup stuff:
2011-09-26 23:31:19 +00:00
fix a1 , a2 , b1 , b2 , dudx1 , dvdx1 ;
2006-12-19 02:25:50 +00:00
fix u0 = fx_u ;
fix u2 = fx_u + fx_du_dx * ( fx_xright - fx_xleft + 1 ) ; // This just needs to be uright from outer loop
fix v0 = fx_v ;
fix v2 = fx_v + fx_dv_dx * ( fx_xright - fx_xleft + 1 ) ; // This just needs to be vright from outer loop
fix w0 = fx_z ;
fix w2 = fx_z + fx_dz_dx * ( fx_xright - fx_xleft + 1 ) ; // This just needs to be zright from outer loop
fix u1 = fixdiv ( ( u0 + u2 ) , ( w0 + w2 ) ) ;
fix v1 = fixdiv ( ( v0 + v2 ) , ( w0 + w2 ) ) ;
int dx = fx_xright - fx_xleft + 1 ;
u0 = fixdiv ( u0 , w0 ) ; // Divide Z out. This should be in outer loop
v0 = fixdiv ( v0 , w0 ) ; // Divide Z out. This should be in outer loop
u2 = fixdiv ( u2 , w2 ) ; // Divide Z out. This should be in outer loop
v2 = fixdiv ( v2 , w2 ) ; // Divide Z out. This should be in outer loop
a1 = ( - 3 * u0 + 4 * u1 - u2 ) / dx ;
b1 = ( - 3 * v0 + 4 * v1 - v2 ) / dx ;
a2 = ( 2 * ( u0 - 2 * u1 + u2 ) ) / ( dx * dx ) ;
b2 = ( 2 * ( v0 - 2 * v1 + v2 ) ) / ( dx * dx ) ;
dudx = a1 + a2 ;
dvdx = b1 + b2 ;
dudx1 = 2 * a2 ;
dvdx1 = 2 * b2 ;
u = u0 ;
v = v0 ;
// Normal lighting setup
l = fx_l > > 8 ;
dldx = fx_dl_dx > > 8 ;
// Normal destination pointer setup
2016-06-05 01:04:25 +00:00
dest = ( uint8_t * ) ( write_buffer + fx_xleft + ( bytes_per_row * fx_y ) ) ;
2006-12-19 02:25:50 +00:00
if ( ! Transparency_on ) {
for ( x = fx_xright - fx_xleft + 1 ; x > 0 ; - - x ) {
2011-01-17 20:00:52 +00:00
if ( + + index > = SWIDTH * SHEIGHT ) return ;
2014-08-08 02:44:27 +00:00
* dest + + = gr_fade_table [ ( l > > 8 ) & 0xff ] [ pixptr [ ( f2i ( v ) & 63 ) * 64 + ( f2i ( u ) & 63 ) ] ] ;
2006-12-19 02:25:50 +00:00
l + = dldx ;
u + = dudx ;
v + = dvdx ;
dudx + = dudx1 ; // Extra add for quadratic!
dvdx + = dvdx1 ; // Extra add for quadratic!
}
} else {
for ( x = fx_xright - fx_xleft + 1 ; x > 0 ; - - x ) {
2011-01-17 20:00:52 +00:00
if ( + + index > = SWIDTH * SHEIGHT ) return ;
2006-12-19 02:25:50 +00:00
c = ( uint ) pixptr [ ( f2i ( v ) & 63 ) * 64 + ( f2i ( u ) & 63 ) ] ;
if ( c ! = 255 )
2014-08-08 02:44:27 +00:00
* dest = gr_fade_table [ ( l > > 8 ) & 0xff ] [ c ] ;
2006-12-19 02:25:50 +00:00
dest + + ;
l + = dldx ;
u + = dudx ;
v + = dvdx ;
dudx + = dudx1 ; // Extra add for quadratic!
dvdx + = dvdx1 ; // Extra add for quadratic!
}
}
}
2006-03-20 17:12:09 +00:00
//runtime selection of optimized tmappers. 12/07/99 Matthew Mueller
//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.
2015-10-21 02:45:44 +00:00
void select_tmap ( const std : : string & type )
2006-03-20 17:12:09 +00:00
{
2015-10-21 02:45:44 +00:00
if ( type = = " fp " )
2006-03-20 17:12:09 +00:00
{
cur_tmap_scanline_per = c_fp_tmap_scanline_per ;
}
2015-10-21 02:45:44 +00:00
else if ( type = = " quad " )
{
2006-12-19 02:25:50 +00:00
cur_tmap_scanline_per = c_tmap_scanline_quad ;
}
2006-03-20 17:12:09 +00:00
else {
cur_tmap_scanline_per = c_tmap_scanline_per ;
}
}
2015-12-05 22:57:24 +00:00
}