From 0593f158ba66028ad77ac4ae8e6a0bc26a972e32 Mon Sep 17 00:00:00 2001 From: tmj-fstate Date: Mon, 6 Apr 2020 15:59:07 +0200 Subject: [PATCH] build 200406. power relay cab indicators logic tweak, cab update logic tweak, compartment lights logic tweak, automatic coupling crash workaround, pantograph power draw fix --- Driver.h | 2 +- DynObj.cpp | 55 +- McZapkie/MOVER.h | 2 + McZapkie/Mover.cpp | 33 +- Train.cpp | 2029 ++++++++++++++++++++++---------------------- simulation.cpp | 5 + version.h | 2 +- 7 files changed, 1080 insertions(+), 1048 deletions(-) diff --git a/Driver.h b/Driver.h index 1396d2b6..8241e166 100644 --- a/Driver.h +++ b/Driver.h @@ -446,8 +446,8 @@ private: // consist // methods public: + bool CheckVehicles( TOrders user = Wait_for_orders ); private: - bool CheckVehicles(TOrders user = Wait_for_orders); bool PrepareEngine(); bool ReleaseEngine(); void Doors(bool const Open, int const Side = 0); diff --git a/DynObj.cpp b/DynObj.cpp index 14167c90..6e44e78d 100644 --- a/DynObj.cpp +++ b/DynObj.cpp @@ -664,7 +664,12 @@ TDynamicObject::toggle_lights() { if( true == SectionLightsActive ) { // switch all lights off... - MoverParameters->BatterySwitch( false ); + for( auto §ion : Sections ) { + auto const sectionname { section.compartment->pName }; + if( sectionname.rfind( "cab", 0 ) != 0 ) { + section.light_level = 0.0; + } + } SectionLightsActive = false; } else { @@ -684,7 +689,6 @@ TDynamicObject::toggle_lights() { section.light_level = ( Random() < 0.75 ? 0.75f : 0.15f ); } } - MoverParameters->BatterySwitch( true ); SectionLightsActive = true; } } @@ -2848,14 +2852,19 @@ bool TDynamicObject::Update(double dt, double dt1) // couplers if( ( MoverParameters->Couplers[ 0 ].CouplingFlag != coupling::faux ) && ( MoverParameters->Couplers[ 1 ].CouplingFlag != coupling::faux ) ) { - MoverParameters->InsideConsist = true; } else { - MoverParameters->InsideConsist = false; } - // + // HACK: we're using sound event to detect whether vehicle was connected to another + if( TestFlag( MoverParameters->AIFlag, sound::attachcoupler ) ) { + auto *driver{ ctOwner ? ctOwner : Mechanik }; + if( driver != nullptr ) { + driver->CheckVehicles( Connect ); + } + SetFlag( MoverParameters->AIFlag, -sound::attachcoupler ); + } // napiecie sieci trakcyjnej // Ra 15-01: przeliczenie poboru prądu powinno być robione wcześniej, żeby na @@ -3448,11 +3457,35 @@ bool TDynamicObject::Update(double dt, double dt1) + MoverParameters->TotalCurrent; // prąd pobierany przez pojazd - bez sensu z tym (TotalCurrent) // TotalCurrent to bedzie prad nietrakcyjny (niezwiazany z napedem) // fCurrent+=fabs(MoverParameters->Voltage)*1e-6; //prąd płynący przez woltomierz, rozładowuje kondensator orgromowy 4µF +/* double fPantCurrent = fCurrent; // normalnie cały prąd przez jeden pantograf - if (iAnimType[ANIM_PANTS] > 1) // a jeśli są dwa pantografy //Ra 1014-11: proteza, trzeba zrobić sensowniej - if (pants[0].fParamPants->hvPowerWire && - pants[1].fParamPants->hvPowerWire) // i oba podłączone do drutów + if (iAnimType[ANIM_PANTS] > 1) { // a jeśli są dwa pantografy //Ra 1014-11: proteza, trzeba zrobić sensowniej + if (pants[0].fParamPants->hvPowerWire && pants[1].fParamPants->hvPowerWire) { // i oba podłączone do drutów fPantCurrent = fCurrent * 0.5; // to dzielimy prąd równo na oba (trochę bez sensu, ale lepiej tak niż podwoić prąd) + } + } +*/ + // test whether more than one pantograph touches the wire + // NOTE: we're duplicating lot of code from below + // TODO: clean this up + auto activepantographs { 0 }; + for( int idx = 0; idx < iAnimType[ ANIM_PANTS ]; ++idx ) { + auto const *pantograph { pants[ idx ].fParamPants }; + if( Global.bLiveTraction == false ) { + if( pantograph->PantWys >= 1.2 ) { + ++activepantographs; + } + } + else { + if( ( pantograph->hvPowerWire != nullptr ) + && ( true == MoverParameters->Pantographs[ end::front ].is_active ) + && ( pantograph->PantTraction - pantograph->PantWys < 0.01 ) ) { // tolerancja niedolegania + ++activepantographs; + } + } + } + auto const fPantCurrent { fCurrent / std::max( 1, activepantographs ) }; + for (int i = 0; i < iAnimType[ANIM_PANTS]; ++i) { // pętla po wszystkich pantografach p = pants[i].fParamPants; @@ -3773,9 +3806,9 @@ bool TDynamicObject::Update(double dt, double dt1) // compartment lights // if the vehicle has a controller, we base the light state on state of the controller otherwise we check the vehicle itself - if( ( ctOwner != nullptr ? ctOwner->Controlling()->Battery != SectionLightsActive : - Mechanik != nullptr ? false : // don't touch lights in a stand-alone manned vehicle - MoverParameters->CompartmentLights.is_active == true ) ) { // without controller switch the lights off + if( ( ctOwner != nullptr ? SectionLightsActive != MoverParameters->CompartmentLights.is_active : + Mechanik != nullptr ? SectionLightsActive != MoverParameters->CompartmentLights.is_active : + SectionLightsActive ) ) { // without controller switch the lights off toggle_lights(); } diff --git a/McZapkie/MOVER.h b/McZapkie/MOVER.h index b8df0634..91197c57 100644 --- a/McZapkie/MOVER.h +++ b/McZapkie/MOVER.h @@ -284,6 +284,7 @@ static int const eimc_f_Uzh = 8; static int const eimc_f_DU = 9; static int const eimc_f_I0 = 10; static int const eimc_f_cfu = 11; +static int const eimc_f_cfuH = 12; static int const eimc_p_F0 = 13; static int const eimc_p_a1 = 14; static int const eimc_p_Pmax = 15; @@ -1304,6 +1305,7 @@ public: std::array Neighbours; // potential collision sources bool EventFlag = false; /*!o true jesli cos nietypowego sie wydarzy*/ int SoundFlag = 0; /*!o patrz stale sound_ */ + int AIFlag{ 0 }; // HACK: events of interest for consist owner double DistCounter = 0.0; /*! licznik kilometrow */ double V = 0.0; //predkosc w [m/s] względem sprzęgów (dodania gdy jedzie w stronę 0) double Vel = 0.0; //moduł prędkości w [km/h], używany przez AI diff --git a/McZapkie/Mover.cpp b/McZapkie/Mover.cpp index bca8f347..4e5ca721 100644 --- a/McZapkie/Mover.cpp +++ b/McZapkie/Mover.cpp @@ -1923,7 +1923,7 @@ void TMoverParameters::PantographsCheck( double const Timestep ) { void TMoverParameters::LightsCheck( double const Timestep ) { - auto const lowvoltagepower { ( + auto const converterpower { ( ( ConverterFlag ) || ( ( ( Couplers[ end::front ].CouplingFlag & coupling::permanent ) != 0 ) && ( Couplers[ end::front ].Connected->ConverterFlag ) ) || ( ( ( Couplers[ end::rear ].CouplingFlag & coupling::permanent ) != 0 ) && ( Couplers[ end::rear ].Connected->ConverterFlag ) ) ) }; @@ -1932,7 +1932,7 @@ void TMoverParameters::LightsCheck( double const Timestep ) { light.is_active = ( // TODO: bind properly power source when ld is in place - ( Battery || lowvoltagepower ) // power source + ( Battery || converterpower ) // power source && ( false == light.is_disabled ) && ( ( true == light.is_active ) || ( light.start_type == start_t::manual ? @@ -1944,7 +1944,7 @@ void TMoverParameters::LightsCheck( double const Timestep ) { 1.0f : 0.0f ) // TODO: bind properly power source when ld is in place - * ( lowvoltagepower ? 1.0f : + * ( converterpower ? 1.0f : Battery ? 0.5f : 0.0f ) * light.dimming; @@ -4602,15 +4602,14 @@ void TMoverParameters::ComputeTotalForce(double dt) { Fb = BrakeForce(RunningTrack); // poslizg auto Fwheels { FTrain - Fb * Sign( V ) }; - if( ( Vel > 0.001 ) // crude trap, to prevent braked stationary vehicles from passing fb > mass * adhesive test + if( ( Vel > 0.1 ) // crude trap, to prevent braked stationary vehicles from passing fb > mass * adhesive test && ( std::abs(Fwheels) > TotalMassxg * Adhesive( RunningTrack.friction ) ) ) { SlippingWheels = true; } double temp_nrot = nrot; if (true == SlippingWheels) { - temp_nrot = ComputeRotatingWheel(Fwheels - Sign(nrot * M_PI * WheelDiameter - V) * - Adhesive(RunningTrack.friction) * TotalMassxg, dt, nrot); + temp_nrot = ComputeRotatingWheel(Fwheels - Sign(nrot * M_PI * WheelDiameter - V) * Adhesive(RunningTrack.friction) * TotalMassxg, dt, nrot); if (Sign(nrot * M_PI * WheelDiameter - V)*Sign(temp_nrot * M_PI * WheelDiameter - V) < 0) { SlippingWheels = false; @@ -4960,8 +4959,13 @@ double TMoverParameters::CouplerForce( int const End, double dt ) { && ( coupler.type() == othercoupler.type() ) && ( coupler.CouplingFlag == coupling::faux ) ) { // sprzeganie wagonow z samoczynnymi sprzegami + if( Attach( End, otherend, othervehicle, ( coupler.AutomaticCouplingFlag & othercoupler.AutomaticCouplingFlag ) ) ) { + SetFlag( AIFlag, sound::attachcoupler ); + } +/* coupler.CouplingFlag = ( coupler.AutomaticCouplingFlag & othercoupler.AutomaticCouplingFlag ); SetFlag( coupler.sounds, sound::attachcoupler ); +*/ } } } @@ -5201,11 +5205,11 @@ double TMoverParameters::TractionForce( double dt ) { case TEngineType::DieselElectric: { // TODO: move this to the auto relay check when the electric engine code paths are unified StLinFlag &= MotorConnectorsCheck(); + StLinFlag &= ( MainCtrlActualPos > 0 ); StLinFlag |= ( - ( MainCtrlActualPos == 0 ) - && ( TrainType != dt_EZT ? - MainCtrlPowerPos() == 1 : - MainCtrlPowerPos() > 0 ) ); + ( Mains ) + && ( MainCtrlActualPos == 0 ) + && ( MainCtrlPowerPos() > 0 ) ); break; } @@ -5847,8 +5851,10 @@ double TMoverParameters::TractionForce( double dt ) { else tmp = eimc[eimc_f_Uzmax]; + auto f_cfu { DynamicBrakeFlag ? eimc[eimc_f_cfuH] : eimc[eimc_f_cfu] }; + eimv[eimv_Uzsmax] = Min0R(EngineVoltage - eimc[eimc_f_DU], tmp); - eimv[eimv_fkr] = eimv[eimv_Uzsmax] / eimc[eimc_f_cfu]; + eimv[eimv_fkr] = eimv[eimv_Uzsmax] / f_cfu; if( (eimv_pr < 0 ) ) { eimv[ eimv_Pmax ] = eimc[ eimc_p_Ph ]; } @@ -5866,7 +5872,7 @@ double TMoverParameters::TractionForce( double dt ) { eimv[ eimv_fkr ] / std::max( abs( enrot ) * eimc[ eimc_s_p ] + eimc[ eimc_s_dfmax ] * eimv[ eimv_ks ], eimc[ eimc_s_dfmax ] ) ) - * eimc[ eimc_f_cfu ] + * f_cfu / eimc[ eimc_s_cfu ] ) * ( eimc[ eimc_s_dfmax ] * eimc[ eimc_s_dfic ] * eimc[ eimc_s_cim ] ) * Transmision.Ratio * NPoweredAxles * 2.0 / WheelDiameter; @@ -5908,7 +5914,7 @@ double TMoverParameters::TractionForce( double dt ) { // eimv[eimv_U]:=Max0R(eimv[eimv_Uzsmax],Min0R(eimc[eimc_f_cfu]*eimv[eimv_fp],eimv[eimv_Uzsmax])); // eimv[eimv_pole]:=eimv[eimv_U]/(eimv[eimv_fp]*eimc[eimc_s_cfu]); if ((abs(eimv[eimv_fp]) <= eimv[eimv_fkr])) - eimv[eimv_pole] = eimc[eimc_f_cfu] / eimc[eimc_s_cfu]; + eimv[eimv_pole] = f_cfu / eimc[eimc_s_cfu]; else eimv[eimv_pole] = eimv[eimv_Uzsmax] / eimc[eimc_s_cfu] / abs(eimv[eimv_fp]); eimv[eimv_U] = eimv[eimv_pole] * eimv[eimv_fp] * eimc[eimc_s_cfu]; @@ -10248,6 +10254,7 @@ void TMoverParameters::LoadFIZ_Engine( std::string const &Input ) { extract_value( eimc[ eimc_f_DU ], "DU", Input, "" ); extract_value( eimc[ eimc_f_I0 ], "I0", Input, "" ); extract_value( eimc[ eimc_f_cfu ], "fcfu", Input, "" ); + extract_value( eimc[ eimc_f_cfuH ], "fcfuH", Input, to_string(eimc[eimc_f_cfu])); extract_value( eimc[ eimc_p_F0 ], "F0", Input, "" ); extract_value( eimc[ eimc_p_a1 ], "a1", Input, "" ); extract_value( eimc[ eimc_p_Pmax ], "Pmax", Input, "" ); diff --git a/Train.cpp b/Train.cpp index a4eb605b..4315cbb3 100644 --- a/Train.cpp +++ b/Train.cpp @@ -498,9 +498,11 @@ bool TTrain::Init(TDynamicObject *NewDynamicObject, bool e3d) Global.CurrentMaxTextureSize = Global.iMaxCabTextureSize; auto const result{ LoadMMediaFile( DynamicObject->asBaseDir + DynamicObject->MoverParameters->TypeName + ".mmd" ) }; Global.CurrentMaxTextureSize = Global.iMaxTextureSize; +/* if( false == result ) { return false; } +*/ } // Ra: taka proteza - przesłanie kierunku do członów connected @@ -5914,1101 +5916,1084 @@ bool TTrain::Update( double const Deltatime ) UpdateCab(); - if (DynamicObject->mdKabina) - { // Ra: TODO: odczyty klawiatury/pulpitu nie powinny być uzależnione od istnienia modelu kabiny - - if( ( DynamicObject->Mechanik != nullptr ) - && ( false == DynamicObject->Mechanik->AIControllFlag ) ) { - // nie blokujemy AI - if( ( mvOccupied->TrainType == dt_ET40 ) - || ( mvOccupied->TrainType == dt_EP05 ) - || ( mvOccupied->HasCamshaft ) ) { - // dla ET40 i EU05 automatyczne cofanie nastawnika - i tak nie będzie to działać dobrze... - // TODO: use deltatime to stabilize speed + if( ( DynamicObject->Mechanik != nullptr ) + && ( false == DynamicObject->Mechanik->AIControllFlag ) ) { + // nie blokujemy AI + if( ( mvOccupied->TrainType == dt_ET40 ) + || ( mvOccupied->TrainType == dt_EP05 ) + || ( mvOccupied->HasCamshaft ) ) { + // dla ET40 i EU05 automatyczne cofanie nastawnika - i tak nie będzie to działać dobrze... + // TODO: use deltatime to stabilize speed /* - if( false == ( - ( input::command == user_command::mastercontrollerset ) - || ( input::command == user_command::mastercontrollerincrease ) - || ( input::command == user_command::mastercontrollerdecrease ) ) ) { + if( false == ( + ( input::command == user_command::mastercontrollerset ) + || ( input::command == user_command::mastercontrollerincrease ) + || ( input::command == user_command::mastercontrollerdecrease ) ) ) { */ - if( false == ( m_mastercontrollerinuse || Global.ctrlState ) ) { - m_mastercontrollerreturndelay -= Deltatime; - if( m_mastercontrollerreturndelay < 0.f ) { - m_mastercontrollerreturndelay = EU07_CONTROLLER_BASERETURNDELAY; - if( mvOccupied->MainCtrlPos > mvOccupied->MainCtrlActualPos ) { - mvOccupied->DecMainCtrl( 1 ); - } - else if( mvOccupied->MainCtrlPos < mvOccupied->MainCtrlActualPos ) { - // Ra 15-01: a to nie miało być tylko cofanie? - mvOccupied->IncMainCtrl( 1 ); - } + if( false == ( m_mastercontrollerinuse || Global.ctrlState ) ) { + m_mastercontrollerreturndelay -= Deltatime; + if( m_mastercontrollerreturndelay < 0.f ) { + m_mastercontrollerreturndelay = EU07_CONTROLLER_BASERETURNDELAY; + if( mvOccupied->MainCtrlPos > mvOccupied->MainCtrlActualPos ) { + mvOccupied->DecMainCtrl( 1 ); + } + else if( mvOccupied->MainCtrlPos < mvOccupied->MainCtrlActualPos ) { + // Ra 15-01: a to nie miało być tylko cofanie? + mvOccupied->IncMainCtrl( 1 ); } } } -/* - if( ( mvOccupied->BrakeHandle == TBrakeHandle::FVel6 ) - && ( mvOccupied->fBrakeCtrlPos < 0.0 ) - && ( Global.iFeedbackMode < 3 ) ) { - // Odskakiwanie hamulce EP - if( false == ( - ( input::command == user_command::trainbrakeset ) - || ( input::command == user_command::trainbrakedecrease ) - || ( input::command == user_command::trainbrakecharging ) ) ) { - set_train_brake( 0 ); - } - } -*/ } + } - // McZapkie: predkosc wyswietlana na tachometrze brana jest z obrotow kol - auto const maxtacho { 3.0 }; - fTachoVelocity = static_cast( std::min( std::abs(11.31 * mvControlled->WheelDiameter * mvControlled->nrot), mvControlled->Vmax * 1.05) ); - { // skacze osobna zmienna - float ff = simulation::Time.data().wSecond; // skacze co sekunde - pol sekundy - // pomiar, pol sekundy ustawienie - if (ff != fTachoTimer) // jesli w tej sekundzie nie zmienial - { - if (fTachoVelocity > 1) // jedzie - fTachoVelocityJump = fTachoVelocity + (2.0 - LocalRandom(3) + LocalRandom(3)) * 0.5; - else - fTachoVelocityJump = 0; // stoi - fTachoTimer = ff; // juz zmienil - } - } - if (fTachoVelocity > 1) // McZapkie-270503: podkrecanie tachometru + // McZapkie: predkosc wyswietlana na tachometrze brana jest z obrotow kol + auto const maxtacho { 3.0 }; + fTachoVelocity = static_cast( std::min( std::abs(11.31 * mvControlled->WheelDiameter * mvControlled->nrot), mvControlled->Vmax * 1.05) ); + { // skacze osobna zmienna + float ff = simulation::Time.data().wSecond; // skacze co sekunde - pol sekundy + // pomiar, pol sekundy ustawienie + if (ff != fTachoTimer) // jesli w tej sekundzie nie zmienial { - // szybciej zacznij stukac - fTachoCount = std::min( maxtacho, fTachoCount + Deltatime * 3 ); - } - else if( fTachoCount > 0 ) { - // schodz powoli - niektore haslery to ze 4 sekundy potrafia stukac - fTachoCount = std::max( 0.0, fTachoCount - Deltatime * 0.66 ); - } - - // Ra 2014-09: napięcia i prądy muszą być ustalone najpierw, bo wysyłane są ewentualnie na PoKeys - if( ( mvControlled->EngineType != TEngineType::DieselElectric ) - && ( mvControlled->EngineType != TEngineType::ElectricInductionMotor ) ) { // Ra 2014-09: czy taki rozdzia? ma sens? - fHVoltage = std::max( - mvControlled->PantographVoltage, - mvControlled->GetAnyTrainsetVoltage() ); // Winger czy to nie jest zle? - } - // *mvControlled->Mains); - else { - fHVoltage = mvControlled->EngineVoltage; - } - if (ShowNextCurrent) - { // jeśli pokazywać drugi człon - if (mvSecond) - { // o ile jest ten drugi - fHCurrent[0] = mvSecond->ShowCurrent(0) * 1.05; - fHCurrent[1] = mvSecond->ShowCurrent(1) * 1.05; - fHCurrent[2] = mvSecond->ShowCurrent(2) * 1.05; - fHCurrent[3] = mvSecond->ShowCurrent(3) * 1.05; - } + if (fTachoVelocity > 1) // jedzie + fTachoVelocityJump = fTachoVelocity + (2.0 - LocalRandom(3) + LocalRandom(3)) * 0.5; else - fHCurrent[0] = fHCurrent[1] = fHCurrent[2] = fHCurrent[3] = - 0.0; // gdy nie ma człona + fTachoVelocityJump = 0; // stoi + fTachoTimer = ff; // juz zmienil + } + } + if (fTachoVelocity > 1) // McZapkie-270503: podkrecanie tachometru + { + // szybciej zacznij stukac + fTachoCount = std::min( maxtacho, fTachoCount + Deltatime * 3 ); + } + else if( fTachoCount > 0 ) { + // schodz powoli - niektore haslery to ze 4 sekundy potrafia stukac + fTachoCount = std::max( 0.0, fTachoCount - Deltatime * 0.66 ); + } + + // Ra 2014-09: napięcia i prądy muszą być ustalone najpierw, bo wysyłane są ewentualnie na PoKeys + if( ( mvControlled->EngineType != TEngineType::DieselElectric ) + && ( mvControlled->EngineType != TEngineType::ElectricInductionMotor ) ) { // Ra 2014-09: czy taki rozdzia? ma sens? + fHVoltage = std::max( + mvControlled->PantographVoltage, + mvControlled->GetAnyTrainsetVoltage() ); // Winger czy to nie jest zle? + } + // *mvControlled->Mains); + else { + fHVoltage = mvControlled->EngineVoltage; + } + if (ShowNextCurrent) + { // jeśli pokazywać drugi człon + if (mvSecond) + { // o ile jest ten drugi + fHCurrent[0] = mvSecond->ShowCurrent(0) * 1.05; + fHCurrent[1] = mvSecond->ShowCurrent(1) * 1.05; + fHCurrent[2] = mvSecond->ShowCurrent(2) * 1.05; + fHCurrent[3] = mvSecond->ShowCurrent(3) * 1.05; } else - { // normalne pokazywanie - fHCurrent[0] = mvControlled->ShowCurrent(0); - fHCurrent[1] = mvControlled->ShowCurrent(1); - fHCurrent[2] = mvControlled->ShowCurrent(2); - fHCurrent[3] = mvControlled->ShowCurrent(3); - } + fHCurrent[0] = fHCurrent[1] = fHCurrent[2] = fHCurrent[3] = + 0.0; // gdy nie ma człona + } + else + { // normalne pokazywanie + fHCurrent[0] = mvControlled->ShowCurrent(0); + fHCurrent[1] = mvControlled->ShowCurrent(1); + fHCurrent[2] = mvControlled->ShowCurrent(2); + fHCurrent[3] = mvControlled->ShowCurrent(3); + } - bool kier = (DynamicObject->DirectionGet() * mvOccupied->CabOccupied > 0); - TDynamicObject *p = DynamicObject->GetFirstDynamic(mvOccupied->CabOccupied < 0 ? end::rear : end::front, 4); - int in = 0; - fEIMParams[0][6] = 0; - iCarNo = 0; - iPowerNo = 0; - iUnitNo = 1; + bool kier = (DynamicObject->DirectionGet() * mvOccupied->CabOccupied > 0); + TDynamicObject *p = DynamicObject->GetFirstDynamic(mvOccupied->CabOccupied < 0 ? end::rear : end::front, 4); + int in = 0; + fEIMParams[0][6] = 0; + iCarNo = 0; + iPowerNo = 0; + iUnitNo = 1; - for (int i = 0; i < 8; i++) + for (int i = 0; i < 8; i++) + { + bMains[i] = false; + fCntVol[i] = 0.0f; + bPants[i][0] = false; + bPants[i][1] = false; + bFuse[i] = false; + bBatt[i] = false; + bConv[i] = false; + bComp[i][0] = false; + bComp[i][1] = false; + bHeat[i] = false; + } + for (int i = 0; i < 20; i++) + { + if (p) { - bMains[i] = false; - fCntVol[i] = 0.0f; - bPants[i][0] = false; - bPants[i][1] = false; - bFuse[i] = false; - bBatt[i] = false; - bConv[i] = false; - bComp[i][0] = false; - bComp[i][1] = false; - bHeat[i] = false; + fPress[i][0] = p->MoverParameters->BrakePress; + fPress[i][1] = p->MoverParameters->PipePress; + fPress[i][2] = p->MoverParameters->ScndPipePress; + bBrakes[i][0] = p->MoverParameters->SpringBrake.IsActive; + bBrakes[i][1] = p->MoverParameters->SpringBrake.ShuttOff; + bDoors[i][1] = ( p->MoverParameters->Doors.instances[ side::left ].position > 0.f ); + bDoors[i][2] = ( p->MoverParameters->Doors.instances[ side::right ].position > 0.f ); + bDoors[i][3] = ( p->MoverParameters->Doors.instances[ side::left ].step_position > 0.f ); + bDoors[i][4] = ( p->MoverParameters->Doors.instances[ side::right ].step_position > 0.f ); + bDoors[i][0] = ( bDoors[i][1] || bDoors[i][2] ); + iDoorNo[i] = p->iAnimType[ANIM_DOORS]; + iUnits[i] = iUnitNo; + cCode[i] = p->MoverParameters->TypeName[p->MoverParameters->TypeName.length() - 1]; + asCarName[i] = p->name(); + if( p->MoverParameters->EnginePowerSource.SourceType == TPowerSource::CurrentCollector ) { + 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 ); + } + 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) + { + bComp[iUnitNo - 1][1] = (bComp[iUnitNo - 1][1] || p->MoverParameters->CompressorFlag); + } + if ((in < 8) && (p->MoverParameters->eimc[eimc_p_Pmax] > 1)) + { + fEIMParams[1 + in][0] = p->MoverParameters->eimv[eimv_Fmax]; + fEIMParams[1 + in][1] = Max0R(fEIMParams[1 + in][0], 0); + fEIMParams[1 + in][2] = -Min0R(fEIMParams[1 + in][0], 0); + fEIMParams[1 + in][3] = p->MoverParameters->eimv[eimv_Fmax] / + Max0R(p->MoverParameters->eimv[eimv_Fful], 1); + fEIMParams[1 + in][4] = Max0R(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][7] = p->MoverParameters->eimv[eimv_U]; + fEIMParams[1 + in][8] = p->MoverParameters->Itot;//p->MoverParameters->eimv[eimv_Ipoj]; + fEIMParams[1 + in][9] = p->MoverParameters->EngineVoltage; + fEIMParams[0][6] += fEIMParams[1 + in][8]; + bMains[in] = p->MoverParameters->Mains; + fCntVol[in] = p->MoverParameters->BatteryVoltage; + bFuse[in] = p->MoverParameters->FuseFlag; + bBatt[in] = p->MoverParameters->Battery; + bConv[in] = p->MoverParameters->ConverterFlag; + bHeat[in] = p->MoverParameters->Heating; + in++; + iPowerNo = in; + } + if ((in < 8) + && ((p->MoverParameters->EngineType==TEngineType::DieselEngine) + ||(p->MoverParameters->EngineType==TEngineType::DieselElectric))) + { + fDieselParams[1 + in][0] = p->MoverParameters->enrot*60; + fDieselParams[1 + in][1] = p->MoverParameters->nrot; + fDieselParams[1 + in][2] = p->MoverParameters->RList[p->MoverParameters->MainCtrlPos].R; + fDieselParams[1 + in][3] = p->MoverParameters->dizel_fill; + fDieselParams[1 + in][4] = p->MoverParameters->RList[p->MoverParameters->MainCtrlPos].Mn; + fDieselParams[1 + in][5] = p->MoverParameters->dizel_engage; + fDieselParams[1 + in][6] = p->MoverParameters->dizel_heat.Twy; + fDieselParams[1 + in][7] = p->MoverParameters->OilPump.pressure; + fDieselParams[1 + in][8] = p->MoverParameters->dizel_heat.Ts; + fDieselParams[1 + in][9] = p->MoverParameters->hydro_R_Fill; + bMains[in] = p->MoverParameters->Mains; + fCntVol[in] = p->MoverParameters->BatteryVoltage; + bFuse[in] = p->MoverParameters->FuseFlag; + bBatt[in] = p->MoverParameters->Battery; + bConv[in] = p->MoverParameters->ConverterFlag; + bHeat[in] = p->MoverParameters->Heating; + in++; + iPowerNo = in; + } + // p = p->NextC(4); //prev + if ((kier ? p->NextC(128) : p->PrevC(128)) != (kier ? p->NextC(4) : p->PrevC(4))) + iUnitNo++; + p = (kier ? p->NextC(4) : p->PrevC(4)); + iCarNo = i + 1; } - for (int i = 0; i < 20; i++) + else { - if (p) - { - fPress[i][0] = p->MoverParameters->BrakePress; - fPress[i][1] = p->MoverParameters->PipePress; - fPress[i][2] = p->MoverParameters->ScndPipePress; - bBrakes[i][0] = p->MoverParameters->SpringBrake.IsActive; - bBrakes[i][1] = p->MoverParameters->SpringBrake.ShuttOff; - bDoors[i][1] = ( p->MoverParameters->Doors.instances[ side::left ].position > 0.f ); - bDoors[i][2] = ( p->MoverParameters->Doors.instances[ side::right ].position > 0.f ); - bDoors[i][3] = ( p->MoverParameters->Doors.instances[ side::left ].step_position > 0.f ); - bDoors[i][4] = ( p->MoverParameters->Doors.instances[ side::right ].step_position > 0.f ); - bDoors[i][0] = ( bDoors[i][1] || bDoors[i][2] ); - iDoorNo[i] = p->iAnimType[ANIM_DOORS]; - iUnits[i] = iUnitNo; - cCode[i] = p->MoverParameters->TypeName[p->MoverParameters->TypeName.length() - 1]; - asCarName[i] = p->name(); - if( p->MoverParameters->EnginePowerSource.SourceType == TPowerSource::CurrentCollector ) { - 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 ); - } - 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) - { - bComp[iUnitNo - 1][1] = (bComp[iUnitNo - 1][1] || p->MoverParameters->CompressorFlag); - } - if ((in < 8) && (p->MoverParameters->eimc[eimc_p_Pmax] > 1)) - { - fEIMParams[1 + in][0] = p->MoverParameters->eimv[eimv_Fmax]; - fEIMParams[1 + in][1] = Max0R(fEIMParams[1 + in][0], 0); - fEIMParams[1 + in][2] = -Min0R(fEIMParams[1 + in][0], 0); - fEIMParams[1 + in][3] = p->MoverParameters->eimv[eimv_Fmax] / - Max0R(p->MoverParameters->eimv[eimv_Fful], 1); - fEIMParams[1 + in][4] = Max0R(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][7] = p->MoverParameters->eimv[eimv_U]; - fEIMParams[1 + in][8] = p->MoverParameters->Itot;//p->MoverParameters->eimv[eimv_Ipoj]; - fEIMParams[1 + in][9] = p->MoverParameters->EngineVoltage; - fEIMParams[0][6] += fEIMParams[1 + in][8]; - bMains[in] = p->MoverParameters->Mains; - fCntVol[in] = p->MoverParameters->BatteryVoltage; - bFuse[in] = p->MoverParameters->FuseFlag; - bBatt[in] = p->MoverParameters->Battery; - bConv[in] = p->MoverParameters->ConverterFlag; - bHeat[in] = p->MoverParameters->Heating; - in++; - iPowerNo = in; - } - if ((in < 8) - && ((p->MoverParameters->EngineType==TEngineType::DieselEngine) - ||(p->MoverParameters->EngineType==TEngineType::DieselElectric))) - { - fDieselParams[1 + in][0] = p->MoverParameters->enrot*60; - fDieselParams[1 + in][1] = p->MoverParameters->nrot; - fDieselParams[1 + in][2] = p->MoverParameters->RList[p->MoverParameters->MainCtrlPos].R; - fDieselParams[1 + in][3] = p->MoverParameters->dizel_fill; - fDieselParams[1 + in][4] = p->MoverParameters->RList[p->MoverParameters->MainCtrlPos].Mn; - fDieselParams[1 + in][5] = p->MoverParameters->dizel_engage; - fDieselParams[1 + in][6] = p->MoverParameters->dizel_heat.Twy; - fDieselParams[1 + in][7] = p->MoverParameters->OilPump.pressure; - fDieselParams[1 + in][8] = p->MoverParameters->dizel_heat.Ts; - fDieselParams[1 + in][9] = p->MoverParameters->hydro_R_Fill; - bMains[in] = p->MoverParameters->Mains; - fCntVol[in] = p->MoverParameters->BatteryVoltage; - bFuse[in] = p->MoverParameters->FuseFlag; - bBatt[in] = p->MoverParameters->Battery; - bConv[in] = p->MoverParameters->ConverterFlag; - bHeat[in] = p->MoverParameters->Heating; - in++; - iPowerNo = in; - } - // p = p->NextC(4); //prev - if ((kier ? p->NextC(128) : p->PrevC(128)) != (kier ? p->NextC(4) : p->PrevC(4))) - iUnitNo++; - p = (kier ? p->NextC(4) : p->PrevC(4)); - iCarNo = i + 1; - } - else - { - fPress[i][0] - = fPress[i][1] - = fPress[i][2] - = 0; - bDoors[i][0] - = bDoors[i][1] - = bDoors[i][2] - = bDoors[i][3] - = bDoors[i][4] - = false; - bBrakes[i][0] - = bBrakes[i][1] - = false; - bSlip[i] = false; - iUnits[i] = 0; - cCode[i] = 0; //'0'; - asCarName[i] = ""; - } + fPress[i][0] + = fPress[i][1] + = fPress[i][2] + = 0; + bDoors[i][0] + = bDoors[i][1] + = bDoors[i][2] + = bDoors[i][3] + = bDoors[i][4] + = false; + bBrakes[i][0] + = bBrakes[i][1] + = false; + bSlip[i] = false; + iUnits[i] = 0; + cCode[i] = 0; //'0'; + asCarName[i] = ""; } + } // if (mvControlled == mvOccupied) // fEIMParams[0][3] = mvControlled->eimv[eimv_Fzad]; // procent zadany // else // fEIMParams[0][3] = // mvControlled->eimv[eimv_Fzad] - mvOccupied->LocalBrakeRatio(); // procent zadany - fEIMParams[0][3] = mvOccupied->eimic_real; - fEIMParams[0][4] = Max0R(fEIMParams[0][3], 0); - fEIMParams[0][5] = -Min0R(fEIMParams[0][3], 0); - fEIMParams[0][1] = fEIMParams[0][4] * mvControlled->eimv[eimv_Fful]; - fEIMParams[0][2] = fEIMParams[0][5] * mvControlled->eimv[eimv_Fful]; - fEIMParams[0][0] = fEIMParams[0][1] - fEIMParams[0][2]; - fEIMParams[0][7] = 0; - fEIMParams[0][8] = 0; - fEIMParams[0][9] = 0; + fEIMParams[0][3] = mvOccupied->eimic_real; + fEIMParams[0][4] = Max0R(fEIMParams[0][3], 0); + fEIMParams[0][5] = -Min0R(fEIMParams[0][3], 0); + fEIMParams[0][1] = fEIMParams[0][4] * mvControlled->eimv[eimv_Fful]; + fEIMParams[0][2] = fEIMParams[0][5] * mvControlled->eimv[eimv_Fful]; + fEIMParams[0][0] = fEIMParams[0][1] - fEIMParams[0][2]; + fEIMParams[0][7] = 0; + fEIMParams[0][8] = 0; + fEIMParams[0][9] = 0; - for (int i = in; i < 8; i++) - { - for (int j = 0; j <= 9; j++) - { - fEIMParams[1 + i][j] = 0; - fDieselParams[1 + i][j] = 0; - } - } + for (int i = in; i < 8; i++) + { + for (int j = 0; j <= 9; j++) + { + fEIMParams[1 + i][j] = 0; + fDieselParams[1 + i][j] = 0; + } + } #ifdef _WIN32 - if (Global.iFeedbackMode == 4) { - // wykonywać tylko gdy wyprowadzone na pulpit - // Ra: sterowanie miernikiem: zbiornik główny - Console::ValueSet(0, mvOccupied->Compressor); - // Ra: sterowanie miernikiem: przewód główny - Console::ValueSet(1, mvOccupied->PipePress); - // Ra: sterowanie miernikiem: cylinder hamulcowy - Console::ValueSet(2, mvOccupied->BrakePress); - // woltomierz wysokiego napięcia - Console::ValueSet(3, fHVoltage); - // Ra: sterowanie miernikiem: drugi amperomierz - Console::ValueSet(4, fHCurrent[2]); - // pierwszy amperomierz; dla EZT prąd całkowity - Console::ValueSet(5, fHCurrent[(mvControlled->TrainType & dt_EZT) ? 0 : 1]); - // Ra: prędkość na pin 43 - wyjście analogowe (to nie jest PWM); skakanie zapewnia mechanika napędu - Console::ValueSet(6, fTachoVelocity); - } + if (Global.iFeedbackMode == 4) { + // wykonywać tylko gdy wyprowadzone na pulpit + // Ra: sterowanie miernikiem: zbiornik główny + Console::ValueSet(0, mvOccupied->Compressor); + // Ra: sterowanie miernikiem: przewód główny + Console::ValueSet(1, mvOccupied->PipePress); + // Ra: sterowanie miernikiem: cylinder hamulcowy + Console::ValueSet(2, mvOccupied->BrakePress); + // woltomierz wysokiego napięcia + Console::ValueSet(3, fHVoltage); + // Ra: sterowanie miernikiem: drugi amperomierz + Console::ValueSet(4, fHCurrent[2]); + // pierwszy amperomierz; dla EZT prąd całkowity + Console::ValueSet(5, fHCurrent[(mvControlled->TrainType & dt_EZT) ? 0 : 1]); + // Ra: prędkość na pin 43 - wyjście analogowe (to nie jest PWM); skakanie zapewnia mechanika napędu + Console::ValueSet(6, fTachoVelocity); + } #endif - //------------------ - // hunter-261211: nadmiarowy przetwornicy i ogrzewania - // Ra 15-01: to musi stąd wylecieć - zależności nie mogą być w kabinie - if (mvControlled->ConverterFlag == true) - { - fConverterTimer += Deltatime; - if ((mvControlled->CompressorFlag == true) && (mvControlled->CompressorPower == 1) && - ((mvControlled->EngineType == TEngineType::ElectricSeriesMotor) || - (mvControlled->TrainType == dt_EZT)) && - (DynamicObject->Controller == Humandriver) // hunter-110212: poprawka dla EZT - && ( false == DynamicObject->Mechanik->AIControllFlag ) ) - { // hunter-091012: poprawka (zmiana warunku z CompressorPower /rozne od 0/ na /rowne 1/) - if (fConverterTimer < fConverterPrzekaznik) - { - mvControlled->ConvOvldFlag = true; - if (mvControlled->TrainType != dt_EZT) - mvControlled->MainSwitch( false, ( mvControlled->TrainType == dt_EZT ? range_t::unit : range_t::local ) ); + //------------------ + // hunter-261211: nadmiarowy przetwornicy i ogrzewania + // Ra 15-01: to musi stąd wylecieć - zależności nie mogą być w kabinie + if (mvControlled->ConverterFlag == true) + { + fConverterTimer += Deltatime; + if ((mvControlled->CompressorFlag == true) && (mvControlled->CompressorPower == 1) && + ((mvControlled->EngineType == TEngineType::ElectricSeriesMotor) || + (mvControlled->TrainType == dt_EZT)) && + (DynamicObject->Controller == Humandriver) // hunter-110212: poprawka dla EZT + && ( false == DynamicObject->Mechanik->AIControllFlag ) ) + { // hunter-091012: poprawka (zmiana warunku z CompressorPower /rozne od 0/ na /rowne 1/) + if (fConverterTimer < fConverterPrzekaznik) + { + mvControlled->ConvOvldFlag = true; + if (mvControlled->TrainType != dt_EZT) + mvControlled->MainSwitch( false, ( mvControlled->TrainType == dt_EZT ? range_t::unit : range_t::local ) ); + } + else if( fConverterTimer >= fConverterPrzekaznik ) { + // changed switch from always true to take into account state of the compressor switch + mvControlled->CompressorSwitch( mvControlled->CompressorAllow ); + } + } + } + else + fConverterTimer = 0; + //------------------ + auto const lowvoltagepower { mvControlled->Battery || mvControlled->ConverterFlag }; + + // youBy - prad w drugim czlonie: galaz lub calosc + { + TDynamicObject *tmp { nullptr }; + if (DynamicObject->NextConnected()) + if ((TestFlag(mvControlled->Couplers[end::rear].CouplingFlag, ctrain_controll)) && + (mvOccupied->CabOccupied == 1)) + tmp = DynamicObject->NextConnected(); + if (DynamicObject->PrevConnected()) + if ((TestFlag(mvControlled->Couplers[end::front].CouplingFlag, ctrain_controll)) && + (mvOccupied->CabOccupied == -1)) + tmp = DynamicObject->PrevConnected(); + if( tmp ) { + if( tmp->MoverParameters->Power > 0 ) { + if( ggI1B.SubModel ) { + ggI1B.UpdateValue( tmp->MoverParameters->ShowCurrent( 1 ) ); + ggI1B.Update(); } - else if( fConverterTimer >= fConverterPrzekaznik ) { - // changed switch from always true to take into account state of the compressor switch - mvControlled->CompressorSwitch( mvControlled->CompressorAllow ); + if( ggI2B.SubModel ) { + ggI2B.UpdateValue( tmp->MoverParameters->ShowCurrent( 2 ) ); + ggI2B.Update(); + } + if( ggI3B.SubModel ) { + ggI3B.UpdateValue( tmp->MoverParameters->ShowCurrent( 3 ) ); + ggI3B.Update(); + } + if( ggItotalB.SubModel ) { + ggItotalB.UpdateValue( tmp->MoverParameters->ShowCurrent( 0 ) ); + ggItotalB.Update(); + } + if( ggWater1TempB.SubModel ) { + ggWater1TempB.UpdateValue( tmp->MoverParameters->dizel_heat.temperatura1 ); + ggWater1TempB.Update(); + } + if( ggOilPressB.SubModel ) { + ggOilPressB.UpdateValue( tmp->MoverParameters->OilPump.pressure ); + ggOilPressB.Update(); } } } + } + // McZapkie-300302: zegarek + if (ggClockMInd.SubModel) + { + ggClockSInd.UpdateValue(simulation::Time.data().wSecond); + ggClockSInd.Update(); + ggClockMInd.UpdateValue(simulation::Time.data().wMinute); + ggClockMInd.Update(); + ggClockHInd.UpdateValue(simulation::Time.data().wHour + simulation::Time.data().wMinute / 60.0); + ggClockHInd.Update(); + } + + Cabine[iCabn].Update( lowvoltagepower ); // nowy sposób ustawienia animacji +/* + if (ggZbS.SubModel) + { + ggZbS.UpdateValue(mvOccupied->Handle->GetCP()); + ggZbS.Update(); + } +*/ + // replacement for the above. TODO: move it to a more suitable place + m_brakehandlecp = mvOccupied->Handle->GetCP(); + + // youBy - napiecie na silnikach + if (ggEngineVoltage.SubModel) + { + if (mvControlled->DynamicBrakeFlag) + { + ggEngineVoltage.UpdateValue(std::abs(mvControlled->Im * 5)); + } else - fConverterTimer = 0; - //------------------ - auto const lowvoltagepower { mvControlled->Battery || mvControlled->ConverterFlag }; - - // youBy - prad w drugim czlonie: galaz lub calosc { - TDynamicObject *tmp { nullptr }; - if (DynamicObject->NextConnected()) - if ((TestFlag(mvControlled->Couplers[end::rear].CouplingFlag, ctrain_controll)) && - (mvOccupied->CabOccupied == 1)) - tmp = DynamicObject->NextConnected(); - if (DynamicObject->PrevConnected()) - if ((TestFlag(mvControlled->Couplers[end::front].CouplingFlag, ctrain_controll)) && - (mvOccupied->CabOccupied == -1)) - tmp = DynamicObject->PrevConnected(); - if( tmp ) { - if( tmp->MoverParameters->Power > 0 ) { - if( ggI1B.SubModel ) { - ggI1B.UpdateValue( tmp->MoverParameters->ShowCurrent( 1 ) ); - ggI1B.Update(); - } - if( ggI2B.SubModel ) { - ggI2B.UpdateValue( tmp->MoverParameters->ShowCurrent( 2 ) ); - ggI2B.Update(); - } - if( ggI3B.SubModel ) { - ggI3B.UpdateValue( tmp->MoverParameters->ShowCurrent( 3 ) ); - ggI3B.Update(); - } - if( ggItotalB.SubModel ) { - ggItotalB.UpdateValue( tmp->MoverParameters->ShowCurrent( 0 ) ); - ggItotalB.Update(); - } - if( ggWater1TempB.SubModel ) { - ggWater1TempB.UpdateValue( tmp->MoverParameters->dizel_heat.temperatura1 ); - ggWater1TempB.Update(); - } - if( ggOilPressB.SubModel ) { - ggOilPressB.UpdateValue( tmp->MoverParameters->OilPump.pressure ); - ggOilPressB.Update(); - } - } - } - } - // McZapkie-300302: zegarek - if (ggClockMInd.SubModel) - { - ggClockSInd.UpdateValue(simulation::Time.data().wSecond); - ggClockSInd.Update(); - ggClockMInd.UpdateValue(simulation::Time.data().wMinute); - ggClockMInd.Update(); - ggClockHInd.UpdateValue(simulation::Time.data().wHour + simulation::Time.data().wMinute / 60.0); - ggClockHInd.Update(); - } - - Cabine[iCabn].Update( lowvoltagepower ); // nowy sposób ustawienia animacji -/* - if (ggZbS.SubModel) - { - ggZbS.UpdateValue(mvOccupied->Handle->GetCP()); - ggZbS.Update(); - } -*/ - // replacement for the above. TODO: move it to a more suitable place - m_brakehandlecp = mvOccupied->Handle->GetCP(); - - // youBy - napiecie na silnikach - if (ggEngineVoltage.SubModel) - { - if (mvControlled->DynamicBrakeFlag) + int x; + if ((mvControlled->TrainType == dt_ET42) && + (mvControlled->Imax == mvControlled->ImaxHi)) + x = 1; + else + x = 2; + if ((mvControlled->RList[mvControlled->MainCtrlActualPos].Mn > 0) && + (std::abs(mvControlled->Im) > 0)) { - ggEngineVoltage.UpdateValue(std::abs(mvControlled->Im * 5)); + ggEngineVoltage.UpdateValue( + (x * (std::abs(mvControlled->EngineVoltage) - + mvControlled->RList[mvControlled->MainCtrlActualPos].R * + std::abs(mvControlled->Im)) / + mvControlled->RList[mvControlled->MainCtrlActualPos].Mn)); } else { - int x; - if ((mvControlled->TrainType == dt_ET42) && - (mvControlled->Imax == mvControlled->ImaxHi)) - x = 1; - else - x = 2; - if ((mvControlled->RList[mvControlled->MainCtrlActualPos].Mn > 0) && - (std::abs(mvControlled->Im) > 0)) - { - ggEngineVoltage.UpdateValue( - (x * (std::abs(mvControlled->EngineVoltage) - - mvControlled->RList[mvControlled->MainCtrlActualPos].R * - std::abs(mvControlled->Im)) / - mvControlled->RList[mvControlled->MainCtrlActualPos].Mn)); - } - else - { - ggEngineVoltage.UpdateValue(0); - } + ggEngineVoltage.UpdateValue(0); } - ggEngineVoltage.Update(); } + ggEngineVoltage.Update(); + } - // Winger 140404 - woltomierz NN - if (ggLVoltage.SubModel) + // Winger 140404 - woltomierz NN + if (ggLVoltage.SubModel) + { + // NOTE: since we don't have functional converter object, we're faking it here by simple check whether converter is on + // TODO: implement object-based circuits and power systems model so we can have this working more properly + ggLVoltage.UpdateValue( + std::max( + ( mvControlled->ConverterFlag ? + mvControlled->NominalBatteryVoltage : + 0.0 ), + ( mvControlled->Battery ? + mvControlled->BatteryVoltage : + 0.0 ) ) ); + ggLVoltage.Update(); + } + + if (mvControlled->EngineType == TEngineType::DieselElectric) + { // ustawienie zmiennych dla silnika spalinowego + fEngine[1] = mvControlled->ShowEngineRotation(1); + fEngine[2] = mvControlled->ShowEngineRotation(2); + } + + else if (mvControlled->EngineType == TEngineType::DieselEngine) + { // albo dla innego spalinowego + fEngine[1] = mvControlled->ShowEngineRotation(1); + fEngine[2] = mvControlled->ShowEngineRotation(2); + fEngine[3] = mvControlled->ShowEngineRotation(3); + if (ggMainGearStatus.SubModel) { - // NOTE: since we don't have functional converter object, we're faking it here by simple check whether converter is on - // TODO: implement object-based circuits and power systems model so we can have this working more properly - ggLVoltage.UpdateValue( - std::max( - ( mvControlled->ConverterFlag ? - mvControlled->NominalBatteryVoltage : - 0.0 ), - ( mvControlled->Battery ? - mvControlled->BatteryVoltage : - 0.0 ) ) ); - ggLVoltage.Update(); + if (mvControlled->Mains) + ggMainGearStatus.UpdateValue(1.1 - std::abs(mvControlled->dizel_automaticgearstatus)); + else + ggMainGearStatus.UpdateValue(0.0); + ggMainGearStatus.Update(); } - - if (mvControlled->EngineType == TEngineType::DieselElectric) - { // ustawienie zmiennych dla silnika spalinowego - fEngine[1] = mvControlled->ShowEngineRotation(1); - fEngine[2] = mvControlled->ShowEngineRotation(2); + if (ggIgnitionKey.SubModel) + { + ggIgnitionKey.UpdateValue( + ( mvControlled->Mains ) + || ( mvControlled->dizel_startup ) + || ( fMainRelayTimer > 0.f ) + || ( ( ggMainButton.SubModel != nullptr ) && ( ggMainButton.GetDesiredValue() > 0.95 ) ) + || ( ( ggMainOnButton.SubModel != nullptr ) && ( ggMainOnButton.GetDesiredValue() > 0.95 ) ) ); + ggIgnitionKey.Update(); } + } - else if (mvControlled->EngineType == TEngineType::DieselEngine) - { // albo dla innego spalinowego - fEngine[1] = mvControlled->ShowEngineRotation(1); - fEngine[2] = mvControlled->ShowEngineRotation(2); - fEngine[3] = mvControlled->ShowEngineRotation(3); - if (ggMainGearStatus.SubModel) - { - if (mvControlled->Mains) - ggMainGearStatus.UpdateValue(1.1 - std::abs(mvControlled->dizel_automaticgearstatus)); - else - ggMainGearStatus.UpdateValue(0.0); - ggMainGearStatus.Update(); - } - if (ggIgnitionKey.SubModel) - { - ggIgnitionKey.UpdateValue( - ( mvControlled->Mains ) - || ( mvControlled->dizel_startup ) - || ( fMainRelayTimer > 0.f ) - || ( ( ggMainButton.SubModel != nullptr ) && ( ggMainButton.GetDesiredValue() > 0.95 ) ) - || ( ( ggMainOnButton.SubModel != nullptr ) && ( ggMainOnButton.GetDesiredValue() > 0.95 ) ) ); - ggIgnitionKey.Update(); + if (mvControlled->SlippingWheels) { + // Ra 2014-12: lokomotywy 181/182 dostają SlippingWheels po zahamowaniu powyżej 2.85 bara i buczały + double veldiff = (DynamicObject->GetVelocity() - fTachoVelocity) / mvControlled->Vmax; + if( veldiff < -0.01 ) { + // 1% Vmax rezerwy, żeby 181/182 nie buczały po zahamowaniu, ale to proteza + if( std::abs( mvControlled->Im ) > 10.0 ) { + btLampkaPoslizg.Turn( true ); } } + } + else { + btLampkaPoslizg.Turn( false ); + } - if (mvControlled->SlippingWheels) { - // Ra 2014-12: lokomotywy 181/182 dostają SlippingWheels po zahamowaniu powyżej 2.85 bara i buczały - double veldiff = (DynamicObject->GetVelocity() - fTachoVelocity) / mvControlled->Vmax; - if( veldiff < -0.01 ) { - // 1% Vmax rezerwy, żeby 181/182 nie buczały po zahamowaniu, ale to proteza - if( std::abs( mvControlled->Im ) > 10.0 ) { - btLampkaPoslizg.Turn( true ); - } + if ((mvControlled->Mains) || (mvControlled->TrainType == dt_EZT)) + { + btLampkaNadmSil.Turn(mvControlled->FuseFlagCheck()); + } + else + { + btLampkaNadmSil.Turn( false ); + } + + if( true == lowvoltagepower ) { + // alerter test + if( true == CAflag ) { + if( ggSecurityResetButton.GetDesiredValue() > 0.95 ) { + fCzuwakTestTimer += Deltatime; + } + if( fCzuwakTestTimer > 1.0 ) { + SetFlag( mvOccupied->SecuritySystem.Status, s_CAtest ); + } + } + // McZapkie-141102: SHP i czuwak, TODO: sygnalizacja kabinowa + if( mvOccupied->SecuritySystem.Status != s_off ) { + if( fBlinkTimer > fCzuwakBlink ) + fBlinkTimer = -fCzuwakBlink; + else + fBlinkTimer += Deltatime; + // hunter-091012: dodanie testu czuwaka + if( ( TestFlag( mvOccupied->SecuritySystem.Status, s_aware ) ) + || ( TestFlag( mvOccupied->SecuritySystem.Status, s_CAtest ) ) ) { + btLampkaCzuwaka.Turn( fBlinkTimer > 0 ); + } + else + btLampkaCzuwaka.Turn( false ); + + btLampkaSHP.Turn( TestFlag( mvOccupied->SecuritySystem.Status, s_active ) ); + } + else // wylaczone + { + btLampkaCzuwaka.Turn( false ); + btLampkaSHP.Turn( false ); + } + + btLampkaWylSzybki.Turn( + ( ( (m_linebreakerstate == 2) + || (true == mvControlled->Mains) ) ? + true : + false ) ); + btLampkaWylSzybkiOff.Turn( + ( ( ( m_linebreakerstate == 2 ) + || ( true == mvControlled->Mains ) ) ? + false : + true ) ); + btLampkaMainBreakerReady.Turn( + ( ( ( mvControlled->MainsInitTimeCountdown > 0.0 ) + || ( m_linebreakerstate == 2 ) + || ( true == mvControlled->Mains ) ) ? + false : + true ) ); + + btLampkaPrzetw.Turn( mvControlled->ConverterFlag ); + btLampkaPrzetwOff.Turn( false == mvControlled->ConverterFlag ); + btLampkaNadmPrzetw.Turn( mvControlled->ConvOvldFlag ); + + btLampkaOpory.Turn( + mvControlled->StLinFlag ? + mvControlled->ResistorsFlagCheck() : + false ); + + btLampkaBezoporowa.Turn( + ( true == mvControlled->ResistorsFlagCheck() ) + || ( mvControlled->MainCtrlActualPos == 0 ) ); // do EU04 + + btLampkaStyczn.Turn( + ( ( mvControlled->StLinFlag ) || ( mvControlled->BrakePress > 2.0 ) || ( mvControlled->PipePress < 3.6 ) ) ? + false : + ( mvControlled->BrakePress < 1.0 ) ); // mozna prowadzic rozruch + + btLampkaPrzekRozn.Turn( + ( ( mvControlled->GroundRelay ) || ( mvControlled->BrakePress > 2.0 ) || ( mvControlled->PipePress < 3.6 ) ) ? + false : + ( mvControlled->BrakePress < 1.0 ) ); // relay is off and needs a reset + + if( ( ( mvControlled->CabOccupied == 1 ) && ( TestFlag( mvControlled->Couplers[ end::rear ].CouplingFlag, coupling::control ) ) ) + || ( ( mvControlled->CabOccupied == -1 ) && ( TestFlag( mvControlled->Couplers[ end::front ].CouplingFlag, coupling::control ) ) ) ) { + btLampkaUkrotnienie.Turn( true ); + } + else { + btLampkaUkrotnienie.Turn( false ); + } + + // if + // ((TestFlag(mvControlled->BrakeStatus,+b_Rused+b_Ractive)))//Lampka drugiego stopnia hamowania + btLampkaHamPosp.Turn((TestFlag(mvOccupied->Hamulec->GetBrakeStatus(), 1))); // lampka drugiego stopnia hamowania + //TODO: youBy wyciągnąć flagę wysokiego stopnia + + // hunter-121211: lampka zanikowo-pradowego wentylatorow: + btLampkaNadmWent.Turn( ( mvControlled->RventRot < 5.0 ) && ( mvControlled->ResistorsFlagCheck() ) ); + //------- + + btLampkaWysRozr.Turn(!(mvControlled->Imax < mvControlled->ImaxHi)); + + if( ( false == mvControlled->DelayCtrlFlag ) + && ( ( mvControlled->ScndCtrlActualPos > 0 ) + || ( ( mvControlled->RList[ mvControlled->MainCtrlActualPos ].ScndAct != 0 ) + && ( mvControlled->RList[ mvControlled->MainCtrlActualPos ].ScndAct != 255 ) ) ) ) { + btLampkaBoczniki.Turn( true ); + } + else { + btLampkaBoczniki.Turn( false ); + } + + btLampkaNapNastHam.Turn(mvControlled->DirActive != 0); // napiecie na nastawniku hamulcowym + btLampkaSprezarka.Turn(mvControlled->CompressorFlag); // mutopsitka dziala + btLampkaSprezarkaOff.Turn( false == mvControlled->CompressorFlag ); + btLampkaFuelPumpOff.Turn( false == mvControlled->FuelPump.is_active ); + // boczniki + unsigned char scp; // Ra: dopisałem "unsigned" + // Ra: w SU45 boczniki wchodzą na MainCtrlPos, a nie na MainCtrlActualPos + // - pokićkał ktoś? + scp = mvControlled->RList[mvControlled->MainCtrlPos].ScndAct; + scp = (scp == 255 ? 0 : scp); // Ra: whatta hella is this? + if ((mvControlled->ScndCtrlPos > 0) || (mvControlled->ScndInMain != 0) && (scp > 0)) + { // boczniki pojedynczo + btLampkaBocznik1.Turn( true ); + btLampkaBocznik2.Turn(mvControlled->ScndCtrlPos > 1); + btLampkaBocznik3.Turn(mvControlled->ScndCtrlPos > 2); + btLampkaBocznik4.Turn(mvControlled->ScndCtrlPos > 3); + } + else + { // wyłączone wszystkie cztery + btLampkaBocznik1.Turn( false ); + btLampkaBocznik2.Turn( false ); + btLampkaBocznik3.Turn( false ); + btLampkaBocznik4.Turn( false ); + } + + if( mvControlled->Signalling == true ) { + if( mvOccupied->BrakePress >= 1.45f ) { + btLampkaHamowanie1zes.Turn( true ); + } + if( mvControlled->BrakePress < 0.75f ) { + btLampkaHamowanie1zes.Turn( false ); } } else { - btLampkaPoslizg.Turn( false ); + btLampkaHamowanie1zes.Turn( false ); } - if ((mvControlled->Mains) || (mvControlled->TrainType == dt_EZT)) - { - btLampkaNadmSil.Turn(mvControlled->FuseFlagCheck()); - } - else - { - btLampkaNadmSil.Turn( false ); - } - - if( true == lowvoltagepower ) { - // alerter test - if( true == CAflag ) { - if( ggSecurityResetButton.GetDesiredValue() > 0.95 ) { - fCzuwakTestTimer += Deltatime; - } - if( fCzuwakTestTimer > 1.0 ) { - SetFlag( mvOccupied->SecuritySystem.Status, s_CAtest ); - } + switch (mvControlled->TrainType) { + // zależnie od typu lokomotywy + case dt_EZT: { + btLampkaHamienie.Turn( ( mvControlled->BrakePress >= 0.2 ) && mvControlled->Signalling ); + break; } - // McZapkie-141102: SHP i czuwak, TODO: sygnalizacja kabinowa - if( mvOccupied->SecuritySystem.Status != s_off ) { - if( fBlinkTimer > fCzuwakBlink ) - fBlinkTimer = -fCzuwakBlink; - else - fBlinkTimer += Deltatime; - // hunter-091012: dodanie testu czuwaka - if( ( TestFlag( mvOccupied->SecuritySystem.Status, s_aware ) ) - || ( TestFlag( mvOccupied->SecuritySystem.Status, s_CAtest ) ) ) { - btLampkaCzuwaka.Turn( fBlinkTimer > 0 ); + case dt_ET41: { + // odhamowanie drugiego członu + if( mvSecond ) { + // bo może komuś przyjść do głowy jeżdżenie jednym członem + btLampkaHamienie.Turn( mvSecond->BrakePress < 0.4 ); } - else - btLampkaCzuwaka.Turn( false ); + break; + } + default: { + btLampkaHamienie.Turn( ( mvOccupied->BrakePress >= 0.1 ) || mvControlled->DynamicBrakeFlag ); + btLampkaBrakingOff.Turn( ( mvOccupied->BrakePress < 0.1 ) && ( false == mvControlled->DynamicBrakeFlag ) ); + break; + } + } + // KURS90 + btLampkaMaxSila.Turn(abs(mvControlled->Im) >= 350); + btLampkaPrzekrMaxSila.Turn(abs(mvControlled->Im) >= 450); + btLampkaRadio.Turn(mvOccupied->Radio); + btLampkaRadioStop.Turn( mvOccupied->Radio && mvOccupied->RadioStopFlag ); + btLampkaHamulecReczny.Turn(mvOccupied->ManualBrakePos > 0); + // NBMX wrzesien 2003 - drzwi oraz sygnał odjazdu + btLampkaDoorLeft.Turn( DynamicObject->Mechanik->IsAnyDoorOpen[ ( cab_to_end() == end::front ? side::left : side::right ) ] ); + btLampkaDoorRight.Turn( DynamicObject->Mechanik->IsAnyDoorOpen[ ( cab_to_end() == end::front ? side::right : side::left ) ] ); + btLampkaBlokadaDrzwi.Turn( mvOccupied->Doors.is_locked ); + btLampkaDoorLockOff.Turn( false == mvOccupied->Doors.lock_enabled ); + btLampkaDepartureSignal.Turn( mvControlled->DepartureSignal ); + btLampkaNapNastHam.Turn((mvControlled->DirActive != 0) && (mvOccupied->EpFuse)); // napiecie na nastawniku hamulcowym + btLampkaForward.Turn(mvControlled->DirActive > 0); // jazda do przodu + btLampkaBackward.Turn(mvControlled->DirActive < 0); // jazda do tyłu + btLampkaED.Turn(mvControlled->DynamicBrakeFlag); // hamulec ED + btLampkaBrakeProfileG.Turn( TestFlag( mvOccupied->BrakeDelayFlag, bdelay_G ) ); + btLampkaBrakeProfileP.Turn( TestFlag( mvOccupied->BrakeDelayFlag, bdelay_P ) ); + btLampkaBrakeProfileR.Turn( TestFlag( mvOccupied->BrakeDelayFlag, bdelay_R ) ); + btLampkaSpringBrakeActive.Turn( mvOccupied->SpringBrake.IsActive ); + btLampkaSpringBrakeInactive.Turn( !mvOccupied->SpringBrake.IsActive ); + // light indicators + // NOTE: sides are hardcoded to deal with setups where single cab is equipped with all indicators + btLampkaUpperLight.Turn( ( mvOccupied->iLights[ end::front ] & light::headlight_upper ) != 0 ); + btLampkaLeftLight.Turn( ( mvOccupied->iLights[ end::front ] & light::headlight_left ) != 0 ); + btLampkaRightLight.Turn( ( mvOccupied->iLights[ end::front ] & light::headlight_right ) != 0 ); + btLampkaLeftEndLight.Turn( ( mvOccupied->iLights[ end::front ] & light::redmarker_left ) != 0 ); + btLampkaRightEndLight.Turn( ( mvOccupied->iLights[ end::front ] & light::redmarker_right ) != 0 ); + btLampkaRearUpperLight.Turn( ( mvOccupied->iLights[ end::rear ] & light::headlight_upper ) != 0 ); + btLampkaRearLeftLight.Turn( ( mvOccupied->iLights[ end::rear ] & light::headlight_left ) != 0 ); + btLampkaRearRightLight.Turn( ( mvOccupied->iLights[ end::rear ] & light::headlight_right ) != 0 ); + btLampkaRearLeftEndLight.Turn( ( mvOccupied->iLights[ end::rear ] & light::redmarker_left ) != 0 ); + btLampkaRearRightEndLight.Turn( ( mvOccupied->iLights[ end::rear ] & light::redmarker_right ) != 0 ); + // others + btLampkaMalfunction.Turn( mvControlled->dizel_heat.PA ); + btLampkaMotorBlowers.Turn( ( mvControlled->MotorBlowers[ end::front ].is_active ) && ( mvControlled->MotorBlowers[ end::rear ].is_active ) ); + btLampkaCoolingFans.Turn( mvControlled->RventRot > 1.0 ); + btLampkaTempomat.Turn( mvOccupied->SpeedCtrlUnit.IsActive ); + btLampkaDistanceCounter.Turn( m_distancecounter >= 0.f ); + // universal devices state indicators + for( auto idx = 0; idx < btUniversals.size(); ++idx ) { + btUniversals[ idx ].Turn( ggUniversals[ idx ].GetValue() > 0.5 ); + } + } + else { + // wylaczone + btLampkaCzuwaka.Turn( false ); + btLampkaSHP.Turn( false ); + btLampkaWylSzybki.Turn( false ); + btLampkaWylSzybkiOff.Turn( false ); + btLampkaMainBreakerReady.Turn( false ); + btLampkaWysRozr.Turn( false ); + btLampkaOpory.Turn( false ); + btLampkaStyczn.Turn( false ); + btLampkaUkrotnienie.Turn( false ); + btLampkaHamPosp.Turn( false ); + btLampkaBoczniki.Turn( false ); + btLampkaNapNastHam.Turn( false ); + btLampkaPrzetw.Turn( false ); + btLampkaPrzetwOff.Turn( false ); + btLampkaNadmPrzetw.Turn( false ); + btLampkaSprezarka.Turn( false ); + btLampkaSprezarkaOff.Turn( false ); + btLampkaFuelPumpOff.Turn( false ); + btLampkaBezoporowa.Turn( false ); + btLampkaHamowanie1zes.Turn( false ); + btLampkaHamienie.Turn( false ); + btLampkaBrakingOff.Turn( false ); + btLampkaBrakeProfileG.Turn( false ); + btLampkaBrakeProfileP.Turn( false ); + btLampkaBrakeProfileR.Turn( false ); + btLampkaSpringBrakeActive.Turn( false ); + btLampkaSpringBrakeInactive.Turn( false ); + btLampkaMaxSila.Turn( false ); + btLampkaPrzekrMaxSila.Turn( false ); + btLampkaRadio.Turn( false ); + btLampkaRadioStop.Turn( false ); + btLampkaHamulecReczny.Turn( false ); + btLampkaDoorLeft.Turn( false ); + btLampkaDoorRight.Turn( false ); + btLampkaBlokadaDrzwi.Turn( false ); + btLampkaDoorLockOff.Turn( false ); + btLampkaDepartureSignal.Turn( false ); + btLampkaNapNastHam.Turn( false ); + btLampkaForward.Turn( false ); + btLampkaBackward.Turn( false ); + btLampkaED.Turn( false ); + // light indicators + btLampkaUpperLight.Turn( false ); + btLampkaLeftLight.Turn( false ); + btLampkaRightLight.Turn( false ); + btLampkaLeftEndLight.Turn( false ); + btLampkaRightEndLight.Turn( false ); + btLampkaRearUpperLight.Turn( false ); + btLampkaRearLeftLight.Turn( false ); + btLampkaRearRightLight.Turn( false ); + btLampkaRearLeftEndLight.Turn( false ); + btLampkaRearRightEndLight.Turn( false ); + // others + btLampkaMalfunction.Turn( false ); + btLampkaMotorBlowers.Turn( false ); + btLampkaCoolingFans.Turn( false ); + btLampkaTempomat.Turn( false ); + btLampkaDistanceCounter.Turn( false ); + // universal devices state indicators + for( auto &universal : btUniversals ) { + universal.Turn( false ); + } + } - btLampkaSHP.Turn( TestFlag( mvOccupied->SecuritySystem.Status, s_active ) ); + { // yB - wskazniki drugiego czlonu + TDynamicObject *tmp { nullptr }; //=mvControlled->mvSecond; //Ra 2014-07: trzeba to jeszcze wyjąć z kabiny... + // Ra 2014-07: no nie ma potrzeby szukać tego w każdej klatce + if ((TestFlag(mvControlled->Couplers[1].CouplingFlag, ctrain_controll)) && + (mvOccupied->CabOccupied > 0)) + tmp = DynamicObject->NextConnected(); + if ((TestFlag(mvControlled->Couplers[0].CouplingFlag, ctrain_controll)) && + (mvOccupied->CabOccupied < 0)) + tmp = DynamicObject->PrevConnected(); + + if( tmp ) { + if( lowvoltagepower ) { + + auto const *mover{ tmp->MoverParameters }; + + btLampkaWylSzybkiB.Turn( mover->Mains ); + btLampkaWylSzybkiBOff.Turn( + ( false == mover->Mains ) + /*&& ( mover->MainsInitTimeCountdown <= 0.0 )*/ + /*&& ( fHVoltage != 0.0 )*/ ); + + btLampkaOporyB.Turn( mover->ResistorsFlagCheck() ); + btLampkaBezoporowaB.Turn( + ( true == mover->ResistorsFlagCheck() ) + || ( mover->MainCtrlActualPos == 0 ) ); // do EU04 + + if( ( mover->StLinFlag ) + || ( mover->BrakePress > 2.0 ) + || ( mover->PipePress < 3.6 ) ) { + btLampkaStycznB.Turn( false ); + } + else if( mover->BrakePress < 1.0 ) { + btLampkaStycznB.Turn( true ); // mozna prowadzic rozruch + } + // hunter-271211: sygnalizacja poslizgu w pierwszym pojezdzie, gdy wystapi w drugim + btLampkaPoslizg.Turn( mover->SlippingWheels ); + + btLampkaSprezarkaB.Turn( mover->CompressorFlag ); // mutopsitka dziala + btLampkaSprezarkaBOff.Turn( false == mover->CompressorFlag ); + if( mvControlled->Signalling == true ) { + if( mover->BrakePress >= 1.45f ) { + btLampkaHamowanie2zes.Turn( true ); + } + if( mover->BrakePress < 0.75f ) { + btLampkaHamowanie2zes.Turn( false ); + } + } + else { + btLampkaHamowanie2zes.Turn( false ); + } + btLampkaNadmPrzetwB.Turn( mover->ConvOvldFlag ); // nadmiarowy przetwornicy? + btLampkaPrzetwB.Turn( mover->ConverterFlag ); // zalaczenie przetwornicy + btLampkaPrzetwBOff.Turn( false == mover->ConverterFlag ); + btLampkaHVoltageB.Turn( mover->NoVoltRelay && mover->OvervoltageRelay ); + btLampkaMalfunctionB.Turn( mover->dizel_heat.PA ); + // motor fuse indicator turns on if the fuse was blown in any unit under control + if( mover->Mains ) { + btLampkaNadmSil.Turn( btLampkaNadmSil.GetValue() || mover->FuseFlagCheck() ); + } } else // wylaczone { - btLampkaCzuwaka.Turn( false ); - btLampkaSHP.Turn( false ); + btLampkaWylSzybkiB.Turn( false ); + btLampkaWylSzybkiBOff.Turn( false ); + btLampkaOporyB.Turn( false ); + btLampkaStycznB.Turn( false ); + btLampkaSprezarkaB.Turn( false ); + btLampkaSprezarkaBOff.Turn( false ); + btLampkaBezoporowaB.Turn( false ); + btLampkaHamowanie2zes.Turn( false ); + btLampkaNadmPrzetwB.Turn( false ); + btLampkaPrzetwB.Turn( false ); + btLampkaPrzetwBOff.Turn( false ); + btLampkaHVoltageB.Turn( false ); + btLampkaMalfunctionB.Turn( false ); } + } + } + // McZapkie-080602: obroty (albo translacje) regulatorow + if( ggJointCtrl.SubModel != nullptr ) { + // joint master controller moves forward to adjust power and backward to adjust brakes + auto const brakerangemultiplier { + /* NOTE: scaling disabled as it was conflicting with associating sounds with control positions + ( mvControlled->CoupledCtrl ? + mvControlled->MainCtrlPosNo + mvControlled->ScndCtrlPosNo : + mvControlled->MainCtrlPosNo ) + / static_cast(LocalBrakePosNo) + */ + 1 }; + ggJointCtrl.UpdateValue( + ( mvOccupied->LocalBrakePosA > 0.0 ? mvOccupied->LocalBrakePosA * LocalBrakePosNo * -1 * brakerangemultiplier : + mvControlled->CoupledCtrl ? double( mvControlled->MainCtrlPos + mvControlled->ScndCtrlPos ) : + double( mvControlled->MainCtrlPos ) ), + dsbNastawnikJazdy ); + ggJointCtrl.Update(); + } + if ( ggMainCtrl.SubModel != nullptr ) { - btLampkaWylSzybki.Turn( - ( ( (m_linebreakerstate == 2) - || (true == mvControlled->Mains) ) ? - true : - false ) ); - btLampkaWylSzybkiOff.Turn( - ( ( ( m_linebreakerstate == 2 ) - || ( true == mvControlled->Mains ) ) ? - false : - true ) ); - btLampkaMainBreakerReady.Turn( - ( ( ( mvControlled->MainsInitTimeCountdown > 0.0 ) - || ( m_linebreakerstate == 2 ) - || ( true == mvControlled->Mains ) ) ? - false : - true ) ); +#ifdef _WIN32 + if( ( DynamicObject->Mechanik != nullptr ) + && ( false == DynamicObject->Mechanik->AIControllFlag ) // nie blokujemy AI + && ( Global.iFeedbackMode == 4 ) + && ( Global.fCalibrateIn[ 2 ][ 1 ] != 0.0 ) ) { - btLampkaPrzetw.Turn( mvControlled->ConverterFlag ); - btLampkaPrzetwOff.Turn( false == mvControlled->ConverterFlag ); - btLampkaNadmPrzetw.Turn( mvControlled->ConvOvldFlag ); + set_master_controller( Console::AnalogCalibrateGet( 2 ) * mvOccupied->MainCtrlPosNo ); + } +#endif - btLampkaOpory.Turn( - mvControlled->StLinFlag ? - mvControlled->ResistorsFlagCheck() : - false ); - - btLampkaBezoporowa.Turn( - ( true == mvControlled->ResistorsFlagCheck() ) - || ( mvControlled->MainCtrlActualPos == 0 ) ); // do EU04 - - btLampkaStyczn.Turn( - ( ( mvControlled->StLinFlag ) /* || ( mvControlled->BrakePress > 2.0 ) || ( mvControlled->PipePress < 3.6 ) */ ) ? - false : - ( mvControlled->BrakePress < 1.0 ) ); // mozna prowadzic rozruch - - btLampkaPrzekRozn.Turn( - ( ( mvControlled->GroundRelay ) || ( mvControlled->BrakePress > 2.0 ) || ( mvControlled->PipePress < 3.6 ) ) ? - false : - ( mvControlled->BrakePress < 1.0 ) ); // relay is off and needs a reset - - if( ( ( mvControlled->CabOccupied == 1 ) && ( TestFlag( mvControlled->Couplers[ end::rear ].CouplingFlag, coupling::control ) ) ) - || ( ( mvControlled->CabOccupied == -1 ) && ( TestFlag( mvControlled->Couplers[ end::front ].CouplingFlag, coupling::control ) ) ) ) { - btLampkaUkrotnienie.Turn( true ); - } - else { - btLampkaUkrotnienie.Turn( false ); - } - - // if - // ((TestFlag(mvControlled->BrakeStatus,+b_Rused+b_Ractive)))//Lampka drugiego stopnia hamowania - btLampkaHamPosp.Turn((TestFlag(mvOccupied->Hamulec->GetBrakeStatus(), 1))); // lampka drugiego stopnia hamowania - //TODO: youBy wyciągnąć flagę wysokiego stopnia - - // hunter-121211: lampka zanikowo-pradowego wentylatorow: - btLampkaNadmWent.Turn( ( mvControlled->RventRot < 5.0 ) && ( mvControlled->ResistorsFlagCheck() ) ); - //------- - - btLampkaWysRozr.Turn(!(mvControlled->Imax < mvControlled->ImaxHi)); - - if( ( false == mvControlled->DelayCtrlFlag ) - && ( ( mvControlled->ScndCtrlActualPos > 0 ) - || ( ( mvControlled->RList[ mvControlled->MainCtrlActualPos ].ScndAct != 0 ) - && ( mvControlled->RList[ mvControlled->MainCtrlActualPos ].ScndAct != 255 ) ) ) ) { - btLampkaBoczniki.Turn( true ); - } - else { - btLampkaBoczniki.Turn( false ); - } - - btLampkaNapNastHam.Turn(mvControlled->DirActive != 0); // napiecie na nastawniku hamulcowym - btLampkaSprezarka.Turn(mvControlled->CompressorFlag); // mutopsitka dziala - btLampkaSprezarkaOff.Turn( false == mvControlled->CompressorFlag ); - btLampkaFuelPumpOff.Turn( false == mvControlled->FuelPump.is_active ); - // boczniki - unsigned char scp; // Ra: dopisałem "unsigned" - // Ra: w SU45 boczniki wchodzą na MainCtrlPos, a nie na MainCtrlActualPos - // - pokićkał ktoś? - scp = mvControlled->RList[mvControlled->MainCtrlPos].ScndAct; - scp = (scp == 255 ? 0 : scp); // Ra: whatta hella is this? - if ((mvControlled->ScndCtrlPos > 0) || (mvControlled->ScndInMain != 0) && (scp > 0)) - { // boczniki pojedynczo - btLampkaBocznik1.Turn( true ); - btLampkaBocznik2.Turn(mvControlled->ScndCtrlPos > 1); - btLampkaBocznik3.Turn(mvControlled->ScndCtrlPos > 2); - btLampkaBocznik4.Turn(mvControlled->ScndCtrlPos > 3); - } - else - { // wyłączone wszystkie cztery - btLampkaBocznik1.Turn( false ); - btLampkaBocznik2.Turn( false ); - btLampkaBocznik3.Turn( false ); - btLampkaBocznik4.Turn( false ); - } - - if( mvControlled->Signalling == true ) { - if( mvOccupied->BrakePress >= 1.45f ) { - btLampkaHamowanie1zes.Turn( true ); - } - if( mvControlled->BrakePress < 0.75f ) { - btLampkaHamowanie1zes.Turn( false ); - } - } - else { - btLampkaHamowanie1zes.Turn( false ); - } - - switch (mvControlled->TrainType) { - // zależnie od typu lokomotywy - case dt_EZT: { - btLampkaHamienie.Turn( ( mvControlled->BrakePress >= 0.2 ) && mvControlled->Signalling ); - break; - } - case dt_ET41: { - // odhamowanie drugiego członu - if( mvSecond ) { - // bo może komuś przyjść do głowy jeżdżenie jednym członem - btLampkaHamienie.Turn( mvSecond->BrakePress < 0.4 ); - } - break; - } - default: { - btLampkaHamienie.Turn( ( mvOccupied->BrakePress >= 0.1 ) || mvControlled->DynamicBrakeFlag ); - btLampkaBrakingOff.Turn( ( mvOccupied->BrakePress < 0.1 ) && ( false == mvControlled->DynamicBrakeFlag ) ); - break; - } - } - // KURS90 - btLampkaMaxSila.Turn(abs(mvControlled->Im) >= 350); - btLampkaPrzekrMaxSila.Turn(abs(mvControlled->Im) >= 450); - btLampkaRadio.Turn(mvOccupied->Radio); - btLampkaRadioStop.Turn( mvOccupied->Radio && mvOccupied->RadioStopFlag ); - btLampkaHamulecReczny.Turn(mvOccupied->ManualBrakePos > 0); - // NBMX wrzesien 2003 - drzwi oraz sygnał odjazdu - btLampkaDoorLeft.Turn( DynamicObject->Mechanik->IsAnyDoorOpen[ ( cab_to_end() == end::front ? side::left : side::right ) ] ); - btLampkaDoorRight.Turn( DynamicObject->Mechanik->IsAnyDoorOpen[ ( cab_to_end() == end::front ? side::right : side::left ) ] ); - btLampkaBlokadaDrzwi.Turn( mvOccupied->Doors.is_locked ); - btLampkaDoorLockOff.Turn( false == mvOccupied->Doors.lock_enabled ); - btLampkaDepartureSignal.Turn( mvControlled->DepartureSignal ); - btLampkaNapNastHam.Turn((mvControlled->DirActive != 0) && (mvOccupied->EpFuse)); // napiecie na nastawniku hamulcowym - btLampkaForward.Turn(mvControlled->DirActive > 0); // jazda do przodu - btLampkaBackward.Turn(mvControlled->DirActive < 0); // jazda do tyłu - btLampkaED.Turn(mvControlled->DynamicBrakeFlag); // hamulec ED - btLampkaBrakeProfileG.Turn( TestFlag( mvOccupied->BrakeDelayFlag, bdelay_G ) ); - btLampkaBrakeProfileP.Turn( TestFlag( mvOccupied->BrakeDelayFlag, bdelay_P ) ); - btLampkaBrakeProfileR.Turn( TestFlag( mvOccupied->BrakeDelayFlag, bdelay_R ) ); - btLampkaSpringBrakeActive.Turn( mvOccupied->SpringBrake.IsActive ); - btLampkaSpringBrakeInactive.Turn( !mvOccupied->SpringBrake.IsActive ); - // light indicators - // NOTE: sides are hardcoded to deal with setups where single cab is equipped with all indicators - btLampkaUpperLight.Turn( ( mvOccupied->iLights[ end::front ] & light::headlight_upper ) != 0 ); - btLampkaLeftLight.Turn( ( mvOccupied->iLights[ end::front ] & light::headlight_left ) != 0 ); - btLampkaRightLight.Turn( ( mvOccupied->iLights[ end::front ] & light::headlight_right ) != 0 ); - btLampkaLeftEndLight.Turn( ( mvOccupied->iLights[ end::front ] & light::redmarker_left ) != 0 ); - btLampkaRightEndLight.Turn( ( mvOccupied->iLights[ end::front ] & light::redmarker_right ) != 0 ); - btLampkaRearUpperLight.Turn( ( mvOccupied->iLights[ end::rear ] & light::headlight_upper ) != 0 ); - btLampkaRearLeftLight.Turn( ( mvOccupied->iLights[ end::rear ] & light::headlight_left ) != 0 ); - btLampkaRearRightLight.Turn( ( mvOccupied->iLights[ end::rear ] & light::headlight_right ) != 0 ); - btLampkaRearLeftEndLight.Turn( ( mvOccupied->iLights[ end::rear ] & light::redmarker_left ) != 0 ); - btLampkaRearRightEndLight.Turn( ( mvOccupied->iLights[ end::rear ] & light::redmarker_right ) != 0 ); - // others - btLampkaMalfunction.Turn( mvControlled->dizel_heat.PA ); - btLampkaMotorBlowers.Turn( ( mvControlled->MotorBlowers[ end::front ].is_active ) && ( mvControlled->MotorBlowers[ end::rear ].is_active ) ); - btLampkaCoolingFans.Turn( mvControlled->RventRot > 1.0 ); - btLampkaTempomat.Turn( mvOccupied->SpeedCtrlUnit.IsActive ); - btLampkaDistanceCounter.Turn( m_distancecounter >= 0.f ); - // universal devices state indicators - for( auto idx = 0; idx < btUniversals.size(); ++idx ) { - btUniversals[ idx ].Turn( ggUniversals[ idx ].GetValue() > 0.5 ); - } + if( mvControlled->CoupledCtrl ) { + ggMainCtrl.UpdateValue( + double( mvControlled->MainCtrlPos + mvControlled->ScndCtrlPos ), + dsbNastawnikJazdy ); } else { - // wylaczone - btLampkaCzuwaka.Turn( false ); - btLampkaSHP.Turn( false ); - btLampkaWylSzybki.Turn( false ); - btLampkaWylSzybkiOff.Turn( false ); - btLampkaMainBreakerReady.Turn( false ); - btLampkaWysRozr.Turn( false ); - btLampkaOpory.Turn( false ); - btLampkaStyczn.Turn( false ); - btLampkaUkrotnienie.Turn( false ); - btLampkaHamPosp.Turn( false ); - btLampkaBoczniki.Turn( false ); - btLampkaNapNastHam.Turn( false ); - btLampkaPrzetw.Turn( false ); - btLampkaPrzetwOff.Turn( false ); - btLampkaNadmPrzetw.Turn( false ); - btLampkaSprezarka.Turn( false ); - btLampkaSprezarkaOff.Turn( false ); - btLampkaFuelPumpOff.Turn( false ); - btLampkaBezoporowa.Turn( false ); - btLampkaHamowanie1zes.Turn( false ); - btLampkaHamienie.Turn( false ); - btLampkaBrakingOff.Turn( false ); - btLampkaBrakeProfileG.Turn( false ); - btLampkaBrakeProfileP.Turn( false ); - btLampkaBrakeProfileR.Turn( false ); - btLampkaSpringBrakeActive.Turn( false ); - btLampkaSpringBrakeInactive.Turn( false ); - btLampkaMaxSila.Turn( false ); - btLampkaPrzekrMaxSila.Turn( false ); - btLampkaRadio.Turn( false ); - btLampkaRadioStop.Turn( false ); - btLampkaHamulecReczny.Turn( false ); - btLampkaDoorLeft.Turn( false ); - btLampkaDoorRight.Turn( false ); - btLampkaBlokadaDrzwi.Turn( false ); - btLampkaDoorLockOff.Turn( false ); - btLampkaDepartureSignal.Turn( false ); - btLampkaNapNastHam.Turn( false ); - btLampkaForward.Turn( false ); - btLampkaBackward.Turn( false ); - btLampkaED.Turn( false ); - // light indicators - btLampkaUpperLight.Turn( false ); - btLampkaLeftLight.Turn( false ); - btLampkaRightLight.Turn( false ); - btLampkaLeftEndLight.Turn( false ); - btLampkaRightEndLight.Turn( false ); - btLampkaRearUpperLight.Turn( false ); - btLampkaRearLeftLight.Turn( false ); - btLampkaRearRightLight.Turn( false ); - btLampkaRearLeftEndLight.Turn( false ); - btLampkaRearRightEndLight.Turn( false ); - // others - btLampkaMalfunction.Turn( false ); - btLampkaMotorBlowers.Turn( false ); - btLampkaCoolingFans.Turn( false ); - btLampkaTempomat.Turn( false ); - btLampkaDistanceCounter.Turn( false ); - // universal devices state indicators - for( auto &universal : btUniversals ) { - universal.Turn( false ); - } - } - - { // yB - wskazniki drugiego czlonu - TDynamicObject *tmp { nullptr }; //=mvControlled->mvSecond; //Ra 2014-07: trzeba to jeszcze wyjąć z kabiny... - // Ra 2014-07: no nie ma potrzeby szukać tego w każdej klatce - if ((TestFlag(mvControlled->Couplers[1].CouplingFlag, ctrain_controll)) && - (mvOccupied->CabOccupied > 0)) - tmp = DynamicObject->NextConnected(); - if ((TestFlag(mvControlled->Couplers[0].CouplingFlag, ctrain_controll)) && - (mvOccupied->CabOccupied < 0)) - tmp = DynamicObject->PrevConnected(); - - if( tmp ) { - if( lowvoltagepower ) { - - auto const *mover{ tmp->MoverParameters }; - - btLampkaWylSzybkiB.Turn( mover->Mains ); - btLampkaWylSzybkiBOff.Turn( - ( false == mover->Mains ) - /*&& ( mover->MainsInitTimeCountdown <= 0.0 )*/ - /*&& ( fHVoltage != 0.0 )*/ ); - - btLampkaOporyB.Turn( mover->ResistorsFlagCheck() ); - btLampkaBezoporowaB.Turn( - ( true == mover->ResistorsFlagCheck() ) - || ( mover->MainCtrlActualPos == 0 ) ); // do EU04 - - if( ( mover->StLinFlag ) - || ( mover->BrakePress > 2.0 ) - || ( mover->PipePress < 3.6 ) ) { - btLampkaStycznB.Turn( false ); - } - else if( mover->BrakePress < 1.0 ) { - btLampkaStycznB.Turn( true ); // mozna prowadzic rozruch - } - // hunter-271211: sygnalizacja poslizgu w pierwszym pojezdzie, gdy wystapi w drugim - btLampkaPoslizg.Turn( mover->SlippingWheels ); - - btLampkaSprezarkaB.Turn( mover->CompressorFlag ); // mutopsitka dziala - btLampkaSprezarkaBOff.Turn( false == mover->CompressorFlag ); - if( mvControlled->Signalling == true ) { - if( mover->BrakePress >= 1.45f ) { - btLampkaHamowanie2zes.Turn( true ); - } - if( mover->BrakePress < 0.75f ) { - btLampkaHamowanie2zes.Turn( false ); - } - } - else { - btLampkaHamowanie2zes.Turn( false ); - } - btLampkaNadmPrzetwB.Turn( mover->ConvOvldFlag ); // nadmiarowy przetwornicy? - btLampkaPrzetwB.Turn( mover->ConverterFlag ); // zalaczenie przetwornicy - btLampkaPrzetwBOff.Turn( false == mover->ConverterFlag ); - btLampkaHVoltageB.Turn( mover->NoVoltRelay && mover->OvervoltageRelay ); - btLampkaMalfunctionB.Turn( mover->dizel_heat.PA ); - // motor fuse indicator turns on if the fuse was blown in any unit under control - if( mover->Mains ) { - btLampkaNadmSil.Turn( btLampkaNadmSil.GetValue() || mover->FuseFlagCheck() ); - } - } - else // wylaczone - { - btLampkaWylSzybkiB.Turn( false ); - btLampkaWylSzybkiBOff.Turn( false ); - btLampkaOporyB.Turn( false ); - btLampkaStycznB.Turn( false ); - btLampkaSprezarkaB.Turn( false ); - btLampkaSprezarkaBOff.Turn( false ); - btLampkaBezoporowaB.Turn( false ); - btLampkaHamowanie2zes.Turn( false ); - btLampkaNadmPrzetwB.Turn( false ); - btLampkaPrzetwB.Turn( false ); - btLampkaPrzetwBOff.Turn( false ); - btLampkaHVoltageB.Turn( false ); - btLampkaMalfunctionB.Turn( false ); - } - } - } - // McZapkie-080602: obroty (albo translacje) regulatorow - if( ggJointCtrl.SubModel != nullptr ) { - // joint master controller moves forward to adjust power and backward to adjust brakes - auto const brakerangemultiplier { - /* NOTE: scaling disabled as it was conflicting with associating sounds with control positions - ( mvControlled->CoupledCtrl ? - mvControlled->MainCtrlPosNo + mvControlled->ScndCtrlPosNo : - mvControlled->MainCtrlPosNo ) - / static_cast(LocalBrakePosNo) - */ - 1 }; - ggJointCtrl.UpdateValue( - ( mvOccupied->LocalBrakePosA > 0.0 ? mvOccupied->LocalBrakePosA * LocalBrakePosNo * -1 * brakerangemultiplier : - mvControlled->CoupledCtrl ? double( mvControlled->MainCtrlPos + mvControlled->ScndCtrlPos ) : - double( mvControlled->MainCtrlPos ) ), + ggMainCtrl.UpdateValue( + double( mvControlled->MainCtrlPos ), dsbNastawnikJazdy ); - ggJointCtrl.Update(); } - if ( ggMainCtrl.SubModel != nullptr ) { - + ggMainCtrl.Update(); + } + if (ggMainCtrlAct.SubModel) + { + if (mvControlled->CoupledCtrl) + ggMainCtrlAct.UpdateValue( + double(mvControlled->MainCtrlActualPos + mvControlled->ScndCtrlActualPos)); + else + ggMainCtrlAct.UpdateValue(double(mvControlled->MainCtrlActualPos)); + ggMainCtrlAct.Update(); + } + if (ggScndCtrl.SubModel) { + // Ra: od byte odejmowane boolean i konwertowane potem na double? + ggScndCtrl.UpdateValue( + double( mvControlled->ScndCtrlPos + - ( ( mvControlled->TrainType == dt_ET42 ) && mvControlled->DynamicBrakeFlag ) ), + dsbNastawnikBocz ); + ggScndCtrl.Update(); + } + ggScndCtrlButton.Update( lowvoltagepower ); + ggDistanceCounterButton.Update(); + if (ggDirKey.SubModel) { + if (mvControlled->TrainType != dt_EZT) + ggDirKey.UpdateValue( + double(mvControlled->DirActive), + dsbReverserKey); + else + ggDirKey.UpdateValue( + double(mvControlled->DirActive) + double(mvControlled->Imin == mvControlled->IminHi), + dsbReverserKey); + ggDirKey.Update(); + } + if (ggBrakeCtrl.SubModel) + { #ifdef _WIN32 - if( ( DynamicObject->Mechanik != nullptr ) - && ( false == DynamicObject->Mechanik->AIControllFlag ) // nie blokujemy AI - && ( Global.iFeedbackMode == 4 ) - && ( Global.fCalibrateIn[ 2 ][ 1 ] != 0.0 ) ) { - - set_master_controller( Console::AnalogCalibrateGet( 2 ) * mvOccupied->MainCtrlPosNo ); + if (DynamicObject->Mechanik ? + (DynamicObject->Mechanik->AIControllFlag ? false : + (Global.iFeedbackMode == 4 /*|| (Global.bMWDmasterEnable && Global.bMWDBreakEnable)*/)) : + false) // nie blokujemy AI + { // Ra: nie najlepsze miejsce, ale na początek gdzieś to dać trzeba + // Firleju: dlatego kasujemy i zastepujemy funkcją w Console + if (mvOccupied->BrakeHandle == TBrakeHandle::FV4a) + { + double b = Console::AnalogCalibrateGet(0); + b = b * 8.0 - 2.0; + b = clamp( b, -2.0, mvOccupied->BrakeCtrlPosNo ); // przycięcie zmiennej do granic + ggBrakeCtrl.UpdateValue(b); // przesów bez zaokrąglenia + mvOccupied->BrakeLevelSet(b); } -#endif - - if( mvControlled->CoupledCtrl ) { - ggMainCtrl.UpdateValue( - double( mvControlled->MainCtrlPos + mvControlled->ScndCtrlPos ), - dsbNastawnikJazdy ); + if (mvOccupied->BrakeHandle == TBrakeHandle::FVel6) // może można usunąć ograniczenie do FV4a i FVel6? + { + double b = Console::AnalogCalibrateGet(0); + b = b * 7.0 - 1.0; + b = clamp( b, -1.0, mvOccupied->BrakeCtrlPosNo ); // przycięcie zmiennej do granic + ggBrakeCtrl.UpdateValue(b); // przesów bez zaokrąglenia + mvOccupied->BrakeLevelSet(b); } - else { - ggMainCtrl.UpdateValue( - double( mvControlled->MainCtrlPos ), - dsbNastawnikJazdy ); - } - ggMainCtrl.Update(); - } - if (ggMainCtrlAct.SubModel) - { - if (mvControlled->CoupledCtrl) - ggMainCtrlAct.UpdateValue( - double(mvControlled->MainCtrlActualPos + mvControlled->ScndCtrlActualPos)); - else - ggMainCtrlAct.UpdateValue(double(mvControlled->MainCtrlActualPos)); - ggMainCtrlAct.Update(); - } - if (ggScndCtrl.SubModel) { - // Ra: od byte odejmowane boolean i konwertowane potem na double? - ggScndCtrl.UpdateValue( - double( mvControlled->ScndCtrlPos - - ( ( mvControlled->TrainType == dt_ET42 ) && mvControlled->DynamicBrakeFlag ) ), - dsbNastawnikBocz ); - ggScndCtrl.Update(); - } - ggScndCtrlButton.Update( lowvoltagepower ); - ggDistanceCounterButton.Update(); - if (ggDirKey.SubModel) { - if (mvControlled->TrainType != dt_EZT) - ggDirKey.UpdateValue( - double(mvControlled->DirActive), - dsbReverserKey); - else - ggDirKey.UpdateValue( - double(mvControlled->DirActive) + double(mvControlled->Imin == mvControlled->IminHi), - dsbReverserKey); - ggDirKey.Update(); - } - if (ggBrakeCtrl.SubModel) - { -#ifdef _WIN32 - if (DynamicObject->Mechanik ? - (DynamicObject->Mechanik->AIControllFlag ? false : - (Global.iFeedbackMode == 4 /*|| (Global.bMWDmasterEnable && Global.bMWDBreakEnable)*/)) : - false) // nie blokujemy AI - { // Ra: nie najlepsze miejsce, ale na początek gdzieś to dać trzeba - // Firleju: dlatego kasujemy i zastepujemy funkcją w Console - if (mvOccupied->BrakeHandle == TBrakeHandle::FV4a) - { - double b = Console::AnalogCalibrateGet(0); - b = b * 8.0 - 2.0; - b = clamp( b, -2.0, mvOccupied->BrakeCtrlPosNo ); // przycięcie zmiennej do granic - ggBrakeCtrl.UpdateValue(b); // przesów bez zaokrąglenia - mvOccupied->BrakeLevelSet(b); - } - if (mvOccupied->BrakeHandle == TBrakeHandle::FVel6) // może można usunąć ograniczenie do FV4a i FVel6? - { - double b = Console::AnalogCalibrateGet(0); - b = b * 7.0 - 1.0; - b = clamp( b, -1.0, mvOccupied->BrakeCtrlPosNo ); // przycięcie zmiennej do granic - ggBrakeCtrl.UpdateValue(b); // przesów bez zaokrąglenia - mvOccupied->BrakeLevelSet(b); - } - // else //standardowa prodedura z kranem powiązanym z klawiaturą - // ggBrakeCtrl.UpdateValue(double(mvOccupied->BrakeCtrlPos)); - } -#endif // else //standardowa prodedura z kranem powiązanym z klawiaturą // ggBrakeCtrl.UpdateValue(double(mvOccupied->BrakeCtrlPos)); - ggBrakeCtrl.UpdateValue(mvOccupied->fBrakeCtrlPos); - ggBrakeCtrl.Update(); } - - if( ggLocalBrake.SubModel != nullptr ) { -#ifdef _WIN32 - if( ( DynamicObject->Mechanik != nullptr ) - && ( false == DynamicObject->Mechanik->AIControllFlag ) // nie blokujemy AI - && ( mvOccupied->BrakeLocHandle == TBrakeHandle::FD1 ) - && ( ( Global.iFeedbackMode == 4 ) - /*|| ( Global.bMWDmasterEnable && Global.bMWDBreakEnable )*/ ) ) { - // Ra: nie najlepsze miejsce, ale na początek gdzieś to dać trzeba - // Firleju: dlatego kasujemy i zastepujemy funkcją w Console - auto const b = clamp( - Console::AnalogCalibrateGet( 1 ), - 0.0, - 1.0 ); - mvOccupied->LocalBrakePosA = b; - ggLocalBrake.UpdateValue( b * LocalBrakePosNo ); - } - else #endif - { - // standardowa prodedura z kranem powiązanym z klawiaturą - ggLocalBrake.UpdateValue( mvOccupied->LocalBrakePosA * LocalBrakePosNo ); - } - ggLocalBrake.Update(); - } - ggAlarmChain.Update(); - ggBrakeProfileCtrl.Update(); - ggBrakeProfileG.Update(); - ggBrakeProfileR.Update(); - ggBrakeOperationModeCtrl.Update(); - ggMaxCurrentCtrl.Update(); - // NBMX wrzesien 2003 - drzwi - ggDoorLeftPermitButton.Update(); - ggDoorRightPermitButton.Update(); - ggDoorPermitPresetButton.Update(); - ggDoorLeftButton.Update(); - ggDoorRightButton.Update(); - ggDoorLeftOnButton.Update(); - ggDoorRightOnButton.Update(); - ggDoorLeftOffButton.Update(); - ggDoorRightOffButton.Update(); - ggDoorAllOnButton.Update(); - ggDoorAllOffButton.Update(); - ggDoorSignallingButton.Update(); - // NBMX dzwignia sprezarki - ggCompressorButton.Update(); - ggCompressorLocalButton.Update(); - ggCompressorListButton.Update(); - - //--------- - // hunter-080812: poprawka na ogrzewanie w elektrykach - usuniete uzaleznienie od przetwornicy - if( ( mvControlled->Heating == true ) - && ( mvControlled->ConvOvldFlag == false ) ) - btLampkaOgrzewanieSkladu.Turn( true ); - else - btLampkaOgrzewanieSkladu.Turn( false ); - - //---------- - - // lights - auto const lightpower { ( - InstrumentLightType == 0 ? mvControlled->Battery || mvControlled->ConverterFlag : - InstrumentLightType == 1 ? mvControlled->Mains : - InstrumentLightType == 2 ? mvControlled->ConverterFlag : - InstrumentLightType == 3 ? mvControlled->Battery || mvControlled->ConverterFlag : - InstrumentLightType == 4 ? mvControlled->Battery || mvControlled->ConverterFlag : - false ) }; - InstrumentLightActive = ( - InstrumentLightType == 3 ? true : // TODO: link the light state with the state of the master key - InstrumentLightType == 4 ? ( mvOccupied->iLights[end::front] != 0 ) || ( mvOccupied->iLights[end::rear] != 0 ) : - InstrumentLightActive ); - btInstrumentLight.Turn( InstrumentLightActive && lightpower ); - btDashboardLight.Turn( DashboardLightActive && lightpower ); - btTimetableLight.Turn( TimetableLightActive && lightpower ); - - // guziki: - ggMainOffButton.Update(); - ggMainOnButton.Update(); - ggMainButton.Update(); - ggSecurityResetButton.Update(); - ggReleaserButton.Update(); - ggSpringBrakeOnButton.Update(); - ggSpringBrakeOffButton.Update(); - ggUniveralBrakeButton1.Update(); - ggUniveralBrakeButton2.Update(); - ggUniveralBrakeButton3.Update(); - ggEPFuseButton.Update(); - ggAntiSlipButton.Update(); - ggSandButton.Update(); - ggAutoSandButton.Update(); - ggFuseButton.Update(); - ggConverterFuseButton.Update(); - ggStLinOffButton.Update(); - ggRadioChannelSelector.Update(); - ggRadioChannelPrevious.Update(); - ggRadioChannelNext.Update(); - ggRadioStop.Update(); - ggRadioTest.Update(); - ggRadioCall3.Update(); - ggRadioVolumeSelector.Update(); - ggRadioVolumePrevious.Update(); - ggRadioVolumeNext.Update(); - ggDepartureSignalButton.Update(); -/* - ggPantFrontButton.Update(); - ggPantRearButton.Update(); - ggPantFrontButtonOff.Update(); - ggPantRearButtonOff.Update(); -*/ - ggPantAllDownButton.Update(); - ggPantSelectedDownButton.Update(); - ggPantSelectedButton.Update(); - ggPantSelectButton.Update(); - ggPantCompressorButton.Update(); - ggPantCompressorValve.Update(); - - ggLightsButton.Update(); - ggUpperLightButton.Update(); - ggLeftLightButton.Update(); - ggRightLightButton.Update(); - ggLeftEndLightButton.Update(); - ggRightEndLightButton.Update(); - // hunter-230112 - ggRearUpperLightButton.Update(); - ggRearLeftLightButton.Update(); - ggRearRightLightButton.Update(); - ggRearLeftEndLightButton.Update(); - ggRearRightEndLightButton.Update(); - ggDimHeadlightsButton.Update(); - //------------ - ggConverterButton.Update(); - ggConverterLocalButton.Update(); - ggConverterOffButton.Update(); - ggTrainHeatingButton.Update(); - ggSignallingButton.Update(); - ggNextCurrentButton.Update(); - ggHornButton.Update(); - ggHornLowButton.Update(); - ggHornHighButton.Update(); - ggWhistleButton.Update(); - if( DynamicObject->Mechanik != nullptr ) { - ggHelperButton.UpdateValue( DynamicObject->Mechanik->HelperState ); - } - ggHelperButton.Update(); - - ggSpeedControlIncreaseButton.Update( lowvoltagepower ); - ggSpeedControlDecreaseButton.Update( lowvoltagepower ); - ggSpeedControlPowerIncreaseButton.Update( lowvoltagepower ); - ggSpeedControlPowerDecreaseButton.Update( lowvoltagepower ); - for (auto &speedctrlbutton : ggSpeedCtrlButtons) { - speedctrlbutton.Update( lowvoltagepower ); - } - for( auto &universal : ggUniversals ) { - universal.Update(); - } - for( auto &relayresetbutton : ggRelayResetButtons ) { - relayresetbutton.Update(); - } - // hunter-091012 - ggInstrumentLightButton.Update(); - ggDashboardLightButton.Update(); - ggTimetableLightButton.Update(); - ggCabLightDimButton.Update(); - ggCompartmentLightsButton.Update(); - ggCompartmentLightsOnButton.Update(); - ggCompartmentLightsOffButton.Update(); - ggBatteryButton.Update(); - ggBatteryOnButton.Update(); - ggBatteryOffButton.Update(); - - ggWaterPumpBreakerButton.Update(); - ggWaterPumpButton.Update(); - ggWaterHeaterBreakerButton.Update(); - ggWaterHeaterButton.Update(); - ggWaterCircuitsLinkButton.Update(); - ggFuelPumpButton.Update(); - ggOilPumpButton.Update(); - ggMotorBlowersFrontButton.Update(); - ggMotorBlowersRearButton.Update(); - ggMotorBlowersAllOffButton.Update(); - //------ + // else //standardowa prodedura z kranem powiązanym z klawiaturą + // ggBrakeCtrl.UpdateValue(double(mvOccupied->BrakeCtrlPos)); + ggBrakeCtrl.UpdateValue(mvOccupied->fBrakeCtrlPos); + ggBrakeCtrl.Update(); } + + if( ggLocalBrake.SubModel != nullptr ) { +#ifdef _WIN32 + if( ( DynamicObject->Mechanik != nullptr ) + && ( false == DynamicObject->Mechanik->AIControllFlag ) // nie blokujemy AI + && ( mvOccupied->BrakeLocHandle == TBrakeHandle::FD1 ) + && ( ( Global.iFeedbackMode == 4 ) +/* || ( Global.bMWDmasterEnable && Global.bMWDBreakEnable )*/ ) ) { + // Ra: nie najlepsze miejsce, ale na początek gdzieś to dać trzeba + // Firleju: dlatego kasujemy i zastepujemy funkcją w Console + auto const b = clamp( + Console::AnalogCalibrateGet( 1 ), + 0.0, + 1.0 ); + mvOccupied->LocalBrakePosA = b; + ggLocalBrake.UpdateValue( b * LocalBrakePosNo ); + } + else +#endif + { + // standardowa prodedura z kranem powiązanym z klawiaturą + ggLocalBrake.UpdateValue( mvOccupied->LocalBrakePosA * LocalBrakePosNo ); + } + ggLocalBrake.Update(); + } + ggAlarmChain.Update(); + ggBrakeProfileCtrl.Update(); + ggBrakeProfileG.Update(); + ggBrakeProfileR.Update(); + ggBrakeOperationModeCtrl.Update(); + ggMaxCurrentCtrl.Update(); + // NBMX wrzesien 2003 - drzwi + ggDoorLeftPermitButton.Update(); + ggDoorRightPermitButton.Update(); + ggDoorPermitPresetButton.Update(); + ggDoorLeftButton.Update(); + ggDoorRightButton.Update(); + ggDoorLeftOnButton.Update(); + ggDoorRightOnButton.Update(); + ggDoorLeftOffButton.Update(); + ggDoorRightOffButton.Update(); + ggDoorAllOnButton.Update(); + ggDoorAllOffButton.Update(); + ggDoorSignallingButton.Update(); + // NBMX dzwignia sprezarki + ggCompressorButton.Update(); + ggCompressorLocalButton.Update(); + ggCompressorListButton.Update(); + + //--------- + // hunter-080812: poprawka na ogrzewanie w elektrykach - usuniete uzaleznienie od przetwornicy + if( ( mvControlled->Heating == true ) + && ( mvControlled->ConvOvldFlag == false ) ) + btLampkaOgrzewanieSkladu.Turn( true ); + else + btLampkaOgrzewanieSkladu.Turn( false ); + + //---------- + + // lights + auto const lightpower { ( + InstrumentLightType == 0 ? mvControlled->Battery || mvControlled->ConverterFlag : + InstrumentLightType == 1 ? mvControlled->Mains : + InstrumentLightType == 2 ? mvControlled->ConverterFlag : + InstrumentLightType == 3 ? mvControlled->Battery || mvControlled->ConverterFlag : + InstrumentLightType == 4 ? mvControlled->Battery || mvControlled->ConverterFlag : + false ) }; + InstrumentLightActive = ( + InstrumentLightType == 3 ? true : // TODO: link the light state with the state of the master key + InstrumentLightType == 4 ? ( mvOccupied->iLights[end::front] != 0 ) || ( mvOccupied->iLights[end::rear] != 0 ) : + InstrumentLightActive ); + btInstrumentLight.Turn( InstrumentLightActive && lightpower ); + btDashboardLight.Turn( DashboardLightActive && lightpower ); + btTimetableLight.Turn( TimetableLightActive && lightpower ); + + // guziki: + ggMainOffButton.Update(); + ggMainOnButton.Update(); + ggMainButton.Update(); + ggSecurityResetButton.Update(); + ggReleaserButton.Update(); + ggSpringBrakeOnButton.Update(); + ggSpringBrakeOffButton.Update(); + ggUniveralBrakeButton1.Update(); + ggUniveralBrakeButton2.Update(); + ggUniveralBrakeButton3.Update(); + ggEPFuseButton.Update(); + ggAntiSlipButton.Update(); + ggSandButton.Update(); + ggAutoSandButton.Update(); + ggFuseButton.Update(); + ggConverterFuseButton.Update(); + ggStLinOffButton.Update(); + ggRadioChannelSelector.Update(); + ggRadioChannelPrevious.Update(); + ggRadioChannelNext.Update(); + ggRadioStop.Update(); + ggRadioTest.Update(); + ggRadioCall3.Update(); + ggRadioVolumeSelector.Update(); + ggRadioVolumePrevious.Update(); + ggRadioVolumeNext.Update(); + ggDepartureSignalButton.Update(); +/* + ggPantFrontButton.Update(); + ggPantRearButton.Update(); + ggPantFrontButtonOff.Update(); + ggPantRearButtonOff.Update(); +*/ + ggPantAllDownButton.Update(); + ggPantSelectedDownButton.Update(); + ggPantSelectedButton.Update(); + ggPantSelectButton.Update(); + ggPantCompressorButton.Update(); + ggPantCompressorValve.Update(); + + ggLightsButton.Update(); + ggUpperLightButton.Update(); + ggLeftLightButton.Update(); + ggRightLightButton.Update(); + ggLeftEndLightButton.Update(); + ggRightEndLightButton.Update(); + // hunter-230112 + ggRearUpperLightButton.Update(); + ggRearLeftLightButton.Update(); + ggRearRightLightButton.Update(); + ggRearLeftEndLightButton.Update(); + ggRearRightEndLightButton.Update(); + ggDimHeadlightsButton.Update(); + //------------ + ggConverterButton.Update(); + ggConverterLocalButton.Update(); + ggConverterOffButton.Update(); + ggTrainHeatingButton.Update(); + ggSignallingButton.Update(); + ggNextCurrentButton.Update(); + ggHornButton.Update(); + ggHornLowButton.Update(); + ggHornHighButton.Update(); + ggWhistleButton.Update(); + if( DynamicObject->Mechanik != nullptr ) { + ggHelperButton.UpdateValue( DynamicObject->Mechanik->HelperState ); + } + ggHelperButton.Update(); + + ggSpeedControlIncreaseButton.Update( lowvoltagepower ); + ggSpeedControlDecreaseButton.Update( lowvoltagepower ); + ggSpeedControlPowerIncreaseButton.Update( lowvoltagepower ); + ggSpeedControlPowerDecreaseButton.Update( lowvoltagepower ); + for (auto &speedctrlbutton : ggSpeedCtrlButtons) { + speedctrlbutton.Update( lowvoltagepower ); + } + for( auto &universal : ggUniversals ) { + universal.Update(); + } + for( auto &relayresetbutton : ggRelayResetButtons ) { + relayresetbutton.Update(); + } + // hunter-091012 + ggInstrumentLightButton.Update(); + ggDashboardLightButton.Update(); + ggTimetableLightButton.Update(); + ggCabLightDimButton.Update(); + ggCompartmentLightsButton.Update(); + ggCompartmentLightsOnButton.Update(); + ggCompartmentLightsOffButton.Update(); + ggBatteryButton.Update(); + ggBatteryOnButton.Update(); + ggBatteryOffButton.Update(); + + ggWaterPumpBreakerButton.Update(); + ggWaterPumpButton.Update(); + ggWaterHeaterBreakerButton.Update(); + ggWaterHeaterButton.Update(); + ggWaterCircuitsLinkButton.Update(); + ggFuelPumpButton.Update(); + ggOilPumpButton.Update(); + ggMotorBlowersFrontButton.Update(); + ggMotorBlowersRearButton.Update(); + ggMotorBlowersAllOffButton.Update(); + // wyprowadzenie sygnałów dla haslera na PoKeys (zaznaczanie na taśmie) btHaslerBrakes.Turn(DynamicObject->MoverParameters->BrakePress > 0.4); // ciśnienie w cylindrach btHaslerCurrent.Turn(DynamicObject->MoverParameters->Im != 0.0); // prąd na silnikach diff --git a/simulation.cpp b/simulation.cpp index ba1a2bd4..f40c7022 100644 --- a/simulation.cpp +++ b/simulation.cpp @@ -26,6 +26,7 @@ http://mozilla.org/MPL/2.0/. #include "scene.h" #include "Train.h" #include "application.h" +#include "Logs.h" namespace simulation { @@ -267,6 +268,10 @@ void state_manager::process_commands() { else { delete train; train = nullptr; + if( targetvehicle->name() == Global.local_start_vehicle ) { + ErrorLog( "Failed to initialize player train, \"" + Global.local_start_vehicle + "\"" ); + Global.local_start_vehicle = "ghostview"; + } } } diff --git a/version.h b/version.h index ead6fcb4..d75ea4a5 100644 --- a/version.h +++ b/version.h @@ -1,5 +1,5 @@ #pragma once #define VERSION_MAJOR 20 -#define VERSION_MINOR 322 +#define VERSION_MINOR 406 #define VERSION_REVISION 0