16
0
mirror of https://github.com/MaSzyna-EU07/maszyna.git synced 2026-07-24 06:29:18 +02:00

combined rain sound support, soundproofing customization support, event diagnostics enhancement, power grid diagnostics enhancement, windowed full screen mode, ai coupling logic tweaks, minor bug fixes

This commit is contained in:
tmj-fstate
2020-10-01 03:01:17 +02:00
parent 4da87e98d9
commit 730ba72516
20 changed files with 234 additions and 186 deletions

View File

@@ -2021,9 +2021,7 @@ void TController::Activation()
if (initiallocalbrakelevel > 0.0) // hamowanie tylko jeśli był wcześniej zahamowany (bo możliwe, że jedzie!) if (initiallocalbrakelevel > 0.0) // hamowanie tylko jeśli był wcześniej zahamowany (bo możliwe, że jedzie!)
mvOccupied->LocalBrakePosA = initiallocalbrakelevel; // zahamuj jak wcześniej mvOccupied->LocalBrakePosA = initiallocalbrakelevel; // zahamuj jak wcześniej
*/ */
if( initialspringbrakestate ) { mvOccupied->SpringBrakeActivate( initialspringbrakestate );
mvOccupied->SpringBrakeActivate( initialspringbrakestate );
}
CheckVehicles(); // sprawdzenie składu, AI zapali światła CheckVehicles(); // sprawdzenie składu, AI zapali światła
TableClear(); // resetowanie tabelki skanowania torów TableClear(); // resetowanie tabelki skanowania torów
} }
@@ -2292,11 +2290,15 @@ bool TController::CheckVehicles(TOrders user)
if (p->Mechanik != this) // ale chodzi o inny pojazd, niż aktualnie sprawdzający if (p->Mechanik != this) // ale chodzi o inny pojazd, niż aktualnie sprawdzający
if( p->Mechanik->iDrivigFlags & movePrimary ) { if( p->Mechanik->iDrivigFlags & movePrimary ) {
// a tamten ma priorytet // a tamten ma priorytet
// TODO: take into account drivers' operating modes, one or more of them might be on banking duty
if( ( iDrivigFlags & movePrimary ) if( ( iDrivigFlags & movePrimary )
&& ( mvOccupied->DirAbsolute ) && ( mvOccupied->DirAbsolute )
&& ( mvOccupied->BrakeCtrlPos >= -1 ) ) { && ( mvOccupied->BrakeCtrlPos >= -1 ) ) {
// jeśli rządzi i ma kierunek // jeśli rządzi i ma kierunek
p->Mechanik->primary( false ); // dezaktywuje tamtego p->Mechanik->primary( false ); // dezaktywuje tamtego
p->Mechanik->ZeroLocalBrake();
p->MoverParameters->BrakeLevelSet( p->MoverParameters->Handle->GetPos( bh_NP ) ); // odcięcie na zaworze maszynisty
p->Mechanik->BrakeLevelSet( p->MoverParameters->BrakeCtrlPos ); //ustawienie zmiennej GBH
} }
else { else {
main = false; // nici z rządzenia main = false; // nici z rządzenia
@@ -2445,6 +2447,14 @@ bool TController::CheckVehicles(TOrders user)
|| ( mvControlling->EngineType == TEngineType::DieselEngine ) ) ? ( Global.AirTemperature < 10 ) : || ( mvControlling->EngineType == TEngineType::DieselEngine ) ) ? ( Global.AirTemperature < 10 ) :
true ); true );
} }
if( ( true == TestFlag( iDrivigFlags, moveConnect ) )
&& ( true == TestFlag( OrderCurrentGet(), Connect ) ) ) {
iCoupler = 0; // dalsza jazda manewrowa już bez łączenia
iDrivigFlags &= ~moveConnect; // zdjęcie flagi doczepiania
SetVelocity( 0, 0, stopJoin ); // wyłączyć przyspieszanie
JumpToNextOrder(); // wykonanie następnej komendy
}
} }
else { // gdy człowiek i gdy nastąpiło połącznie albo rozłączenie else { // gdy człowiek i gdy nastąpiło połącznie albo rozłączenie
// Ra 2014-02: lepiej tu niż w pętli obsługującej komendy, bo tam się zmieni informacja o składzie // Ra 2014-02: lepiej tu niż w pętli obsługującej komendy, bo tam się zmieni informacja o składzie
@@ -2808,6 +2818,9 @@ bool TController::PrepareEngine()
if( lookup != brakepositions.end() ) { if( lookup != brakepositions.end() ) {
BrakeLevelSet( lookup->second ); // GBH BrakeLevelSet( lookup->second ); // GBH
} }
// sync spring brake state across consist
mvOccupied->SpringBrakeActivate( mvOccupied->SpringBrake.Activate );
OK = ( false == IsAnyConverterOverloadRelayOpen ) OK = ( false == IsAnyConverterOverloadRelayOpen )
&& ( VelforDriver == -1 ); && ( VelforDriver == -1 );
} }
@@ -3479,17 +3492,28 @@ bool TController::IncSpeed()
} }
break; break;
case TEngineType::ElectricInductionMotor: case TEngineType::ElectricInductionMotor:
if (!IsAnyMotorOverloadRelayOpen) if( !IsAnyMotorOverloadRelayOpen ) {
if (Ready || (iDrivigFlags & movePress) || (mvOccupied->ShuntMode)) //{(BrakePress<=0.01*MaxBrakePress)} if( Ready || ( iDrivigFlags & movePress ) || ( mvOccupied->ShuntMode ) ) //{(BrakePress<=0.01*MaxBrakePress)}
{ {
OK = IncSpeedEIM(); OK = IncSpeedEIM();
// cruise control if( ( mvControlling->SpeedCtrl ) && ( mvControlling->Mains ) ) {
auto const SpeedCntrlVel { ( // cruise control
( ActualProximityDist > std::max( 50.0, fMaxProximityDist ) ) ? auto const couplinginprogress{ ( true == TestFlag( iDrivigFlags, moveConnect ) ) && ( true == TestFlag( OrderCurrentGet(), Connect ) ) };
VelDesired : auto const SpeedCntrlVel{ (
min_speed( VelDesired, VelNext ) ) }; ( ActualProximityDist > std::max( 50.0, fMaxProximityDist ) ) || ( couplinginprogress ) ?
SpeedCntrl(SpeedCntrlVel); VelDesired :
min_speed( VelDesired, VelNext ) ) };
if( ( SpeedCntrlVel >= mvControlling->SpeedCtrlUnit.MinVelocity )
&& ( SpeedCntrlVel - mvControlling->SpeedCtrlUnit.MinVelocity == quantize( SpeedCntrlVel - mvControlling->SpeedCtrlUnit.MinVelocity, mvControlling->SpeedCtrlUnit.VelocityStep ) ) ) {
SpeedCntrl( SpeedCntrlVel );
}
else if( SpeedCntrlVel > 0.1 ) {
SpeedCntrl( 0.0 );
mvControlling->DecScndCtrl( 2 );
}
}
} }
}
break; break;
case TEngineType::WheelsDriven: case TEngineType::WheelsDriven:
if (!mvControlling->CabActive) if (!mvControlling->CabActive)
@@ -3505,16 +3529,19 @@ bool TController::IncSpeed()
// mvControlling->ShuntMode=(OrderList[OrderPos]&Shunt)||(fMass>224000.0); // mvControlling->ShuntMode=(OrderList[OrderPos]&Shunt)||(fMass>224000.0);
} }
if ((mvControlling->SpeedCtrl)&&(mvControlling->Mains)) {// cruise control if ((mvControlling->SpeedCtrl)&&(mvControlling->Mains)) {// cruise control
auto const SpeedCntrlVel{ ( auto const couplinginprogress { ( true == TestFlag( iDrivigFlags, moveConnect ) ) && ( true == TestFlag( OrderCurrentGet(), Connect ) ) };
(ActualProximityDist > std::max(50.0, fMaxProximityDist)) ? auto const SpeedCntrlVel { (
VelDesired : ( ActualProximityDist > std::max( 50.0, fMaxProximityDist ) ) || ( couplinginprogress ) ?
min_speed(VelDesired, VelNext)) }; VelDesired :
if (SpeedCntrlVel >= mvControlling->SpeedCtrlUnit.MinVelocity) { min_speed( VelDesired, VelNext ) ) };
SpeedCntrl(SpeedCntrlVel); if( ( SpeedCntrlVel >= mvControlling->SpeedCtrlUnit.MinVelocity )
} && ( SpeedCntrlVel - mvControlling->SpeedCtrlUnit.MinVelocity == quantize( SpeedCntrlVel - mvControlling->SpeedCtrlUnit.MinVelocity, mvControlling->SpeedCtrlUnit.VelocityStep ) ) ) {
else if (SpeedCntrlVel > 0.1) { SpeedCntrl(SpeedCntrlVel);
SpeedCntrl(0.0); }
} else if (SpeedCntrlVel > 0.1) {
SpeedCntrl(0.0);
mvControlling->DecScndCtrl( 2 );
}
} }
if (mvControlling->EIMCtrlType > 0) { if (mvControlling->EIMCtrlType > 0) {
if (true == Ready) if (true == Ready)
@@ -3538,6 +3565,7 @@ bool TController::IncSpeed()
} }
if( false == mvControlling->Mains ) { if( false == mvControlling->Mains ) {
SpeedCntrl(0.0); SpeedCntrl(0.0);
mvControlling->DecScndCtrl( 2 );
mvOccupied->MainSwitch( true ); mvOccupied->MainSwitch( true );
mvOccupied->ConverterSwitch( true ); mvOccupied->ConverterSwitch( true );
mvOccupied->CompressorSwitch( true ); mvOccupied->CompressorSwitch( true );
@@ -5428,11 +5456,7 @@ TController::UpdateSituation(double dt) {
iCoupler ); iCoupler );
if( vehicleparameters->Couplers[ end ].CouplingFlag == iCoupler ) { if( vehicleparameters->Couplers[ end ].CouplingFlag == iCoupler ) {
// jeżeli został podłączony // jeżeli został podłączony
iCoupler = 0; // dalsza jazda manewrowa już bez łączenia
iDrivigFlags &= ~moveConnect; // zdjęcie flagi doczepiania
SetVelocity( 0, 0, stopJoin ); // wyłączyć przyspieszanie
CheckVehicles( Connect ); // sprawdzić światła nowego składu CheckVehicles( Connect ); // sprawdzić światła nowego składu
JumpToNextOrder(); // wykonanie następnej komendy
} }
} }
} }

