JurassicParkTrespasser/jp2_pc/Source/Lib/Renderer/Primitives/Walk.hpp
2018-01-01 23:07:24 +01:00

373 lines
10 KiB
C++

/**********************************************************************************************
*
* Copyright © DreamWorks Interactive. 1996
*
* Contents:
* Defines objects for walking through 1D and 2D surfaces.
*
* Bugs:
*
* To do:
* Change the name of the module to 'TexWalk.hpp.'
*
**********************************************************************************************
*
* $Log:: /JP2_PC/Source/Lib/Renderer/Primitives/Walk.hpp $
*
* 13 98.09.19 12:39a Mmouni
* Added "forceinline" to many small inline functions.
* Inlined some functions for speed.
*
* 12 97/10/23 10:57a Pkeet
* Added a K6 3D switch.
*
* 11 9/15/97 2:04p Mmouni
* Now uses u4TextureTileMaskStepU so that tiling works without shifting.
*
* 10 7/07/97 11:53p Rwyatt
* No includes headers that contain assembly code from the processor specific directories
*
* 9 1/15/97 1:02p Pkeet
* Moved the assembly versions of the 2d initializing functions to WalkEx.hpp. Removed fog
* parameters.
*
* 8 12/15/96 3:18p Pkeet
* Added the 'InitializePos' function.
*
* 7 12/11/96 9:04p Pkeet
* Added the inline function for assembly initialization of the CWalk2D class.
*
* 6 12/11/96 7:15p Pkeet
* Initial assembly implementation of the initialize member function of CWalk2D.
*
* 5 12/11/96 5:26p Pkeet
* Changing initializing parameters for the 2D walking from doubles to floats.
*
* 4 12/09/96 1:27p Pkeet
* Added the dGet member function.
*
* 3 8/12/96 7:15p Pkeet
* Added comments. Changed the 'SetData' member functions to 'Initialize.'
*
* 2 7/10/96 1:48p Pkeet
* Added additional comments.
*
* 1 7/10/96 12:17p Pkeet
* Initial implementation.
*
*********************************************************************************************/
#ifndef HEADER_LIB_RENDERER_PRIMITIVES_WALK_HPP
#define HEADER_LIB_RENDERER_PRIMITIVES_WALK_HPP
//
// Includes.
//
#include "Config.hpp"
#include "Lib/Types/BigFixed.hpp"
// Global mask for tiling U integer step.
extern uint32 u4TextureTileMaskStepU;
//
// Class definitions.
//
//*********************************************************************************************
//
class CWalk1D
//
// A 64 bit fixed point type with an offset value and offset functions for the integer
// portion. Simplifies walking through 2D texture maps when used with CWalk2D.
//
// Notes:
// This class differs from the UBigFixed type in that instead of having an integer portion
// representing units of one, its integer portion represents units of some arbitrary size.
//
// So, for example, in the UBigFixed type when a carry is generated in the fractional
// portion as a result of addition, one is added to the integer portion. In the CWalk1D
// type, when the fractional values generate a carry, an arbitrary amount is added to the
// integer portion instead of a one.
//
// This type is a precursor to CWalk2D, an object which essentially encapsulates Michael
// Abrash's trick to walking arbitrary-sized texture maps. For more information, consult
// documentation for CWalk2D and for the '+=' overloaded operator associated with it.
//
// This class contains a 64 bit fixed point variable instead of being inherited from it
// to prevent errors in its use.
//
//**************************************
{
public:
UBigFixed bfxValue; // 64 bit fixed point value as a base value.
int iOffsetPerLine; // Units for the integer portion of the value.
public:
//*****************************************************************************************
//
forceinline void Initialize
(
float f,
int i_offset_per_line
)
//
// Sets the member variables of the class based on a floating-point value and a arbitrary
// walk offset.
//
//**************************************
{
// Set the offset value.
iOffsetPerLine = i_offset_per_line;
// Convert the floating point value to a 64 bit fixed point value.
bfxValue = f;
// Set the integer portion of the value into offset units.
bfxValue.i4Int *= i_offset_per_line;
}
//*****************************************************************************************
//
forceinline CWalk1D operator-
(
) const
//
// Returns the negative this value.
//
// Notes:
// The negative of a 64 bit value (ei., a 32.32 fixed point value) is found by
// subtracting the value from 0. If the fractional component of the original value
// is not zero, a borrow will be performed from the integer portion.
//
// This function approximates this behaviour by performing a one's complement on
// the fractional portion of the value instead of a two's complement. A borrow will
// always be performed on the integer portion. This function is therefore
// not totally accurate, but it is fast. The loss of accuracy is negligible, however.
//
//**************************************
{
CWalk1D fw_return_val; // Return value.
// Copy the offset the return value.
fw_return_val.iOffsetPerLine = iOffsetPerLine;
// Negate the integer portion and "borrow" the offset value.
fw_return_val.bfxValue.i4Int = -bfxValue.i4Int - iOffsetPerLine;
// Perform a one's complement on the fractional value.
fw_return_val.bfxValue.u4Frac = ~bfxValue.u4Frac;
return fw_return_val;
}
// Conversion to double.
double dGet() const
{
double d_int = double(bfxValue.i4Int / iOffsetPerLine);
double d_frac = double(bfxValue.u4Frac) * dFracMultiplier;
return d_int + d_frac;
}
};
//*********************************************************************************************
//
class CWalk2D
//
// An object for walking through arbitrary-sized texture maps.
//
// Notes:
// If the object represents a delta, iUVInt[1] represents the value to add to the integer
// portion if there is no carry from the addition of the fractional portions, iUVInt[0]
// represents the value to add if there is a carry.
//
// If the object represents an accumulative value, the integer portion is contained in
// iUVInt[1], which represents the index into the bitmap being walked.
//
// For further information on how this class works, consult the notes associated with
// the overloaded '+=' operator for this class.
//
//**************************************
{
public:
int iUVInt[2]; // The integer components of the Walk object.
uint uUFrac; // The U fractional component.
uint uVFrac; // The V fractional component.
public:
//******************************************************************************************
//
// Constructors.
//
forceinline CWalk2D
(
)
{
}
//*****************************************************************************************
//
forceinline CWalk2D
(
const UBigFixed& bfx_u, // The 'U' component.
const CWalk1D& w1d_v // The 'V' component.
)
//
// Constructs the CWalk2D object given two values.
//
//**************************************
{
Initialize(bfx_u, w1d_v);
}
//*****************************************************************************************
//
forceinline CWalk2D
(
float f_u, // The 'U' component.
float f_v, // The 'V' component.
int i_width // The width of the texture map.
)
//
// Constructs the CWalk2D object given two values.
//
//**************************************
{
// Don't use this bit of code just yet.
//Assert(0);
Initialize(f_u, f_v, i_width);
}
//******************************************************************************************
//
// Member functions.
//
//*****************************************************************************************
//
forceinline void Initialize
(
float f_u, // The 'U' component.
float f_v, // The 'V' component.
int i_width // The width of the texture map.
)
//
// Sets the fractional and integer parts of the CWalk2D object.
//
//**************************************
{
// Don't use this bit of code just yet.
//Assert(0);
UBigFixed bfx_u; // Fixed point version of 'u.'
CWalk1D w1d_v; // Fixed point version of 'v.'
bfx_u = double(f_u);
w1d_v.Initialize(double(f_v), i_width);
Initialize(bfx_u, w1d_v);
}
//*****************************************************************************************
//
forceinline void Initialize
(
const UBigFixed& bfx_u, // The 'U' component.
const CWalk1D& w1d_v // The 'V' component.
)
//
// Sets the fractional and integer parts of the CWalk2D object.
//
//**************************************
{
// Set the U and V fractional values.
// MSM: Masked to keep only 16 fractional bits becuase
// some of the Pentium primitives utilize the low part of
// the registers the fractional bits are kept in.
uUFrac = bfx_u.u4Frac & 0xFFFF0000;
uVFrac = w1d_v.bfxValue.u4Frac & 0xFFFF0000;
// Set the combined integer value, and generate a carry version.
// U must be masked for tiled texture before being combined with V.
iUVInt[1] = (bfx_u.i4Int & u4TextureTileMaskStepU) + w1d_v.bfxValue.i4Int;
iUVInt[0] = iUVInt[1] + w1d_v.iOffsetPerLine;
}
};
//
// Global functions.
//
#if !VER_ASM
//*****************************************************************************************
//
forceinline void Initialize
(
CWalk2D& rw2d,
float f_u, // The 'U' component.
float f_v, // The 'V' component.
int i_width // The width of the texture map.
)
//
// Sets the fractional and integer parts of the CWalk2D object.
//
//**************************************
{
CWalk2D w2d(f_u, f_v, i_width);
rw2d = w2d;
}
//*****************************************************************************************
//
forceinline void InitializePos
(
CWalk2D& rw2d,
float f_u, // The 'U' component.
float f_v, // The 'V' component.
int i_width // The width of the texture map.
)
//
// Sets the fractional and integer parts of the CWalk2D object.
//
//**************************************
{
Initialize(rw2d, f_u, f_v, i_width);
}
#endif // !VER_ASM
//
// Optimized versions of overloaded functions.
//
//**********************************************************************************************
#if TARGET_PROCESSOR == PROCESSOR_PENTIUM
#include "Lib/Renderer/Primitives/P5/WalkEx.hpp"
#elif TARGET_PROCESSOR == PROCESSOR_PENTIUMPRO
#include "Lib/Renderer/Primitives/P6/WalkEx.hpp"
#elif TARGET_PROCESSOR == PROCESSOR_K6_3D
#include "Lib/Renderer/Primitives/AMDK6/WalkEx.hpp"
#else
#error Invalid [No] target processor specified
#endif
//**********************************************************************************************
#endif