mirror of
https://github.com/id-Software/DOOM-3-BFG.git
synced 2025-04-22 09:40:46 +00:00
Merged Quake 1 lightstyle support from Iced-Hellfire
This commit is contained in:
parent
b85db1e865
commit
1f2f6896e1
10 changed files with 379 additions and 21 deletions
|
@ -1692,7 +1692,7 @@ int idEntity::GetModelDefHandle()
|
|||
idEntity::UpdateRenderEntity
|
||||
================
|
||||
*/
|
||||
bool idEntity::UpdateRenderEntity( renderEntity_s* renderEntity, const renderView_t* renderView )
|
||||
bool idEntity::UpdateRenderEntity( renderEntity_t* renderEntity, const renderView_t* renderView )
|
||||
{
|
||||
if( gameLocal.inCinematic && gameLocal.skipCinematic )
|
||||
{
|
||||
|
@ -1721,7 +1721,7 @@ idEntity::ModelCallback
|
|||
NOTE: may not change the game state whatsoever!
|
||||
================
|
||||
*/
|
||||
bool idEntity::ModelCallback( renderEntity_s* renderEntity, const renderView_t* renderView )
|
||||
bool idEntity::ModelCallback( renderEntity_t* renderEntity, const renderView_t* renderView )
|
||||
{
|
||||
idEntity* ent;
|
||||
|
||||
|
|
|
@ -302,8 +302,8 @@ public:
|
|||
|
||||
// animation
|
||||
virtual bool UpdateAnimationControllers();
|
||||
bool UpdateRenderEntity( renderEntity_s* renderEntity, const renderView_t* renderView );
|
||||
static bool ModelCallback( renderEntity_s* renderEntity, const renderView_t* renderView );
|
||||
bool UpdateRenderEntity( renderEntity_t* renderEntity, const renderView_t* renderView );
|
||||
static bool ModelCallback( renderEntity_t* renderEntity, const renderView_t* renderView );
|
||||
virtual idAnimator* GetAnimator(); // returns animator object used by this entity
|
||||
|
||||
// sound
|
||||
|
@ -571,6 +571,14 @@ private:
|
|||
void UpdatePVSAreas();
|
||||
|
||||
// events
|
||||
public:
|
||||
// jmarshall
|
||||
idVec3 GetOrigin( void );
|
||||
float DistanceTo( idEntity* ent );
|
||||
float DistanceTo( const idVec3& pos ) const;
|
||||
idStr GetNextKey( const char* prefix, const char* lastMatch );
|
||||
// jmarshall end
|
||||
|
||||
void Event_GetName();
|
||||
void Event_SetName( const char* name );
|
||||
void Event_FindTargets();
|
||||
|
@ -641,6 +649,16 @@ private:
|
|||
void Event_GuiNamedEvent( int guiNum, const char* event );
|
||||
};
|
||||
|
||||
ID_INLINE float idEntity::DistanceTo( idEntity* ent )
|
||||
{
|
||||
return DistanceTo( ent->GetPhysics()->GetOrigin() );
|
||||
}
|
||||
|
||||
ID_INLINE float idEntity::DistanceTo( const idVec3& pos ) const
|
||||
{
|
||||
return ( pos - GetPhysics()->GetOrigin() ).LengthFast();
|
||||
}
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
|
|
|
@ -2590,6 +2590,22 @@ void idGameLocal::RunEntityThink( idEntity& ent, idUserCmdMgr& userCmdMgr )
|
|||
|
||||
idCVar g_recordTrace( "g_recordTrace", "0", CVAR_BOOL, "" );
|
||||
|
||||
// jmarshall
|
||||
/*
|
||||
================
|
||||
idGameLocal::RunSharedThink
|
||||
================
|
||||
*/
|
||||
void idGameLocal::RunSharedThink( void )
|
||||
{
|
||||
idEntity* ent;
|
||||
for( ent = activeEntities.Next(); ent != NULL; ent = ent->activeNode.Next() )
|
||||
{
|
||||
ent->SharedThink();
|
||||
}
|
||||
}
|
||||
// jmarshall end
|
||||
|
||||
/*
|
||||
================
|
||||
idGameLocal::RunFrame
|
||||
|
@ -2766,7 +2782,9 @@ void idGameLocal::RunFrame( idUserCmdMgr& cmdMgr, gameReturn_t& ret )
|
|||
}
|
||||
|
||||
RunTimeGroup2( cmdMgr );
|
||||
|
||||
// jmarshall
|
||||
RunSharedThink();
|
||||
// jmarshall end
|
||||
// Run catch-up for any client projectiles.
|
||||
// This is done after the main think so that all projectiles will be up-to-date
|
||||
// when snapshots are created.
|
||||
|
|
|
@ -718,6 +718,8 @@ private:
|
|||
void ShowTargets();
|
||||
void RunDebugInfo();
|
||||
|
||||
void RunSharedThink();
|
||||
|
||||
void InitScriptForMap();
|
||||
void SetScriptFPS( const float com_engineHz );
|
||||
void SpawnPlayer( int clientNum );
|
||||
|
|
|
@ -166,6 +166,7 @@ void idGameEdit::ParseSpawnArgsToRenderLight( const idDict* args, renderLight_t*
|
|||
args->GetBool( "parallel", "0", renderLight->parallel );
|
||||
|
||||
args->GetString( "texture", "lights/squarelight1", &texture );
|
||||
|
||||
// allow this to be NULL
|
||||
renderLight->shader = declManager->FindMaterial( texture, false );
|
||||
}
|
||||
|
@ -177,6 +178,12 @@ idLight::UpdateChangeableSpawnArgs
|
|||
*/
|
||||
void idLight::UpdateChangeableSpawnArgs( const idDict* source )
|
||||
{
|
||||
// jmarshall
|
||||
lightStyleFrameTime = spawnArgs.GetInt( "ls_frametime", "100" );
|
||||
lightStyle = spawnArgs.GetInt( "style", -1 );
|
||||
|
||||
lightStyleState.Reset();
|
||||
// jmarshall end
|
||||
|
||||
idEntity::UpdateChangeableSpawnArgs( source );
|
||||
|
||||
|
@ -336,6 +343,9 @@ void idLight::Spawn()
|
|||
|
||||
// do the parsing the same way dmap and the editor do
|
||||
gameEdit->ParseSpawnArgsToRenderLight( &spawnArgs, &renderLight );
|
||||
// jmarshall: Store the original light radius for the light style.
|
||||
lightStyleBase = renderLight.lightRadius;
|
||||
// jmarshall end
|
||||
|
||||
// we need the origin and axis relative to the physics origin/axis
|
||||
localLightOrigin = ( renderLight.origin - GetPhysics()->GetOrigin() ) * GetPhysics()->GetAxis().Transpose();
|
||||
|
@ -397,6 +407,30 @@ void idLight::Spawn()
|
|||
spawnArgs.GetBool( "break", "0", breakOnTrigger );
|
||||
spawnArgs.GetInt( "count", "1", count );
|
||||
|
||||
// jmarshall
|
||||
lightStyleFrameTime = spawnArgs.GetInt( "ls_frametime", "100" );
|
||||
lightStyle = spawnArgs.GetInt( "style", -1 );
|
||||
|
||||
int numStyles = spawnArgs.GetInt( "num_styles", "0" );
|
||||
if( numStyles > 0 )
|
||||
{
|
||||
for( int i = 0; i < numStyles; i++ )
|
||||
{
|
||||
idStr style = spawnArgs.GetString( va( "light_style%d", i ) );
|
||||
light_styles.Append( style );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// RB: it's not defined in entityDef light so use predefined Quake 1 table
|
||||
for( int i = 0; i < 12; i++ )
|
||||
{
|
||||
idStr style = spawnArgs.GetString( va( "light_style%d", i ), predef_lightstyles[ i ] );
|
||||
light_styles.Append( style );
|
||||
}
|
||||
}
|
||||
// jmarshall end
|
||||
|
||||
triggercount = 0;
|
||||
|
||||
fadeFrom.Set( 1, 1, 1, 1 );
|
||||
|
@ -886,6 +920,104 @@ void idLight::Think()
|
|||
Present();
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
idLight::SharedThink
|
||||
================
|
||||
*/
|
||||
// jmarshall
|
||||
void idLight::SharedThink()
|
||||
{
|
||||
float lightval;
|
||||
int stringlength;
|
||||
float offset;
|
||||
int offsetwhole;
|
||||
int otime;
|
||||
int lastch, nextch;
|
||||
|
||||
if( lightStyle == -1 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if( lightStyle > light_styles.Num() )
|
||||
{
|
||||
//gameLocal.Error( "Light style out of range\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
idStr dl_stylestring = light_styles[lightStyle];
|
||||
|
||||
otime = gameLocal.time - lightStyleState.dl_time;
|
||||
stringlength = dl_stylestring.Length();
|
||||
|
||||
// it's been a long time since you were updated, lets assume a reset
|
||||
if( otime > 2 * lightStyleFrameTime )
|
||||
{
|
||||
otime = 0;
|
||||
lightStyleState.dl_frame = lightStyleState.dl_oldframe = 0;
|
||||
lightStyleState.dl_backlerp = 0;
|
||||
}
|
||||
|
||||
lightStyleState.dl_time = gameLocal.time;
|
||||
|
||||
offset = ( ( float )otime ) / lightStyleFrameTime;
|
||||
offsetwhole = ( int )offset;
|
||||
|
||||
lightStyleState.dl_backlerp += offset;
|
||||
|
||||
|
||||
if( lightStyleState.dl_backlerp > 1 ) // we're moving on to the next frame
|
||||
{
|
||||
lightStyleState.dl_oldframe = lightStyleState.dl_oldframe + ( int )lightStyleState.dl_backlerp;
|
||||
lightStyleState.dl_frame = lightStyleState.dl_oldframe + 1;
|
||||
if( lightStyleState.dl_oldframe >= stringlength )
|
||||
{
|
||||
lightStyleState.dl_oldframe = ( lightStyleState.dl_oldframe ) % stringlength;
|
||||
//if (cent->dl_oldframe < 3 && cent->dl_sound) { // < 3 so if an alarm comes back into the pvs it will only start a sound if it's going to be closely synced with the light, otherwise wait till the next cycle
|
||||
// engine->S_StartSound(NULL, cent->currentState.number, CHAN_AUTO, cgs.gameSounds[cent->dl_sound]);
|
||||
//}
|
||||
}
|
||||
|
||||
if( lightStyleState.dl_frame >= stringlength )
|
||||
{
|
||||
lightStyleState.dl_frame = ( lightStyleState.dl_frame ) % stringlength;
|
||||
}
|
||||
|
||||
lightStyleState.dl_backlerp = lightStyleState.dl_backlerp - ( int )lightStyleState.dl_backlerp;
|
||||
}
|
||||
|
||||
|
||||
lastch = dl_stylestring[lightStyleState.dl_oldframe] - 'a';
|
||||
nextch = dl_stylestring[lightStyleState.dl_frame] - 'a';
|
||||
|
||||
lightval = ( lastch * ( 1.0 - lightStyleState.dl_backlerp ) ) + ( nextch * lightStyleState.dl_backlerp );
|
||||
|
||||
// ydnar: dlight values go from 0-1.5ish
|
||||
#if 0
|
||||
lightval = ( lightval * ( 1000.0f / 24.0f ) ) - 200.0f; // they want 'm' as the "middle" value as 300
|
||||
lightval = max( 0.0f, lightval );
|
||||
lightval = min( 1000.0f, lightval );
|
||||
#else
|
||||
lightval *= 0.071429f;
|
||||
lightval = Max( 0.0f, lightval );
|
||||
lightval = Min( 20.0f, lightval );
|
||||
#endif
|
||||
|
||||
renderLight.lightRadius.x = lightval * lightStyleBase.x;
|
||||
renderLight.lightRadius.y = lightval * lightStyleBase.y;
|
||||
renderLight.lightRadius.z = lightval * lightStyleBase.z;
|
||||
|
||||
|
||||
if( !common->IsClient() )
|
||||
{
|
||||
BecomeActive( TH_THINK );
|
||||
}
|
||||
|
||||
PresentLightDefChange();
|
||||
}
|
||||
// jmarshall end
|
||||
|
||||
/*
|
||||
================
|
||||
idLight::ClientThink
|
||||
|
|
|
@ -41,6 +41,37 @@ extern const idEventDef EV_Light_GetLightParm;
|
|||
extern const idEventDef EV_Light_SetLightParm;
|
||||
extern const idEventDef EV_Light_SetLightParms;
|
||||
|
||||
// jmarshall
|
||||
struct rvmLightStyleState_t
|
||||
{
|
||||
rvmLightStyleState_t();
|
||||
|
||||
int dl_frame;
|
||||
float dl_framef;
|
||||
int dl_oldframe;
|
||||
int dl_time;
|
||||
float dl_backlerp;
|
||||
|
||||
void Reset();
|
||||
};
|
||||
|
||||
ID_INLINE rvmLightStyleState_t::rvmLightStyleState_t()
|
||||
{
|
||||
Reset();
|
||||
}
|
||||
|
||||
ID_INLINE void rvmLightStyleState_t::Reset()
|
||||
{
|
||||
dl_frame = 0;
|
||||
dl_framef = 0;
|
||||
dl_oldframe = 0;
|
||||
dl_time = 0;
|
||||
dl_backlerp = 0;
|
||||
}
|
||||
// jmarshall end
|
||||
|
||||
|
||||
|
||||
class idLight : public idEntity
|
||||
{
|
||||
public:
|
||||
|
@ -60,7 +91,9 @@ public:
|
|||
virtual void FreeLightDef();
|
||||
virtual bool GetPhysicsToSoundTransform( idVec3& origin, idMat3& axis );
|
||||
void Present();
|
||||
|
||||
// jmarshall
|
||||
virtual void SharedThink();
|
||||
// jmarshall end
|
||||
void SaveState( idDict* args );
|
||||
virtual void SetColor( float red, float green, float blue );
|
||||
virtual void SetColor( const idVec4& color );
|
||||
|
@ -122,6 +155,11 @@ private:
|
|||
|
||||
bool breakOnTrigger;
|
||||
int count;
|
||||
// jmarshall
|
||||
int lightStyle;
|
||||
int lightStyleFrameTime;
|
||||
idVec3 lightStyleBase;
|
||||
// jmarshall end
|
||||
int triggercount;
|
||||
idEntity* lightParent;
|
||||
idVec4 fadeFrom;
|
||||
|
@ -148,6 +186,11 @@ private:
|
|||
void Event_SetSoundHandles();
|
||||
void Event_FadeOut( float time );
|
||||
void Event_FadeIn( float time );
|
||||
|
||||
// jmarshall
|
||||
idList<idStr> light_styles;
|
||||
rvmLightStyleState_t lightStyleState;
|
||||
// jmarshall end
|
||||
};
|
||||
|
||||
#endif /* !__GAME_LIGHT_H__ */
|
||||
|
|
|
@ -246,6 +246,7 @@ public:
|
|||
const char* GetSuperclass() const;
|
||||
void FindUninitializedMemory();
|
||||
|
||||
virtual void SharedThink() { }
|
||||
void Save( idSaveGame* savefile ) const {};
|
||||
void Restore( idRestoreGame* savefile ) {};
|
||||
|
||||
|
|
|
@ -367,6 +367,40 @@ typedef enum
|
|||
|
||||
class idSoundEmitter;
|
||||
|
||||
// RB: predefined Quake 1 light styles
|
||||
static char* predef_lightstyles[] =
|
||||
{
|
||||
"m",
|
||||
"mmnmmommommnonmmonqnmmo",
|
||||
"abcdefghijklmnopqrstuvwxyzyxwvutsrqponmlkjihgfedcba",
|
||||
"mmmmmaaaaammmmmaaaaaabcdefgabcdefg",
|
||||
"mamamamamama",
|
||||
"jklmnopqrstuvwxyzyxwvutsrqponmlkj",
|
||||
"nmonqnmomnmomomno",
|
||||
"mmmaaaabcdefgmmmmaaaammmaamm",
|
||||
"mmmaaammmaaammmabcdefaaaammmmabcdefmmmaaaa",
|
||||
"aaaaaaaazzzzzzzz",
|
||||
"mmamammmmammamamaaamammma",
|
||||
"abcdefghijklmnopqrrqponmlkjihgfedcba"
|
||||
};
|
||||
|
||||
static char* predef_lightstylesinfo[] =
|
||||
{
|
||||
"Normal",
|
||||
"Flicker A",
|
||||
"Slow Strong Pulse",
|
||||
"Candle A",
|
||||
"Fast Strobe",
|
||||
"Gentle Pulse",
|
||||
"Flicker B",
|
||||
"Candle B",
|
||||
"Candle C",
|
||||
"Slow Strobe",
|
||||
"Fluorescent Flicker",
|
||||
"Slow Pulse (no black)"
|
||||
};
|
||||
// RB end
|
||||
|
||||
class idMaterial : public idDecl
|
||||
{
|
||||
public:
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
Doom 3 GPL Source Code
|
||||
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
|
||||
Copyright (C) 2015 Daniel Gibson
|
||||
Copyright (C) 2020-2021 Robert Beckebans
|
||||
|
||||
This file is part of the Doom 3 GPL Source Code ("Doom 3 Source Code").
|
||||
|
||||
|
@ -68,9 +69,9 @@ void LightInfo::Defaults()
|
|||
lightRadius.Zero();
|
||||
castShadows = true;
|
||||
castSpecular = true;
|
||||
castDiffuse = true;
|
||||
hasCenter = false;
|
||||
isParallel = false;
|
||||
lightStyle = -1;
|
||||
}
|
||||
|
||||
|
||||
|
@ -95,7 +96,6 @@ void LightInfo::DefaultProjected()
|
|||
|
||||
void LightInfo::FromDict( const idDict* e )
|
||||
{
|
||||
|
||||
lightRadius.Zero();
|
||||
lightTarget.Zero();
|
||||
lightRight.Zero();
|
||||
|
@ -106,7 +106,6 @@ void LightInfo::FromDict( const idDict* e )
|
|||
|
||||
castShadows = !e->GetBool( "noshadows" );
|
||||
castSpecular = !e->GetBool( "nospecular" );
|
||||
castDiffuse = !e->GetBool( "nodiffuse" );
|
||||
fallOff = e->GetFloat( "falloff" );
|
||||
strTexture = e->GetString( "texture" );
|
||||
|
||||
|
@ -176,6 +175,9 @@ void LightInfo::FromDict( const idDict* e )
|
|||
hasCenter = true;
|
||||
}
|
||||
}
|
||||
|
||||
// RB: Quake 1 light styles
|
||||
lightStyle = e->GetInt( "style", -1 );
|
||||
}
|
||||
|
||||
// the returned idDict is supposed to be used by idGameEdit::EntityChangeSpawnArgs()
|
||||
|
@ -190,7 +192,6 @@ void LightInfo::ToDict( idDict* e )
|
|||
|
||||
e->Set( "noshadows", ( !castShadows ) ? "1" : "0" );
|
||||
e->Set( "nospecular", ( !castSpecular ) ? "1" : "0" );
|
||||
e->Set( "nodiffuse", ( !castDiffuse ) ? "1" : "0" );
|
||||
|
||||
e->SetFloat( "falloff", fallOff );
|
||||
|
||||
|
@ -265,6 +266,16 @@ void LightInfo::ToDict( idDict* e )
|
|||
e->Set( "light_center", DELETE_VAL );
|
||||
e->Set( "parallel", DELETE_VAL );
|
||||
}
|
||||
|
||||
// RB: Quake 1 light styles
|
||||
if( lightStyle != -1 )
|
||||
{
|
||||
e->SetInt( "style", lightStyle );
|
||||
}
|
||||
else
|
||||
{
|
||||
e->Set( "style", DELETE_VAL );
|
||||
}
|
||||
}
|
||||
|
||||
LightInfo::LightInfo()
|
||||
|
@ -303,10 +314,14 @@ void LightEditor::Init( const idDict* dict, idEntity* light )
|
|||
LoadLightTextures();
|
||||
}
|
||||
|
||||
if( styleNames.Num() == 0 )
|
||||
{
|
||||
LoadLightStyles();
|
||||
}
|
||||
|
||||
if( dict )
|
||||
{
|
||||
original.FromDict( dict );
|
||||
//current = original;
|
||||
cur.FromDict( dict );
|
||||
|
||||
const char* name = dict->GetString( "name", NULL );
|
||||
|
@ -319,6 +334,7 @@ void LightEditor::Init( const idDict* dict, idEntity* light )
|
|||
{
|
||||
idassert( 0 && "LightEditor::Init(): Given entity has no 'name' property?!" );
|
||||
entityName = ""; // TODO: generate name or handle gracefully or something?
|
||||
title.Format( "Light Editor: <unnamed> light" );
|
||||
}
|
||||
|
||||
currentTextureIndex = 0;
|
||||
|
@ -336,6 +352,12 @@ void LightEditor::Init( const idDict* dict, idEntity* light )
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// RB: light styles
|
||||
if( original.lightStyle >= 0 )
|
||||
{
|
||||
currentStyleIndex = original.lightStyle + 1;
|
||||
}
|
||||
}
|
||||
this->lightEntity = light;
|
||||
}
|
||||
|
@ -348,6 +370,8 @@ void LightEditor::Reset()
|
|||
lightEntity = NULL;
|
||||
currentTextureIndex = 0;
|
||||
currentTexture = NULL;
|
||||
|
||||
currentStyleIndex = 0;
|
||||
}
|
||||
|
||||
namespace
|
||||
|
@ -365,37 +389,45 @@ public:
|
|||
void LightEditor::LoadLightTextures()
|
||||
{
|
||||
textureNames.Clear();
|
||||
|
||||
int count = declManager->GetNumDecls( DECL_MATERIAL );
|
||||
const idMaterial* mat;
|
||||
|
||||
for( int i = 0; i < count; i++ )
|
||||
{
|
||||
mat = declManager->MaterialByIndex( i, false );
|
||||
const idMaterial* mat = declManager->MaterialByIndex( i, false );
|
||||
|
||||
idStr str = mat->GetName();
|
||||
str.ToLower(); // FIXME: why? (this is from old doom3 code)
|
||||
|
||||
if( str.Icmpn( "lights/", strlen( "lights/" ) ) == 0 || str.Icmpn( "fogs/", strlen( "fogs/" ) ) == 0 )
|
||||
{
|
||||
textureNames.Append( str );
|
||||
}
|
||||
}
|
||||
|
||||
textureNames.SortWithTemplate( idSort_textureNames() );
|
||||
}
|
||||
|
||||
// static
|
||||
bool LightEditor::TextureItemsGetter( void* data, int idx, const char** out_text )
|
||||
bool LightEditor::TextureItemsGetter( void* data, int idx, const char** outText )
|
||||
{
|
||||
LightEditor* self = static_cast<LightEditor*>( data );
|
||||
if( idx == 0 )
|
||||
{
|
||||
*out_text = "<No Texture>";
|
||||
*outText = "<No Texture>";
|
||||
return true;
|
||||
}
|
||||
--idx; // as index 0 has special purpose, the "real" index is one less
|
||||
|
||||
// as index 0 has special purpose, the "real" index is one less
|
||||
--idx;
|
||||
|
||||
if( idx < 0 || idx >= self->textureNames.Num() )
|
||||
{
|
||||
*out_text = "<Invalid Index!>";
|
||||
*outText = "<Invalid Index!>";
|
||||
return false;
|
||||
}
|
||||
*out_text = self->textureNames[idx].c_str();
|
||||
|
||||
*outText = self->textureNames[idx].c_str();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -403,6 +435,7 @@ bool LightEditor::TextureItemsGetter( void* data, int idx, const char** out_text
|
|||
void LightEditor::LoadCurrentTexture()
|
||||
{
|
||||
currentTexture = NULL;
|
||||
|
||||
if( currentTextureIndex > 0 && cur.strTexture.Length() > 0 )
|
||||
{
|
||||
const idMaterial* mat = declManager->FindMaterial( cur.strTexture, false );
|
||||
|
@ -413,12 +446,67 @@ void LightEditor::LoadCurrentTexture()
|
|||
}
|
||||
}
|
||||
|
||||
void LightEditor::LoadLightStyles()
|
||||
{
|
||||
styleNames.Clear();
|
||||
|
||||
const idDeclEntityDef* decl = static_cast<const idDeclEntityDef*>( declManager->FindType( DECL_ENTITYDEF, "light", false ) );
|
||||
if( decl == NULL )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int numStyles = decl->dict.GetInt( "num_styles", "0" );
|
||||
if( numStyles > 0 )
|
||||
{
|
||||
for( int i = 0; i < numStyles; i++ )
|
||||
{
|
||||
idStr style = decl->dict.GetString( va( "light_style%d", i ) );
|
||||
styleNames.Append( style );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// RB: it's not defined in entityDef light so use predefined Quake 1 table
|
||||
for( int i = 0; i < 12; i++ )
|
||||
{
|
||||
idStr style( predef_lightstylesinfo[ i ] );
|
||||
styleNames.Append( style );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
bool LightEditor::StyleItemsGetter( void* data, int idx, const char** outText )
|
||||
{
|
||||
LightEditor* self = static_cast<LightEditor*>( data );
|
||||
if( idx == 0 )
|
||||
{
|
||||
*outText = "<No Lightstyle>";
|
||||
return true;
|
||||
}
|
||||
|
||||
// as index 0 has special purpose, the "real" index is one less
|
||||
--idx;
|
||||
|
||||
if( idx < 0 || idx >= self->styleNames.Num() )
|
||||
{
|
||||
*outText = "<Invalid Index!>";
|
||||
return false;
|
||||
}
|
||||
|
||||
*outText = self->styleNames[idx].c_str();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void LightEditor::TempApplyChanges()
|
||||
{
|
||||
if( lightEntity != NULL )
|
||||
{
|
||||
idDict d;
|
||||
cur.ToDict( &d );
|
||||
|
||||
gameEdit->EntityChangeSpawnArgs( lightEntity, &d );
|
||||
gameEdit->EntityUpdateChangeableSpawnArgs( lightEntity, NULL );
|
||||
}
|
||||
|
@ -448,6 +536,7 @@ void LightEditor::SaveChanges()
|
|||
gameEdit->MapAddEntity( &d );
|
||||
#endif // 0
|
||||
}
|
||||
|
||||
gameEdit->MapSave();
|
||||
}
|
||||
|
||||
|
@ -457,6 +546,7 @@ void LightEditor::CancelChanges()
|
|||
{
|
||||
idDict d;
|
||||
original.ToDict( &d );
|
||||
|
||||
gameEdit->EntityChangeSpawnArgs( lightEntity, &d );
|
||||
gameEdit->EntityUpdateChangeableSpawnArgs( lightEntity, NULL );
|
||||
}
|
||||
|
@ -476,8 +566,7 @@ void LightEditor::DrawWindow()
|
|||
bool changes = false;
|
||||
|
||||
changes |= ImGui::Checkbox( "Cast Shadows", &cur.castShadows );
|
||||
ImGui::SameLine();
|
||||
changes |= ImGui::Checkbox( "Cast Diffuse", &cur.castDiffuse );
|
||||
//ImGui::SameLine();
|
||||
changes |= ImGui::Checkbox( "Cast Specular", &cur.castSpecular );
|
||||
|
||||
ImGui::Spacing();
|
||||
|
@ -573,9 +662,20 @@ void LightEditor::DrawWindow()
|
|||
|
||||
ImGui::Unindent();
|
||||
|
||||
if( ImGui::Combo( "Style", ¤tStyleIndex, StyleItemsGetter, this, styleNames.Num() + 1 ) )
|
||||
{
|
||||
changes = true;
|
||||
|
||||
// -1 because 0 is "<No Lightstyle>"
|
||||
cur.lightStyle = ( currentStyleIndex > 0 ) ? currentStyleIndex - 1 : -1;
|
||||
}
|
||||
|
||||
ImGui::Spacing();
|
||||
|
||||
if( ImGui::Combo( "Texture", ¤tTextureIndex, TextureItemsGetter, this, textureNames.Num() + 1 ) )
|
||||
{
|
||||
changes = true;
|
||||
|
||||
// -1 because 0 is "<No Texture>"
|
||||
cur.strTexture = ( currentTextureIndex > 0 ) ? textureNames[currentTextureIndex - 1] : "";
|
||||
LoadCurrentTexture();
|
||||
|
@ -592,6 +692,8 @@ void LightEditor::DrawWindow()
|
|||
// then only the changed attribute (e.g. color) would be set to all lights,
|
||||
// but they'd keep their other individual properties (eg radius)
|
||||
|
||||
ImGui::Spacing();
|
||||
|
||||
if( ImGui::Button( "Save to .map" ) )
|
||||
{
|
||||
SaveChanges();
|
||||
|
|
|
@ -70,9 +70,9 @@ public:
|
|||
idVec3 lightRadius;
|
||||
bool castShadows;
|
||||
bool castSpecular;
|
||||
bool castDiffuse;
|
||||
bool hasCenter;
|
||||
bool isParallel;
|
||||
int lightStyle;
|
||||
|
||||
LightInfo();
|
||||
|
||||
|
@ -85,6 +85,7 @@ public:
|
|||
|
||||
class LightEditor
|
||||
{
|
||||
private:
|
||||
idStr title;
|
||||
idStr entityName;
|
||||
LightInfo original;
|
||||
|
@ -96,6 +97,13 @@ class LightEditor
|
|||
int currentTextureIndex;
|
||||
idImage* currentTexture;
|
||||
|
||||
// RB: light style support
|
||||
idList<idStr> styleNames;
|
||||
int currentStyleIndex;
|
||||
|
||||
void LoadLightStyles();
|
||||
static bool StyleItemsGetter( void* data, int idx, const char** out_text );
|
||||
|
||||
void Init( const idDict* dict, idEntity* light );
|
||||
void Reset();
|
||||
|
||||
|
|
Loading…
Reference in a new issue