2013-06-23 07:49:34 +00:00
/*
2017-03-12 15:56:00 +00:00
* * _gl_dynlight . cpp
2013-06-23 07:49:34 +00:00
* * Light definitions for actors .
* *
* * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
* * Copyright 2003 Timothy Stump
* * Copyright 2005 Christoph Oelckers
* * All rights reserved .
* *
* * Redistribution and use in source and binary forms , with or without
* * modification , are permitted provided that the following conditions
* * are met :
* *
* * 1. Redistributions of source code must retain the above copyright
* * notice , this list of conditions and the following disclaimer .
* * 2. Redistributions in binary form must reproduce the above copyright
* * notice , this list of conditions and the following disclaimer in the
* * documentation and / or other materials provided with the distribution .
* * 3. The name of the author may not be used to endorse or promote products
* * derived from this software without specific prior written permission .
* *
* * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ` ` AS IS ' ' AND ANY EXPRESS OR
* * IMPLIED WARRANTIES , INCLUDING , BUT NOT LIMITED TO , THE IMPLIED WARRANTIES
* * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED .
* * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT , INDIRECT ,
* * INCIDENTAL , SPECIAL , EXEMPLARY , OR CONSEQUENTIAL DAMAGES ( INCLUDING , BUT
* * NOT LIMITED TO , PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES ; LOSS OF USE ,
* * DATA , OR PROFITS ; OR BUSINESS INTERRUPTION ) HOWEVER CAUSED AND ON ANY
* * THEORY OF LIABILITY , WHETHER IN CONTRACT , STRICT LIABILITY , OR TORT
* * ( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF THE USE OF
* * THIS SOFTWARE , EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE .
* * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
* *
*/
# include <ctype.h>
# include "i_system.h"
# include "doomtype.h"
# include "c_cvars.h"
# include "c_dispatch.h"
# include "m_random.h"
# include "sc_man.h"
# include "templates.h"
# include "w_wad.h"
# include "gi.h"
# include "r_state.h"
# include "stats.h"
# include "zstring.h"
# include "d_dehacked.h"
2017-01-01 23:28:30 +00:00
# include "v_text.h"
2017-01-08 17:45:30 +00:00
# include "g_levellocals.h"
2017-03-12 15:56:00 +00:00
# include "a_dynlight.h"
2013-06-23 07:49:34 +00:00
int ScriptDepth ;
void gl_InitGlow ( FScanner & sc ) ;
void gl_ParseBrightmap ( FScanner & sc , int ) ;
void gl_DestroyUserShaders ( ) ;
void gl_ParseHardwareShader ( FScanner & sc , int deflump ) ;
void gl_ParseSkybox ( FScanner & sc ) ;
void gl_ParseDetailTexture ( FScanner & sc ) ;
void gl_ParseVavoomSkybox ( ) ;
//==========================================================================
//
// Dehacked aliasing
//
//==========================================================================
2016-02-05 11:31:41 +00:00
inline PClassActor * GetRealType ( PClassActor * ti )
2013-06-23 07:49:34 +00:00
{
2016-02-05 11:31:41 +00:00
PClassActor * rep = ti - > GetReplacement ( false ) ;
2017-02-08 14:47:22 +00:00
if ( rep ! = ti & & rep ! = NULL & & rep - > IsDescendantOf ( NAME_DehackedPickup ) )
2013-06-23 07:49:34 +00:00
{
2016-02-05 11:31:41 +00:00
return rep ;
2013-06-23 07:49:34 +00:00
}
return ti ;
}
//==========================================================================
//
// Light associations
//
//==========================================================================
class FLightAssociation
{
public :
//FLightAssociation();
FLightAssociation ( FName actorName , const char * frameName , FName lightName )
: m_ActorName ( actorName ) , m_AssocLight ( lightName )
{
2014-12-29 15:35:30 +00:00
strncpy ( m_FrameName , frameName , 8 ) ;
2013-06-23 07:49:34 +00:00
}
FName ActorName ( ) { return m_ActorName ; }
const char * FrameName ( ) { return m_FrameName ; }
FName Light ( ) { return m_AssocLight ; }
void ReplaceLightName ( FName newName ) { m_AssocLight = newName ; }
protected :
char m_FrameName [ 8 ] ;
FName m_ActorName , m_AssocLight ;
} ;
TArray < FLightAssociation > LightAssociations ;
//==========================================================================
//
// Light definitions
//
//==========================================================================
class FLightDefaults
{
public :
FLightDefaults ( FName name , ELightType type ) ;
void ApplyProperties ( ADynamicLight * light ) const ;
FName GetName ( ) const { return m_Name ; }
2016-03-24 12:38:37 +00:00
void SetParameter ( double p ) { m_Param = p ; }
2017-02-03 09:13:16 +00:00
void SetArg ( int arg , int val ) { m_Args [ arg ] = val ; }
int GetArg ( int arg ) { return m_Args [ arg ] ; }
2017-01-02 10:41:27 +00:00
uint8_t GetAttenuate ( ) const { return m_attenuate ; }
2016-03-24 12:38:37 +00:00
void SetOffset ( float * ft ) { m_Pos . X = ft [ 0 ] ; m_Pos . Z = ft [ 1 ] ; m_Pos . Y = ft [ 2 ] ; }
2013-06-23 07:49:34 +00:00
void SetSubtractive ( bool subtract ) { m_subtractive = subtract ; }
void SetAdditive ( bool add ) { m_additive = add ; }
void SetDontLightSelf ( bool add ) { m_dontlightself = add ; }
2016-12-07 22:17:18 +00:00
void SetAttenuate ( bool on ) { m_attenuate = on ; }
2013-06-23 07:49:34 +00:00
void SetHalo ( bool halo ) { m_halo = halo ; }
2017-03-01 19:54:37 +00:00
void OrderIntensities ( )
{
if ( m_Args [ LIGHT_INTENSITY ] > m_Args [ LIGHT_SECONDARY_INTENSITY ] )
{
std : : swap ( m_Args [ LIGHT_INTENSITY ] , m_Args [ LIGHT_SECONDARY_INTENSITY ] ) ;
m_swapped = true ;
}
}
2013-06-23 07:49:34 +00:00
protected :
FName m_Name ;
2017-01-19 16:40:34 +00:00
int m_Args [ 5 ] ;
2016-03-24 12:38:37 +00:00
double m_Param ;
DVector3 m_Pos ;
2013-06-23 07:49:34 +00:00
ELightType m_type ;
2016-12-07 22:17:18 +00:00
int8_t m_attenuate ;
2013-06-23 07:49:34 +00:00
bool m_subtractive , m_additive , m_halo , m_dontlightself ;
2017-03-01 19:54:37 +00:00
bool m_swapped = false ;
2013-06-23 07:49:34 +00:00
} ;
TArray < FLightDefaults * > LightDefaults ;
//-----------------------------------------------------------------------------
//
//
//
//-----------------------------------------------------------------------------
FLightDefaults : : FLightDefaults ( FName name , ELightType type )
{
m_Name = name ;
m_type = type ;
2016-03-24 12:38:37 +00:00
m_Pos . Zero ( ) ;
2017-01-19 16:40:34 +00:00
memset ( m_Args , 0 , sizeof ( m_Args ) ) ;
2016-03-24 12:38:37 +00:00
m_Param = 0 ;
2013-06-23 07:49:34 +00:00
m_subtractive = false ;
m_additive = false ;
m_halo = false ;
m_dontlightself = false ;
2016-12-07 22:17:18 +00:00
m_attenuate = - 1 ;
2013-06-23 07:49:34 +00:00
}
void FLightDefaults : : ApplyProperties ( ADynamicLight * light ) const
{
2016-12-23 14:25:39 +00:00
auto oldtype = light - > lighttype ;
2013-06-23 07:49:34 +00:00
light - > lighttype = m_type ;
2016-12-06 17:35:34 +00:00
light - > specialf1 = m_Param ;
2016-03-24 12:38:37 +00:00
light - > SetOffset ( m_Pos ) ;
2013-06-23 07:49:34 +00:00
light - > halo = m_halo ;
2016-09-04 10:45:09 +00:00
for ( int a = 0 ; a < 3 ; a + + ) light - > args [ a ] = clamp < int > ( ( int ) ( m_Args [ a ] ) , 0 , 255 ) ;
2017-03-01 19:54:37 +00:00
light - > args [ LIGHT_INTENSITY ] = m_Args [ LIGHT_INTENSITY ] ;
light - > args [ LIGHT_SECONDARY_INTENSITY ] = m_Args [ LIGHT_SECONDARY_INTENSITY ] ;
2016-03-24 12:38:37 +00:00
light - > flags4 & = ~ ( MF4_ADDITIVE | MF4_SUBTRACTIVE | MF4_DONTLIGHTSELF ) ;
if ( m_subtractive ) light - > flags4 | = MF4_SUBTRACTIVE ;
if ( m_additive ) light - > flags4 | = MF4_ADDITIVE ;
if ( m_dontlightself ) light - > flags4 | = MF4_DONTLIGHTSELF ;
2016-12-06 17:35:34 +00:00
light - > m_tickCount = 0 ;
2016-12-23 14:25:39 +00:00
if ( m_type = = PulseLight )
{
float pulseTime = float ( m_Param / TICRATE ) ;
light - > m_lastUpdate = level . maptime ;
2017-03-01 19:54:37 +00:00
if ( m_swapped ) light - > m_cycler . SetParams ( float ( light - > args [ LIGHT_SECONDARY_INTENSITY ] ) , float ( light - > args [ LIGHT_INTENSITY ] ) , pulseTime , oldtype = = PulseLight ) ;
else light - > m_cycler . SetParams ( float ( light - > args [ LIGHT_INTENSITY ] ) , float ( light - > args [ LIGHT_SECONDARY_INTENSITY ] ) , pulseTime , oldtype = = PulseLight ) ;
2016-12-23 14:25:39 +00:00
light - > m_cycler . ShouldCycle ( true ) ;
light - > m_cycler . SetCycleType ( CYCLE_Sin ) ;
2017-03-12 15:56:00 +00:00
light - > m_currentRadius = ( float ) light - > m_cycler . GetVal ( ) ;
2017-01-29 11:00:05 +00:00
if ( light - > m_currentRadius < = 0 ) light - > m_currentRadius = 1 ;
2017-03-01 19:54:37 +00:00
light - > swapped = m_swapped ;
2016-12-23 14:25:39 +00:00
}
2016-12-07 22:17:18 +00:00
switch ( m_attenuate )
{
case 0 : light - > flags4 & = ~ MF4_ATTENUATE ; break ;
case 1 : light - > flags4 | = MF4_ATTENUATE ; break ;
2017-03-12 15:56:00 +00:00
default : if ( level . flags3 & LEVEL3_ATTENUATE ) light - > flags4 | = MF4_ATTENUATE ; else light - > flags4 & = ~ MF4_ATTENUATE ; break ;
2016-12-07 22:17:18 +00:00
}
}
2013-06-23 07:49:34 +00:00
//==========================================================================
//
// light definition file parser
//
//==========================================================================
static const char * LightTags [ ] =
{
" color " ,
" size " ,
" secondarySize " ,
" offset " ,
" chance " ,
" interval " ,
" scale " ,
" frame " ,
" light " ,
" { " ,
" } " ,
" subtractive " ,
" additive " ,
" halo " ,
" dontlightself " ,
2016-12-07 22:17:18 +00:00
" attenuate " ,
2013-06-23 07:49:34 +00:00
NULL
} ;
enum {
LIGHTTAG_COLOR ,
LIGHTTAG_SIZE ,
LIGHTTAG_SECSIZE ,
LIGHTTAG_OFFSET ,
LIGHTTAG_CHANCE ,
LIGHTTAG_INTERVAL ,
LIGHTTAG_SCALE ,
LIGHTTAG_FRAME ,
LIGHTTAG_LIGHT ,
LIGHTTAG_OPENBRACE ,
LIGHTTAG_CLOSEBRACE ,
LIGHTTAG_SUBTRACTIVE ,
LIGHTTAG_ADDITIVE ,
LIGHTTAG_HALO ,
LIGHTTAG_DONTLIGHTSELF ,
2016-12-07 22:17:18 +00:00
LIGHTTAG_ATTENUATE
2013-06-23 07:49:34 +00:00
} ;
extern int ScriptDepth ;
//==========================================================================
//
//
//
//==========================================================================
2017-03-12 15:56:00 +00:00
inline float ParseFloat ( FScanner & sc )
2013-06-23 07:49:34 +00:00
{
sc . GetFloat ( ) ;
return float ( sc . Float ) ;
}
2017-03-12 15:56:00 +00:00
inline int ParseInt ( FScanner & sc )
2013-06-23 07:49:34 +00:00
{
sc . GetNumber ( ) ;
return sc . Number ;
}
2017-03-12 15:56:00 +00:00
inline char * ParseString ( FScanner & sc )
2013-06-23 07:49:34 +00:00
{
sc . GetString ( ) ;
return sc . String ;
}
2017-03-12 15:56:00 +00:00
static void ParseTriple ( FScanner & sc , float floatVal [ 3 ] )
2013-06-23 07:49:34 +00:00
{
for ( int i = 0 ; i < 3 ; i + + )
{
2017-03-12 15:56:00 +00:00
floatVal [ i ] = ParseFloat ( sc ) ;
2013-06-23 07:49:34 +00:00
}
}
2017-03-12 15:56:00 +00:00
static void AddLightDefaults ( FLightDefaults * defaults )
2013-06-23 07:49:34 +00:00
{
FLightDefaults * temp ;
unsigned int i ;
// remove duplicates
for ( i = 0 ; i < LightDefaults . Size ( ) ; i + + )
{
temp = LightDefaults [ i ] ;
if ( temp - > GetName ( ) = = defaults - > GetName ( ) )
{
delete temp ;
LightDefaults . Delete ( i ) ;
break ;
}
}
2017-03-12 15:56:00 +00:00
// If the current renderer cannot handle attenuated lights we need to reduce the radius here to account for the far more bright lights this would create.
if ( /*!Renderer->CanAttenuate() &&*/ ( defaults - > GetAttenuate ( ) ) )
2017-01-02 10:41:27 +00:00
{
defaults - > SetArg ( LIGHT_INTENSITY , defaults - > GetArg ( LIGHT_INTENSITY ) * 2 / 3 ) ;
defaults - > SetArg ( LIGHT_SECONDARY_INTENSITY , defaults - > GetArg ( LIGHT_SECONDARY_INTENSITY ) * 2 / 3 ) ;
}
2013-06-23 07:49:34 +00:00
LightDefaults . Push ( defaults ) ;
}
//-----------------------------------------------------------------------------
//
//
//
//-----------------------------------------------------------------------------
2017-03-12 15:56:00 +00:00
static void ParsePointLight ( FScanner & sc )
2013-06-23 07:49:34 +00:00
{
int type ;
float floatTriple [ 3 ] ;
int intVal ;
FLightDefaults * defaults ;
// get name
sc . GetString ( ) ;
FName name = sc . String ;
// check for opening brace
sc . GetString ( ) ;
if ( sc . Compare ( " { " ) )
{
defaults = new FLightDefaults ( name , PointLight ) ;
ScriptDepth + + ;
while ( ScriptDepth )
{
sc . GetString ( ) ;
type = sc . MatchString ( LightTags ) ;
switch ( type )
{
case LIGHTTAG_OPENBRACE :
ScriptDepth + + ;
break ;
case LIGHTTAG_CLOSEBRACE :
ScriptDepth - - ;
break ;
case LIGHTTAG_COLOR :
2017-03-12 15:56:00 +00:00
ParseTriple ( sc , floatTriple ) ;
2013-06-23 07:49:34 +00:00
defaults - > SetArg ( LIGHT_RED , clamp < int > ( ( int ) ( floatTriple [ 0 ] * 255 ) , 0 , 255 ) ) ;
defaults - > SetArg ( LIGHT_GREEN , clamp < int > ( ( int ) ( floatTriple [ 1 ] * 255 ) , 0 , 255 ) ) ;
defaults - > SetArg ( LIGHT_BLUE , clamp < int > ( ( int ) ( floatTriple [ 2 ] * 255 ) , 0 , 255 ) ) ;
break ;
case LIGHTTAG_OFFSET :
2017-03-12 15:56:00 +00:00
ParseTriple ( sc , floatTriple ) ;
2013-06-23 07:49:34 +00:00
defaults - > SetOffset ( floatTriple ) ;
break ;
case LIGHTTAG_SIZE :
2017-03-12 15:56:00 +00:00
intVal = clamp < int > ( ParseInt ( sc ) , 1 , 1024 ) ;
2013-06-23 07:49:34 +00:00
defaults - > SetArg ( LIGHT_INTENSITY , intVal ) ;
break ;
case LIGHTTAG_SUBTRACTIVE :
2017-03-12 15:56:00 +00:00
defaults - > SetSubtractive ( ParseInt ( sc ) ! = 0 ) ;
2013-06-23 07:49:34 +00:00
break ;
case LIGHTTAG_ADDITIVE :
2017-03-12 15:56:00 +00:00
defaults - > SetAdditive ( ParseInt ( sc ) ! = 0 ) ;
2013-06-23 07:49:34 +00:00
break ;
case LIGHTTAG_HALO :
2017-03-12 15:56:00 +00:00
defaults - > SetHalo ( ParseInt ( sc ) ! = 0 ) ;
2013-06-23 07:49:34 +00:00
break ;
case LIGHTTAG_DONTLIGHTSELF :
2017-03-12 15:56:00 +00:00
defaults - > SetDontLightSelf ( ParseInt ( sc ) ! = 0 ) ;
2013-06-23 07:49:34 +00:00
break ;
2016-12-07 22:17:18 +00:00
case LIGHTTAG_ATTENUATE :
2017-03-12 15:56:00 +00:00
defaults - > SetAttenuate ( ParseInt ( sc ) ! = 0 ) ;
2016-12-07 22:17:18 +00:00
break ;
2013-06-23 07:49:34 +00:00
default :
sc . ScriptError ( " Unknown tag: %s \n " , sc . String ) ;
}
}
2017-03-12 15:56:00 +00:00
AddLightDefaults ( defaults ) ;
2013-06-23 07:49:34 +00:00
}
else
{
sc . ScriptError ( " Expected '{'. \n " ) ;
}
}
//-----------------------------------------------------------------------------
//
//
//
//-----------------------------------------------------------------------------
2017-03-12 15:56:00 +00:00
static void ParsePulseLight ( FScanner & sc )
2013-06-23 07:49:34 +00:00
{
int type ;
float floatVal , floatTriple [ 3 ] ;
int intVal ;
FLightDefaults * defaults ;
// get name
sc . GetString ( ) ;
FName name = sc . String ;
// check for opening brace
sc . GetString ( ) ;
if ( sc . Compare ( " { " ) )
{
defaults = new FLightDefaults ( name , PulseLight ) ;
ScriptDepth + + ;
while ( ScriptDepth )
{
sc . GetString ( ) ;
type = sc . MatchString ( LightTags ) ;
switch ( type )
{
case LIGHTTAG_OPENBRACE :
ScriptDepth + + ;
break ;
case LIGHTTAG_CLOSEBRACE :
ScriptDepth - - ;
break ;
case LIGHTTAG_COLOR :
2017-03-12 15:56:00 +00:00
ParseTriple ( sc , floatTriple ) ;
2013-06-23 07:49:34 +00:00
defaults - > SetArg ( LIGHT_RED , clamp < int > ( ( int ) ( floatTriple [ 0 ] * 255 ) , 0 , 255 ) ) ;
defaults - > SetArg ( LIGHT_GREEN , clamp < int > ( ( int ) ( floatTriple [ 1 ] * 255 ) , 0 , 255 ) ) ;
defaults - > SetArg ( LIGHT_BLUE , clamp < int > ( ( int ) ( floatTriple [ 2 ] * 255 ) , 0 , 255 ) ) ;
break ;
case LIGHTTAG_OFFSET :
2017-03-12 15:56:00 +00:00
ParseTriple ( sc , floatTriple ) ;
2013-06-23 07:49:34 +00:00
defaults - > SetOffset ( floatTriple ) ;
break ;
case LIGHTTAG_SIZE :
2017-03-12 15:56:00 +00:00
intVal = clamp < int > ( ParseInt ( sc ) , 1 , 1024 ) ;
2013-06-23 07:49:34 +00:00
defaults - > SetArg ( LIGHT_INTENSITY , intVal ) ;
break ;
case LIGHTTAG_SECSIZE :
2017-03-12 15:56:00 +00:00
intVal = clamp < int > ( ParseInt ( sc ) , 1 , 1024 ) ;
2013-06-23 07:49:34 +00:00
defaults - > SetArg ( LIGHT_SECONDARY_INTENSITY , intVal ) ;
break ;
case LIGHTTAG_INTERVAL :
2017-03-12 15:56:00 +00:00
floatVal = ParseFloat ( sc ) ;
2016-03-24 12:38:37 +00:00
defaults - > SetParameter ( floatVal * TICRATE ) ;
2013-06-23 07:49:34 +00:00
break ;
case LIGHTTAG_SUBTRACTIVE :
2017-03-12 15:56:00 +00:00
defaults - > SetSubtractive ( ParseInt ( sc ) ! = 0 ) ;
2013-06-23 07:49:34 +00:00
break ;
case LIGHTTAG_HALO :
2017-03-12 15:56:00 +00:00
defaults - > SetHalo ( ParseInt ( sc ) ! = 0 ) ;
2013-06-23 07:49:34 +00:00
break ;
case LIGHTTAG_DONTLIGHTSELF :
2017-03-12 15:56:00 +00:00
defaults - > SetDontLightSelf ( ParseInt ( sc ) ! = 0 ) ;
2013-06-23 07:49:34 +00:00
break ;
2016-12-07 22:17:18 +00:00
case LIGHTTAG_ATTENUATE :
2017-03-12 15:56:00 +00:00
defaults - > SetAttenuate ( ParseInt ( sc ) ! = 0 ) ;
2016-12-07 22:17:18 +00:00
break ;
2013-06-23 07:49:34 +00:00
default :
sc . ScriptError ( " Unknown tag: %s \n " , sc . String ) ;
}
}
2017-03-01 19:54:37 +00:00
defaults - > OrderIntensities ( ) ;
2016-12-06 17:35:34 +00:00
2017-03-12 15:56:00 +00:00
AddLightDefaults ( defaults ) ;
2013-06-23 07:49:34 +00:00
}
else
{
sc . ScriptError ( " Expected '{'. \n " ) ;
}
}
//-----------------------------------------------------------------------------
//
//
//
//-----------------------------------------------------------------------------
2017-03-12 15:56:00 +00:00
void ParseFlickerLight ( FScanner & sc )
2013-06-23 07:49:34 +00:00
{
int type ;
float floatVal , floatTriple [ 3 ] ;
int intVal ;
FLightDefaults * defaults ;
// get name
sc . GetString ( ) ;
FName name = sc . String ;
// check for opening brace
sc . GetString ( ) ;
if ( sc . Compare ( " { " ) )
{
defaults = new FLightDefaults ( name , FlickerLight ) ;
ScriptDepth + + ;
while ( ScriptDepth )
{
sc . GetString ( ) ;
type = sc . MatchString ( LightTags ) ;
switch ( type )
{
case LIGHTTAG_OPENBRACE :
ScriptDepth + + ;
break ;
case LIGHTTAG_CLOSEBRACE :
ScriptDepth - - ;
break ;
case LIGHTTAG_COLOR :
2017-03-12 15:56:00 +00:00
ParseTriple ( sc , floatTriple ) ;
2013-06-23 07:49:34 +00:00
defaults - > SetArg ( LIGHT_RED , clamp < int > ( ( int ) ( floatTriple [ 0 ] * 255 ) , 0 , 255 ) ) ;
defaults - > SetArg ( LIGHT_GREEN , clamp < int > ( ( int ) ( floatTriple [ 1 ] * 255 ) , 0 , 255 ) ) ;
defaults - > SetArg ( LIGHT_BLUE , clamp < int > ( ( int ) ( floatTriple [ 2 ] * 255 ) , 0 , 255 ) ) ;
break ;
case LIGHTTAG_OFFSET :
2017-03-12 15:56:00 +00:00
ParseTriple ( sc , floatTriple ) ;
2013-06-23 07:49:34 +00:00
defaults - > SetOffset ( floatTriple ) ;
break ;
case LIGHTTAG_SIZE :
2017-03-12 15:56:00 +00:00
intVal = clamp < int > ( ParseInt ( sc ) , 1 , 1024 ) ;
2013-06-23 07:49:34 +00:00
defaults - > SetArg ( LIGHT_INTENSITY , intVal ) ;
break ;
case LIGHTTAG_SECSIZE :
2017-03-12 15:56:00 +00:00
intVal = clamp < int > ( ParseInt ( sc ) , 1 , 1024 ) ;
2013-06-23 07:49:34 +00:00
defaults - > SetArg ( LIGHT_SECONDARY_INTENSITY , intVal ) ;
break ;
case LIGHTTAG_CHANCE :
2017-03-12 15:56:00 +00:00
floatVal = ParseFloat ( sc ) ;
2016-03-24 12:38:37 +00:00
defaults - > SetParameter ( floatVal * 360. ) ;
2013-06-23 07:49:34 +00:00
break ;
case LIGHTTAG_SUBTRACTIVE :
2017-03-12 15:56:00 +00:00
defaults - > SetSubtractive ( ParseInt ( sc ) ! = 0 ) ;
2013-06-23 07:49:34 +00:00
break ;
case LIGHTTAG_HALO :
2017-03-12 15:56:00 +00:00
defaults - > SetHalo ( ParseInt ( sc ) ! = 0 ) ;
2013-06-23 07:49:34 +00:00
break ;
case LIGHTTAG_DONTLIGHTSELF :
2017-03-12 15:56:00 +00:00
defaults - > SetDontLightSelf ( ParseInt ( sc ) ! = 0 ) ;
2013-06-23 07:49:34 +00:00
break ;
2016-12-07 22:17:18 +00:00
case LIGHTTAG_ATTENUATE :
2017-03-12 15:56:00 +00:00
defaults - > SetAttenuate ( ParseInt ( sc ) ! = 0 ) ;
2016-12-07 22:17:18 +00:00
break ;
2013-06-23 07:49:34 +00:00
default :
sc . ScriptError ( " Unknown tag: %s \n " , sc . String ) ;
}
}
2017-03-01 19:54:37 +00:00
defaults - > OrderIntensities ( ) ;
2017-03-12 15:56:00 +00:00
AddLightDefaults ( defaults ) ;
2013-06-23 07:49:34 +00:00
}
else
{
sc . ScriptError ( " Expected '{'. \n " ) ;
}
}
//-----------------------------------------------------------------------------
//
//
//
//-----------------------------------------------------------------------------
2017-03-12 15:56:00 +00:00
void ParseFlickerLight2 ( FScanner & sc )
2013-06-23 07:49:34 +00:00
{
int type ;
float floatVal , floatTriple [ 3 ] ;
int intVal ;
FLightDefaults * defaults ;
// get name
sc . GetString ( ) ;
FName name = sc . String ;
// check for opening brace
sc . GetString ( ) ;
if ( sc . Compare ( " { " ) )
{
defaults = new FLightDefaults ( name , RandomFlickerLight ) ;
ScriptDepth + + ;
while ( ScriptDepth )
{
sc . GetString ( ) ;
type = sc . MatchString ( LightTags ) ;
switch ( type )
{
case LIGHTTAG_OPENBRACE :
ScriptDepth + + ;
break ;
case LIGHTTAG_CLOSEBRACE :
ScriptDepth - - ;
break ;
case LIGHTTAG_COLOR :
2017-03-12 15:56:00 +00:00
ParseTriple ( sc , floatTriple ) ;
2013-06-23 07:49:34 +00:00
defaults - > SetArg ( LIGHT_RED , clamp < int > ( ( int ) ( floatTriple [ 0 ] * 255 ) , 0 , 255 ) ) ;
defaults - > SetArg ( LIGHT_GREEN , clamp < int > ( ( int ) ( floatTriple [ 1 ] * 255 ) , 0 , 255 ) ) ;
defaults - > SetArg ( LIGHT_BLUE , clamp < int > ( ( int ) ( floatTriple [ 2 ] * 255 ) , 0 , 255 ) ) ;
break ;
case LIGHTTAG_OFFSET :
2017-03-12 15:56:00 +00:00
ParseTriple ( sc , floatTriple ) ;
2013-06-23 07:49:34 +00:00
defaults - > SetOffset ( floatTriple ) ;
break ;
case LIGHTTAG_SIZE :
2017-03-12 15:56:00 +00:00
intVal = clamp < int > ( ParseInt ( sc ) , 1 , 1024 ) ;
2013-06-23 07:49:34 +00:00
defaults - > SetArg ( LIGHT_INTENSITY , intVal ) ;
break ;
case LIGHTTAG_SECSIZE :
2017-03-12 15:56:00 +00:00
intVal = clamp < int > ( ParseInt ( sc ) , 1 , 1024 ) ;
2013-06-23 07:49:34 +00:00
defaults - > SetArg ( LIGHT_SECONDARY_INTENSITY , intVal ) ;
break ;
case LIGHTTAG_INTERVAL :
2017-03-12 15:56:00 +00:00
floatVal = ParseFloat ( sc ) ;
2016-03-24 12:38:37 +00:00
defaults - > SetParameter ( floatVal * 360. ) ;
2013-06-23 07:49:34 +00:00
break ;
case LIGHTTAG_SUBTRACTIVE :
2017-03-12 15:56:00 +00:00
defaults - > SetSubtractive ( ParseInt ( sc ) ! = 0 ) ;
2013-06-23 07:49:34 +00:00
break ;
case LIGHTTAG_HALO :
2017-03-12 15:56:00 +00:00
defaults - > SetHalo ( ParseInt ( sc ) ! = 0 ) ;
2013-06-23 07:49:34 +00:00
break ;
case LIGHTTAG_DONTLIGHTSELF :
2017-03-12 15:56:00 +00:00
defaults - > SetDontLightSelf ( ParseInt ( sc ) ! = 0 ) ;
2013-06-23 07:49:34 +00:00
break ;
2016-12-07 22:17:18 +00:00
case LIGHTTAG_ATTENUATE :
2017-03-12 15:56:00 +00:00
defaults - > SetAttenuate ( ParseInt ( sc ) ! = 0 ) ;
2016-12-07 22:17:18 +00:00
break ;
2013-06-23 07:49:34 +00:00
default :
sc . ScriptError ( " Unknown tag: %s \n " , sc . String ) ;
}
}
if ( defaults - > GetArg ( LIGHT_SECONDARY_INTENSITY ) < defaults - > GetArg ( LIGHT_INTENSITY ) )
{
2017-02-03 09:13:16 +00:00
int v = defaults - > GetArg ( LIGHT_SECONDARY_INTENSITY ) ;
2013-06-23 07:49:34 +00:00
defaults - > SetArg ( LIGHT_SECONDARY_INTENSITY , defaults - > GetArg ( LIGHT_INTENSITY ) ) ;
defaults - > SetArg ( LIGHT_INTENSITY , v ) ;
}
2017-03-12 15:56:00 +00:00
AddLightDefaults ( defaults ) ;
2013-06-23 07:49:34 +00:00
}
else
{
sc . ScriptError ( " Expected '{'. \n " ) ;
}
}
//-----------------------------------------------------------------------------
//
//
//
//-----------------------------------------------------------------------------
2017-03-12 15:56:00 +00:00
static void ParseSectorLight ( FScanner & sc )
2013-06-23 07:49:34 +00:00
{
int type ;
float floatVal ;
float floatTriple [ 3 ] ;
FLightDefaults * defaults ;
// get name
sc . GetString ( ) ;
FName name = sc . String ;
// check for opening brace
sc . GetString ( ) ;
if ( sc . Compare ( " { " ) )
{
defaults = new FLightDefaults ( name , SectorLight ) ;
ScriptDepth + + ;
while ( ScriptDepth )
{
sc . GetString ( ) ;
type = sc . MatchString ( LightTags ) ;
switch ( type )
{
case LIGHTTAG_OPENBRACE :
ScriptDepth + + ;
break ;
case LIGHTTAG_CLOSEBRACE :
ScriptDepth - - ;
break ;
case LIGHTTAG_COLOR :
2017-03-12 15:56:00 +00:00
ParseTriple ( sc , floatTriple ) ;
2013-06-23 07:49:34 +00:00
defaults - > SetArg ( LIGHT_RED , clamp < int > ( ( int ) ( floatTriple [ 0 ] * 255 ) , 0 , 255 ) ) ;
defaults - > SetArg ( LIGHT_GREEN , clamp < int > ( ( int ) ( floatTriple [ 1 ] * 255 ) , 0 , 255 ) ) ;
defaults - > SetArg ( LIGHT_BLUE , clamp < int > ( ( int ) ( floatTriple [ 2 ] * 255 ) , 0 , 255 ) ) ;
break ;
case LIGHTTAG_OFFSET :
2017-03-12 15:56:00 +00:00
ParseTriple ( sc , floatTriple ) ;
2013-06-23 07:49:34 +00:00
defaults - > SetOffset ( floatTriple ) ;
break ;
case LIGHTTAG_SCALE :
2017-03-12 15:56:00 +00:00
floatVal = ParseFloat ( sc ) ;
2017-01-29 11:00:05 +00:00
defaults - > SetArg ( LIGHT_SCALE , clamp ( ( int ) ( floatVal * 255 ) , 1 , 1024 ) ) ;
2013-06-23 07:49:34 +00:00
break ;
case LIGHTTAG_SUBTRACTIVE :
2017-03-12 15:56:00 +00:00
defaults - > SetSubtractive ( ParseInt ( sc ) ! = 0 ) ;
2013-06-23 07:49:34 +00:00
break ;
case LIGHTTAG_HALO :
2017-03-12 15:56:00 +00:00
defaults - > SetHalo ( ParseInt ( sc ) ! = 0 ) ;
2013-06-23 07:49:34 +00:00
break ;
case LIGHTTAG_DONTLIGHTSELF :
2017-03-12 15:56:00 +00:00
defaults - > SetDontLightSelf ( ParseInt ( sc ) ! = 0 ) ;
2013-06-23 07:49:34 +00:00
break ;
2016-12-07 22:17:18 +00:00
case LIGHTTAG_ATTENUATE :
2017-03-12 15:56:00 +00:00
defaults - > SetAttenuate ( ParseInt ( sc ) ! = 0 ) ;
2016-12-07 22:17:18 +00:00
break ;
2013-06-23 07:49:34 +00:00
default :
sc . ScriptError ( " Unknown tag: %s \n " , sc . String ) ;
}
}
2017-03-12 15:56:00 +00:00
AddLightDefaults ( defaults ) ;
2013-06-23 07:49:34 +00:00
}
else
{
sc . ScriptError ( " Expected '{'. \n " ) ;
}
}
//-----------------------------------------------------------------------------
//
//
//
//-----------------------------------------------------------------------------
2017-03-12 15:56:00 +00:00
static void AddLightAssociation ( const char * actor , const char * frame , const char * light )
2013-06-23 07:49:34 +00:00
{
FLightAssociation * temp ;
unsigned int i ;
FLightAssociation assoc ( actor , frame , light ) ;
for ( i = 0 ; i < LightAssociations . Size ( ) ; i + + )
{
temp = & LightAssociations [ i ] ;
if ( temp - > ActorName ( ) = = assoc . ActorName ( ) )
{
if ( strcmp ( temp - > FrameName ( ) , assoc . FrameName ( ) ) = = 0 )
{
temp - > ReplaceLightName ( assoc . Light ( ) ) ;
return ;
}
}
}
LightAssociations . Push ( assoc ) ;
}
//-----------------------------------------------------------------------------
//
//
//
//-----------------------------------------------------------------------------
2017-03-12 15:56:00 +00:00
static void ParseFrame ( FScanner & sc , FString name )
2013-06-23 07:49:34 +00:00
{
int type , startDepth ;
FString frameName ;
// get name
sc . GetString ( ) ;
if ( strlen ( sc . String ) > 8 )
{
sc . ScriptError ( " Name longer than 8 characters: %s \n " , sc . String ) ;
}
frameName = sc . String ;
startDepth = ScriptDepth ;
// check for opening brace
sc . GetString ( ) ;
if ( sc . Compare ( " { " ) )
{
ScriptDepth + + ;
while ( ScriptDepth > startDepth )
{
sc . GetString ( ) ;
type = sc . MatchString ( LightTags ) ;
switch ( type )
{
case LIGHTTAG_OPENBRACE :
ScriptDepth + + ;
break ;
case LIGHTTAG_CLOSEBRACE :
ScriptDepth - - ;
break ;
case LIGHTTAG_LIGHT :
2017-03-12 15:56:00 +00:00
ParseString ( sc ) ;
AddLightAssociation ( name , frameName , sc . String ) ;
2013-06-23 07:49:34 +00:00
break ;
default :
sc . ScriptError ( " Unknown tag: %s \n " , sc . String ) ;
}
}
}
else
{
sc . ScriptError ( " Expected '{'. \n " ) ;
}
}
//-----------------------------------------------------------------------------
//
//
//
//-----------------------------------------------------------------------------
2017-03-12 15:56:00 +00:00
void ParseObject ( FScanner & sc )
2013-06-23 07:49:34 +00:00
{
int type ;
FString name ;
// get name
sc . GetString ( ) ;
name = sc . String ;
2017-03-12 15:56:00 +00:00
if ( ! PClass : : FindActor ( name ) )
2013-06-23 07:49:34 +00:00
sc . ScriptMessage ( " Warning: dynamic lights attached to non-existent actor %s \n " , name . GetChars ( ) ) ;
// check for opening brace
sc . GetString ( ) ;
if ( sc . Compare ( " { " ) )
{
ScriptDepth + + ;
while ( ScriptDepth )
{
sc . GetString ( ) ;
type = sc . MatchString ( LightTags ) ;
switch ( type )
{
case LIGHTTAG_OPENBRACE :
ScriptDepth + + ;
break ;
case LIGHTTAG_CLOSEBRACE :
ScriptDepth - - ;
break ;
case LIGHTTAG_FRAME :
2017-03-12 15:56:00 +00:00
ParseFrame ( sc , name ) ;
2013-06-23 07:49:34 +00:00
break ;
default :
sc . ScriptError ( " Unknown tag: %s \n " , sc . String ) ;
}
}
}
else
{
sc . ScriptError ( " Expected '{'. \n " ) ;
}
}
//-----------------------------------------------------------------------------
//
//
//
//-----------------------------------------------------------------------------
2017-03-12 15:56:00 +00:00
static void ReleaseLights ( )
2013-06-23 07:49:34 +00:00
{
unsigned int i ;
for ( i = 0 ; i < LightDefaults . Size ( ) ; i + + )
{
delete LightDefaults [ i ] ;
}
LightAssociations . Clear ( ) ;
LightDefaults . Clear ( ) ;
}
//==========================================================================
//
//
//
//==========================================================================
// these are the core types available in the *DEFS lump
static const char * CoreKeywords [ ] =
{
" pointlight " ,
" pulselight " ,
" flickerlight " ,
" flickerlight2 " ,
" sectorlight " ,
" object " ,
" clearlights " ,
" shader " ,
" clearshaders " ,
" skybox " ,
" glow " ,
" brightmap " ,
" disable_fullbright " ,
" hardwareshader " ,
" detail " ,
" #include " ,
NULL
} ;
enum
{
LIGHT_POINT ,
LIGHT_PULSE ,
LIGHT_FLICKER ,
LIGHT_FLICKER2 ,
LIGHT_SECTOR ,
LIGHT_OBJECT ,
LIGHT_CLEAR ,
TAG_SHADER ,
TAG_CLEARSHADERS ,
TAG_SKYBOX ,
TAG_GLOW ,
TAG_BRIGHTMAP ,
TAG_DISABLE_FB ,
TAG_HARDWARESHADER ,
TAG_DETAIL ,
TAG_INCLUDE ,
} ;
//==========================================================================
//
// This is only here so any shader definition for ZDoomGL can be skipped
// There is no functionality for this stuff!
//
//==========================================================================
2017-03-12 15:56:00 +00:00
bool _gl_ParseShader ( FScanner & sc )
2013-06-23 07:49:34 +00:00
{
int ShaderDepth = 0 ;
if ( sc . GetString ( ) )
{
char * tmp ;
tmp = strstr ( sc . String , " { " ) ;
while ( tmp )
{
ShaderDepth + + ;
tmp + + ;
tmp = strstr ( tmp , " { " ) ;
}
tmp = strstr ( sc . String , " } " ) ;
while ( tmp )
{
ShaderDepth - - ;
tmp + + ;
tmp = strstr ( tmp , " } " ) ;
}
if ( ShaderDepth = = 0 ) return true ;
}
return false ;
}
//==========================================================================
//
// Light associations per actor class
//
//==========================================================================
class FInternalLightAssociation
{
public :
FInternalLightAssociation ( FLightAssociation * asso ) ;
int Sprite ( ) const { return m_sprite ; }
int Frame ( ) const { return m_frame ; }
const FLightDefaults * Light ( ) const { return m_AssocLight ; }
protected :
int m_sprite ;
int m_frame ;
FLightDefaults * m_AssocLight ;
} ;
//==========================================================================
//
//
//
//==========================================================================
FInternalLightAssociation : : FInternalLightAssociation ( FLightAssociation * asso )
{
m_AssocLight = NULL ;
for ( unsigned int i = 0 ; i < LightDefaults . Size ( ) ; i + + )
{
if ( LightDefaults [ i ] - > GetName ( ) = = asso - > Light ( ) )
{
m_AssocLight = LightDefaults [ i ] ;
break ;
}
}
m_sprite = - 1 ;
m_frame = - 1 ;
for ( unsigned i = 0 ; i < sprites . Size ( ) ; + + i )
{
if ( strncmp ( sprites [ i ] . name , asso - > FrameName ( ) , 4 ) = = 0 )
{
m_sprite = ( int ) i ;
break ;
}
}
// Only handle lights for full frames.
// I won't bother with special lights for single rotations
// because there is no decent use for them!
if ( strlen ( asso - > FrameName ( ) ) = = 5 | | asso - > FrameName ( ) [ 5 ] = = ' 0 ' )
{
m_frame = toupper ( asso - > FrameName ( ) [ 4 ] ) - ' A ' ;
}
}
//==========================================================================
//
// State lights
//
//==========================================================================
TArray < FName > ParsedStateLights ;
TArray < FLightDefaults * > StateLights ;
//==========================================================================
//
//
//
//==========================================================================
2017-03-12 15:56:00 +00:00
void InitializeActorLights ( )
2013-06-23 07:49:34 +00:00
{
for ( unsigned int i = 0 ; i < LightAssociations . Size ( ) ; i + + )
{
2016-02-05 11:31:41 +00:00
PClassActor * ti = PClass : : FindActor ( LightAssociations [ i ] . ActorName ( ) ) ;
2013-06-23 07:49:34 +00:00
if ( ti )
{
ti = GetRealType ( ti ) ;
2017-03-12 15:56:00 +00:00
// put this in the class data arena so that we do not have to worry about deleting it ourselves.
void * mem = ClassDataAllocator . Alloc ( sizeof ( FInternalLightAssociation ) ) ;
FInternalLightAssociation * iasso = new ( mem ) FInternalLightAssociation ( & LightAssociations [ i ] ) ;
if ( iasso - > Light ( ) ! = nullptr )
ti - > LightAssociations . Push ( iasso ) ;
2013-06-23 07:49:34 +00:00
}
}
// we don't need the parser data for the light associations anymore
LightAssociations . Clear ( ) ;
LightAssociations . ShrinkToFit ( ) ;
StateLights . Resize ( ParsedStateLights . Size ( ) + 1 ) ;
for ( unsigned i = 0 ; i < ParsedStateLights . Size ( ) ; i + + )
{
if ( ParsedStateLights [ i ] ! = NAME_None )
{
StateLights [ i ] = ( FLightDefaults * ) - 1 ; // something invalid that's not NULL.
for ( unsigned int j = 0 ; j < LightDefaults . Size ( ) ; j + + )
{
if ( LightDefaults [ j ] - > GetName ( ) = = ParsedStateLights [ i ] )
{
StateLights [ i ] = LightDefaults [ j ] ;
break ;
}
}
}
else StateLights [ i ] = NULL ;
}
StateLights [ StateLights . Size ( ) - 1 ] = NULL ; // terminator
ParsedStateLights . Clear ( ) ;
ParsedStateLights . ShrinkToFit ( ) ;
}
//==========================================================================
//
//
//
//==========================================================================
2017-03-12 15:56:00 +00:00
void AActor : : AttachLight ( unsigned int count , const FLightDefaults * lightdef )
2013-06-23 07:49:34 +00:00
{
ADynamicLight * light ;
2017-03-12 15:56:00 +00:00
if ( count < AttachedLights . Size ( ) )
2013-06-23 07:49:34 +00:00
{
2017-03-12 15:56:00 +00:00
light = barrier_cast < ADynamicLight * > ( AttachedLights [ count ] ) ;
2013-06-23 07:49:34 +00:00
assert ( light ! = NULL ) ;
}
else
{
2017-03-12 15:56:00 +00:00
light = Spawn < ADynamicLight > ( Pos ( ) , NO_REPLACE ) ;
light - > target = this ;
2013-06-23 07:49:34 +00:00
light - > owned = true ;
2016-10-16 07:12:43 +00:00
light - > ObjectFlags | = OF_Transient ;
2016-12-06 17:35:34 +00:00
//light->flags4 |= MF4_ATTENUATE;
2017-03-12 15:56:00 +00:00
AttachedLights . Push ( light ) ;
2013-06-23 07:49:34 +00:00
}
light - > flags2 & = ~ MF2_DORMANT ;
lightdef - > ApplyProperties ( light ) ;
}
//==========================================================================
//
// per-state light adjustment
//
//==========================================================================
2017-03-12 15:56:00 +00:00
void AActor : : SetDynamicLights ( )
2013-06-23 07:49:34 +00:00
{
2017-03-12 15:56:00 +00:00
TArray < FInternalLightAssociation * > & LightAssociations = GetClass ( ) - > LightAssociations ;
2013-06-23 07:49:34 +00:00
unsigned int count = 0 ;
2017-03-12 15:56:00 +00:00
if ( state = = NULL ) return ;
if ( LightAssociations . Size ( ) > 0 )
2013-06-23 07:49:34 +00:00
{
ADynamicLight * lights , * tmpLight ;
unsigned int i ;
lights = tmpLight = NULL ;
for ( i = 0 ; i < LightAssociations . Size ( ) ; i + + )
{
if ( LightAssociations [ i ] - > Sprite ( ) = = sprite & &
( LightAssociations [ i ] - > Frame ( ) = = frame | | LightAssociations [ i ] - > Frame ( ) = = - 1 ) )
{
2017-03-12 15:56:00 +00:00
AttachLight ( count + + , LightAssociations [ i ] - > Light ( ) ) ;
2013-06-23 07:49:34 +00:00
}
}
}
2017-03-12 15:56:00 +00:00
if ( count = = 0 & & state - > Light > 0 )
2013-06-23 07:49:34 +00:00
{
2017-03-12 15:56:00 +00:00
for ( int i = state - > Light ; StateLights [ i ] ! = NULL ; i + + )
2013-06-23 07:49:34 +00:00
{
if ( StateLights [ i ] ! = ( FLightDefaults * ) - 1 )
{
2017-03-12 15:56:00 +00:00
AttachLight ( count + + , StateLights [ i ] ) ;
2013-06-23 07:49:34 +00:00
}
}
}
2017-03-12 15:56:00 +00:00
for ( ; count < AttachedLights . Size ( ) ; count + + )
{
AttachedLights [ count ] - > flags2 | = MF2_DORMANT ;
memset ( AttachedLights [ count ] - > args , 0 , 3 * sizeof ( args [ 0 ] ) ) ;
}
}
//==========================================================================
//
// Needed for garbage collection
//
//==========================================================================
size_t AActor : : PropagateMark ( )
{
for ( unsigned i = 0 ; i < AttachedLights . Size ( ) ; i + + )
2013-06-23 07:49:34 +00:00
{
2017-03-12 15:56:00 +00:00
GC : : Mark ( AttachedLights [ i ] ) ;
2013-06-23 07:49:34 +00:00
}
2017-03-12 15:56:00 +00:00
return Super : : PropagateMark ( ) ;
2013-06-23 07:49:34 +00:00
}
//==========================================================================
//
// This is called before saving the game
//
//==========================================================================
2017-03-12 15:56:00 +00:00
void AActor : : DeleteAllAttachedLights ( )
2013-06-23 07:49:34 +00:00
{
TThinkerIterator < AActor > it ;
AActor * a ;
ADynamicLight * l ;
while ( ( a = it . Next ( ) ) )
{
2017-03-12 15:56:00 +00:00
a - > AttachedLights . Clear ( ) ;
2013-06-23 07:49:34 +00:00
}
TThinkerIterator < ADynamicLight > it2 ;
l = it2 . Next ( ) ;
while ( l )
{
ADynamicLight * ll = it2 . Next ( ) ;
if ( l - > owned ) l - > Destroy ( ) ;
l = ll ;
}
}
//==========================================================================
//
//
//
//==========================================================================
2017-03-12 15:56:00 +00:00
void AActor : : RecreateAllAttachedLights ( )
2013-06-23 07:49:34 +00:00
{
TThinkerIterator < AActor > it ;
AActor * a ;
while ( ( a = it . Next ( ) ) )
{
2017-03-12 15:56:00 +00:00
a - > SetDynamicLights ( ) ;
2013-06-23 07:49:34 +00:00
}
}
//==========================================================================
// The actual light def parsing code is there.
// DoParseDefs is no longer called directly by ParseDefs, now it's called
// by LoadDynLightDefs, which wasn't simply integrated into ParseDefs
// because of the way the code needs to load two out of five lumps.
//==========================================================================
2017-03-12 15:56:00 +00:00
static void DoParseDefs ( FScanner & sc , int workingLump )
2013-06-23 07:49:34 +00:00
{
int recursion = 0 ;
int lump , type ;
// Get actor class name.
while ( true )
{
sc . SavePos ( ) ;
if ( ! sc . GetToken ( ) )
{
return ;
}
type = sc . MatchString ( CoreKeywords ) ;
switch ( type )
{
case TAG_INCLUDE :
{
sc . MustGetString ( ) ;
// This is not using sc.Open because it can print a more useful error message when done here
lump = Wads . CheckNumForFullName ( sc . String , true ) ;
if ( lump = = - 1 )
sc . ScriptError ( " Lump '%s' not found " , sc . String ) ;
FScanner newscanner ( lump ) ;
2017-03-12 15:56:00 +00:00
DoParseDefs ( newscanner , lump ) ;
2013-06-23 07:49:34 +00:00
break ;
}
case LIGHT_POINT :
2017-03-12 15:56:00 +00:00
ParsePointLight ( sc ) ;
2013-06-23 07:49:34 +00:00
break ;
case LIGHT_PULSE :
2017-03-12 15:56:00 +00:00
ParsePulseLight ( sc ) ;
2013-06-23 07:49:34 +00:00
break ;
case LIGHT_FLICKER :
2017-03-12 15:56:00 +00:00
ParseFlickerLight ( sc ) ;
2013-06-23 07:49:34 +00:00
break ;
case LIGHT_FLICKER2 :
2017-03-12 15:56:00 +00:00
ParseFlickerLight2 ( sc ) ;
2013-06-23 07:49:34 +00:00
break ;
case LIGHT_SECTOR :
2017-03-12 15:56:00 +00:00
ParseSectorLight ( sc ) ;
2013-06-23 07:49:34 +00:00
break ;
case LIGHT_OBJECT :
2017-03-12 15:56:00 +00:00
ParseObject ( sc ) ;
2013-06-23 07:49:34 +00:00
break ;
case LIGHT_CLEAR :
2017-03-12 15:56:00 +00:00
// This has been intentionally removed
2013-06-23 07:49:34 +00:00
break ;
case TAG_SHADER :
2017-03-12 15:56:00 +00:00
_gl_ParseShader ( sc ) ;
2013-06-23 07:49:34 +00:00
break ;
case TAG_CLEARSHADERS :
break ;
case TAG_SKYBOX :
gl_ParseSkybox ( sc ) ;
break ;
case TAG_GLOW :
gl_InitGlow ( sc ) ;
break ;
case TAG_BRIGHTMAP :
gl_ParseBrightmap ( sc , workingLump ) ;
break ;
case TAG_HARDWARESHADER :
gl_ParseHardwareShader ( sc , workingLump ) ;
break ;
case TAG_DETAIL :
gl_ParseDetailTexture ( sc ) ;
break ;
case TAG_DISABLE_FB :
{
/* not implemented.
sc . MustGetString ( ) ;
const PClass * cls = PClass : : FindClass ( sc . String ) ;
if ( cls ) GetDefaultByType ( cls ) - > renderflags | = RF_NEVERFULLBRIGHT ;
*/
}
break ;
default :
sc . ScriptError ( " Error parsing defs. Unknown tag: %s. \n " , sc . String ) ;
break ;
}
}
}
//==========================================================================
//
//
//
//==========================================================================
2017-03-12 15:56:00 +00:00
static void LoadGLDefs ( const char * defsLump )
2013-06-23 07:49:34 +00:00
{
int workingLump , lastLump ;
2017-01-01 23:28:30 +00:00
static const char * gldefsnames [ ] = { " GLDEFS " , defsLump , nullptr } ;
2013-06-23 07:49:34 +00:00
lastLump = 0 ;
2017-01-01 23:28:30 +00:00
while ( ( workingLump = Wads . FindLumpMulti ( gldefsnames , & lastLump ) ) ! = - 1 )
2013-06-23 07:49:34 +00:00
{
FScanner sc ( workingLump ) ;
2017-03-12 15:56:00 +00:00
DoParseDefs ( sc , workingLump ) ;
2013-06-23 07:49:34 +00:00
}
}
//==========================================================================
//
//
//
//==========================================================================
2017-03-12 15:56:00 +00:00
void ParseGLDefs ( )
2013-06-23 07:49:34 +00:00
{
const char * defsLump = NULL ;
2017-03-12 15:56:00 +00:00
atterm ( ReleaseLights ) ;
ReleaseLights ( ) ;
2013-06-23 07:49:34 +00:00
gl_DestroyUserShaders ( ) ;
switch ( gameinfo . gametype )
{
case GAME_Heretic :
defsLump = " HTICDEFS " ;
break ;
case GAME_Hexen :
defsLump = " HEXNDEFS " ;
break ;
case GAME_Strife :
defsLump = " STRFDEFS " ;
break ;
case GAME_Doom :
defsLump = " DOOMDEFS " ;
break ;
case GAME_Chex :
defsLump = " CHEXDEFS " ;
break ;
default : // silence GCC
break ;
}
gl_ParseVavoomSkybox ( ) ;
2017-03-12 15:56:00 +00:00
LoadGLDefs ( defsLump ) ;
InitializeActorLights ( ) ;
2013-06-23 07:49:34 +00:00
}
//==========================================================================
//
//
//
//==========================================================================
void AddStateLight ( FState * State , const char * lname )
{
if ( State - > Light = = 0 )
{
ParsedStateLights . Push ( NAME_None ) ;
State - > Light = ParsedStateLights . Push ( FName ( lname ) ) ;
}
else
{
ParsedStateLights . Push ( FName ( lname ) ) ;
}
}