View File

@@ -6284,6 +6284,17 @@ void TDynamicObject::LoadMMediaFile( std::string const &TypeName, std::string co
>> HuntingShake.fadein_end; >> HuntingShake.fadein_end;
} }
else if( token == "soundproofing:" ) {
for( auto &soundproofingtable : m_soundproofing ) {
for( auto &soundproofingelement : soundproofingtable ) {
auto const value { parser.getToken<float>( false ) };
if( value != -1.f ) {
soundproofingelement = std::sqrtf( clamp( value, 0.f, 1.f ) );
}
}
}
}
else if( token == "jointcabs:" ) { else if( token == "jointcabs:" ) {
parser.getTokens(); parser.getTokens();
parser >> JointCabs; parser >> JointCabs;
@@ -6786,7 +6797,8 @@ TDynamicObject::update_neighbours() {
neighbour.vehicle_end = std::get<int>( lookup ); neighbour.vehicle_end = std::get<int>( lookup );
neighbour.distance = std::get<double>( lookup ); neighbour.distance = std::get<double>( lookup );
if( neighbour.distance < ( neighbour.vehicle->MoverParameters->CategoryFlag == 2 ? 50 : 100 ) ) { if( ( neighbour.vehicle )
&& ( neighbour.distance < ( neighbour.vehicle->MoverParameters->CategoryFlag == 2 ? 50 : 100 ) ) ) {
// at short distances (re)calculate range between couplers directly // at short distances (re)calculate range between couplers directly
neighbour.distance = TMoverParameters::CouplerDist( MoverParameters, neighbour.vehicle->MoverParameters ); neighbour.distance = TMoverParameters::CouplerDist( MoverParameters, neighbour.vehicle->MoverParameters );
// take into account potential adapters attached to the couplers // take into account potential adapters attached to the couplers
@@ -6835,7 +6847,9 @@ TDynamicObject::find_vehicle( int const Direction, double const Distance ) const
// jeśli następny tor jest podpięty od Point2 // jeśli następny tor jest podpięty od Point2
direction = -direction; // to zmieniamy kierunek szukania na tym torze direction = -direction; // to zmieniamy kierunek szukania na tym torze
} }
track = track->CurrentNext(); // potem dopiero zmieniamy wskaźnik if( track ) {
track = track->CurrentNext(); // potem dopiero zmieniamy wskaźnik
}
} }
else { else {
// w kierunku Point1 // w kierunku Point1
@@ -6845,7 +6859,9 @@ TDynamicObject::find_vehicle( int const Direction, double const Distance ) const
// jeśli poprzedni tor nie jest podpięty od Point2 // jeśli poprzedni tor nie jest podpięty od Point2
direction = -direction; // to zmieniamy kierunek szukania na tym torze direction = -direction; // to zmieniamy kierunek szukania na tym torze
} }
track = track->CurrentPrev(); // potem dopiero zmieniamy wskaźnik if( track ) {
track = track->CurrentPrev(); // potem dopiero zmieniamy wskaźnik
}
} }
if (track) { if (track) {
// jesli jest kolejny odcinek toru // jesli jest kolejny odcinek toru

View File

@@ -516,6 +516,16 @@ private:
std::vector<doorspeaker_sounds> m_doorspeakers; std::vector<doorspeaker_sounds> m_doorspeakers;
pasystem_sounds m_pasystem; pasystem_sounds m_pasystem;
std::array<
std::array<float, 6> // listener: rear cab, engine, front cab, window, attached camera, free camera
, 5> m_soundproofing = {{
{{ EU07_SOUNDPROOFING_NONE, EU07_SOUNDPROOFING_STRONG, EU07_SOUNDPROOFING_NONE, EU07_SOUNDPROOFING_SOME, EU07_SOUNDPROOFING_STRONG, EU07_SOUNDPROOFING_STRONG }}, // internal sounds
{{ EU07_SOUNDPROOFING_STRONG, EU07_SOUNDPROOFING_NONE, EU07_SOUNDPROOFING_STRONG, EU07_SOUNDPROOFING_SOME, EU07_SOUNDPROOFING_SOME, EU07_SOUNDPROOFING_SOME }}, // engine sounds
{{ EU07_SOUNDPROOFING_STRONG, EU07_SOUNDPROOFING_STRONG, EU07_SOUNDPROOFING_STRONG, EU07_SOUNDPROOFING_SOME, EU07_SOUNDPROOFING_SOME, EU07_SOUNDPROOFING_NONE }}, // external sound
{{ EU07_SOUNDPROOFING_VERYSTRONG, EU07_SOUNDPROOFING_VERYSTRONG, EU07_SOUNDPROOFING_VERYSTRONG, EU07_SOUNDPROOFING_STRONG, EU07_SOUNDPROOFING_STRONG, EU07_SOUNDPROOFING_NONE }}, // external ambient sound
{{ EU07_SOUNDPROOFING_NONE, EU07_SOUNDPROOFING_NONE, EU07_SOUNDPROOFING_NONE, EU07_SOUNDPROOFING_NONE, EU07_SOUNDPROOFING_NONE, EU07_SOUNDPROOFING_NONE }}, // custom sounds
}};
coupleradapter_data m_coupleradapter; coupleradapter_data m_coupleradapter;
bool renderme; // yB - czy renderowac bool renderme; // yB - czy renderowac
@@ -729,6 +739,9 @@ private:
void move_set(double distance); void move_set(double distance);
// playes specified announcement, potentially preceding it with a chime // playes specified announcement, potentially preceding it with a chime
void announce( announcement_t const Announcement, bool const Chime = true ); void announce( announcement_t const Announcement, bool const Chime = true );
// returns soundproofing for specified sound type and listener location
float soundproofing( int const Placement, int const Listener ) const {
return m_soundproofing[ Placement - 1 ][ Listener + 1 ]; }
double MED[9][8]; // lista zmiennych do debugowania hamulca ED double MED[9][8]; // lista zmiennych do debugowania hamulca ED
static std::string const MED_labels[ 8 ]; static std::string const MED_labels[ 8 ];

View File

@@ -523,7 +523,6 @@ updatevalues_event::run_() {
+ ( ( m_input.flags & flags::text ) ? m_input.data_text : "X" ) + "] [" + ( ( m_input.flags & flags::text ) ? m_input.data_text : "X" ) + "] ["
+ ( ( m_input.flags & flags::value1 ) ? to_string( m_input.data_value_1, 2 ) : "X" ) + "] [" + ( ( m_input.flags & flags::value1 ) ? to_string( m_input.data_value_1, 2 ) : "X" ) + "] ["
+ ( ( m_input.flags & flags::value2 ) ? to_string( m_input.data_value_2, 2 ) : "X" ) + "]" ); + ( ( m_input.flags & flags::value2 ) ? to_string( m_input.data_value_2, 2 ) : "X" ) + "]" );
// TODO: dump status of target cells after the operation
for( auto &target : m_targets ) { for( auto &target : m_targets ) {
auto *targetcell { static_cast<TMemCell *>( std::get<scene::basic_node *>( target ) ) }; auto *targetcell { static_cast<TMemCell *>( std::get<scene::basic_node *>( target ) ) };
if( targetcell == nullptr ) { continue; } if( targetcell == nullptr ) { continue; }
@@ -532,13 +531,18 @@ updatevalues_event::run_() {
m_input.data_value_1, m_input.data_value_1,
m_input.data_value_2, m_input.data_value_2,
m_input.flags ); m_input.flags );
WriteLog( " Memcell: " + targetcell->name() + " - " + targetcell->Values() );
// targetcell->LogValues();
if( targetcell->Track == nullptr ) { continue; } if( targetcell->Track == nullptr ) { continue; }
// McZapkie-100302 - updatevalues oprocz zmiany wartosci robi putcommand dla wszystkich 'dynamic' na danym torze // McZapkie-100302 - updatevalues oprocz zmiany wartosci robi putcommand dla wszystkich 'dynamic' na danym torze
auto const location { targetcell->location() }; auto const location { targetcell->location() };
for( auto dynamic : targetcell->Track->Dynamics ) { for( auto vehicle : targetcell->Track->Dynamics ) {
targetcell->PutCommand( if( vehicle->Mechanik ) {
dynamic->Mechanik, targetcell->PutCommand(
&location ); vehicle->Mechanik,
&location );
WriteLog( " Vehicle: [" + vehicle->name() + "]" );
}
} }
} }
} }
@@ -771,8 +775,10 @@ putvalues_event::run_() {
m_input.location.z, m_input.location.z,
m_input.location.y }; m_input.location.y };
std::string vehiclename;
if( m_activator->Mechanik ) { if( m_activator->Mechanik ) {
// przekazanie rozkazu do AI // przekazanie rozkazu do AI
vehiclename = m_activator->Mechanik->Vehicle()->name();
m_activator->Mechanik->PutCommand( m_activator->Mechanik->PutCommand(
m_input.data_text, m_input.data_text,
m_input.data_value_1, m_input.data_value_1,
@@ -784,6 +790,7 @@ putvalues_event::run_() {
// send the command to consist owner, // send the command to consist owner,
// we're acting on presumption there's hardly ever need to issue command to unmanned vehicle // we're acting on presumption there's hardly ever need to issue command to unmanned vehicle
// and the intended recipient moved between vehicles after the event was queued // and the intended recipient moved between vehicles after the event was queued
vehiclename = m_activator->ctOwner->Vehicle()->name();
m_activator->ctOwner->PutCommand( m_activator->ctOwner->PutCommand(
m_input.data_text, m_input.data_text,
m_input.data_value_1, m_input.data_value_1,
@@ -792,12 +799,15 @@ putvalues_event::run_() {
} }
else { else {
// przekazanie do pojazdu // przekazanie do pojazdu
vehiclename = m_activator->name();
m_activator->MoverParameters->PutCommand( m_activator->MoverParameters->PutCommand(
m_input.data_text, m_input.data_text,
m_input.data_value_1, m_input.data_value_1,
m_input.data_value_2, m_input.data_value_2,
loc ); loc );
} }
WriteLog( " Vehicle: [" + vehiclename + "]" );
} }
// export_as_text() subclass details // export_as_text() subclass details
@@ -927,13 +937,18 @@ copyvalues_event::run_() {
m_input.data_value_1, m_input.data_value_1,
m_input.data_value_2, m_input.data_value_2,
m_input.flags ); m_input.flags );
WriteLog( " Memcell: " + targetcell->name() + " - " + targetcell->Values() );
// targetcell->LogValues();
if( targetcell->Track == nullptr ) { continue; } if( targetcell->Track == nullptr ) { continue; }
// McZapkie-100302 - updatevalues oprocz zmiany wartosci robi putcommand dla wszystkich 'dynamic' na danym torze // McZapkie-100302 - updatevalues oprocz zmiany wartosci robi putcommand dla wszystkich 'dynamic' na danym torze
auto const location { targetcell->location() }; auto const location { targetcell->location() };
for( auto dynamic : targetcell->Track->Dynamics ) { for( auto vehicle : targetcell->Track->Dynamics ) {
targetcell->PutCommand( if( vehicle->Mechanik ) {
dynamic->Mechanik, targetcell->PutCommand(
&location ); vehicle->Mechanik,
&location );
WriteLog( " Vehicle: [" + vehicle->name() + "]" );
}
} }
} }
} }
@@ -1142,11 +1157,7 @@ logvalues_event::run_() {
for( auto &target : m_targets ) { for( auto &target : m_targets ) {
auto *targetcell { static_cast<TMemCell *>( std::get<scene::basic_node *>( target ) ) }; auto *targetcell { static_cast<TMemCell *>( std::get<scene::basic_node *>( target ) ) };
if( targetcell == nullptr ) { continue; } if( targetcell == nullptr ) { continue; }
WriteLog( targetcell->LogValues();
"Memcell \"" + targetcell->name() + "\": ["
+ targetcell->Text() + "] ["
+ to_string( targetcell->Value1(), 2 ) + "] ["
+ to_string( targetcell->Value2(), 2 ) + "]" );
} }
} }
} }

