mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-07-22 20:59:19 +02:00
build 210508. spring brake sound support, internaldata sounds update fix, minor bug fixes
This commit is contained in:
@@ -2709,10 +2709,11 @@ bool TController::PrepareEngine()
|
|||||||
cue_action( locale::string::driver_hint_pantographcompressoroff ); // sprężarkę pantografów można już wyłączyć
|
cue_action( locale::string::driver_hint_pantographcompressoroff ); // sprężarkę pantografów można już wyłączyć
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// TODO: make pantograph setup a part of control_pantographs() and call it here instead
|
||||||
if( ( fOverhead2 == -1.0 ) && ( iOverheadDown == 0 ) ) {
|
if( ( fOverhead2 == -1.0 ) && ( iOverheadDown == 0 ) ) {
|
||||||
cue_action( locale::string::driver_hint_pantographsvalveon );
|
cue_action( locale::string::driver_hint_pantographsvalveon );
|
||||||
cue_action( locale::string::driver_hint_frontpantographvalveon );
|
cue_action( locale::string::driver_hint_frontpantographvalveon, ( iDirection >= 0 ? 5 : 0 ) );
|
||||||
cue_action( locale::string::driver_hint_rearpantographvalveon );
|
cue_action( locale::string::driver_hint_rearpantographvalveon, ( iDirection >= 0 ? 0 : 5 ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
24
DynObj.cpp
24
DynObj.cpp
@@ -4209,7 +4209,7 @@ void TDynamicObject::RenderSounds() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Dzwiek odluzniacza
|
// Dzwiek odluzniacza
|
||||||
if( MoverParameters->Hamulec->GetStatus() & b_rls ) {
|
if( MoverParameters->Hamulec->Releaser() ) {
|
||||||
sReleaser
|
sReleaser
|
||||||
.gain(
|
.gain(
|
||||||
clamp<float>(
|
clamp<float>(
|
||||||
@@ -4294,6 +4294,19 @@ void TDynamicObject::RenderSounds() {
|
|||||||
rsPisk.stop();
|
rsPisk.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// spring brake
|
||||||
|
if( m_springbrakesounds.state != MoverParameters->SpringBrake.Activate ) {
|
||||||
|
m_springbrakesounds.state = MoverParameters->SpringBrake.Activate;
|
||||||
|
if( m_springbrakesounds.state ) {
|
||||||
|
m_springbrakesounds.activate.play( sound_flags::exclusive );
|
||||||
|
m_springbrakesounds.release.stop();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
m_springbrakesounds.activate.stop();
|
||||||
|
m_springbrakesounds.release.play( sound_flags::exclusive );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// other sounds
|
// other sounds
|
||||||
// load exchange
|
// load exchange
|
||||||
if( MoverParameters->LoadStatus & 1 ) {
|
if( MoverParameters->LoadStatus & 1 ) {
|
||||||
@@ -5702,6 +5715,15 @@ void TDynamicObject::LoadMMediaFile( std::string const &TypeName, std::string co
|
|||||||
rsUnbrake.deserialize( parser, sound_type::single, sound_parameters::range );
|
rsUnbrake.deserialize( parser, sound_type::single, sound_parameters::range );
|
||||||
rsUnbrake.owner( this );
|
rsUnbrake.owner( this );
|
||||||
}
|
}
|
||||||
|
// spring brake sounds
|
||||||
|
else if( token == "springbrake:" ) {
|
||||||
|
m_springbrakesounds.activate.deserialize( parser, sound_type::single );
|
||||||
|
m_springbrakesounds.activate.owner( this );
|
||||||
|
}
|
||||||
|
else if( token == "springbrakeoff:" ) {
|
||||||
|
m_springbrakesounds.release.deserialize( parser, sound_type::single );
|
||||||
|
m_springbrakesounds.release.owner( this );
|
||||||
|
}
|
||||||
|
|
||||||
else if( token == "derail:" ) {
|
else if( token == "derail:" ) {
|
||||||
// dzwiek przy wykolejeniu
|
// dzwiek przy wykolejeniu
|
||||||
|
|||||||
7
DynObj.h
7
DynObj.h
@@ -421,6 +421,12 @@ private:
|
|||||||
sound_source announcement;
|
sound_source announcement;
|
||||||
std::deque<sound_source> announcement_queue; // fifo queue
|
std::deque<sound_source> announcement_queue; // fifo queue
|
||||||
};
|
};
|
||||||
|
struct springbrake_sounds {
|
||||||
|
sound_source activate { sound_placement::external };
|
||||||
|
sound_source release { sound_placement::external };
|
||||||
|
bool state { false };
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
// methods
|
// methods
|
||||||
void ABuLittleUpdate(double ObjSqrDist);
|
void ABuLittleUpdate(double ObjSqrDist);
|
||||||
@@ -496,6 +502,7 @@ private:
|
|||||||
sound_source m_emergencybrake { sound_placement::engine };
|
sound_source m_emergencybrake { sound_placement::engine };
|
||||||
double m_emergencybrakeflow{ 0.f };
|
double m_emergencybrakeflow{ 0.f };
|
||||||
sound_source sReleaser { sound_placement::external };
|
sound_source sReleaser { sound_placement::external };
|
||||||
|
springbrake_sounds m_springbrakesounds;
|
||||||
sound_source rsSlippery { sound_placement::external, EU07_SOUND_BRAKINGCUTOFFRANGE }; // moved from cab
|
sound_source rsSlippery { sound_placement::external, EU07_SOUND_BRAKINGCUTOFFRANGE }; // moved from cab
|
||||||
sound_source sSand { sound_placement::external };
|
sound_source sSand { sound_placement::external };
|
||||||
// moving part and other external sounds
|
// moving part and other external sounds
|
||||||
|
|||||||
41
Gauge.cpp
41
Gauge.cpp
@@ -286,25 +286,25 @@ TGauge::Load_mapping( cParser &Input, TGauge::scratch_data &Scratchpad ) {
|
|||||||
return true; // return value marks a key: value pair was extracted, nothing about whether it's recognized
|
return true; // return value marks a key: value pair was extracted, nothing about whether it's recognized
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
TGauge::UpdateValue( float fNewDesired ) {
|
|
||||||
|
|
||||||
return UpdateValue( fNewDesired, nullptr );
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
TGauge::UpdateValue( float fNewDesired, sound_source &Fallbacksound ) {
|
|
||||||
|
|
||||||
return UpdateValue( fNewDesired, &Fallbacksound );
|
|
||||||
}
|
|
||||||
|
|
||||||
// ustawienie wartości docelowej. plays provided fallback sound, if no sound was defined in the control itself
|
// ustawienie wartości docelowej. plays provided fallback sound, if no sound was defined in the control itself
|
||||||
void
|
bool
|
||||||
TGauge::UpdateValue( float fNewDesired, sound_source *Fallbacksound ) {
|
TGauge::UpdateValue( float fNewDesired, std::optional<sound_source> &Fallbacksound ) {
|
||||||
|
|
||||||
|
if( false == UpdateValue( fNewDesired ) ) {
|
||||||
|
if( Fallbacksound ) {
|
||||||
|
Fallbacksound->play( m_soundtype );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
TGauge::UpdateValue( float fNewDesired ) {
|
||||||
|
|
||||||
auto const desiredtimes100 = static_cast<int>( std::round( 100.0 * fNewDesired ) );
|
auto const desiredtimes100 = static_cast<int>( std::round( 100.0 * fNewDesired ) );
|
||||||
if( desiredtimes100 == static_cast<int>( std::round( 100.0 * m_targetvalue ) ) ) {
|
if( desiredtimes100 == static_cast<int>( std::round( 100.0 * m_targetvalue ) ) ) {
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
m_targetvalue = fNewDesired;
|
m_targetvalue = fNewDesired;
|
||||||
// if there's any sound associated with new requested value, play it
|
// if there's any sound associated with new requested value, play it
|
||||||
@@ -315,7 +315,7 @@ TGauge::UpdateValue( float fNewDesired, sound_source *Fallbacksound ) {
|
|||||||
auto const lookup = m_soundfxvalues.find( desiredtimes100 / 100 );
|
auto const lookup = m_soundfxvalues.find( desiredtimes100 / 100 );
|
||||||
if( lookup != m_soundfxvalues.end() ) {
|
if( lookup != m_soundfxvalues.end() ) {
|
||||||
lookup->second.play();
|
lookup->second.play();
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -329,20 +329,17 @@ TGauge::UpdateValue( float fNewDesired, sound_source *Fallbacksound ) {
|
|||||||
// shift up
|
// shift up
|
||||||
if( false == m_soundfxincrease.empty() ) {
|
if( false == m_soundfxincrease.empty() ) {
|
||||||
m_soundfxincrease.play( m_soundtype );
|
m_soundfxincrease.play( m_soundtype );
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if( currentvalue > fNewDesired ) {
|
else if( currentvalue > fNewDesired ) {
|
||||||
// shift down
|
// shift down
|
||||||
if( false == m_soundfxdecrease.empty() ) {
|
if( false == m_soundfxdecrease.empty() ) {
|
||||||
m_soundfxdecrease.play( m_soundtype );
|
m_soundfxdecrease.play( m_soundtype );
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( Fallbacksound != nullptr ) {
|
return false; // no suitable sound was found
|
||||||
// ...and if that fails too, try the provided fallback sound from legacy system
|
|
||||||
Fallbacksound->play( m_soundtype );
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void TGauge::PutValue(float fNewDesired)
|
void TGauge::PutValue(float fNewDesired)
|
||||||
|
|||||||
6
Gauge.h
6
Gauge.h
@@ -43,8 +43,8 @@ public:
|
|||||||
*this = TGauge(); }
|
*this = TGauge(); }
|
||||||
void Init(TSubModel *Submodel, TSubModel *Submodelon, TGaugeAnimation Type, float Scale = 1, float Offset = 0, float Friction = 0, float Value = 0, float const Endvalue = -1.0, float const Endscale = -1.0, bool const Interpolate = false );
|
void Init(TSubModel *Submodel, TSubModel *Submodelon, TGaugeAnimation Type, float Scale = 1, float Offset = 0, float Friction = 0, float Value = 0, float const Endvalue = -1.0, float const Endscale = -1.0, bool const Interpolate = false );
|
||||||
void Load(cParser &Parser, TDynamicObject const *Owner, double const mul = 1.0);
|
void Load(cParser &Parser, TDynamicObject const *Owner, double const mul = 1.0);
|
||||||
void UpdateValue( float fNewDesired );
|
bool UpdateValue( float fNewDesired );
|
||||||
void UpdateValue( float fNewDesired, sound_source &Fallbacksound );
|
bool UpdateValue( float fNewDesired, std::optional<sound_source> &Fallbacksound );
|
||||||
void PutValue(float fNewDesired);
|
void PutValue(float fNewDesired);
|
||||||
float GetValue() const;
|
float GetValue() const;
|
||||||
float GetDesiredValue() const;
|
float GetDesiredValue() const;
|
||||||
@@ -79,8 +79,6 @@ private:
|
|||||||
// imports member data pair from the config file
|
// imports member data pair from the config file
|
||||||
bool
|
bool
|
||||||
Load_mapping( cParser &Input, TGauge::scratch_data &Scratchpad );
|
Load_mapping( cParser &Input, TGauge::scratch_data &Scratchpad );
|
||||||
void
|
|
||||||
UpdateValue( float fNewDesired, sound_source *Fallbacksound );
|
|
||||||
float
|
float
|
||||||
GetScaledValue() const;
|
GetScaledValue() const;
|
||||||
void
|
void
|
||||||
|
|||||||
652
Train.cpp
652
Train.cpp
@@ -671,32 +671,33 @@ dictionary_source *TTrain::GetTrainState( dictionary_source const &Extraparamete
|
|||||||
for( int j = 0; j < 10; ++j )
|
for( int j = 0; j < 10; ++j )
|
||||||
dict->insert( ( "eimp_t_" + std::string( TXTT[ j ] ) ), fEIMParams[ 0 ][ j ] );
|
dict->insert( ( "eimp_t_" + std::string( TXTT[ j ] ) ), fEIMParams[ 0 ][ j ] );
|
||||||
for( int i = 0; i < 8; ++i ) {
|
for( int i = 0; i < 8; ++i ) {
|
||||||
|
auto const idx { std::to_string( i + 1 ) };
|
||||||
for( int j = 0; j < 10; ++j )
|
for( int j = 0; j < 10; ++j )
|
||||||
dict->insert( ( "eimp_c" + std::to_string( i + 1 ) + "_" + std::string( TXTC[ j ] ) ), fEIMParams[ i + 1 ][ j ] );
|
dict->insert( ( "eimp_c" + idx + "_" + std::string( TXTC[ j ] ) ), fEIMParams[ i + 1 ][ j ] );
|
||||||
|
|
||||||
for (int j = 0; j < 10; ++j)
|
for (int j = 0; j < 10; ++j)
|
||||||
dict->insert(("diesel_param_" + std::to_string(i + 1) + "_" + std::string(TXTD[j])), fDieselParams[i + 1][j]);
|
dict->insert(("diesel_param_" + idx + "_" + std::string(TXTD[j])), fDieselParams[i + 1][j]);
|
||||||
|
|
||||||
dict->insert( ( "eimp_c" + std::to_string( i + 1 ) + "_ms" ), bMains[ i ] );
|
dict->insert( ( "eimp_c" + idx + "_ms" ), bMains[ i ] );
|
||||||
dict->insert( ( "eimp_c" + std::to_string( i + 1 ) + "_cv" ), fCntVol[ i ] );
|
dict->insert( ( "eimp_c" + idx + "_cv" ), fCntVol[ i ] );
|
||||||
dict->insert( ( "eimp_u" + std::to_string( i + 1 ) + "_pf" ), bPants[ i ][ 0 ] );
|
dict->insert( ( "eimp_c" + idx + "_fuse" ), bFuse[ i ] );
|
||||||
dict->insert( ( "eimp_u" + std::to_string( i + 1 ) + "_pr" ), bPants[ i ][ 1 ] );
|
dict->insert( ( "eimp_c" + idx + "_batt" ), bBatt[ i ] );
|
||||||
dict->insert( ( "eimp_c" + std::to_string( i + 1 ) + "_fuse" ), bFuse[ i ] );
|
dict->insert( ( "eimp_c" + idx + "_conv" ), bConv[ i ] );
|
||||||
dict->insert( ( "eimp_c" + std::to_string( i + 1 ) + "_batt" ), bBatt[ i ] );
|
dict->insert( ( "eimp_c" + idx + "_heat" ), bHeat[ i ] );
|
||||||
dict->insert( ( "eimp_c" + std::to_string( i + 1 ) + "_conv" ), bConv[ i ] );
|
|
||||||
dict->insert( ( "eimp_u" + std::to_string( i + 1 ) + "_comp_a" ), bComp[ i ][ 0 ] );
|
dict->insert( ( "eimp_u" + idx + "_pf" ), bPants[ i ][ 0 ] );
|
||||||
dict->insert( ( "eimp_u" + std::to_string( i + 1 ) + "_comp_w" ), bComp[ i ][ 1 ] );
|
dict->insert( ( "eimp_u" + idx + "_pr" ), bPants[ i ][ 1 ] );
|
||||||
//dict->insert( ( "eimp_c" + std::to_string( i + 1 ) + "_comp_a" ), bComp[ i ][ 2 ]);
|
dict->insert( ( "eimp_u" + idx + "_comp_a" ), bComp[ i ][ 0 ] );
|
||||||
//dict->insert( ( "eimp_c" + std::to_string( i + 1 ) + "_comp_w" ), bComp[ i ][ 3 ]);
|
dict->insert( ( "eimp_u" + idx + "_comp_w" ), bComp[ i ][ 1 ] );
|
||||||
dict->insert( ( "eimp_c" + std::to_string( i + 1 ) + "_heat" ), bHeat[ i ] );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dict->insert( "compressors_no", (int)bCompressors.size() );
|
dict->insert( "compressors_no", (int)bCompressors.size() );
|
||||||
for (int i = 0; i < bCompressors.size(); i++)
|
for (int i = 0; i < bCompressors.size(); i++)
|
||||||
{
|
{
|
||||||
dict->insert("compressors_" + std::to_string(i + 1) + "_allow", std::get<0>(bCompressors[i]));
|
auto const idx { std::to_string( i + 1 ) };
|
||||||
dict->insert("compressors_" + std::to_string(i + 1) + "_work", std::get<1>(bCompressors[i]));
|
dict->insert("compressors_" + idx + "_allow", std::get<0>(bCompressors[i]));
|
||||||
dict->insert("compressors_" + std::to_string(i + 1) + "_car_no", std::get<2>(bCompressors[i]));
|
dict->insert("compressors_" + idx + "_work", std::get<1>(bCompressors[i]));
|
||||||
|
dict->insert("compressors_" + idx + "_car_no", std::get<2>(bCompressors[i]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -856,7 +857,9 @@ void TTrain::set_train_brake( double const Position ) {
|
|||||||
( ( originalbrakeposition / 100 == 0 ) || ( originalbrakeposition / 100 >= 5 ) )
|
( ( originalbrakeposition / 100 == 0 ) || ( originalbrakeposition / 100 >= 5 ) )
|
||||||
&& ( ( mvOccupied->BrakeCtrlPos == 0 ) || ( mvOccupied->BrakeCtrlPos >= 5 ) ) ) ) ) {
|
&& ( ( mvOccupied->BrakeCtrlPos == 0 ) || ( mvOccupied->BrakeCtrlPos >= 5 ) ) ) ) ) {
|
||||||
// sound feedback if the lever movement activates one of the switches
|
// sound feedback if the lever movement activates one of the switches
|
||||||
dsbPneumaticSwitch.play();
|
if( dsbPneumaticSwitch ) {
|
||||||
|
dsbPneumaticSwitch->play();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1839,7 +1842,9 @@ void TTrain::OnCommand_epbrakecontroltoggle( TTrain *Train, command_data const &
|
|||||||
// turn on
|
// turn on
|
||||||
if( Train->mvOccupied->EpFuseSwitch( true ) ) {
|
if( Train->mvOccupied->EpFuseSwitch( true ) ) {
|
||||||
// audio feedback
|
// audio feedback
|
||||||
Train->dsbPneumaticSwitch.play();
|
if( Train->dsbPneumaticSwitch ) {
|
||||||
|
Train->dsbPneumaticSwitch->play();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -1851,7 +1856,9 @@ void TTrain::OnCommand_epbrakecontroltoggle( TTrain *Train, command_data const &
|
|||||||
// potentially turn on
|
// potentially turn on
|
||||||
if( Train->mvOccupied->EpFuseSwitch( true ) ) {
|
if( Train->mvOccupied->EpFuseSwitch( true ) ) {
|
||||||
// audio feedback
|
// audio feedback
|
||||||
Train->dsbPneumaticSwitch.play();
|
if( Train->dsbPneumaticSwitch ) {
|
||||||
|
Train->dsbPneumaticSwitch->play();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
// visual feedback
|
// visual feedback
|
||||||
@@ -6379,23 +6386,27 @@ bool TTrain::Update( double const Deltatime )
|
|||||||
bPants[iUnitNo - 1][end::front] = ( bPants[iUnitNo - 1][end::front] || p->MoverParameters->Pantographs[end::front].is_active );
|
bPants[iUnitNo - 1][end::front] = ( bPants[iUnitNo - 1][end::front] || p->MoverParameters->Pantographs[end::front].is_active );
|
||||||
bPants[iUnitNo - 1][end::rear] = ( bPants[iUnitNo - 1][end::rear] || p->MoverParameters->Pantographs[end::rear].is_active );
|
bPants[iUnitNo - 1][end::rear] = ( bPants[iUnitNo - 1][end::rear] || p->MoverParameters->Pantographs[end::rear].is_active );
|
||||||
}
|
}
|
||||||
|
// TBD, TODO: clean up compressor data arrangement?
|
||||||
|
if( iUnitNo <= 8 ) {
|
||||||
bComp[iUnitNo - 1][0] = (bComp[iUnitNo - 1][0] || p->MoverParameters->CompressorAllow || (p->MoverParameters->CompressorStart == start_t::automatic));
|
bComp[iUnitNo - 1][0] = (bComp[iUnitNo - 1][0] || p->MoverParameters->CompressorAllow || (p->MoverParameters->CompressorStart == start_t::automatic));
|
||||||
bSlip[i] = p->MoverParameters->SlippingWheels;
|
}
|
||||||
if (p->MoverParameters->CompressorSpeed > 0.00001)
|
if (p->MoverParameters->CompressorSpeed > 0.00001)
|
||||||
{
|
{
|
||||||
|
if( iUnitNo <= 8 ) {
|
||||||
bComp[iUnitNo - 1][1] = (bComp[iUnitNo - 1][1] || p->MoverParameters->CompressorFlag);
|
bComp[iUnitNo - 1][1] = (bComp[iUnitNo - 1][1] || p->MoverParameters->CompressorFlag);
|
||||||
|
}
|
||||||
bCompressors.emplace_back(
|
bCompressors.emplace_back(
|
||||||
p->MoverParameters->CompressorAllow || (p->MoverParameters->CompressorStart == start_t::automatic),
|
p->MoverParameters->CompressorAllow || (p->MoverParameters->CompressorStart == start_t::automatic),
|
||||||
p->MoverParameters->CompressorFlag,
|
p->MoverParameters->CompressorFlag,
|
||||||
i);
|
i);
|
||||||
}
|
}
|
||||||
|
bSlip[i] = p->MoverParameters->SlippingWheels;
|
||||||
if ((in < 8) && (p->MoverParameters->eimc[eimc_p_Pmax] > 1))
|
if ((in < 8) && (p->MoverParameters->eimc[eimc_p_Pmax] > 1))
|
||||||
{
|
{
|
||||||
fEIMParams[1 + in][0] = p->MoverParameters->eimv[eimv_Fmax];
|
fEIMParams[1 + in][0] = p->MoverParameters->eimv[eimv_Fmax];
|
||||||
fEIMParams[1 + in][1] = Max0R(fEIMParams[1 + in][0], 0);
|
fEIMParams[1 + in][1] = Max0R(fEIMParams[1 + in][0], 0);
|
||||||
fEIMParams[1 + in][2] = -Min0R(fEIMParams[1 + in][0], 0);
|
fEIMParams[1 + in][2] = -Min0R(fEIMParams[1 + in][0], 0);
|
||||||
fEIMParams[1 + in][3] = p->MoverParameters->eimv[eimv_Fmax] /
|
fEIMParams[1 + in][3] = p->MoverParameters->eimv[eimv_Fmax] / Max0R(p->MoverParameters->eimv[eimv_Fful], 1);
|
||||||
Max0R(p->MoverParameters->eimv[eimv_Fful], 1);
|
|
||||||
fEIMParams[1 + in][4] = Max0R(fEIMParams[1 + in][3], 0);
|
fEIMParams[1 + in][4] = Max0R(fEIMParams[1 + in][3], 0);
|
||||||
fEIMParams[1 + in][5] = -Min0R(fEIMParams[1 + in][3], 0);
|
fEIMParams[1 + in][5] = -Min0R(fEIMParams[1 + in][3], 0);
|
||||||
fEIMParams[1 + in][6] = p->MoverParameters->eimv[eimv_If];
|
fEIMParams[1 + in][6] = p->MoverParameters->eimv[eimv_If];
|
||||||
@@ -6437,10 +6448,9 @@ bool TTrain::Update( double const Deltatime )
|
|||||||
in++;
|
in++;
|
||||||
iPowerNo = in;
|
iPowerNo = in;
|
||||||
}
|
}
|
||||||
// p = p->NextC(4); //prev
|
if ((kier ? p->NextC(coupling::permanent) : p->PrevC(coupling::permanent)) != (kier ? p->NextC(coupling::control) : p->PrevC(coupling::control)))
|
||||||
if ((kier ? p->NextC(128) : p->PrevC(128)) != (kier ? p->NextC(4) : p->PrevC(4)))
|
|
||||||
iUnitNo++;
|
iUnitNo++;
|
||||||
p = (kier ? p->NextC(4) : p->PrevC(4));
|
p = (kier ? p->NextC(coupling::control) : p->PrevC(coupling::control));
|
||||||
iCarNo = i + 1;
|
iCarNo = i + 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -7437,32 +7447,34 @@ TTrain::update_sounds( double const Deltatime ) {
|
|||||||
}
|
}
|
||||||
m_lastlocalbrakepressure = mvOccupied->LocBrakePress;
|
m_lastlocalbrakepressure = mvOccupied->LocBrakePress;
|
||||||
// local brake, release
|
// local brake, release
|
||||||
|
if( rsSBHiss ) {
|
||||||
if( ( m_localbrakepressurechange < -0.05f )
|
if( ( m_localbrakepressurechange < -0.05f )
|
||||||
&& ( mvOccupied->LocBrakePress > mvOccupied->BrakePress - 0.05 ) ) {
|
&& ( mvOccupied->LocBrakePress > mvOccupied->BrakePress - 0.05 ) ) {
|
||||||
rsSBHiss
|
rsSBHiss->gain( clamp( rsSBHiss->m_amplitudeoffset + rsSBHiss->m_amplitudefactor * -m_localbrakepressurechange * 0.05, 0.0, 1.5 ) );
|
||||||
.gain( clamp( rsSBHiss.m_amplitudeoffset + rsSBHiss.m_amplitudefactor * -m_localbrakepressurechange * 0.05, 0.0, 1.5 ) )
|
rsSBHiss->play( sound_flags::exclusive | sound_flags::looping );
|
||||||
.play( sound_flags::exclusive | sound_flags::looping );
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// don't stop the sound too abruptly
|
// don't stop the sound too abruptly
|
||||||
volume = std::max( 0.0, rsSBHiss.gain() - 0.1 * Deltatime );
|
volume = std::max( 0.0, rsSBHiss->gain() - 0.1 * Deltatime );
|
||||||
rsSBHiss.gain( volume );
|
rsSBHiss->gain( volume );
|
||||||
if( volume < 0.05 ) {
|
if( volume < 0.05 ) {
|
||||||
rsSBHiss.stop();
|
rsSBHiss->stop();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// local brake, engage
|
// local brake, engage
|
||||||
|
if( rsSBHissU ) {
|
||||||
if( m_localbrakepressurechange > 0.05f ) {
|
if( m_localbrakepressurechange > 0.05f ) {
|
||||||
rsSBHissU
|
rsSBHissU->gain( clamp( rsSBHissU->m_amplitudeoffset + rsSBHissU->m_amplitudefactor * m_localbrakepressurechange * 0.05, 0.0, 1.5 ) );
|
||||||
.gain( clamp( rsSBHissU.m_amplitudeoffset + rsSBHissU.m_amplitudefactor * m_localbrakepressurechange * 0.05, 0.0, 1.5 ) )
|
rsSBHissU->play( sound_flags::exclusive | sound_flags::looping );
|
||||||
.play( sound_flags::exclusive | sound_flags::looping );
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// don't stop the sound too abruptly
|
// don't stop the sound too abruptly
|
||||||
volume = std::max( 0.0, rsSBHissU.gain() - 0.1 * Deltatime );
|
volume = std::max( 0.0, rsSBHissU->gain() - 0.1 * Deltatime );
|
||||||
rsSBHissU.gain( volume );
|
rsSBHissU->gain( volume );
|
||||||
if( volume < 0.05 ) {
|
if( volume < 0.05 ) {
|
||||||
rsSBHissU.stop();
|
rsSBHissU->stop();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -7471,97 +7483,105 @@ TTrain::update_sounds( double const Deltatime ) {
|
|||||||
if( ( mvOccupied->BrakeHandle == TBrakeHandle::FV4a )
|
if( ( mvOccupied->BrakeHandle == TBrakeHandle::FV4a )
|
||||||
|| ( mvOccupied->BrakeHandle == TBrakeHandle::FVel6 ) ) {
|
|| ( mvOccupied->BrakeHandle == TBrakeHandle::FVel6 ) ) {
|
||||||
// upuszczanie z PG
|
// upuszczanie z PG
|
||||||
|
if( rsHiss ) {
|
||||||
fPPress = interpolate( fPPress, static_cast<float>( mvOccupied->Handle->GetSound( s_fv4a_b ) ), 0.05f );
|
fPPress = interpolate( fPPress, static_cast<float>( mvOccupied->Handle->GetSound( s_fv4a_b ) ), 0.05f );
|
||||||
volume = (
|
volume = (
|
||||||
fPPress > 0 ?
|
fPPress > 0 ?
|
||||||
rsHiss.m_amplitudefactor * fPPress * 0.25 :
|
rsHiss->m_amplitudefactor * fPPress * 0.25 :
|
||||||
0 );
|
0 );
|
||||||
if( volume * brakevolumescale > 0.05 ) {
|
if( volume * brakevolumescale > 0.05 ) {
|
||||||
rsHiss
|
rsHiss->gain( volume * brakevolumescale );
|
||||||
.gain( volume * brakevolumescale )
|
rsHiss->play( sound_flags::exclusive | sound_flags::looping );
|
||||||
.play( sound_flags::exclusive | sound_flags::looping );
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
rsHiss.stop();
|
rsHiss->stop();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// napelnianie PG
|
// napelnianie PG
|
||||||
|
if( rsHissU ) {
|
||||||
fNPress = interpolate( fNPress, static_cast<float>( mvOccupied->Handle->GetSound( s_fv4a_u ) ), 0.25f );
|
fNPress = interpolate( fNPress, static_cast<float>( mvOccupied->Handle->GetSound( s_fv4a_u ) ), 0.25f );
|
||||||
volume = (
|
volume = (
|
||||||
fNPress > 0 ?
|
fNPress > 0 ?
|
||||||
rsHissU.m_amplitudefactor * fNPress :
|
rsHissU->m_amplitudefactor * fNPress :
|
||||||
0 );
|
0 );
|
||||||
if( volume * brakevolumescale > 0.05 ) {
|
if( volume * brakevolumescale > 0.05 ) {
|
||||||
rsHissU
|
rsHissU->gain( volume * brakevolumescale );
|
||||||
.gain( volume * brakevolumescale )
|
rsHissU->play( sound_flags::exclusive | sound_flags::looping );
|
||||||
.play( sound_flags::exclusive | sound_flags::looping );
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
rsHissU.stop();
|
rsHissU->stop();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// upuszczanie przy naglym
|
// upuszczanie przy naglym
|
||||||
volume = mvOccupied->Handle->GetSound( s_fv4a_e ) * rsHissE.m_amplitudefactor;
|
if( rsHissE ) {
|
||||||
|
volume = mvOccupied->Handle->GetSound( s_fv4a_e ) * rsHissE->m_amplitudefactor;
|
||||||
if( volume * brakevolumescale > 0.05 ) {
|
if( volume * brakevolumescale > 0.05 ) {
|
||||||
rsHissE
|
rsHissE->gain( volume * brakevolumescale );
|
||||||
.gain( volume * brakevolumescale )
|
rsHissE->play( sound_flags::exclusive | sound_flags::looping );
|
||||||
.play( sound_flags::exclusive | sound_flags::looping );
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
rsHissE.stop();
|
rsHissE->stop();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// upuszczanie sterujacego fala
|
// upuszczanie sterujacego fala
|
||||||
volume = mvOccupied->Handle->GetSound( s_fv4a_x ) * rsHissX.m_amplitudefactor;
|
if( rsHissX ) {
|
||||||
|
volume = mvOccupied->Handle->GetSound( s_fv4a_x ) * rsHissX->m_amplitudefactor;
|
||||||
if( volume * brakevolumescale > 0.05 ) {
|
if( volume * brakevolumescale > 0.05 ) {
|
||||||
rsHissX
|
rsHissX->gain( volume * brakevolumescale );
|
||||||
.gain( volume * brakevolumescale )
|
rsHissX->play( sound_flags::exclusive | sound_flags::looping );
|
||||||
.play( sound_flags::exclusive | sound_flags::looping );
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
rsHissX.stop();
|
rsHissX->stop();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// upuszczanie z czasowego
|
// upuszczanie z czasowego
|
||||||
volume = mvOccupied->Handle->GetSound( s_fv4a_t ) * rsHissT.m_amplitudefactor;
|
if( rsHissT ) {
|
||||||
|
volume = mvOccupied->Handle->GetSound( s_fv4a_t ) * rsHissT->m_amplitudefactor;
|
||||||
if( volume * brakevolumescale > 0.05 ) {
|
if( volume * brakevolumescale > 0.05 ) {
|
||||||
rsHissT
|
rsHissT->gain( volume * brakevolumescale );
|
||||||
.gain( volume * brakevolumescale )
|
rsHissT->play( sound_flags::exclusive | sound_flags::looping );
|
||||||
.play( sound_flags::exclusive | sound_flags::looping );
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
rsHissT.stop();
|
rsHissT->stop();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// jesli nie FV4a
|
// jesli nie FV4a
|
||||||
// upuszczanie z PG
|
// upuszczanie z PG
|
||||||
|
if( rsHiss ) {
|
||||||
fPPress = ( 4.0f * fPPress + std::max( mvOccupied->dpLocalValve, mvOccupied->dpMainValve ) ) / ( 4.0f + 1.0f );
|
fPPress = ( 4.0f * fPPress + std::max( mvOccupied->dpLocalValve, mvOccupied->dpMainValve ) ) / ( 4.0f + 1.0f );
|
||||||
volume = (
|
volume = (
|
||||||
fPPress > 0.0f ?
|
fPPress > 0.0f ?
|
||||||
2.0 * rsHiss.m_amplitudefactor * fPPress :
|
2.0 * rsHiss->m_amplitudefactor * fPPress :
|
||||||
0.0 );
|
0.0 );
|
||||||
if( volume > 0.05 ) {
|
if( volume > 0.05 ) {
|
||||||
rsHiss
|
rsHiss->gain( volume );
|
||||||
.gain( volume )
|
rsHiss->play( sound_flags::exclusive | sound_flags::looping );
|
||||||
.play( sound_flags::exclusive | sound_flags::looping );
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
rsHiss.stop();
|
rsHiss->stop();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// napelnianie PG
|
// napelnianie PG
|
||||||
|
if( rsHissU ) {
|
||||||
fNPress = ( 4.0f * fNPress + Min0R( mvOccupied->dpLocalValve, mvOccupied->dpMainValve ) ) / ( 4.0f + 1.0f );
|
fNPress = ( 4.0f * fNPress + Min0R( mvOccupied->dpLocalValve, mvOccupied->dpMainValve ) ) / ( 4.0f + 1.0f );
|
||||||
volume = (
|
volume = (
|
||||||
fNPress < 0.0f ?
|
fNPress < 0.0f ?
|
||||||
-1.0 * rsHissU.m_amplitudefactor * fNPress :
|
-1.0 * rsHissU->m_amplitudefactor * fNPress :
|
||||||
0.0 );
|
0.0 );
|
||||||
if( volume > 0.01 ) {
|
if( volume > 0.01 ) {
|
||||||
rsHissU
|
rsHissU->gain( volume );
|
||||||
.gain( volume )
|
rsHissU->play( sound_flags::exclusive | sound_flags::looping );
|
||||||
.play( sound_flags::exclusive | sound_flags::looping );
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
rsHissU.stop();
|
rsHissU->stop();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} // koniec nie FV4a
|
} // koniec nie FV4a
|
||||||
|
|
||||||
// brakes
|
// brakes
|
||||||
|
if( rsBrake ) {
|
||||||
if( ( mvOccupied->UnitBrakeForce > 10.0 )
|
if( ( mvOccupied->UnitBrakeForce > 10.0 )
|
||||||
&& ( mvOccupied->Vel > 0.05 ) ) {
|
&& ( mvOccupied->Vel > 0.05 ) ) {
|
||||||
|
|
||||||
@@ -7573,49 +7593,54 @@ TTrain::update_sounds( double const Deltatime ) {
|
|||||||
volume = (
|
volume = (
|
||||||
FreeFlyModeFlag ?
|
FreeFlyModeFlag ?
|
||||||
0.0 :
|
0.0 :
|
||||||
rsBrake.m_amplitudeoffset
|
rsBrake->m_amplitudeoffset
|
||||||
+ std::sqrt( brakeforceratio * interpolate( 0.4, 1.0, ( mvOccupied->Vel / ( 1 + mvOccupied->Vmax ) ) ) ) * rsBrake.m_amplitudefactor );
|
+ std::sqrt( brakeforceratio * interpolate( 0.4, 1.0, ( mvOccupied->Vel / ( 1 + mvOccupied->Vmax ) ) ) ) * rsBrake->m_amplitudefactor );
|
||||||
rsBrake
|
rsBrake->pitch( rsBrake->m_frequencyoffset + mvOccupied->Vel * rsBrake->m_frequencyfactor );
|
||||||
.pitch( rsBrake.m_frequencyoffset + mvOccupied->Vel * rsBrake.m_frequencyfactor )
|
rsBrake->gain( volume );
|
||||||
.gain( volume )
|
rsBrake->play( sound_flags::exclusive | sound_flags::looping );
|
||||||
.play( sound_flags::exclusive | sound_flags::looping );
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
rsBrake.stop();
|
rsBrake->stop();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ambient sound
|
// ambient sound
|
||||||
// since it's typically ticking of the clock we can center it on tachometer or on middle of compartment bounding area
|
// since it's typically ticking of the clock we can center it on tachometer or on middle of compartment bounding area
|
||||||
rsFadeSound.play( sound_flags::exclusive | sound_flags::looping );
|
if( rsFadeSound ) {
|
||||||
|
rsFadeSound->play( sound_flags::exclusive | sound_flags::looping );
|
||||||
|
}
|
||||||
|
|
||||||
if( mvControlled->TrainType == dt_181 ) {
|
if( dsbSlipAlarm ) {
|
||||||
// alarm przy poslizgu dla 181/182 - BOMBARDIER
|
// alarm przy poslizgu dla 181/182 - BOMBARDIER
|
||||||
if( ( mvControlled->SlippingWheels )
|
if( ( mvControlled->SlippingWheels )
|
||||||
&& ( DynamicObject->GetVelocity() > 1.0 ) ) {
|
&& ( DynamicObject->GetVelocity() > 1.0 ) ) {
|
||||||
dsbSlipAlarm.play( sound_flags::exclusive | sound_flags::looping );
|
dsbSlipAlarm->play( sound_flags::exclusive | sound_flags::looping );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
dsbSlipAlarm.stop();
|
dsbSlipAlarm->stop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// szum w czasie jazdy
|
// szum w czasie jazdy
|
||||||
|
if( rsRunningNoise ) {
|
||||||
if( ( false == FreeFlyModeFlag )
|
if( ( false == FreeFlyModeFlag )
|
||||||
&& ( false == Global.CabWindowOpen )
|
&& ( false == Global.CabWindowOpen )
|
||||||
&& ( DynamicObject->GetVelocity() > 0.5 ) ) {
|
&& ( DynamicObject->GetVelocity() > 0.5 ) ) {
|
||||||
|
|
||||||
update_sounds_runningnoise( rsRunningNoise );
|
update_sounds_runningnoise( *rsRunningNoise );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// don't play the optional ending sound if the listener switches views
|
// don't play the optional ending sound if the listener switches views
|
||||||
rsRunningNoise.stop( true == FreeFlyModeFlag );
|
rsRunningNoise->stop( true == FreeFlyModeFlag );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// hunting oscillation noise
|
// hunting oscillation noise
|
||||||
|
if( rsHuntingNoise ) {
|
||||||
if( ( false == FreeFlyModeFlag )
|
if( ( false == FreeFlyModeFlag )
|
||||||
&& ( false == Global.CabWindowOpen )
|
&& ( false == Global.CabWindowOpen )
|
||||||
&& ( DynamicObject->GetVelocity() > 0.5 )
|
&& ( DynamicObject->GetVelocity() > 0.5 )
|
||||||
&& ( DynamicObject->IsHunting ) ) {
|
&& ( DynamicObject->IsHunting ) ) {
|
||||||
|
|
||||||
update_sounds_runningnoise( rsHuntingNoise );
|
update_sounds_runningnoise( *rsHuntingNoise );
|
||||||
// modify calculated sound volume by hunting amount
|
// modify calculated sound volume by hunting amount
|
||||||
auto const huntingamount =
|
auto const huntingamount =
|
||||||
interpolate(
|
interpolate(
|
||||||
@@ -7624,63 +7649,68 @@ TTrain::update_sounds( double const Deltatime ) {
|
|||||||
( mvOccupied->Vel - DynamicObject->HuntingShake.fadein_begin ) / ( DynamicObject->HuntingShake.fadein_end - DynamicObject->HuntingShake.fadein_begin ),
|
( mvOccupied->Vel - DynamicObject->HuntingShake.fadein_begin ) / ( DynamicObject->HuntingShake.fadein_end - DynamicObject->HuntingShake.fadein_begin ),
|
||||||
0.0, 1.0 ) );
|
0.0, 1.0 ) );
|
||||||
|
|
||||||
rsHuntingNoise.gain( rsHuntingNoise.gain() * huntingamount );
|
rsHuntingNoise->gain( rsHuntingNoise->gain() * huntingamount );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// don't play the optional ending sound if the listener switches views
|
// don't play the optional ending sound if the listener switches views
|
||||||
rsHuntingNoise.stop( true == FreeFlyModeFlag );
|
rsHuntingNoise->stop( true == FreeFlyModeFlag );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// rain sound
|
// rain sound
|
||||||
|
if( m_rainsound ) {
|
||||||
if( ( false == FreeFlyModeFlag )
|
if( ( false == FreeFlyModeFlag )
|
||||||
&& ( false == Global.CabWindowOpen )
|
&& ( false == Global.CabWindowOpen )
|
||||||
&& ( Global.Weather == "rain:" ) ) {
|
&& ( Global.Weather == "rain:" ) ) {
|
||||||
if( m_rainsound.is_combined() ) {
|
if( m_rainsound->is_combined() ) {
|
||||||
m_rainsound.pitch( Global.Overcast - 1.0 );
|
m_rainsound->pitch( Global.Overcast - 1.0 );
|
||||||
}
|
}
|
||||||
m_rainsound
|
m_rainsound->gain( m_rainsound->m_amplitudeoffset + m_rainsound->m_amplitudefactor * 1.f );
|
||||||
.gain( m_rainsound.m_amplitudeoffset + m_rainsound.m_amplitudefactor * 1.f )
|
m_rainsound->play( sound_flags::exclusive | sound_flags::looping );
|
||||||
.play( sound_flags::exclusive | sound_flags::looping );
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
m_rainsound.stop();
|
m_rainsound->stop();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( dsbHasler ) {
|
||||||
if( fTachoCount >= 3.f ) {
|
if( fTachoCount >= 3.f ) {
|
||||||
auto const frequency{ (
|
auto const frequency{ (
|
||||||
true == dsbHasler.is_combined() ?
|
true == dsbHasler->is_combined() ?
|
||||||
fTachoVelocity * 0.01 :
|
fTachoVelocity * 0.01 :
|
||||||
dsbHasler.m_frequencyoffset + dsbHasler.m_frequencyfactor ) };
|
dsbHasler->m_frequencyoffset + dsbHasler->m_frequencyfactor ) };
|
||||||
dsbHasler
|
dsbHasler->pitch( frequency );
|
||||||
.pitch( frequency )
|
dsbHasler->gain( dsbHasler->m_amplitudeoffset + dsbHasler->m_amplitudefactor );
|
||||||
.gain( dsbHasler.m_amplitudeoffset + dsbHasler.m_amplitudefactor )
|
dsbHasler->play( sound_flags::exclusive | sound_flags::looping );
|
||||||
.play( sound_flags::exclusive | sound_flags::looping );
|
|
||||||
}
|
}
|
||||||
else if( fTachoCount < 1.f ) {
|
else if( fTachoCount < 1.f ) {
|
||||||
dsbHasler.stop();
|
dsbHasler->stop();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// power-reliant sounds
|
// power-reliant sounds
|
||||||
if( mvOccupied->Power24vIsAvailable || mvOccupied->Power110vIsAvailable ) {
|
if( mvOccupied->Power24vIsAvailable || mvOccupied->Power110vIsAvailable ) {
|
||||||
// McZapkie-141102: SHP i czuwak, TODO: sygnalizacja kabinowa
|
// McZapkie-141102: SHP i czuwak, TODO: sygnalizacja kabinowa
|
||||||
// hunter-091012: rozdzielenie alarmow
|
// hunter-091012: rozdzielenie alarmow
|
||||||
|
if( dsbBuzzer ) {
|
||||||
if( TestFlag( mvOccupied->SecuritySystem.Status, s_CAalarm )
|
if( TestFlag( mvOccupied->SecuritySystem.Status, s_CAalarm )
|
||||||
|| TestFlag( mvOccupied->SecuritySystem.Status, s_SHPalarm ) ) {
|
|| TestFlag( mvOccupied->SecuritySystem.Status, s_SHPalarm ) ) {
|
||||||
|
|
||||||
if( false == dsbBuzzer.is_playing() ) {
|
if( false == dsbBuzzer->is_playing() ) {
|
||||||
dsbBuzzer
|
dsbBuzzer->pitch( dsbBuzzer->m_frequencyoffset + dsbBuzzer->m_frequencyfactor );
|
||||||
.pitch( dsbBuzzer.m_frequencyoffset + dsbBuzzer.m_frequencyfactor )
|
dsbBuzzer->gain( dsbBuzzer->m_amplitudeoffset + dsbBuzzer->m_amplitudefactor );
|
||||||
.gain( dsbBuzzer.m_amplitudeoffset + dsbBuzzer.m_amplitudefactor )
|
dsbBuzzer->play( sound_flags::looping );
|
||||||
.play( sound_flags::looping );
|
|
||||||
Console::BitsSet( 1 << 14 ); // ustawienie bitu 16 na PoKeys
|
Console::BitsSet( 1 << 14 ); // ustawienie bitu 16 na PoKeys
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if( true == dsbBuzzer.is_playing() ) {
|
if( true == dsbBuzzer->is_playing() ) {
|
||||||
dsbBuzzer.stop();
|
dsbBuzzer->stop();
|
||||||
Console::BitsClear( 1 << 14 ); // ustawienie bitu 16 na PoKeys
|
Console::BitsClear( 1 << 14 ); // ustawienie bitu 16 na PoKeys
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
// distance meter alert
|
// distance meter alert
|
||||||
|
if( m_distancecounterclear ) {
|
||||||
auto const *owner{ (
|
auto const *owner{ (
|
||||||
DynamicObject->ctOwner != nullptr ?
|
DynamicObject->ctOwner != nullptr ?
|
||||||
DynamicObject->ctOwner :
|
DynamicObject->ctOwner :
|
||||||
@@ -7689,19 +7719,23 @@ TTrain::update_sounds( double const Deltatime ) {
|
|||||||
// play assigned sound if the train travelled its full length since meter activation
|
// play assigned sound if the train travelled its full length since meter activation
|
||||||
// TBD: check all combinations of directions and active cab
|
// TBD: check all combinations of directions and active cab
|
||||||
m_distancecounter = -1.f; // turn off the meter after its task is done
|
m_distancecounter = -1.f; // turn off the meter after its task is done
|
||||||
m_distancecounterclear
|
m_distancecounterclear->pitch( m_distancecounterclear->m_frequencyoffset + m_distancecounterclear->m_frequencyfactor );
|
||||||
.pitch( m_distancecounterclear.m_frequencyoffset + m_distancecounterclear.m_frequencyfactor )
|
m_distancecounterclear->gain( m_distancecounterclear->m_amplitudeoffset + m_distancecounterclear->m_amplitudefactor );
|
||||||
.gain( m_distancecounterclear.m_amplitudeoffset + m_distancecounterclear.m_amplitudefactor )
|
m_distancecounterclear->play( sound_flags::exclusive );
|
||||||
.play( sound_flags::exclusive );
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// stop power-reliant sounds if power is cut
|
// stop power-reliant sounds if power is cut
|
||||||
if( true == dsbBuzzer.is_playing() ) {
|
if( dsbBuzzer ) {
|
||||||
dsbBuzzer.stop();
|
if( true == dsbBuzzer->is_playing() ) {
|
||||||
|
dsbBuzzer->stop();
|
||||||
Console::BitsClear( 1 << 14 ); // ustawienie bitu 16 na PoKeys
|
Console::BitsClear( 1 << 14 ); // ustawienie bitu 16 na PoKeys
|
||||||
}
|
}
|
||||||
m_distancecounterclear.stop();
|
}
|
||||||
|
if( m_distancecounterclear ) {
|
||||||
|
m_distancecounterclear->stop();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
update_sounds_radio();
|
update_sounds_radio();
|
||||||
@@ -7784,12 +7818,14 @@ void TTrain::update_sounds_radio() {
|
|||||||
message.second->gain( volume );
|
message.second->gain( volume );
|
||||||
}
|
}
|
||||||
// radiostop
|
// radiostop
|
||||||
|
if( m_radiostop ) {
|
||||||
if( ( true == radioenabled )
|
if( ( true == radioenabled )
|
||||||
&& ( true == mvOccupied->RadioStopFlag ) ) {
|
&& ( true == mvOccupied->RadioStopFlag ) ) {
|
||||||
m_radiostop.play( sound_flags::exclusive | sound_flags::looping );
|
m_radiostop->play( sound_flags::exclusive | sound_flags::looping );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
m_radiostop.stop();
|
m_radiostop->stop();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -7832,10 +7868,43 @@ bool TTrain::CabChange(int iDirection)
|
|||||||
// wczytywanie pliku z danymi multimedialnymi (dzwieki, kontrolki, kabiny)
|
// wczytywanie pliku z danymi multimedialnymi (dzwieki, kontrolki, kabiny)
|
||||||
bool TTrain::LoadMMediaFile(std::string const &asFileName)
|
bool TTrain::LoadMMediaFile(std::string const &asFileName)
|
||||||
{
|
{
|
||||||
|
// initialize sounds so potential entries from previous vehicle don't stick around
|
||||||
|
std::unordered_map<
|
||||||
|
std::string,
|
||||||
|
std::tuple<std::optional<sound_source> &, sound_placement, float, sound_type, int, double>>
|
||||||
|
internalsounds = {
|
||||||
|
{"ctrl:", {dsbNastawnikJazdy, sound_placement::internal, EU07_SOUND_CABCONTROLSCUTOFFRANGE, sound_type::single, 0, 100.0}},
|
||||||
|
{"ctrlscnd:", {dsbNastawnikBocz, sound_placement::internal, EU07_SOUND_CABCONTROLSCUTOFFRANGE, sound_type::single, 0, 100.0}},
|
||||||
|
{"reverserkey:", {dsbReverserKey, sound_placement::internal, EU07_SOUND_CABCONTROLSCUTOFFRANGE, sound_type::single, 0, 100.0}},
|
||||||
|
{"buzzer:", {dsbBuzzer, sound_placement::internal, EU07_SOUND_CABCONTROLSCUTOFFRANGE, sound_type::single, 0, 100.0}},
|
||||||
|
{"radiostop:", {m_radiostop, sound_placement::internal, EU07_SOUND_CABCONTROLSCUTOFFRANGE, sound_type::single, 0, 100.0}},
|
||||||
|
{"slipalarm:", {dsbSlipAlarm, sound_placement::internal, EU07_SOUND_CABCONTROLSCUTOFFRANGE, sound_type::single, 0, 100.0}},
|
||||||
|
{"distancecounter:", {m_distancecounterclear, sound_placement::internal, EU07_SOUND_CABCONTROLSCUTOFFRANGE, sound_type::single, 0, 100.0}},
|
||||||
|
{"tachoclock:", {dsbHasler, sound_placement::internal, EU07_SOUND_CABCONTROLSCUTOFFRANGE, sound_type::single, 0, 100.0}},
|
||||||
|
{"switch:", {dsbSwitch, sound_placement::internal, EU07_SOUND_CABCONTROLSCUTOFFRANGE, sound_type::single, 0, 100.0}},
|
||||||
|
{"pneumaticswitch:", {dsbPneumaticSwitch, sound_placement::internal, EU07_SOUND_CABCONTROLSCUTOFFRANGE, sound_type::single, 0, 100.0}},
|
||||||
|
{"airsound:", {rsHiss, sound_placement::internal, EU07_SOUND_CABCONTROLSCUTOFFRANGE, sound_type::single, sound_parameters::amplitude, 100.0}},
|
||||||
|
{"airsound2:", {rsHissU, sound_placement::internal, EU07_SOUND_CABCONTROLSCUTOFFRANGE, sound_type::single, sound_parameters::amplitude, 100.0}},
|
||||||
|
{"airsound3:", {rsHissE, sound_placement::internal, EU07_SOUND_CABCONTROLSCUTOFFRANGE, sound_type::single, sound_parameters::amplitude, 100.0}},
|
||||||
|
{"airsound4:", {rsHissX, sound_placement::internal, EU07_SOUND_CABCONTROLSCUTOFFRANGE, sound_type::single, sound_parameters::amplitude, 100.0}},
|
||||||
|
{"airsound5:", {rsHissT, sound_placement::internal, EU07_SOUND_CABCONTROLSCUTOFFRANGE, sound_type::single, sound_parameters::amplitude, 100.0}},
|
||||||
|
{"localbrakesound:", {rsSBHiss, sound_placement::internal, EU07_SOUND_CABCONTROLSCUTOFFRANGE, sound_type::single, sound_parameters::amplitude, 100.0}},
|
||||||
|
{"localbrakesound2:", {rsSBHissU, sound_placement::internal, EU07_SOUND_CABCONTROLSCUTOFFRANGE, sound_type::single, sound_parameters::amplitude, 100.0}},
|
||||||
|
{"brakesound:", {rsBrake, sound_placement::internal, -1, sound_type::single, sound_parameters::amplitude | sound_parameters::frequency, 100.0}},
|
||||||
|
{"fadesound:", {rsFadeSound, sound_placement::internal, EU07_SOUND_CABCONTROLSCUTOFFRANGE, sound_type::single, 0, 100.0}},
|
||||||
|
{"runningnoise:", {rsRunningNoise, sound_placement::internal, EU07_SOUND_GLOBALRANGE, sound_type::single, sound_parameters::amplitude | sound_parameters::frequency, mvOccupied->Vmax }},
|
||||||
|
{"huntingnoise:", {rsHuntingNoise, sound_placement::internal, EU07_SOUND_GLOBALRANGE, sound_type::single, sound_parameters::amplitude | sound_parameters::frequency, mvOccupied->Vmax }},
|
||||||
|
{"rainsound:", {m_rainsound, sound_placement::internal, -1, sound_type::single, 0, 100.0}},
|
||||||
|
};
|
||||||
|
for( auto &soundconfig : internalsounds ) {
|
||||||
|
std::get<std::optional<sound_source> &>( soundconfig.second ).reset();
|
||||||
|
}
|
||||||
|
// NOTE: since radiosound is an incomplete template not using std::optional it gets a special treatment
|
||||||
|
m_radiosound.owner( DynamicObject );
|
||||||
|
|
||||||
cParser parser( asFileName, cParser::buffer_FILE, DynamicObject->asBaseDir );
|
cParser parser( asFileName, cParser::buffer_FILE, DynamicObject->asBaseDir );
|
||||||
// NOTE: yaml-style comments are disabled until conflict in use of # is resolved
|
// NOTE: yaml-style comments are disabled until conflict in use of # is resolved
|
||||||
// parser.addCommentStyle( "#", "\n" );
|
// parser.addCommentStyle( "#", "\n" );
|
||||||
|
|
||||||
std::string token;
|
std::string token;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
@@ -7844,145 +7913,56 @@ bool TTrain::LoadMMediaFile(std::string const &asFileName)
|
|||||||
parser >> token;
|
parser >> token;
|
||||||
} while ((token != "") && (token != "internaldata:"));
|
} while ((token != "") && (token != "internaldata:"));
|
||||||
|
|
||||||
if (token == "internaldata:")
|
if (token == "internaldata:") {
|
||||||
{
|
|
||||||
do
|
do {
|
||||||
{
|
|
||||||
token = "";
|
token = "";
|
||||||
parser.getTokens();
|
parser.getTokens();
|
||||||
parser >> token;
|
parser >> token;
|
||||||
// SEKCJA DZWIEKOW
|
|
||||||
if (token == "ctrl:") {
|
auto lookup { internalsounds.find( token ) };
|
||||||
// nastawnik:
|
if( lookup == internalsounds.end() ) { continue; }
|
||||||
dsbNastawnikJazdy.deserialize( parser, sound_type::single );
|
|
||||||
dsbNastawnikJazdy.owner( DynamicObject );
|
auto const soundconfig { lookup->second };
|
||||||
|
sound_source sound {
|
||||||
|
std::get<sound_placement>( soundconfig ),
|
||||||
|
std::get<float>( soundconfig ) };
|
||||||
|
sound.deserialize(
|
||||||
|
parser,
|
||||||
|
std::get<sound_type>( soundconfig ),
|
||||||
|
std::get<int>( soundconfig ),
|
||||||
|
std::get<double>( soundconfig ) );
|
||||||
|
sound.owner( DynamicObject );
|
||||||
|
std::get<std::optional<sound_source> &>( soundconfig ) = sound;
|
||||||
|
} while( token != "" );
|
||||||
|
|
||||||
|
|
||||||
|
// assign default samples to sound emitters which weren't included in the config file
|
||||||
|
if( !m_rainsound ) {
|
||||||
|
sound_source rainsound;
|
||||||
|
rainsound.deserialize( "rainsound_default", sound_type::single );
|
||||||
|
rainsound.owner( DynamicObject );
|
||||||
|
m_rainsound = rainsound;
|
||||||
}
|
}
|
||||||
else if (token == "ctrlscnd:") {
|
if (!rsSBHiss) {
|
||||||
// hunter-081211: nastawnik bocznikowania
|
|
||||||
dsbNastawnikBocz.deserialize( parser, sound_type::single );
|
|
||||||
dsbNastawnikBocz.owner( DynamicObject );
|
|
||||||
}
|
|
||||||
else if (token == "reverserkey:") {
|
|
||||||
// hunter-131211: dzwiek kierunkowego
|
|
||||||
dsbReverserKey.deserialize( parser, sound_type::single );
|
|
||||||
dsbReverserKey.owner( DynamicObject );
|
|
||||||
}
|
|
||||||
else if (token == "buzzer:") {
|
|
||||||
// bzyczek shp:
|
|
||||||
dsbBuzzer.deserialize( parser, sound_type::single );
|
|
||||||
dsbBuzzer.owner( DynamicObject );
|
|
||||||
}
|
|
||||||
else if( token == "radiostop:" ) {
|
|
||||||
// radiostop
|
|
||||||
m_radiostop.deserialize( parser, sound_type::single );
|
|
||||||
m_radiostop.owner( DynamicObject );
|
|
||||||
}
|
|
||||||
else if (token == "slipalarm:") {
|
|
||||||
// Bombardier 011010: alarm przy poslizgu:
|
|
||||||
dsbSlipAlarm.deserialize( parser, sound_type::single );
|
|
||||||
dsbSlipAlarm.owner( DynamicObject );
|
|
||||||
}
|
|
||||||
else if (token == "distancecounter:") {
|
|
||||||
// distance meter 'good to go' sound
|
|
||||||
m_distancecounterclear.deserialize( parser, sound_type::single );
|
|
||||||
m_distancecounterclear.owner( DynamicObject );
|
|
||||||
}
|
|
||||||
else if (token == "tachoclock:") {
|
|
||||||
// cykanie rejestratora:
|
|
||||||
dsbHasler.deserialize( parser, sound_type::single );
|
|
||||||
dsbHasler.owner( DynamicObject );
|
|
||||||
}
|
|
||||||
else if (token == "switch:") {
|
|
||||||
// przelaczniki:
|
|
||||||
dsbSwitch.deserialize( parser, sound_type::single );
|
|
||||||
dsbSwitch.owner( DynamicObject );
|
|
||||||
}
|
|
||||||
else if (token == "pneumaticswitch:") {
|
|
||||||
// stycznik EP:
|
|
||||||
dsbPneumaticSwitch.deserialize( parser, sound_type::single );
|
|
||||||
dsbPneumaticSwitch.owner( DynamicObject );
|
|
||||||
}
|
|
||||||
else if (token == "airsound:") {
|
|
||||||
// syk:
|
|
||||||
rsHiss.deserialize( parser, sound_type::single, sound_parameters::amplitude );
|
|
||||||
rsHiss.owner( DynamicObject );
|
|
||||||
if( true == rsSBHiss.empty() ) {
|
|
||||||
// fallback for vehicles without defined local brake hiss sound
|
// fallback for vehicles without defined local brake hiss sound
|
||||||
rsSBHiss = rsHiss;
|
rsSBHiss = rsHiss;
|
||||||
}
|
}
|
||||||
}
|
if (!rsSBHissU) {
|
||||||
else if (token == "airsound2:") {
|
|
||||||
// syk:
|
|
||||||
rsHissU.deserialize( parser, sound_type::single, sound_parameters::amplitude );
|
|
||||||
rsHissU.owner( DynamicObject );
|
|
||||||
if( true == rsSBHissU.empty() ) {
|
|
||||||
// fallback for vehicles without defined local brake hiss sound
|
// fallback for vehicles without defined local brake hiss sound
|
||||||
rsSBHissU = rsHissU;
|
rsSBHissU = rsHissU;
|
||||||
}
|
}
|
||||||
|
if (rsBrake) {
|
||||||
|
rsBrake->m_frequencyfactor /= (1 + mvOccupied->Vmax);
|
||||||
}
|
}
|
||||||
else if (token == "airsound3:") {
|
if (rsRunningNoise) {
|
||||||
// syk:
|
rsRunningNoise->m_frequencyfactor /= (1 + mvOccupied->Vmax);
|
||||||
rsHissE.deserialize( parser, sound_type::single, sound_parameters::amplitude );
|
|
||||||
rsHissE.owner( DynamicObject );
|
|
||||||
}
|
}
|
||||||
else if (token == "airsound4:") {
|
if (rsHuntingNoise) {
|
||||||
// syk:
|
rsHuntingNoise->m_frequencyfactor /= (1 + mvOccupied->Vmax);
|
||||||
rsHissX.deserialize( parser, sound_type::single, sound_parameters::amplitude );
|
|
||||||
rsHissX.owner( DynamicObject );
|
|
||||||
}
|
}
|
||||||
else if (token == "airsound5:") {
|
|
||||||
// syk:
|
|
||||||
rsHissT.deserialize( parser, sound_type::single, sound_parameters::amplitude );
|
|
||||||
rsHissT.owner( DynamicObject );
|
|
||||||
}
|
|
||||||
else if (token == "localbrakesound:") {
|
|
||||||
// syk:
|
|
||||||
rsSBHiss.deserialize( parser, sound_type::single, sound_parameters::amplitude );
|
|
||||||
rsSBHiss.owner( DynamicObject );
|
|
||||||
}
|
|
||||||
else if( token == "localbrakesound2:" ) {
|
|
||||||
// syk:
|
|
||||||
rsSBHissU.deserialize( parser, sound_type::single, sound_parameters::amplitude );
|
|
||||||
rsSBHissU.owner( DynamicObject );
|
|
||||||
}
|
|
||||||
else if( token == "brakesound:" ) {
|
|
||||||
// the sound of vehicle body vibrations etc, when brakes are engaged
|
|
||||||
rsBrake.deserialize( parser, sound_type::single, sound_parameters::amplitude | sound_parameters::frequency );
|
|
||||||
rsBrake.owner( DynamicObject );
|
|
||||||
// NOTE: can't pre-calculate amplitude normalization based on max brake force, as this varies depending on vehicle speed
|
|
||||||
rsBrake.m_frequencyfactor /= ( 1 + mvOccupied->Vmax );
|
|
||||||
}
|
|
||||||
else if (token == "fadesound:") {
|
|
||||||
// ambient sound:
|
|
||||||
rsFadeSound.deserialize( parser, sound_type::single );
|
|
||||||
rsFadeSound.owner( DynamicObject );
|
|
||||||
}
|
|
||||||
else if( token == "runningnoise:" ) {
|
|
||||||
// szum podczas jazdy:
|
|
||||||
rsRunningNoise.deserialize( parser, sound_type::single, sound_parameters::amplitude | sound_parameters::frequency, mvOccupied->Vmax );
|
|
||||||
rsRunningNoise.owner( DynamicObject );
|
|
||||||
rsRunningNoise.m_frequencyfactor /= ( 1 + mvOccupied->Vmax );
|
|
||||||
}
|
|
||||||
else if( token == "huntingnoise:" ) {
|
|
||||||
// hunting oscillation sound:
|
|
||||||
rsHuntingNoise.deserialize( parser, sound_type::single, sound_parameters::amplitude | sound_parameters::frequency, mvOccupied->Vmax );
|
|
||||||
rsHuntingNoise.owner( DynamicObject );
|
|
||||||
rsHuntingNoise.m_frequencyfactor /= ( 1 + mvOccupied->Vmax );
|
|
||||||
}
|
|
||||||
else if( token == "rainsound:" ) {
|
|
||||||
// precipitation sound:
|
|
||||||
m_rainsound.deserialize( parser, sound_type::single );
|
|
||||||
m_rainsound.owner( DynamicObject );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} while (token != "");
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
} // nie znalazl sekcji internal
|
|
||||||
*/
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -7991,19 +7971,21 @@ bool TTrain::InitializeCab(int NewCabNo, std::string const &asFileName)
|
|||||||
m_controlmapper.clear();
|
m_controlmapper.clear();
|
||||||
// clear python screens
|
// clear python screens
|
||||||
m_screens.clear();
|
m_screens.clear();
|
||||||
// reset sound positions and owner
|
// reset sound positions
|
||||||
auto const nullvector { glm::vec3() };
|
auto const nullvector { glm::vec3() };
|
||||||
std::vector<sound_source *> sounds = {
|
std::vector<std::reference_wrapper<std::optional<sound_source>>> sounds = {
|
||||||
&dsbReverserKey, &dsbNastawnikJazdy, &dsbNastawnikBocz,
|
dsbReverserKey, dsbNastawnikJazdy, dsbNastawnikBocz,
|
||||||
&dsbSwitch, &dsbPneumaticSwitch,
|
dsbSwitch, dsbPneumaticSwitch,
|
||||||
&rsHiss, &rsHissU, &rsHissE, &rsHissX, &rsHissT, &rsSBHiss, &rsSBHissU,
|
rsHiss, rsHissU, rsHissE, rsHissX, rsHissT, rsSBHiss, rsSBHissU,
|
||||||
&rsFadeSound, &rsRunningNoise, &rsHuntingNoise,
|
rsFadeSound, rsRunningNoise, rsHuntingNoise,
|
||||||
&dsbHasler, &dsbBuzzer, &dsbSlipAlarm, &m_distancecounterclear, &m_radiosound, &m_radiostop
|
dsbHasler, dsbBuzzer, dsbSlipAlarm, m_distancecounterclear, m_rainsound, m_radiostop
|
||||||
};
|
};
|
||||||
for( auto sound : sounds ) {
|
for( auto &sound : sounds ) {
|
||||||
sound->offset( nullvector );
|
if( sound.get() ) {
|
||||||
sound->owner( DynamicObject );
|
sound.get()->offset( nullvector );
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
m_radiosound.offset( nullvector );
|
||||||
// reset view angles
|
// reset view angles
|
||||||
pMechViewAngle = { 0.0, 0.0 };
|
pMechViewAngle = { 0.0, 0.0 };
|
||||||
|
|
||||||
@@ -8011,7 +7993,7 @@ bool TTrain::InitializeCab(int NewCabNo, std::string const &asFileName)
|
|||||||
|
|
||||||
bool parse = false;
|
bool parse = false;
|
||||||
int cabindex = 0;
|
int cabindex = 0;
|
||||||
DynamicObject->mdKabina = NULL; // likwidacja wskaźnika na dotychczasową kabinę
|
DynamicObject->mdKabina = nullptr; // likwidacja wskaźnika na dotychczasową kabinę
|
||||||
switch (NewCabNo)
|
switch (NewCabNo)
|
||||||
{ // ustalenie numeru kabiny do wczytania
|
{ // ustalenie numeru kabiny do wczytania
|
||||||
case -1:
|
case -1:
|
||||||
@@ -8038,59 +8020,8 @@ bool TTrain::InitializeCab(int NewCabNo, std::string const &asFileName)
|
|||||||
token = "";
|
token = "";
|
||||||
parser.getTokens();
|
parser.getTokens();
|
||||||
parser >> token;
|
parser >> token;
|
||||||
/*
|
|
||||||
if( token == "locations:" ) {
|
|
||||||
do {
|
|
||||||
token = "";
|
|
||||||
parser.getTokens(); parser >> token;
|
|
||||||
|
|
||||||
if( token == "radio:" ) {
|
|
||||||
// point in 3d space, in format [ x, y, z ]
|
|
||||||
glm::vec3 radiolocation;
|
|
||||||
parser.getTokens( 3, false, "\n\r\t ,;[]" );
|
|
||||||
parser
|
|
||||||
>> radiolocation.x
|
|
||||||
>> radiolocation.y
|
|
||||||
>> radiolocation.z;
|
|
||||||
radiolocation *= glm::vec3( NewCabNo, 1, NewCabNo );
|
|
||||||
m_radiosound.offset( radiolocation );
|
|
||||||
}
|
|
||||||
|
|
||||||
else if( token == "alerter:" ) {
|
|
||||||
// point in 3d space, in format [ x, y, z ]
|
|
||||||
glm::vec3 alerterlocation;
|
|
||||||
parser.getTokens( 3, false, "\n\r\t ,;[]" );
|
|
||||||
parser
|
|
||||||
>> alerterlocation.x
|
|
||||||
>> alerterlocation.y
|
|
||||||
>> alerterlocation.z;
|
|
||||||
alerterlocation *= glm::vec3( NewCabNo, 1, NewCabNo );
|
|
||||||
dsbBuzzer.offset( alerterlocation );
|
|
||||||
}
|
|
||||||
|
|
||||||
} while( ( token != "" )
|
|
||||||
&& ( token != "endlocations" ) );
|
|
||||||
|
|
||||||
} // locations:
|
|
||||||
*/
|
|
||||||
} while ((token != "") && (token != cabstr));
|
} while ((token != "") && (token != cabstr));
|
||||||
/*
|
|
||||||
if ((cabindex != 1) && (token != cabstr))
|
|
||||||
{
|
|
||||||
// jeśli nie znaleziony wpis kabiny, próba szukania kabiny 1
|
|
||||||
cabstr = "cab1definition:";
|
|
||||||
// crude way to start parsing from beginning
|
|
||||||
parser = std::make_shared<cParser>(asFileName, cParser::buffer_FILE);
|
|
||||||
// NOTE: yaml-style comments are disabled until conflict in use of # is resolved
|
|
||||||
// parser.addCommentStyle( "#", "\n" );
|
|
||||||
do
|
|
||||||
{
|
|
||||||
token = "";
|
|
||||||
parser.getTokens();
|
|
||||||
parser >> token;
|
|
||||||
} while ((token != "") && (token != cabstr));
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
if (token == cabstr)
|
if (token == cabstr)
|
||||||
{
|
{
|
||||||
// jeśli znaleziony wpis kabiny
|
// jeśli znaleziony wpis kabiny
|
||||||
@@ -8288,63 +8219,53 @@ bool TTrain::InitializeCab(int NewCabNo, std::string const &asFileName)
|
|||||||
if (DynamicObject->mdKabina)
|
if (DynamicObject->mdKabina)
|
||||||
{
|
{
|
||||||
*/
|
*/
|
||||||
// assign default samples to sound emitters which weren't included in the config file
|
|
||||||
if( m_rainsound.empty() ) {
|
|
||||||
m_rainsound.deserialize( "rainsound_default", sound_type::single );
|
|
||||||
m_rainsound.owner( DynamicObject );
|
|
||||||
}
|
|
||||||
// configure placement of sound emitters which aren't bound with any device model, and weren't placed manually
|
// configure placement of sound emitters which aren't bound with any device model, and weren't placed manually
|
||||||
// try first to bind sounds to location of possible devices
|
auto const caboffset { glm::dvec3 { ( Cabine[ cabindex ].CabPos1 + Cabine[ cabindex ].CabPos2 ) * 0.5 } +glm::dvec3 { 0, 1, 0 } };
|
||||||
if( dsbReverserKey.offset() == nullvector ) {
|
// NOTE: since radiosound is an incomplete template not using std::optional it gets a special treatment
|
||||||
dsbReverserKey.offset( ggDirKey.model_offset() );
|
|
||||||
}
|
|
||||||
if( dsbNastawnikJazdy.offset() == nullvector ) {
|
|
||||||
dsbNastawnikJazdy.offset( ggJointCtrl.model_offset() );
|
|
||||||
}
|
|
||||||
if( dsbNastawnikJazdy.offset() == nullvector ) {
|
|
||||||
dsbNastawnikJazdy.offset( ggMainCtrl.model_offset() );
|
|
||||||
}
|
|
||||||
if( dsbNastawnikBocz.offset() == nullvector ) {
|
|
||||||
dsbNastawnikBocz.offset( ggScndCtrl.model_offset() );
|
|
||||||
}
|
|
||||||
if( dsbBuzzer.offset() == nullvector ) {
|
|
||||||
dsbBuzzer.offset( btLampkaCzuwaka.model_offset() );
|
|
||||||
}
|
|
||||||
// HACK: alerter is likely to be located somewhere near computer displays
|
|
||||||
if( m_distancecounterclear.offset() == nullvector ) {
|
|
||||||
m_distancecounterclear.offset( btLampkaCzuwaka.model_offset() );
|
|
||||||
}
|
|
||||||
// radio has two potential items which can provide the position
|
|
||||||
if( m_radiosound.offset() == nullvector ) {
|
if( m_radiosound.offset() == nullvector ) {
|
||||||
m_radiosound.offset( btLampkaRadio.model_offset() );
|
m_radiosound.offset( btLampkaRadio.model_offset() );
|
||||||
}
|
}
|
||||||
if( m_radiostop.offset() == nullvector ) {
|
if( m_radiosound.offset() == nullvector ) {
|
||||||
m_radiostop.offset( m_radiosound.offset() );
|
m_radiosound.offset( caboffset );
|
||||||
}
|
}
|
||||||
auto const localbrakeoffset { ggLocalBrake.model_offset() };
|
std::vector<std::pair<std::reference_wrapper<std::optional<sound_source>>, glm::vec3>>
|
||||||
std::vector<sound_source *> localbrakesounds = {
|
soundlocations = {
|
||||||
&rsSBHiss, &rsSBHissU
|
{dsbReverserKey, ggDirKey.model_offset()},
|
||||||
|
{dsbNastawnikJazdy, ggJointCtrl.model_offset()},
|
||||||
|
{dsbNastawnikJazdy, ggMainCtrl.model_offset()}, // NOTE: fallback for vehicles without universal controller
|
||||||
|
{dsbNastawnikBocz, ggScndCtrl.model_offset()},
|
||||||
|
{dsbSwitch, caboffset},
|
||||||
|
{dsbPneumaticSwitch, caboffset},
|
||||||
|
{rsHiss, ggBrakeCtrl.model_offset()},
|
||||||
|
{rsHissU, ggBrakeCtrl.model_offset()},
|
||||||
|
{rsHissE, ggBrakeCtrl.model_offset()},
|
||||||
|
{rsHissX, ggBrakeCtrl.model_offset()},
|
||||||
|
{rsHissT, ggBrakeCtrl.model_offset()},
|
||||||
|
{rsSBHiss, ggLocalBrake.model_offset()},
|
||||||
|
{rsSBHiss, ggBrakeCtrl.model_offset()}, // NOTE: fallback if the local brake model can't be located
|
||||||
|
{rsSBHissU, ggLocalBrake.model_offset()},
|
||||||
|
{rsSBHissU, ggBrakeCtrl.model_offset()}, // NOTE: fallback if the local brake model can't be located
|
||||||
|
{rsFadeSound, caboffset},
|
||||||
|
{rsRunningNoise, caboffset},
|
||||||
|
{rsHuntingNoise, caboffset},
|
||||||
|
{dsbHasler, caboffset},
|
||||||
|
{dsbBuzzer, btLampkaCzuwaka.model_offset()},
|
||||||
|
{dsbSlipAlarm, caboffset},
|
||||||
|
{m_distancecounterclear, btLampkaCzuwaka.model_offset()},
|
||||||
|
{m_rainsound, caboffset},
|
||||||
|
{m_radiostop, m_radiosound.offset()},
|
||||||
};
|
};
|
||||||
for( auto sound : localbrakesounds ) {
|
for( auto & sound : soundlocations ) {
|
||||||
if( sound->offset() == nullvector ) {
|
if( ( sound.first.get() )
|
||||||
sound->offset( localbrakeoffset );
|
&& ( sound.first.get()->offset() == nullvector ) ) {
|
||||||
|
sound.first.get()->offset( sound.second );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// NOTE: if the local brake model can't be located the emitter will also be assigned location of main brake
|
// second pass, in case some items received no positioning due to missing submodels etc
|
||||||
auto const brakeoffset { ggBrakeCtrl.model_offset() };
|
for( auto & sound : soundlocations ) {
|
||||||
std::vector<sound_source *> brakesounds = {
|
if( ( sound.first.get() )
|
||||||
&rsHiss, &rsHissU, &rsHissE, &rsHissX, &rsHissT, &rsSBHiss, &rsSBHissU,
|
&& ( sound.first.get()->offset() == nullvector ) ) {
|
||||||
};
|
sound.first.get()->offset( caboffset );
|
||||||
for( auto sound : brakesounds ) {
|
|
||||||
if( sound->offset() == nullvector ) {
|
|
||||||
sound->offset( brakeoffset );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// for whatever is left fallback on generic location, centre of the cab
|
|
||||||
auto const caboffset { glm::dvec3 { ( Cabine[ cabindex ].CabPos1 + Cabine[ cabindex ].CabPos2 ) * 0.5 } + glm::dvec3 { 0, 1, 0 } };
|
|
||||||
for( auto sound : sounds ) {
|
|
||||||
if( sound->offset() == nullvector ) {
|
|
||||||
sound->offset( caboffset );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -8521,9 +8442,13 @@ TTrain::MoveToVehicle(TDynamicObject *target) {
|
|||||||
DynamicSet(target);
|
DynamicSet(target);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto const filename { Occupied()->TypeName + ".mmd" };
|
||||||
|
LoadMMediaFile( filename );
|
||||||
InitializeCab(
|
InitializeCab(
|
||||||
Occupied()->CabActive,
|
Occupied()->CabActive,
|
||||||
Occupied()->TypeName + ".mmd" );
|
filename );
|
||||||
|
}
|
||||||
|
|
||||||
Dynamic()->ABuSetModelShake( {} ); // zerowanie przesunięcia przed powrotem?
|
Dynamic()->ABuSetModelShake( {} ); // zerowanie przesunięcia przed powrotem?
|
||||||
|
|
||||||
@@ -9544,8 +9469,9 @@ bool TTrain::initialize_gauge(cParser &Parser, std::string const &Label, int con
|
|||||||
gauge.Load(Parser, DynamicObject);
|
gauge.Load(Parser, DynamicObject);
|
||||||
gauge.AssignFloat(&fTachoVelocityJump);
|
gauge.AssignFloat(&fTachoVelocityJump);
|
||||||
// bind tachometer sound location to the meter
|
// bind tachometer sound location to the meter
|
||||||
if( dsbHasler.offset() == glm::vec3() ) {
|
if( dsbHasler
|
||||||
dsbHasler.offset( gauge.model_offset() );
|
&& dsbHasler->offset() == glm::vec3() ) {
|
||||||
|
dsbHasler->offset( gauge.model_offset() );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (Label == "tachometern:")
|
else if (Label == "tachometern:")
|
||||||
@@ -9555,8 +9481,9 @@ bool TTrain::initialize_gauge(cParser &Parser, std::string const &Label, int con
|
|||||||
gauge.Load(Parser, DynamicObject);
|
gauge.Load(Parser, DynamicObject);
|
||||||
gauge.AssignFloat(&fTachoVelocity);
|
gauge.AssignFloat(&fTachoVelocity);
|
||||||
// bind tachometer sound location to the meter
|
// bind tachometer sound location to the meter
|
||||||
if( dsbHasler.offset() == glm::vec3() ) {
|
if( dsbHasler
|
||||||
dsbHasler.offset( gauge.model_offset() );
|
&& dsbHasler->offset() == glm::vec3() ) {
|
||||||
|
dsbHasler->offset( gauge.model_offset() );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (Label == "tachometerd:")
|
else if (Label == "tachometerd:")
|
||||||
@@ -9566,8 +9493,9 @@ bool TTrain::initialize_gauge(cParser &Parser, std::string const &Label, int con
|
|||||||
gauge.Load(Parser, DynamicObject);
|
gauge.Load(Parser, DynamicObject);
|
||||||
gauge.AssignFloat(&fTachoVelocity);
|
gauge.AssignFloat(&fTachoVelocity);
|
||||||
// bind tachometer sound location to the meter
|
// bind tachometer sound location to the meter
|
||||||
if( dsbHasler.offset() == glm::vec3() ) {
|
if( dsbHasler
|
||||||
dsbHasler.offset( gauge.model_offset() );
|
&& dsbHasler->offset() == glm::vec3() ) {
|
||||||
|
dsbHasler->offset( gauge.model_offset() );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ((Label == "hvcurrent1:") || (Label == "hvcurrent1b:"))
|
else if ((Label == "hvcurrent1:") || (Label == "hvcurrent1b:"))
|
||||||
|
|||||||
52
Train.h
52
Train.h
@@ -728,35 +728,33 @@ public: // reszta może by?publiczna
|
|||||||
TButton btHaslerBrakes; // ciśnienie w cylindrach
|
TButton btHaslerBrakes; // ciśnienie w cylindrach
|
||||||
TButton btHaslerCurrent; // prąd na silnikach
|
TButton btHaslerCurrent; // prąd na silnikach
|
||||||
|
|
||||||
sound_source dsbReverserKey { sound_placement::internal, EU07_SOUND_CABCONTROLSCUTOFFRANGE }; // hunter-121211
|
std::optional<sound_source>
|
||||||
sound_source dsbNastawnikJazdy { sound_placement::internal, EU07_SOUND_CABCONTROLSCUTOFFRANGE };
|
dsbNastawnikJazdy,
|
||||||
sound_source dsbNastawnikBocz { sound_placement::internal, EU07_SOUND_CABCONTROLSCUTOFFRANGE }; // hunter-081211
|
dsbNastawnikBocz,
|
||||||
sound_source dsbSwitch { sound_placement::internal, EU07_SOUND_CABCONTROLSCUTOFFRANGE };
|
dsbReverserKey,
|
||||||
sound_source dsbPneumaticSwitch { sound_placement::internal, EU07_SOUND_CABCONTROLSCUTOFFRANGE };
|
dsbBuzzer,
|
||||||
|
m_radiostop,
|
||||||
sound_source rsHiss { sound_placement::internal, EU07_SOUND_CABCONTROLSCUTOFFRANGE }; // upuszczanie
|
dsbSlipAlarm,
|
||||||
sound_source rsHissU { sound_placement::internal, EU07_SOUND_CABCONTROLSCUTOFFRANGE }; // napelnianie
|
m_distancecounterclear,
|
||||||
sound_source rsHissE { sound_placement::internal, EU07_SOUND_CABCONTROLSCUTOFFRANGE }; // nagle
|
dsbHasler,
|
||||||
sound_source rsHissX { sound_placement::internal, EU07_SOUND_CABCONTROLSCUTOFFRANGE }; // fala
|
dsbSwitch,
|
||||||
sound_source rsHissT { sound_placement::internal, EU07_SOUND_CABCONTROLSCUTOFFRANGE }; // czasowy
|
dsbPneumaticSwitch,
|
||||||
sound_source rsSBHiss { sound_placement::internal, EU07_SOUND_CABCONTROLSCUTOFFRANGE }; // local
|
rsHiss,
|
||||||
sound_source rsSBHissU { sound_placement::internal, EU07_SOUND_CABCONTROLSCUTOFFRANGE }; // local, engage brakes
|
rsHissU,
|
||||||
float m_lastlocalbrakepressure { -1.f }; // helper, cached level of pressure in local brake cylinder
|
rsHissE,
|
||||||
float m_localbrakepressurechange { 0.f }; // recent change of pressure in local brake cylinder
|
rsHissX,
|
||||||
sound_source rsBrake { sound_placement::internal, -1 };
|
rsHissT,
|
||||||
|
rsSBHiss,
|
||||||
sound_source rsFadeSound { sound_placement::internal, EU07_SOUND_CABCONTROLSCUTOFFRANGE };
|
rsSBHissU,
|
||||||
sound_source rsRunningNoise{ sound_placement::internal, EU07_SOUND_GLOBALRANGE };
|
rsBrake,
|
||||||
sound_source rsHuntingNoise{ sound_placement::internal, EU07_SOUND_GLOBALRANGE };
|
rsFadeSound,
|
||||||
sound_source m_rainsound { sound_placement::internal, -1 };
|
rsRunningNoise,
|
||||||
|
rsHuntingNoise,
|
||||||
sound_source dsbHasler { sound_placement::internal, EU07_SOUND_CABCONTROLSCUTOFFRANGE };
|
m_rainsound;
|
||||||
sound_source dsbBuzzer { sound_placement::internal, EU07_SOUND_CABCONTROLSCUTOFFRANGE };
|
|
||||||
sound_source dsbSlipAlarm { sound_placement::internal, EU07_SOUND_CABCONTROLSCUTOFFRANGE }; // Bombardier 011010: alarm przy poslizgu dla 181/182
|
|
||||||
sound_source m_radiosound { sound_placement::internal, 2 * EU07_SOUND_CABCONTROLSCUTOFFRANGE }; // cached template for radio messages
|
sound_source m_radiosound { sound_placement::internal, 2 * EU07_SOUND_CABCONTROLSCUTOFFRANGE }; // cached template for radio messages
|
||||||
std::vector<std::pair<int, std::shared_ptr<sound_source>>> m_radiomessages; // list of currently played radio messages
|
std::vector<std::pair<int, std::shared_ptr<sound_source>>> m_radiomessages; // list of currently played radio messages
|
||||||
sound_source m_radiostop { sound_placement::internal, EU07_SOUND_CABCONTROLSCUTOFFRANGE };
|
float m_lastlocalbrakepressure { -1.f }; // helper, cached level of pressure in local brake cylinder
|
||||||
sound_source m_distancecounterclear { sound_placement::internal, EU07_SOUND_CABCONTROLSCUTOFFRANGE }; // distance meter 'good to go' alert
|
float m_localbrakepressurechange { 0.f }; // recent change of pressure in local brake cylinder
|
||||||
/*
|
/*
|
||||||
int iCabLightFlag; // McZapkie:120503: oswietlenie kabiny (0: wyl, 1: przyciemnione, 2: pelne)
|
int iCabLightFlag; // McZapkie:120503: oswietlenie kabiny (0: wyl, 1: przyciemnione, 2: pelne)
|
||||||
bool bCabLight; // hunter-091012: czy swiatlo jest zapalone?
|
bool bCabLight; // hunter-091012: czy swiatlo jest zapalone?
|
||||||
|
|||||||
Reference in New Issue
Block a user