OK, the files for the prerequisites are ready for someone to make
final changes and a patch for them. I’m not setup to compile SDL so I
won’t be doing that bit, but before I trow them onto bugzilla I want
some final-stage feedback, particularly from Sam or Ryan, since I
don’t recall anything else in SDL quite being structured like this.
/*
Simple DirectMedia Layer
Copyright © 1997-2015 Sam Lantinga
This software is provided ‘as-is’, without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
- The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
- Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
- This notice may not be removed or altered from any source distribution.
/
/ common_macros.h */
/* This file provides a standard set of C preprocessor macros. */
#ifndef COMMON_MACROS
define COMMON_MACROS
define IDENTITY( a ) a
define CONCAT( a, … ) PRIMITIVE_CONCAT( a, VA_ARGS )
define PRIMITIVE_CONCAT( a, … ) a ## VA_ARGS
define IFF( b ) PRIMITIVE_CONCAT( IIF_, b )
define IFF_0( t, … ) VA_ARGS
define IIF_1( t, … ) t
define COMPL( b ) PRIMITIVE_CONCAT( COMPL_, b )
define COMPL_0 1
define COMPL_1 0
define BITAND( b ) PRIMITIVE_CONCAT( BITAND_, b )
define BITAND_0( c ) 0
define BITAND_1( c ) c
#endif
/* End common_macros.h */
/*
Simple DirectMedia Layer
Copyright © 1997-2015 Sam Lantinga
This software is provided ‘as-is’, without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
- The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
- Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
- This notice may not be removed or altered from any source distribution.
/
/ common_float.h */
/* This file provides a set of C functions for dealing with floating-point /
/ numbers. */
#ifndef COMMON_FLOAT_H
define COMMON_FLOAT_H
ifndef NAMESPACE
error “common_float.h requires the macro NAMESPACE to be defined.”
else
/* For FLT_EPSILON, DBL_EPSILON and LDBL_EPSILON. */
include <float.h>
include “common_macros.h”
if defined( USE_FLT ) || ( !defined( USE_DBL ) && !defined( USE_LDBL ) )
define FLT_TYPE float
define EPSILON FLT_EPSILON
elif defined( USE_DBL )
define FLT_TYPE double
define EPSILON DBL_EPSILON
else
define FLT_TYPE long double
define EPSILON LDBL_EPSILON
endif
define CEIL CONCAT( NAMESPACE, ceil )
define FLOOR CONCAT( NAMESPACE, floor )
define EQ CONCAT( NAMESPACE, r_eq )
define GR CONCAT( NAMESPACE, r_gr )
define LS CONCAT( NAMESPACE, r_ls )
define GREQ CONCAT( NAMESPACE, r_greq )
define LSEQ CONCAT( NAMESPACE, r_lseq )
define TWEEN CONCAT( NAMESPACE, tween )
define INT_CONSTR CONCAT( NAMESPACE, int_constraints )
/* These are designed to provide PROPER floating-point comparisons. */
int CEIL( FLT_TYPE in, long *result );
int FLOOR( FLT_TYPE in, long *result );
/* Simple comparisons. */
int EQ ( FLT_TYPE a, FLT_TYPE b, FLT_TYPE range );
int GR ( FLT_TYPE a, FLT_TYPE b, FLT_TYPE range );
int LS ( FLT_TYPE a, FLT_TYPE b, FLT_TYPE range );
/* Compound comparisons. */
int GREQ ( FLT_TYPE a, FLT_TYPE b, FLT_TYPE range );
int LSEQ ( FLT_TYPE a, FLT_TYPE b, FLT_TYPE range );
/* Arbitrary-element interpretation. */
int TWEEN ( FLT_TYPE *f1, FLT_TYPE *f2, FLT_TYPE *fdest, size_t
elem_count, FLT_TYPE twval );
/* Arbitrary-element bounds finding. */
int INT_CONSTR ( size_t vertcount, FLT_TYPE *vals, long *ldest,
long *hdest );
endif
#endif
/* End common_float.h */
/*
Simple DirectMedia Layer
Copyright © 1997-2015 Sam Lantinga
This software is provided ‘as-is’, without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
- The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
- Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
- This notice may not be removed or altered from any source distribution.
/
/ common_float.xmacro */
/* This file provides a set of C functions for dealing with floating-point /
/ numbers. */
#ifndef NAMESPACE
error “common_float.xmacro requires the macro NAMESPACE to be defined.”
#else
include <limits.h>
include “common_float.h”
int CEIL( FLT_TYPE in, long *result )
{
if( result && !( (FLT_TYPE)LONG_MIN - 1 > in ) && !( LONG_MAX < in ) )
{
*result = in;
while( *result < in )
{
*result += 1;
}
return( 1 );
}
return( -1 );
}
int FLOOR( FLT_TYPE in, long *result )
{
if( result && !( LONG_MIN > in ) && !( (FLT_TYPE)LONG_MAX + 1 < in ) )
{
*result = in;
while( *result > in )
{
*result -= 1;
}
return( 1 );
}
return( -1 );
}
/* These are designed to provide PROPER floating-point comparisons. */
int EQ ( FLT_TYPE a, FLT_TYPE b, FLT_TYPE range )
{
return
(
(int)( a + range >= b ) ==
(int)( a <= b + range )
);
}
int GR ( FLT_TYPE a, FLT_TYPE b, FLT_TYPE range )
{
return
(
(int)( a + range >= b ) ==
(int)( a >= b + range )
);
}
int LS ( FLT_TYPE a, FLT_TYPE b, FLT_TYPE range )
{
return
(
(int)( a + range <= b ) ==
(int)( a <= b + range)
);
}
int GREQ ( FLT_TYPE a, FLT_TYPE b, FLT_TYPE range )
{
return
(
(
a + range >= b ||
a >= b + range
) ?
(int)1 : (int)0
);
}
int LSEQ ( FLT_TYPE a, FLT_TYPE b, FLT_TYPE range )
{
return
(
(
a + range <= b ||
a <= b + range
) ?
(int)1 : (int)0
);
}
int TWEEN ( FLT_TYPE *f1, FLT_TYPE *f2, FLT_TYPE *fdest, size_t
elem_count, FLT_TYPE twval )
{
if( f1 && f2 && fdest )
{
size_t iter = 0;
while( iter < elem_count )
{
fdest[ iter ] = twval * ( f2[ iter ] - f1[ iter ] ) + f1[ iter ];
++iter;
}
return( 1 );
}
return( -1 );
}
int INT_CONSTR ( size_t vertcount, FLT_TYPE *vals, long *ldest, long *hdest )
{
if( vertcount && vals && ldest && hdest )
{
size_t i = 0;
long high, low;
*ldest = vals[ 0 ];
*hdest = vals[ 0 ];
while( i < vertcount )
{
if( !CEIL( vals[ i ], &high ) )
{
/* Error. */
}
if( !FLOOR( vals[ i ], &low ) )
{
/* Error. */
}
*ldest = (long)( GR ( low, *ldest, EPSILON ) ? *ldest : low );
*hdest = (long)( LS ( high, *hdest, EPSILON ) ? *hdest : high );
++i;
}
return( 1 );
}
return( -1 );
}
include “end_common_float.h”
#endif
/* End common_float.xmacro */
/*
Simple DirectMedia Layer
Copyright © 1997-2015 Sam Lantinga
This software is provided ‘as-is’, without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
- The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
- Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
- This notice may not be removed or altered from any source distribution.
/
/ common_float.c */
/* This file provides a set of C functions for dealing with floating-point /
/ numbers. */
#include “common_macros.h”
/* Try to preserve NAMESPACE, but allow it to be overridden. */
#ifndef CMNFLT_NAMESPACE
define CMNFLT_NAMESPACE IDENTITY( NAMESPACE )
#endif
/* For float functions. */
#define USE_FLT
define NAMESPACE CONCAT( CMNFLT_NAMESPACE, flt_ )
include “common_float.xmacro”
undef NAMESPACE
#undef USE_FLT
/* For double functions. */
#define USE_DBL
define NAMESPACE CONCAT( CMNFLT_NAMESPACE, dbl_ )
include “common_float.xmacro”
undef NAMESPACE
#undef USE_DBL
/* For long-double functions. */
#define USE_LDBL
define NAMESPACE CONCAT( CMNFLT_NAMESPACE, ldbl_ )
include “common_float.xmacro”
undef NAMESPACE
#undef USE_LDBL
The rationale is fairly straightforward: if someone wants more
precision in the renderer, I want them to be able to just change some
configure flags and build. Some things are technically incorrect:
FLOOR should probably call floor() from SDL’s standard library
routines. I’m not willing to setup a, SDL build environment just to do
some testing on code that can be tested “outside”, so I wrote it as a
mirror of CEIL (did you know that SDL doesn’t seem to have a ceil()
fallback?) instead.
This stuff (though I forget whether it was all or just most) gets used
in the functions that I’m working on for textured triangles, so if my
renderoing code is going to be used for that then some form of these
functions needs to be in place.