View File

@@ -100,6 +100,10 @@ global_settings::ConfigParse(cParser &Parser) {
Parser.getTokens(1, false); Parser.getTokens(1, false);
Parser >> fullscreen_monitor; Parser >> fullscreen_monitor;
} }
else if( token == "fullscreenwindowed" ) {
Parser.getTokens();
Parser >> fullscreen_windowed;
}
else if( token == "vsync" ) { else if( token == "vsync" ) {
Parser.getTokens(); Parser.getTokens();
@@ -987,6 +991,7 @@ global_settings::export_as_text( std::ostream &Output ) const {
export_as_text( Output, "basedrawrange", BaseDrawRange ); export_as_text( Output, "basedrawrange", BaseDrawRange );
export_as_text( Output, "fullscreen", bFullScreen ); export_as_text( Output, "fullscreen", bFullScreen );
export_as_text( Output, "fullscreenmonitor", fullscreen_monitor ); export_as_text( Output, "fullscreenmonitor", fullscreen_monitor );
export_as_text( Output, "fullscreenwindowed", fullscreen_windowed );
export_as_text( Output, "vsync", VSync ); export_as_text( Output, "vsync", VSync );
// NOTE: values are changed dynamically during simulation. cache initial settings and export instead // NOTE: values are changed dynamically during simulation. cache initial settings and export instead
if( FreeFlyModeFlag ) { if( FreeFlyModeFlag ) {

View File

@@ -203,6 +203,7 @@ struct global_settings {
std::chrono::duration<float> minframetime{ 0.0f }; std::chrono::duration<float> minframetime{ 0.0f };
std::string fullscreen_monitor; std::string fullscreen_monitor;
bool fullscreen_windowed{ false };
bool python_enabled = true; bool python_enabled = true;
bool python_mipmaps = true; bool python_mipmaps = true;

View File

@@ -1717,13 +1717,17 @@ void TMoverParameters::PowerCouplersCheck( double const Deltatime, coupling cons
for( auto side = 0; side < 2; ++side ) { for( auto side = 0; side < 2; ++side ) {
auto &coupler { Couplers[ side ] }; auto &coupler { Couplers[ side ] };
auto const &connectedothercoupler { coupler.Connected->Couplers[ ( coupler.ConnectedNr == end::front ? end::rear : end::front ) ] };
auto *coupling = ( auto *coupling = (
Coupling == coupling::highvoltage ? &coupler.power_high : Coupling == coupling::highvoltage ? &coupler.power_high :
Coupling == coupling::power110v ? &coupler.power_110v : Coupling == coupling::power110v ? &coupler.power_110v :
Coupling == coupling::power24v ? &coupler.power_24v : Coupling == coupling::power24v ? &coupler.power_24v :
nullptr ); nullptr );
coupling->current = 0.0;
if( coupler.Connected == nullptr ) { continue; }
auto const &connectedothercoupler { coupler.Connected->Couplers[ ( coupler.ConnectedNr == end::front ? end::rear : end::front ) ] };
auto const *connectedothercoupling = ( auto const *connectedothercoupling = (
Coupling == coupling::highvoltage ? &connectedothercoupler.power_high : Coupling == coupling::highvoltage ? &connectedothercoupler.power_high :
Coupling == coupling::power110v ? &connectedothercoupler.power_110v : Coupling == coupling::power110v ? &connectedothercoupler.power_110v :
@@ -1733,7 +1737,6 @@ void TMoverParameters::PowerCouplersCheck( double const Deltatime, coupling cons
Coupling == coupling::highvoltage ? std::abs( Itot ) * IsVehicleEIMBrakingFactor() : Coupling == coupling::highvoltage ? std::abs( Itot ) * IsVehicleEIMBrakingFactor() :
0.0 ); 0.0 );
coupling->current = 0.0;
if( false == localpowersource ) { if( false == localpowersource ) {
// bez napiecia... // bez napiecia...
if( couplervoltage != 0.0 ) { if( couplervoltage != 0.0 ) {
@@ -3493,7 +3496,7 @@ bool TMoverParameters::MainSwitchCheck() const {
} }
case TEngineType::ElectricSeriesMotor: case TEngineType::ElectricSeriesMotor:
case TEngineType::ElectricInductionMotor: { case TEngineType::ElectricInductionMotor: {
powerisavailable == ( std::max( GetTrainsetHighVoltage(), PantographVoltage ) > 0.5 * EnginePowerSource.MaxVoltage ); powerisavailable = ( std::max( GetTrainsetHighVoltage(), PantographVoltage ) > 0.5 * EnginePowerSource.MaxVoltage );
break; break;
} }
default: { default: {

View File

@@ -205,6 +205,16 @@ void TMemCell::AssignEvents(basic_event *e)
OnSent = e; OnSent = e;
}; };
std::string TMemCell::Values() const {
return { "[" + Text() + "] [" + to_string( Value1(), 2 ) + "] [" + to_string( Value2(), 2 ) + "]" };
}
void TMemCell::LogValues() const {
WriteLog( "Memcell " + name() + ": " + Values() );
}
// serialize() subclass details, sends content of the subclass to provided stream // serialize() subclass details, sends content of the subclass to provided stream
void void
TMemCell::serialize_( std::ostream &Output ) const { TMemCell::serialize_( std::ostream &Output ) const {
@@ -264,10 +274,6 @@ void
memory_table::log_all() { memory_table::log_all() {
for( auto *cell : m_items ) { for( auto *cell : m_items ) {
cell->LogValues();
WriteLog( "Memcell \"" + cell->name() + "\": ["
+ cell->Text() + "] ["
+ to_string( cell->Value1(), 2 ) + "] ["
+ to_string( cell->Value2(), 2 ) + "]" );
} }
} }

View File

@@ -51,6 +51,8 @@ public:
TCommandType CommandCheck(); TCommandType CommandCheck();
bool IsVelocity() const; bool IsVelocity() const;
void AssignEvents(basic_event *e); void AssignEvents(basic_event *e);
std::string Values() const;
void LogValues() const;
// members // members
std::string asTrackName; // McZapkie-100302 - zeby nazwe toru na ktory jest Putcommand wysylane pamietac std::string asTrackName; // McZapkie-100302 - zeby nazwe toru na ktory jest Putcommand wysylane pamietac
TTrack *Track { nullptr }; // resolved binding with the specified track TTrack *Track { nullptr }; // resolved binding with the specified track

View File

@@ -372,6 +372,8 @@ TTraction::Connect(int my, TTraction *with, int to) {
iLast = 0; iLast = 0;
} }
if( with == nullptr ) { return; }
with->hvNext[ to ] = this; with->hvNext[ to ] = this;
with->iNext[ to ] = my; with->iNext[ to ] = my;

View File

@@ -74,7 +74,7 @@ bool TTractionPowerSource::Load(cParser *parser) {
bool TTractionPowerSource::Update(double dt) bool TTractionPowerSource::Update(double dt)
{ // powinno być wykonane raz na krok fizyki { // powinno być wykonane raz na krok fizyki
// iloczyn napięcia i admitancji daje prąd // iloczyn napięcia i admitancji daje prąd
if (NominalVoltage * TotalPreviousAdmitance > MaxOutputCurrent) { if (TotalCurrent > MaxOutputCurrent) {
FastFuse = true; FastFuse = true;
FuseCounter += 1; FuseCounter += 1;

View File

@@ -5573,10 +5573,10 @@ void TTrain::OnCommand_occupiedcarcouplingdisconnect( TTrain *Train, command_dat
if( Train->DynamicObject ) { if( Train->DynamicObject ) {
Train->DynamicObject->uncouple( Train->cab_to_end() ); Train->DynamicObject->uncouple( Train->cab_to_end() );
} if( Train->DynamicObject->Mechanik ) {
if( Train->DynamicObject->Mechanik ) { // aktualizacja flag kierunku w składzie
// aktualizacja flag kierunku w składzie Train->DynamicObject->Mechanik->CheckVehicles( Disconnect );
Train->DynamicObject->Mechanik->CheckVehicles( Disconnect ); }
} }
} }
else if( Command.action == GLFW_RELEASE ) { else if( Command.action == GLFW_RELEASE ) {
@@ -5937,15 +5937,17 @@ void TTrain::OnCommand_vehicleboost(TTrain *Train, const command_data &Command)
double boost = Command.param1 != 0.0 ? Command.param1 : 2.78; double boost = Command.param1 != 0.0 ? Command.param1 : 2.78;
TDynamicObject *d = Train->DynamicObject; if( Train->DynamicObject == nullptr ) { return; }
while( d ) {
d->MoverParameters->V += d->DirectionGet() * boost; auto *vehicle { Train->DynamicObject };
d = d->Next(); // pozostałe też while( vehicle ) {
vehicle->MoverParameters->V += vehicle->DirectionGet() * boost;
vehicle = vehicle->Next(); // pozostałe też
} }
d = Train->DynamicObject->Prev(); vehicle = Train->DynamicObject->Prev();
while( d ) { while( vehicle ) {
d->MoverParameters->V += d->DirectionGet() * boost; vehicle->MoverParameters->V += vehicle->DirectionGet() * boost;
d = d->Prev(); // w drugą stronę też vehicle = vehicle->Prev(); // w drugą stronę też
} }
} }
@@ -6491,15 +6493,6 @@ bool TTrain::Update( double const Deltatime )
btLampkaPoslizg.Turn( false ); btLampkaPoslizg.Turn( false );
} }
if ((mvControlled->Mains) || (mvControlled->TrainType == dt_EZT))
{
btLampkaNadmSil.Turn(mvControlled->FuseFlagCheck());
}
else
{
btLampkaNadmSil.Turn( false );
}
if( true == lowvoltagepower ) { if( true == lowvoltagepower ) {
// alerter test // alerter test
if( true == CAflag ) { if( true == CAflag ) {
@@ -6578,6 +6571,11 @@ bool TTrain::Update( double const Deltatime )
false : false :
( mvControlled->BrakePress < 1.0 ) ); // relay is off and needs a reset ( mvControlled->BrakePress < 1.0 ) ); // relay is off and needs a reset
btLampkaNadmSil.Turn(
( ( false == mvControlled->FuseFlagCheck() ) || ( mvControlled->ControlPressureSwitch ) ) ?
false :
( mvControlled->BrakePress < 1.0 ) ); // relay is off and needs a reset
if( ( ( mvControlled->CabOccupied == 1 ) && ( TestFlag( mvControlled->Couplers[ end::rear ].CouplingFlag, coupling::control ) ) ) if( ( ( mvControlled->CabOccupied == 1 ) && ( TestFlag( mvControlled->Couplers[ end::rear ].CouplingFlag, coupling::control ) ) )
|| ( ( mvControlled->CabOccupied == -1 ) && ( TestFlag( mvControlled->Couplers[ end::front ].CouplingFlag, coupling::control ) ) ) ) { || ( ( mvControlled->CabOccupied == -1 ) && ( TestFlag( mvControlled->Couplers[ end::front ].CouplingFlag, coupling::control ) ) ) ) {
btLampkaUkrotnienie.Turn( true ); btLampkaUkrotnienie.Turn( true );
@@ -7398,10 +7396,15 @@ TTrain::update_sounds( double const Deltatime ) {
if( ( false == FreeFlyModeFlag ) if( ( false == FreeFlyModeFlag )
&& ( false == Global.CabWindowOpen ) && ( false == Global.CabWindowOpen )
&& ( Global.Weather == "rain:" ) ) { && ( Global.Weather == "rain:" ) ) {
m_precipitationsound.play( sound_flags::exclusive | sound_flags::looping ); if( m_rainsound.is_combined() ) {
m_rainsound.pitch( Global.Overcast - 1.0 );
}
m_rainsound
.gain( m_rainsound.m_amplitudeoffset + m_rainsound.m_amplitudefactor * 1.f )
.play( sound_flags::exclusive | sound_flags::looping );
} }
else { else {
m_precipitationsound.stop(); m_rainsound.stop();
} }
if( fTachoCount >= 3.f ) { if( fTachoCount >= 3.f ) {
@@ -7743,8 +7746,8 @@ bool TTrain::LoadMMediaFile(std::string const &asFileName)
} }
else if( token == "rainsound:" ) { else if( token == "rainsound:" ) {
// precipitation sound: // precipitation sound:
m_precipitationsound.deserialize( parser, sound_type::single ); m_rainsound.deserialize( parser, sound_type::single );
m_precipitationsound.owner( DynamicObject ); m_rainsound.owner( DynamicObject );
} }
} while (token != ""); } while (token != "");
@@ -8055,9 +8058,9 @@ bool TTrain::InitializeCab(int NewCabNo, std::string const &asFileName)
{ {
*/ */
// assign default samples to sound emitters which weren't included in the config file // assign default samples to sound emitters which weren't included in the config file
if( m_precipitationsound.empty() ) { if( m_rainsound.empty() ) {
m_precipitationsound.deserialize( "rainsound_default", sound_type::single ); m_rainsound.deserialize( "rainsound_default", sound_type::single );
m_precipitationsound.owner( DynamicObject ); 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 // try first to bind sounds to location of possible devices

View File

@@ -726,7 +726,7 @@ public: // reszta może by?publiczna
sound_source rsFadeSound { sound_placement::internal, EU07_SOUND_CABCONTROLSCUTOFFRANGE }; sound_source rsFadeSound { sound_placement::internal, EU07_SOUND_CABCONTROLSCUTOFFRANGE };
sound_source rsRunningNoise{ sound_placement::internal, EU07_SOUND_GLOBALRANGE }; sound_source rsRunningNoise{ sound_placement::internal, EU07_SOUND_GLOBALRANGE };
sound_source rsHuntingNoise{ sound_placement::internal, EU07_SOUND_GLOBALRANGE }; sound_source rsHuntingNoise{ sound_placement::internal, EU07_SOUND_GLOBALRANGE };
sound_source m_precipitationsound { sound_placement::internal, -1 }; sound_source m_rainsound { sound_placement::internal, -1 };
sound_source dsbHasler { sound_placement::internal, EU07_SOUND_CABCONTROLSCUTOFFRANGE }; sound_source dsbHasler { sound_placement::internal, EU07_SOUND_CABCONTROLSCUTOFFRANGE };
sound_source dsbBuzzer { sound_placement::internal, EU07_SOUND_CABCONTROLSCUTOFFRANGE }; sound_source dsbBuzzer { sound_placement::internal, EU07_SOUND_CABCONTROLSCUTOFFRANGE };

View File

@@ -763,8 +763,16 @@ eu07_application::init_glfw() {
} }
} }
if( Global.fullscreen_windowed ) {
// overwrite resolution settings to match default monitor
auto const mode = glfwGetVideoMode( monitor );
Global.iWindowWidth = mode->width;
Global.iWindowHeight = mode->height;
glfwWindowHint( GLFW_DECORATED, GLFW_FALSE );
monitor = nullptr;
}
auto *mainwindow = window( auto *mainwindow = window(
-1, true, Global.iWindowWidth, Global.iWindowHeight, Global.bFullScreen ? monitor : nullptr, true, false ); -1, true, Global.iWindowWidth, Global.iWindowHeight, ( Global.bFullScreen ? monitor : nullptr ), true, false );
if( mainwindow == nullptr ) { if( mainwindow == nullptr ) {
ErrorLog( "Bad init: failed to create glfw window" ); ErrorLog( "Bad init: failed to create glfw window" );

View File

@@ -573,7 +573,8 @@ driver_mode::update_camera( double const Deltatime ) {
// uwzględnienie ruchu wywołanego klawiszami // uwzględnienie ruchu wywołanego klawiszami
if( false == DebugCameraFlag ) { if( false == DebugCameraFlag ) {
// regular camera // regular camera
if( ( false == FreeFlyModeFlag ) if( ( simulation::Train != nullptr )
&& ( false == FreeFlyModeFlag )
&& ( false == Global.CabWindowOpen ) ) { && ( false == Global.CabWindowOpen ) ) {
// if in cab potentially alter camera placement based on changes in train object // if in cab potentially alter camera placement based on changes in train object
Camera.m_owneroffset = simulation::Train->pMechOffset; Camera.m_owneroffset = simulation::Train->pMechOffset;
@@ -583,12 +584,14 @@ driver_mode::update_camera( double const Deltatime ) {
Camera.Update(); Camera.Update();
if( false == FreeFlyModeFlag ) { if( ( simulation::Train != nullptr )
&& ( false == FreeFlyModeFlag ) ) {
// keep the camera within cab boundaries // keep the camera within cab boundaries
Camera.m_owneroffset = simulation::Train->clamp_inside( Camera.m_owneroffset ); Camera.m_owneroffset = simulation::Train->clamp_inside( Camera.m_owneroffset );
} }
if( ( false == FreeFlyModeFlag ) if( ( simulation::Train != nullptr )
&& ( false == FreeFlyModeFlag )
&& ( false == Global.CabWindowOpen ) ) { && ( false == Global.CabWindowOpen ) ) {
// cache cab camera in case of view type switch // cache cab camera in case of view type switch
simulation::Train->pMechViewAngle = { Camera.Angle.x, Camera.Angle.y }; simulation::Train->pMechViewAngle = { Camera.Angle.x, Camera.Angle.y };

View File

@@ -1149,7 +1149,7 @@ debug_panel::update_section_powergrid( std::vector<text_line> &Output ) {
auto const lowpowercolor { glm::vec4( 164.0f / 255.0f, 132.0f / 255.0f, 84.0f / 255.0f, 1.f ) }; auto const lowpowercolor { glm::vec4( 164.0f / 255.0f, 132.0f / 255.0f, 84.0f / 255.0f, 1.f ) };
auto const nopowercolor { glm::vec4( 164.0f / 255.0f, 84.0f / 255.0f, 84.0f / 255.0f, 1.f ) }; auto const nopowercolor { glm::vec4( 164.0f / 255.0f, 84.0f / 255.0f, 84.0f / 255.0f, 1.f ) };
Output.emplace_back( "Name: Output: Timeout:", Global.UITextColor ); Output.emplace_back( "Name: Output: Current: Timeout:", Global.UITextColor );
std::string textline; std::string textline;
@@ -1166,7 +1166,8 @@ debug_panel::update_section_powergrid( std::vector<text_line> &Output ) {
textline = textline =
name.substr( 0, 20 ) name.substr( 0, 20 )
+ " " + to_string( powerstation->OutputVoltage, 0, 5 ) + " " + to_string( powerstation->OutputVoltage, 0, 5 )
+ " " + to_string( powerstation->FuseTimer, 1, 12 ) + " " + to_string( powerstation->TotalCurrent, 1, 8 )
+ " " + to_string( powerstation->FuseTimer, 1, 8 )
+ ( powerstation->FuseCounter == 0 ? + ( powerstation->FuseCounter == 0 ?
"" : "" :
" (x" + to_string( powerstation->FuseCounter ) + ")" ); " (x" + to_string( powerstation->FuseCounter ) + ")" );
@@ -1218,7 +1219,8 @@ debug_panel::update_section_renderer( std::vector<text_line> &Output ) {
+ ", Draw range: " + to_string( Global.BaseDrawRange * Global.fDistanceFactor, 0 ) + "m" + ", Draw range: " + to_string( Global.BaseDrawRange * Global.fDistanceFactor, 0 ) + "m"
// + "; sectors: " + std::to_string( GfxRenderer->m_drawcount ) // + "; sectors: " + std::to_string( GfxRenderer->m_drawcount )
// + ", FPS: " + to_string( Timer::GetFPS(), 2 ); // + ", FPS: " + to_string( Timer::GetFPS(), 2 );
+ ", FPS: " + std::to_string( static_cast<int>(std::round(GfxRenderer->Framerate())) ); + ", FPS: " + std::to_string( static_cast<int>(std::round(GfxRenderer->Framerate())) )
+ ( Global.VSync ? " (vsync on)" : "" );
if( Global.iSlowMotion ) { if( Global.iSlowMotion ) {
textline += " (slowmotion " + to_string( Global.iSlowMotion ) + ")"; textline += " (slowmotion " + to_string( Global.iSlowMotion ) + ")";
} }

View File

@@ -192,7 +192,9 @@ world_environment::update() {
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.play( sound_flags::exclusive | sound_flags::looping ); m_rainsound
.gain( m_rainsound.m_amplitudeoffset + m_rainsound.m_amplitudefactor * 1.f )
.play( sound_flags::exclusive | sound_flags::looping );
} }
else { else {
m_rainsound.stop(); m_rainsound.stop();

131
sound.cpp
View File

@@ -229,6 +229,7 @@ sound_source::deserialize_mapping( cParser &Input ) {
{ "internal", sound_placement::internal }, { "internal", sound_placement::internal },
{ "engine", sound_placement::engine }, { "engine", sound_placement::engine },
{ "external", sound_placement::external }, { "external", sound_placement::external },
{ "custom", sound_placement::custom },
{ "general", sound_placement::general } }; { "general", sound_placement::general } };
auto lookup{ placements.find( value ) }; auto lookup{ placements.find( value ) };
if( lookup != placements.end() ) { if( lookup != placements.end() ) {
@@ -933,115 +934,53 @@ sound_source::update_location() {
m_properties.location = location(); m_properties.location = location();
} }
float const EU07_SOUNDPROOFING_GLOBAL_VERYSTRONG { 0.01f };
float const EU07_SOUNDPROOFING_GLOBAL_STRONG { std::sqrtf( 0.025 ) };
float const EU07_SOUNDPROOFING_GLOBAL_SOME { std::sqrtf( 0.15 ) };
float const EU07_SOUNDPROOFING_GLOBAL_NONE { std::sqrtf( 0.40 ) };
float const EU07_SOUNDPROOFING_STRONG { std::sqrtf( 0.20 ) };
float const EU07_SOUNDPROOFING_SOME { std::sqrtf( 0.65 ) };
float const EU07_SOUNDPROOFING_NONE { 1.f };
bool bool
sound_source::update_soundproofing() { sound_source::update_soundproofing() {
// NOTE, HACK: current cab id can vary from -1 to +1, and we use higher priority values for open cab window and external views // NOTE, HACK: current cab id can vary from -1 to +1, and we use higher priority values for open cab window and external views
// we use this as modifier to force re-calculations when moving between compartments or changing window state // we use this as modifier to force re-calculations when moving between compartments or changing window state
int const occupiedcab = ( auto const *listenervehicle { Global.pCamera.m_owner }; // nullptr in free roam mode
Global.CabWindowOpen ? 2 : auto const occupiedcab { (
Global.CabWindowOpen ? 2 : // window view
FreeFlyModeFlag ? ( FreeFlyModeFlag ? (
Global.pCamera.m_owner ? listenervehicle ?
3 : 3 : // external view
0 ) : 4 ) : // free roam view
( simulation::Train ? listenervehicle->MoverParameters->CabOccupied ) }; // some internal view so we can be sure listener isn't a nullptr
simulation::Train->Occupied()->CabOccupied :
0 ) );
// location-based gain factor: // location-based gain factor:
std::uintptr_t soundproofingstamp = reinterpret_cast<std::uintptr_t>( ( std::uintptr_t soundproofingstamp =
FreeFlyModeFlag ? reinterpret_cast<std::uintptr_t>( listenervehicle )
Global.pCamera.m_owner : + ( listenervehicle ?
( simulation::Train ? occupiedcab :
simulation::Train->Dynamic() : 0 );
nullptr ) ) )
+ occupiedcab;
if( soundproofingstamp == m_properties.soundproofing_stamp ) { return false; } if( soundproofingstamp == m_properties.soundproofing_stamp ) { return false; }
// listener location has changed, calculate new location-based gain factor // listener location has changed, calculate new location-based gain factor
auto const externalcamera { ( Global.CabWindowOpen ) || ( Global.pCamera.m_owner && FreeFlyModeFlag ) }; // TBD, TODO: clean up parameters for soundproofing() call -- make ambient separate, explicit placement
switch( m_placement ) { m_properties.soundproofing = EU07_SOUNDPROOFING_NONE; // default proofing for environment sounds and free listener
case sound_placement::general: { if( m_placement != sound_placement::general ) {
m_properties.soundproofing = ( auto const isambient { ( ( m_placement == sound_placement::external ) && ( m_owner == nullptr ) && ( m_range < -1 ) ? 1 : 0 ) };
m_range >= -1 ? auto const placement { ( isambient ? sound_placement::external_ambient : m_placement ) };
EU07_SOUNDPROOFING_NONE : if( m_owner != nullptr ) {
EU07_SOUNDPROOFING_GLOBAL_NONE ); m_properties.soundproofing =
break; m_owner->soundproofing(
static_cast<int>( placement ),
( m_owner != listenervehicle ?
4 : // part of two-stage calculation owner->outside->listener, or single stage owner->outside one
occupiedcab ) );
} }
case sound_placement::external: { if( ( listenervehicle ) && ( listenervehicle != m_owner ) ) {
if( m_range >= -1 ) { // limited range sound... // if the listener is located in another vehicle, calculate additional proofing of the sound coming from outside
m_properties.soundproofing = ( m_properties.soundproofing *=
soundproofingstamp == 0 ? EU07_SOUNDPROOFING_NONE : // ...with listener outside listenervehicle->soundproofing(
externalcamera ? EU07_SOUNDPROOFING_SOME : // ...with listener inside and window open static_cast<int>( sound_placement::external ) + isambient,
EU07_SOUNDPROOFING_STRONG ); // ...with listener inside and window closed occupiedcab );
}
else { // global sound...
m_properties.soundproofing = (
soundproofingstamp == 0 ? EU07_SOUNDPROOFING_GLOBAL_NONE : // ...with listener outside
externalcamera ? EU07_SOUNDPROOFING_GLOBAL_STRONG : // ...with listener inside and window open
EU07_SOUNDPROOFING_GLOBAL_VERYSTRONG ); // ...with listener inside and window closed
}
break;
}
case sound_placement::internal: {
if( m_range >= -1 ) { // limited range sound
m_properties.soundproofing = (
( FreeFlyModeFlag || externalcamera ) ?
EU07_SOUNDPROOFING_STRONG : // listener outside HACK: won't be true if active vehicle has open window
( simulation::Train->Dynamic() != m_owner ?
EU07_SOUNDPROOFING_STRONG : // in another vehicle
( occupiedcab == 0 ?
EU07_SOUNDPROOFING_STRONG : // listener in the engine compartment
EU07_SOUNDPROOFING_NONE ) ) ); // listener in the cab of the same vehicle
}
else { // global sound
m_properties.soundproofing = (
( FreeFlyModeFlag || externalcamera ) ?
EU07_SOUNDPROOFING_GLOBAL_STRONG : // listener outside HACK: won't be true if active vehicle has open window
( simulation::Train->Dynamic() != m_owner ?
EU07_SOUNDPROOFING_GLOBAL_VERYSTRONG : // in another vehicle
( occupiedcab == 0 ?
EU07_SOUNDPROOFING_GLOBAL_NONE : // listener in the engine compartment
EU07_SOUNDPROOFING_GLOBAL_STRONG ) ) ); // listener in the cab of the same vehicle
}
break;
}
case sound_placement::engine: {
if( m_range >= -1 ) { // limited range sound
m_properties.soundproofing = (
( FreeFlyModeFlag || externalcamera ) ?
EU07_SOUNDPROOFING_SOME : // listener outside or has a window open
( simulation::Train->Dynamic() != m_owner ?
EU07_SOUNDPROOFING_STRONG : // in another vehicle
( occupiedcab == 0 ?
EU07_SOUNDPROOFING_NONE : // listener in the engine compartment
EU07_SOUNDPROOFING_STRONG ) ) ); // listener in another compartment of the same vehicle
}
else { // global sound
m_properties.soundproofing = (
( FreeFlyModeFlag || externalcamera ) ?
EU07_SOUNDPROOFING_GLOBAL_STRONG : // listener outside or has a window open
( simulation::Train->Dynamic() != m_owner ?
EU07_SOUNDPROOFING_GLOBAL_VERYSTRONG : // in another vehicle
( occupiedcab == 0 ?
EU07_SOUNDPROOFING_NONE : // listener in the engine compartment
EU07_SOUNDPROOFING_GLOBAL_STRONG ) ) ); // listener in another compartment of the same vehicle
}
break;
}
default: {
// shouldn't ever land here, but, eh
m_properties.soundproofing = EU07_SOUNDPROOFING_NONE;
break;
} }
} }
// for ambient sounds reduce their volume to account for their placement right on top of the listener
if( m_range < -1 ) {
m_properties.soundproofing *= 0.4f;
}
m_properties.soundproofing_stamp = soundproofingstamp; m_properties.soundproofing_stamp = soundproofingstamp;
return true; return true;

View File

@@ -41,9 +41,16 @@ enum class sound_placement {
general, // source is equally audible in potential carrier and outside of it general, // source is equally audible in potential carrier and outside of it
internal, // source is located inside of the carrier, and less audible when the listener is outside internal, // source is located inside of the carrier, and less audible when the listener is outside
engine, // source is located in the engine compartment, less audible when the listener is outside and even less in the cabs engine, // source is located in the engine compartment, less audible when the listener is outside and even less in the cabs
external // source is located on the outside of the carrier, and less audible when the listener is inside external, // source is located on the outside of the carrier, and less audible when the listener is inside
external_ambient, // source is located on the outside of the carrier, with fixed volume
custom, // source doesn't fit in any standard location or requires custom soundproofing
}; };
auto const EU07_SOUNDPROOFING_NONE{ 1.f };
auto const EU07_SOUNDPROOFING_SOME{ std::sqrtf( 0.65f ) };
auto const EU07_SOUNDPROOFING_STRONG{ std::sqrtf( 0.20f ) };
auto const EU07_SOUNDPROOFING_VERYSTRONG{ std::sqrtf( 0.01f ) };
// mini controller and audio dispatcher; issues play commands for the audio renderer, // mini controller and audio dispatcher; issues play commands for the audio renderer,
// updates parameters of created audio emitters for the playback duration // updates parameters of created audio emitters for the playback duration
// TODO: move to simulation namespace after clean up of owner classes // TODO: move to simulation namespace after clean up of owner classes

View File

@@ -416,6 +416,7 @@ void uart_input::poll()
if (conf.debug) if (conf.debug)
{ {
char buf[buffer.size() * 3 + 1]; char buf[buffer.size() * 3 + 1];
buf[ buffer.size() * 3 ] = NULL;
size_t pos = 0; size_t pos = 0;
for (uint8_t b : buffer) for (uint8_t b : buffer)
pos += sprintf(&buf[pos], "%02X ", b); pos += sprintf(&buf[pos], "%02X ", b);