mirror of
https://github.com/DaedalusX64/daedalus.git
synced 2025-04-02 10:21:48 -04:00
365 lines
11 KiB
C++
365 lines
11 KiB
C++
|
|
#include "Base/Types.h"
|
|
|
|
#include "HLEGraphics/DaedalusVtx.h"
|
|
#include "SysPSP/HLEGraphics/Combiner/BlendConstant.h"
|
|
#include "SysPSP/HLEGraphics/Combiner/RenderSettings.h"
|
|
|
|
CBlendConstantExpression::~CBlendConstantExpression()
|
|
{
|
|
}
|
|
|
|
CBlendConstantExpressionValue::~CBlendConstantExpressionValue()
|
|
{
|
|
}
|
|
|
|
bool CBlendConstantExpressionValue::IsShade() const
|
|
{
|
|
return mConstant == BC_SHADE;
|
|
}
|
|
|
|
c32 CBlendConstantExpressionValue::Evaluate( c32 shade, c32 primitive, c32 environment ) const
|
|
{
|
|
switch( mConstant )
|
|
{
|
|
case BC_SHADE: return shade;
|
|
case BC_PRIMITIVE: return primitive;
|
|
case BC_ENVIRONMENT: return environment;
|
|
case BC_PRIMITIVE_ALPHA: return c32( primitive.GetA(), primitive.GetA(), primitive.GetA(), primitive.GetA() );
|
|
case BC_ENVIRONMENT_ALPHA: return c32( environment.GetA(), environment.GetA(), environment.GetA(), environment.GetA() );
|
|
case BC_1: return c32( 0xffffffff );
|
|
case BC_0: return c32( 0x00000000 );
|
|
}
|
|
#ifdef DAEDALUS_DEBUG_CONSOLE
|
|
DAEDALUS_ERROR( "Unhandled constant" );
|
|
#endif
|
|
return c32( 0xffffffff );
|
|
}
|
|
|
|
c32 CBlendConstantExpressionValue::EvaluateConstant( c32 primitive, c32 environment ) const
|
|
{
|
|
switch( mConstant )
|
|
{
|
|
#ifdef DAEDALUS_DEBUG_CONSOLE
|
|
case BC_SHADE: DAEDALUS_ERROR( "Shouldn't be here" ); return c32( 0xffffffff );
|
|
#else
|
|
case BC_SHADE: return c32( 0xffffffff);
|
|
#endif
|
|
case BC_PRIMITIVE: return primitive;
|
|
case BC_ENVIRONMENT: return environment;
|
|
case BC_PRIMITIVE_ALPHA: return c32( primitive.GetA(), primitive.GetA(), primitive.GetA(), primitive.GetA() );
|
|
case BC_ENVIRONMENT_ALPHA: return c32( environment.GetA(), environment.GetA(), environment.GetA(), environment.GetA() );
|
|
case BC_1: return c32( 0xffffffff );
|
|
case BC_0: return c32( 0x00000000 );
|
|
}
|
|
#ifdef DAEDALUS_DEBUG_CONSOLE
|
|
DAEDALUS_ERROR( "Unhandled constant" );
|
|
#endif
|
|
return c32( 0xffffffff );
|
|
}
|
|
|
|
bool CBlendConstantExpressionValue::TryEvaluateConstant( const SRenderState & state, c32 * out ) const
|
|
{
|
|
switch( mConstant )
|
|
{
|
|
case BC_SHADE: return false;
|
|
case BC_PRIMITIVE: *out = state.PrimitiveColour; return true;
|
|
case BC_ENVIRONMENT: *out = state.EnvironmentColour; return true;
|
|
case BC_PRIMITIVE_ALPHA: *out = c32( state.PrimitiveColour.GetA(), state.PrimitiveColour.GetA(), state.PrimitiveColour.GetA(), state.PrimitiveColour.GetA() ); return true;
|
|
case BC_ENVIRONMENT_ALPHA: *out = c32( state.EnvironmentColour.GetA(), state.EnvironmentColour.GetA(), state.EnvironmentColour.GetA(), state.EnvironmentColour.GetA() ); return true;
|
|
case BC_1: *out = c32( 0xffffffff ); return true;
|
|
case BC_0: *out = c32( 0x00000000 ); return true;
|
|
}
|
|
#ifdef DAEDALUS_DEBUG_CONSOLE
|
|
DAEDALUS_ERROR( "Unhandled constant" );
|
|
#endif
|
|
return false;
|
|
}
|
|
|
|
void CBlendConstantExpressionValue::ApplyExpressionRGB( const SRenderState & state ) const
|
|
{
|
|
// Applying the shade colour leaves the vertex untouched, so bail out
|
|
if( mConstant != BC_SHADE )
|
|
{
|
|
c32 new_colour( EvaluateConstant( state.PrimitiveColour, state.EnvironmentColour ) );
|
|
for( u32 i = 0; i < state.NumVertices; ++i )
|
|
{
|
|
state.Vertices[ i ].Colour.SetBits( new_colour, c32::MASK_RGB );
|
|
}
|
|
}
|
|
}
|
|
|
|
void CBlendConstantExpressionValue::ApplyExpressionAlpha( const SRenderState & state ) const
|
|
{
|
|
// Applying the shade colour leaves the vertex untouched, so bail out
|
|
if( mConstant != BC_SHADE )
|
|
{
|
|
c32 new_colour( EvaluateConstant( state.PrimitiveColour, state.EnvironmentColour ) );
|
|
for( u32 i = 0; i < state.NumVertices; ++i )
|
|
{
|
|
state.Vertices[ i ].Colour.SetBits( new_colour, c32::MASK_A );
|
|
}
|
|
}
|
|
}
|
|
|
|
std::string CBlendConstantExpressionValue::ToString() const
|
|
{
|
|
switch( mConstant )
|
|
{
|
|
case BC_SHADE: return "Shade";
|
|
case BC_PRIMITIVE: return "Primitive";
|
|
case BC_ENVIRONMENT: return "Environment";
|
|
case BC_PRIMITIVE_ALPHA: return "PrimitiveAlpha";
|
|
case BC_ENVIRONMENT_ALPHA: return "EnvironmentAlpha";
|
|
case BC_1: return "1";
|
|
case BC_0: return "0";
|
|
}
|
|
#ifdef DAEDALUS_DEBUG_CONSOLE
|
|
DAEDALUS_ERROR( "Unhandled constant" );
|
|
#endif
|
|
return "?";
|
|
}
|
|
|
|
|
|
template< typename ColOp >
|
|
CBlendConstantExpression2<ColOp>::~CBlendConstantExpression2()
|
|
{
|
|
delete mA;
|
|
delete mB;
|
|
}
|
|
|
|
template< typename ColOp >
|
|
c32 CBlendConstantExpression2<ColOp>::Evaluate( c32 shade, c32 primitive, c32 environment ) const
|
|
{
|
|
c32 a( mA->Evaluate( shade, primitive, environment ) );
|
|
c32 b( mB->Evaluate( shade, primitive, environment ) );
|
|
|
|
return ColOp::Process( a, b );
|
|
}
|
|
|
|
template< typename ColOp >
|
|
c32 CBlendConstantExpression2<ColOp>::EvaluateConstant( c32 primitive, c32 environment ) const
|
|
{
|
|
c32 a( mA->EvaluateConstant( primitive, environment ) );
|
|
c32 b( mB->EvaluateConstant( primitive, environment ) );
|
|
|
|
return ColOp::Process( a, b );
|
|
}
|
|
|
|
template< typename ColOp >
|
|
bool CBlendConstantExpression2<ColOp>::TryEvaluateConstant( const SRenderState & state, c32 * out ) const
|
|
{
|
|
return false;
|
|
}
|
|
|
|
template< typename ColOp >
|
|
void CBlendConstantExpression2<ColOp>::ApplyExpressionRGB( const SRenderState & state ) const
|
|
{
|
|
c32 a; bool have_a( mA->TryEvaluateConstant( state, &a ) );
|
|
c32 b; bool have_b( mB->TryEvaluateConstant( state, &b ) );
|
|
if( have_a && have_b )
|
|
{
|
|
c32 col( ColOp::Process( a, b ) );
|
|
for( u32 i = 0; i < state.NumVertices; ++i )
|
|
{
|
|
state.Vertices[ i ].Colour.SetBits( col, c32::MASK_RGB );
|
|
}
|
|
}
|
|
else if( have_a )
|
|
{
|
|
if( mB->IsShade() )
|
|
{
|
|
for( u32 i = 0; i < state.NumVertices; ++i )
|
|
{
|
|
c32 col( ColOp::Process( a, state.Vertices[ i ].Colour ) );
|
|
|
|
state.Vertices[ i ].Colour.SetBits( col, c32::MASK_RGB );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for( u32 i = 0; i < state.NumVertices; ++i )
|
|
{
|
|
b = mB->Evaluate( state.Vertices[ i ].Colour, state.PrimitiveColour, state.EnvironmentColour );
|
|
|
|
state.Vertices[ i ].Colour.SetBits( ColOp::Process( a, b ), c32::MASK_RGB );
|
|
}
|
|
}
|
|
}
|
|
else if( have_b )
|
|
{
|
|
if( mA->IsShade() )
|
|
{
|
|
for( u32 i = 0; i < state.NumVertices; ++i )
|
|
{
|
|
c32 col( ColOp::Process( state.Vertices[ i ].Colour, b ) );
|
|
|
|
state.Vertices[ i ].Colour.SetBits( col, c32::MASK_RGB );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for( u32 i = 0; i < state.NumVertices; ++i )
|
|
{
|
|
a = mA->Evaluate( state.Vertices[ i ].Colour, state.PrimitiveColour, state.EnvironmentColour );
|
|
|
|
state.Vertices[ i ].Colour.SetBits( ColOp::Process( a, b ), c32::MASK_RGB );
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for( u32 i = 0; i < state.NumVertices; ++i )
|
|
{
|
|
a = mA->Evaluate( state.Vertices[ i ].Colour, state.PrimitiveColour, state.EnvironmentColour );
|
|
b = mB->Evaluate( state.Vertices[ i ].Colour, state.PrimitiveColour, state.EnvironmentColour );
|
|
|
|
state.Vertices[ i ].Colour.SetBits( ColOp::Process( a, b ), c32::MASK_RGB );
|
|
}
|
|
}
|
|
}
|
|
|
|
template< typename ColOp >
|
|
void CBlendConstantExpression2<ColOp>::ApplyExpressionAlpha( const SRenderState & state ) const
|
|
{
|
|
c32 a; bool have_a( mA->TryEvaluateConstant( state, &a ) );
|
|
c32 b; bool have_b( mB->TryEvaluateConstant( state, &b ) );
|
|
if( have_a && have_b )
|
|
{
|
|
c32 col( ColOp::Process( a, b ) );
|
|
for( u32 i = 0; i < state.NumVertices; ++i )
|
|
{
|
|
state.Vertices[ i ].Colour.SetBits( col, c32::MASK_A );
|
|
}
|
|
}
|
|
else if( have_a )
|
|
{
|
|
if( mB->IsShade() )
|
|
{
|
|
for( u32 i = 0; i < state.NumVertices; ++i )
|
|
{
|
|
c32 col( ColOp::Process( a, state.Vertices[ i ].Colour ) );
|
|
|
|
state.Vertices[ i ].Colour.SetBits( col, c32::MASK_A );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for( u32 i = 0; i < state.NumVertices; ++i )
|
|
{
|
|
b = mB->Evaluate( state.Vertices[ i ].Colour, state.PrimitiveColour, state.EnvironmentColour );
|
|
|
|
state.Vertices[ i ].Colour.SetBits( ColOp::Process( a, b ), c32::MASK_A );
|
|
}
|
|
}
|
|
}
|
|
else if( have_b )
|
|
{
|
|
if( mA->IsShade() )
|
|
{
|
|
for( u32 i = 0; i < state.NumVertices; ++i )
|
|
{
|
|
c32 col( ColOp::Process( state.Vertices[ i ].Colour, b ) );
|
|
|
|
state.Vertices[ i ].Colour.SetBits( col, c32::MASK_A );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for( u32 i = 0; i < state.NumVertices; ++i )
|
|
{
|
|
a = mA->Evaluate( state.Vertices[ i ].Colour, state.PrimitiveColour, state.EnvironmentColour );
|
|
|
|
state.Vertices[ i ].Colour.SetBits( ColOp::Process( a, b ), c32::MASK_A );
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for( u32 i = 0; i < state.NumVertices; ++i )
|
|
{
|
|
a = mA->Evaluate( state.Vertices[ i ].Colour, state.PrimitiveColour, state.EnvironmentColour );
|
|
b = mB->Evaluate( state.Vertices[ i ].Colour, state.PrimitiveColour, state.EnvironmentColour );
|
|
|
|
state.Vertices[ i ].Colour.SetBits( ColOp::Process( a, b ), c32::MASK_A );
|
|
}
|
|
}
|
|
}
|
|
|
|
template< typename ColOp >
|
|
std::string CBlendConstantExpression2<ColOp>::ToString() const
|
|
{
|
|
std::string str;
|
|
str += "(" + mA->ToString() + ColOp::OpString() + mB->ToString() + ")";
|
|
return str;
|
|
}
|
|
|
|
|
|
|
|
CBlendConstantExpressionBlend::~CBlendConstantExpressionBlend()
|
|
{
|
|
delete mA;
|
|
delete mB;
|
|
delete mF;
|
|
}
|
|
|
|
c32 CBlendConstantExpressionBlend::Evaluate( c32 shade, c32 primitive, c32 environment ) const
|
|
{
|
|
c32 a( mA->Evaluate( shade, primitive, environment ) );
|
|
c32 b( mB->Evaluate( shade, primitive, environment ) );
|
|
c32 f( mF->Evaluate( shade, primitive, environment ) );
|
|
|
|
return a.Interpolate( b, f );
|
|
}
|
|
|
|
c32 CBlendConstantExpressionBlend::EvaluateConstant( c32 primitive, c32 environment ) const
|
|
{
|
|
c32 a( mA->EvaluateConstant( primitive, environment ) );
|
|
c32 b( mB->EvaluateConstant( primitive, environment ) );
|
|
c32 f( mF->EvaluateConstant( primitive, environment ) );
|
|
|
|
return a.Interpolate( b, f );
|
|
}
|
|
|
|
bool CBlendConstantExpressionBlend::TryEvaluateConstant( const SRenderState & state, c32 * out ) const
|
|
{
|
|
return false;
|
|
}
|
|
|
|
void CBlendConstantExpressionBlend::ApplyExpressionRGB( const SRenderState & state ) const
|
|
{
|
|
for( u32 i = 0; i < state.NumVertices; ++i )
|
|
{
|
|
c32 a( mA->Evaluate( state.Vertices[ i ].Colour, state.PrimitiveColour, state.EnvironmentColour ) );
|
|
c32 b( mB->Evaluate( state.Vertices[ i ].Colour, state.PrimitiveColour, state.EnvironmentColour ) );
|
|
c32 f( mF->Evaluate( state.Vertices[ i ].Colour, state.PrimitiveColour, state.EnvironmentColour ) );
|
|
|
|
state.Vertices[ i ].Colour.SetBits( a.Interpolate( b, f ), c32::MASK_RGB );
|
|
}
|
|
}
|
|
|
|
void CBlendConstantExpressionBlend::ApplyExpressionAlpha( const SRenderState & state ) const
|
|
{
|
|
for( u32 i = 0; i < state.NumVertices; ++i )
|
|
{
|
|
c32 a( mA->Evaluate( state.Vertices[ i ].Colour, state.PrimitiveColour, state.EnvironmentColour ) );
|
|
c32 b( mB->Evaluate( state.Vertices[ i ].Colour, state.PrimitiveColour, state.EnvironmentColour ) );
|
|
c32 f( mF->Evaluate( state.Vertices[ i ].Colour, state.PrimitiveColour, state.EnvironmentColour ) );
|
|
|
|
state.Vertices[ i ].Colour.SetBits( a.Interpolate( b, f ), c32::MASK_A );
|
|
}
|
|
}
|
|
|
|
std::string CBlendConstantExpressionBlend::ToString() const
|
|
{
|
|
std::string str;
|
|
str += "blend(" + mA->ToString() + ", " + mB->ToString() + ", " + mF->ToString() + ")";
|
|
return str;
|
|
}
|
|
|
|
|
|
// Instantiate these typedefs.
|
|
|
|
template class CBlendConstantExpression2< AddOp >;
|
|
template class CBlendConstantExpression2< SubOp >;
|
|
template class CBlendConstantExpression2< MulOp >;
|