From 4e0975f3873f0fe3c49941e8697fa7c8d4256abe Mon Sep 17 00:00:00 2001 From: tmj-fstate Date: Thu, 19 Sep 2019 20:13:36 +0200 Subject: [PATCH] distance counter cab control, load exchange fix --- Driver.cpp | 12 ++++-- Driver.h | 1 + DynObj.cpp | 12 +++++- Train.cpp | 83 +++++++++++++++++++++++++++++++++++------ Train.h | 11 +++++- command.cpp | 3 +- command.h | 1 + driverkeyboardinput.cpp | 28 +++++++++----- drivermouseinput.cpp | 3 ++ translation.cpp | 5 ++- translation.h | 1 + version.h | 2 +- 12 files changed, 132 insertions(+), 30 deletions(-) diff --git a/Driver.cpp b/Driver.cpp index 42a3504d..b6f4a838 100644 --- a/Driver.cpp +++ b/Driver.cpp @@ -981,9 +981,14 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN UpdateDelayFlag(); // perform loading/unloading - auto const platformside = static_cast( std::floor( std::abs( sSpeedTable[ i ].evEvent->input_value( 2 ) ) ) ) % 10; - auto const exchangetime = simulation::Station.update_load( pVehicles[ 0 ], *TrainParams, platformside ); - WaitingSet( exchangetime ); + // HACK: manual check if we didn't already do load exchange at this stop + // TODO: remove the check once the station system is in place + if( m_lastexchangestop != asNextStop ) { + auto const platformside = static_cast( std::floor( std::abs( sSpeedTable[ i ].evEvent->input_value( 2 ) ) ) ) % 10; + auto const exchangetime = simulation::Station.update_load( pVehicles[ 0 ], *TrainParams, platformside ); + WaitingSet( exchangetime ); + m_lastexchangestop = asNextStop; + } if (TrainParams->DirectionChange()) { // jeśli "@" w rozkładzie, to wykonanie dalszych komend @@ -3891,6 +3896,7 @@ bool TController::PutCommand( std::string NewCommand, double NewValue1, double N else TrainParams->NewName(NewCommand); // czyści tabelkę przystanków tsGuardSignal = sound_source { sound_placement::internal, 2 * EU07_SOUND_CABCONTROLSCUTOFFRANGE }; // wywalenie kierownika + m_lastexchangestop.clear(); if (NewCommand != "none") { if (!TrainParams->LoadTTfile( diff --git a/Driver.h b/Driver.h index 852b3282..43107cb1 100644 --- a/Driver.h +++ b/Driver.h @@ -434,6 +434,7 @@ private: Mtable::TTrainParameters *TrainParams = nullptr; // rozkład jazdy zawsze jest, nawet jeśli pusty std::string asNextStop; // nazwa następnego punktu zatrzymania wg rozkładu int iStationStart = 0; // numer pierwszej stacji pokazywanej na podglądzie rozkładu + std::string m_lastexchangestop; // HACK: safeguard to prevent multiple load exchanges per station double fLastStopExpDist = -1.0; // odległość wygasania ostateniego przystanku int iRadioChannel = 1; // numer aktualnego kanału radiowego int iGuardRadio = 0; // numer kanału radiowego kierownika (0, gdy nie używa radia) diff --git a/DynObj.cpp b/DynObj.cpp index a0568347..8663c2e7 100644 --- a/DynObj.cpp +++ b/DynObj.cpp @@ -3132,8 +3132,16 @@ bool TDynamicObject::Update(double dt, double dt1) modelRot.z }; // McZapkie-260202 - dMoveLen przyda sie przy stukocie kol dDOMoveLen = GetdMoveLen() + MoverParameters->ComputeMovement(dt, dt1, ts, tp, tmpTraction, l, r); - if( Mechanik ) - Mechanik->MoveDistanceAdd( dDOMoveLen ); // dodanie aktualnego przemieszczenia + if( Mechanik ) { + // dodanie aktualnego przemieszczenia + Mechanik->MoveDistanceAdd( dDOMoveLen ); + } + if( ( simulation::Train != nullptr ) + && ( simulation::Train->Dynamic() == this ) ) { + // update distance meter in user-controlled cab + // TBD: place the meter on mover logic level? + simulation::Train->add_distance( dDOMoveLen ); + } Move(dDOMoveLen); if (!bEnabled) // usuwane pojazdy nie mają toru { // pojazd do usunięcia diff --git a/Train.cpp b/Train.cpp index 7e98b6bf..f541aba4 100644 --- a/Train.cpp +++ b/Train.cpp @@ -365,7 +365,8 @@ TTrain::commandhandler_map const TTrain::m_commandhandlers = { { user_command::springbrakeshutofftoggle, &TTrain::OnCommand_springbrakeshutofftoggle }, { user_command::springbrakeshutoffenable, &TTrain::OnCommand_springbrakeshutoffenable }, { user_command::springbrakeshutoffdisable, &TTrain::OnCommand_springbrakeshutoffdisable }, - { user_command::springbrakerelease, &TTrain::OnCommand_springbrakerelease } + { user_command::springbrakerelease, &TTrain::OnCommand_springbrakerelease }, + { user_command::distancecounteractivate, &TTrain::OnCommand_distancecounteractivate } }; std::vector const TTrain::fPress_labels = { @@ -471,6 +472,7 @@ dictionary_source *TTrain::GetTrainState() { dict->insert( "converter", mvControlled->ConverterFlag ); dict->insert( "converter_overload", mvControlled->ConvOvldFlag ); dict->insert( "compress", mvControlled->CompressorFlag ); + dict->insert( "pant_compressor", mvControlled->PantCompFlag ); dict->insert( "lights_front", mvOccupied->iLights[ end::front ] ); dict->insert( "lights_rear", mvOccupied->iLights[ end::rear ] ); // reverser @@ -500,6 +502,7 @@ dictionary_source *TTrain::GetTrainState() { // other controls dict->insert( "ca", TestFlag( mvOccupied->SecuritySystem.Status, s_aware ) ); dict->insert( "shp", TestFlag( mvOccupied->SecuritySystem.Status, s_active ) ); + dict->insert( "distance_counter", m_distancecounter ); dict->insert( "pantpress", std::abs( mvControlled->PantPress ) ); dict->insert( "universal3", InstrumentLightActive ); dict->insert( "radio_channel", iRadioChannel ); @@ -581,6 +584,7 @@ dictionary_source *TTrain::GetTrainState() { driver->TrainTimetable()->serialize( dict ); dict->insert( "train_stationstart", driver->iStationStart ); dict->insert( "train_atpassengerstop", driver->IsAtPassengerStop ); + dict->insert( "train_length", driver->fLength ); // world state data dict->insert( "scenario", Global.SceneryFile ); dict->insert( "hours", static_cast( simulation::Time.data().wHour ) ); @@ -988,6 +992,20 @@ void TTrain::OnCommand_tempomattoggle( TTrain *Train, command_data const &Comman } } +void TTrain::OnCommand_distancecounteractivate( TTrain *Train, command_data const &Command ) { + // NOTE: distance meter activation button is presumed to be of impulse type + if( Command.action == GLFW_PRESS ) { + // visual feedback + Train->ggDistanceCounterButton.UpdateValue( 1.0, Train->dsbSwitch ); + // activate or start anew + Train->m_distancecounter = 0.f; + } + else if( Command.action == GLFW_RELEASE ) { + // visual feedback + Train->ggDistanceCounterButton.UpdateValue( 0.0, Train->dsbSwitch ); + } +} + void TTrain::OnCommand_mucurrentindicatorothersourceactivate( TTrain *Train, command_data const &Command ) { if( Train->ggNextCurrentButton.SubModel == nullptr ) { @@ -5989,18 +6007,18 @@ bool TTrain::Update( double const Deltatime ) ( true == mvControlled->ResistorsFlagCheck() ) || ( mvControlled->MainCtrlActualPos == 0 ) ); // do EU04 - if( mvControlled->StLinFlag ) { - btLampkaStyczn.Turn( false ); + btLampkaStyczn.Turn( + mvControlled->StLinFlag ? + false : + mvOccupied->BrakePress < 1.0 ); // mozna prowadzic rozruch + + if( ( ( mvControlled->ActiveCab == 1 ) && ( TestFlag( mvControlled->Couplers[ end::rear ].CouplingFlag, coupling::control ) ) ) + || ( ( mvControlled->ActiveCab == -1 ) && ( TestFlag( mvControlled->Couplers[ end::front ].CouplingFlag, coupling::control ) ) ) ) { + btLampkaUkrotnienie.Turn( true ); } else { - // mozna prowadzic rozruch - btLampkaStyczn.Turn( mvOccupied->BrakePress < 1.0 ); - } - if( ( ( TestFlag( mvControlled->Couplers[ end::rear ].CouplingFlag, coupling::control ) ) && ( mvControlled->CabNo == 1 ) ) - || ( ( TestFlag( mvControlled->Couplers[ end::front ].CouplingFlag, coupling::control ) ) && ( mvControlled->CabNo == -1 ) ) ) - btLampkaUkrotnienie.Turn( true ); - else btLampkaUkrotnienie.Turn( false ); + } // if // ((TestFlag(mvControlled->BrakeStatus,+b_Rused+b_Ractive)))//Lampka drugiego stopnia hamowania @@ -6119,6 +6137,7 @@ bool TTrain::Update( double const Deltatime ) btLampkaMotorBlowers.Turn( ( mvControlled->MotorBlowers[ end::front ].is_active ) && ( mvControlled->MotorBlowers[ end::rear ].is_active ) ); btLampkaCoolingFans.Turn( mvControlled->RventRot > 1.0 ); btLampkaTempomat.Turn( mvControlled->ScndCtrlPos > 0 ); + 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 ); @@ -6183,6 +6202,7 @@ bool TTrain::Update( double const Deltatime ) btLampkaMotorBlowers.Turn( false ); btLampkaCoolingFans.Turn( false ); btLampkaTempomat.Turn( false ); + btLampkaDistanceCounter.Turn( false ); // universal devices state indicators for( auto &universal : btUniversals ) { universal.Turn( false ); @@ -6325,6 +6345,7 @@ bool TTrain::Update( double const Deltatime ) ggScndCtrl.Update(); } ggScndCtrlButton.Update(); + ggDistanceCounterButton.Update(); if (ggDirKey.SubModel) { if (mvControlled->TrainType != dt_EZT) ggDirKey.UpdateValue( @@ -6860,6 +6881,24 @@ TTrain::update_sounds( double const Deltatime ) { else if( fTachoCount < 1.f ) { dsbHasler.stop(); } + + // power-reliant sounds + if( mvControlled->Battery || mvControlled->ConverterFlag ) { + // distance meter alert + if( m_distancecounter > Dynamic()->ctOwner->fLength ) { + // play assigned sound if the train travelled its full length since meter activation + // TBD: check all combinations of directions and active cab + m_distancecounter = -1.f; // turn off the meter after its task is done + m_distancecounterclear + .pitch( m_distancecounterclear.m_frequencyoffset + m_distancecounterclear.m_frequencyfactor ) + .gain( m_distancecounterclear.m_amplitudeoffset + m_distancecounterclear.m_amplitudefactor ) + .play( sound_flags::exclusive ); + } + } + else { + // stop power-reliant sounds if power is cut + m_distancecounterclear.stop(); + } } void TTrain::update_sounds_runningnoise( sound_source &Sound ) { @@ -6947,6 +6986,14 @@ void TTrain::update_sounds_radio() { } } +void TTrain::add_distance( double const Distance ) { + + auto const meterenabled { ( true == ( m_distancecounter >= 0 ) ) && ( mvControlled->Battery || mvControlled->ConverterFlag ) }; + + if( true == meterenabled ) { m_distancecounter += Distance * Occupied()->ActiveCab; } + else { m_distancecounter = -1.f; } +} + bool TTrain::CabChange(int iDirection) { // McZapkie-090902: zmiana kabiny 1->0->2 i z powrotem if( ( DynamicObject->Mechanik == nullptr ) @@ -7036,6 +7083,12 @@ bool TTrain::LoadMMediaFile(std::string const &asFileName) dsbSlipAlarm.deserialize( parser, sound_type::single ); dsbSlipAlarm.owner( DynamicObject ); } + else if (token == "distancecounter:") + { + // distance meter 'good to go' sound + m_distancecounterclear.deserialize( parser, sound_type::single ); + m_distancecounterclear.owner( DynamicObject ); + } else if (token == "tachoclock:") { // cykanie rejestratora: @@ -7161,7 +7214,7 @@ bool TTrain::InitializeCab(int NewCabNo, std::string const &asFileName) &dsbSwitch, &dsbPneumaticSwitch, &rsHiss, &rsHissU, &rsHissE, &rsHissX, &rsHissT, &rsSBHiss, &rsSBHissU, &rsFadeSound, &rsRunningNoise, &rsHuntingNoise, - &dsbHasler, &dsbBuzzer, &dsbSlipAlarm, &m_radiosound, &m_radiostop + &dsbHasler, &dsbBuzzer, &dsbSlipAlarm, &m_distancecounterclear, &m_radiosound, &m_radiostop }; for( auto sound : sounds ) { sound->offset( nullvector ); @@ -7421,6 +7474,10 @@ bool TTrain::InitializeCab(int NewCabNo, std::string const &asFileName) if( dsbBuzzer.offset() == nullvector ) { dsbBuzzer.offset( btLampkaCzuwaka.model_offset() ); } + // HACK: alerter is likely to be located somewhere near computer displays + if( m_distancecounterclear.offset() == nullvector ) { + m_distancecounterclear.offset( btLampkaCzuwaka.model_offset() ); + } // radio has two potential items which can provide the position if( m_radiosound.offset() == nullvector ) { m_radiosound.offset( btLampkaRadio.model_offset() ); @@ -7641,6 +7698,7 @@ void TTrain::clear_cab_controls() ggMainCtrlAct.Clear(); ggScndCtrl.Clear(); ggScndCtrlButton.Clear(); + ggDistanceCounterButton.Clear(); ggDirKey.Clear(); ggBrakeCtrl.Clear(); ggLocalBrake.Clear(); @@ -7824,6 +7882,7 @@ void TTrain::clear_cab_controls() btLampkaMotorBlowers.Clear(); btLampkaCoolingFans.Clear(); btLampkaTempomat.Clear(); + btLampkaDistanceCounter.Clear(); ggLeftLightButton.Clear(); ggRightLightButton.Clear(); @@ -8181,6 +8240,7 @@ bool TTrain::initialize_button(cParser &Parser, std::string const &Label, int co { "i-motorblowers:", btLampkaMotorBlowers }, { "i-coolingfans:", btLampkaCoolingFans }, { "i-tempomat:", btLampkaTempomat }, + { "i-distancecounter:", btLampkaDistanceCounter }, { "i-trainheating:", btLampkaOgrzewanieSkladu }, { "i-security_aware:", btLampkaCzuwaka }, { "i-security_cabsignal:", btLampkaSHP }, @@ -8410,6 +8470,7 @@ bool TTrain::initialize_gauge(cParser &Parser, std::string const &Label, int con { "cablightdim_sw:", ggCabLightDimButton }, { "battery_sw:", ggBatteryButton }, { "tempomat_sw:", ggScndCtrlButton }, + { "distancecounter_sw:", ggDistanceCounterButton }, { "universal0:", ggUniversals[ 0 ] }, { "universal1:", ggUniversals[ 1 ] }, { "universal2:", ggUniversals[ 2 ] }, diff --git a/Train.h b/Train.h index 46439150..0a0766a3 100644 --- a/Train.h +++ b/Train.h @@ -104,11 +104,12 @@ class TTrain { float lv_voltage; }; +// constructors + TTrain(); // methods bool CabChange(int iDirection); bool ShowNextCurrent; // pokaz przd w podlaczonej lokomotywie (ET41) bool InitializeCab(int NewCabNo, std::string const &asFileName); - TTrain(); // McZapkie-010302 bool Init(TDynamicObject *NewDynamicObject, bool e3d = false); @@ -117,6 +118,7 @@ class TTrain { inline std::string GetLabel( TSubModel const *Control ) const { return m_controlmapper.find( Control ); } void UpdateCab(); bool Update( double const Deltatime ); + void add_distance( double const Distance ); void SetLights(); // McZapkie-310302: ladowanie parametrow z pliku bool LoadMMediaFile(std::string const &asFileName); @@ -365,7 +367,7 @@ class TTrain { static void OnCommand_springbrakeshutoffenable(TTrain *Train, command_data const &Command); static void OnCommand_springbrakeshutoffdisable(TTrain *Train, command_data const &Command); static void OnCommand_springbrakerelease(TTrain *Train, command_data const &Command); - + static void OnCommand_distancecounteractivate( TTrain *Train, command_data const &Command ); // members TDynamicObject *DynamicObject { nullptr }; // przestawia zmiana pojazdu [F5] @@ -522,6 +524,8 @@ public: // reszta może by?publiczna TGauge ggMotorBlowersRearButton; // rear traction motor fan switch TGauge ggMotorBlowersAllOffButton; // motor fans shutdown switch + TGauge ggDistanceCounterButton; // distance meter activation button + TButton btLampkaPoslizg; TButton btLampkaStyczn; TButton btLampkaNadmPrzetw; @@ -617,6 +621,7 @@ public: // reszta może by?publiczna TButton btLampkaMotorBlowers; TButton btLampkaCoolingFans; TButton btLampkaTempomat; + TButton btLampkaDistanceCounter; TButton btCabLight; // hunter-171012: lampa oswietlajaca kabine // Ra 2013-12: wirtualne "lampki" do odbijania na haslerze w PoKeys @@ -649,6 +654,7 @@ public: // reszta może by?publiczna sound_source m_radiosound { sound_placement::internal, 2 * EU07_SOUND_CABCONTROLSCUTOFFRANGE }; // cached template for radio messages std::vector>> m_radiomessages; // list of currently played radio messages sound_source m_radiostop { sound_placement::internal, EU07_SOUND_CABCONTROLSCUTOFFRANGE }; + sound_source m_distancecounterclear { sound_placement::internal, EU07_SOUND_CABCONTROLSCUTOFFRANGE }; // distance meter 'good to go' alert /* int iCabLightFlag; // McZapkie:120503: oswietlenie kabiny (0: wyl, 1: przyciemnione, 2: pelne) bool bCabLight; // hunter-091012: czy swiatlo jest zapalone? @@ -702,6 +708,7 @@ private: float m_mastercontrollerreturndelay { 0.f }; int iRadioChannel { 1 }; // numer aktualnego kana?u radiowego std::vector> m_screens; + float m_distancecounter { -1.f }; // distance traveled since meter was activated or -1 if inactive public: float fPress[20][3]; // cisnienia dla wszystkich czlonow diff --git a/command.cpp b/command.cpp index f1e1dbaa..2a0ad3e5 100644 --- a/command.cpp +++ b/command.cpp @@ -244,7 +244,8 @@ commanddescription_sequence Commands_descriptions = { { "springbrakeshutofftoggle", command_target::vehicle }, { "springbrakeshutoffenable", command_target::vehicle }, { "springbrakeshutoffdisable", command_target::vehicle }, - { "springbrakerelease", command_target::vehicle } + { "springbrakerelease", command_target::vehicle }, + { "distancecounteractivate", command_target::vehicle } }; diff --git a/command.h b/command.h index 064d49cf..b20b0281 100644 --- a/command.h +++ b/command.h @@ -238,6 +238,7 @@ enum class user_command { springbrakeshutoffenable, springbrakeshutoffdisable, springbrakerelease, + distancecounteractivate, none = -1 }; diff --git a/driverkeyboardinput.cpp b/driverkeyboardinput.cpp index 6ee2c2a9..849882d6 100644 --- a/driverkeyboardinput.cpp +++ b/driverkeyboardinput.cpp @@ -45,6 +45,9 @@ driverkeyboard_input::default_bindings() { { user_command::independentbrakedecreasefast, GLFW_KEY_KP_7 | keymodifier::shift }, // independentbrakeset, { user_command::independentbrakebailoff, GLFW_KEY_KP_4 }, + // universalbrakebutton1, + // universalbrakebutton2, + // universalbrakebutton3, { user_command::trainbrakeincrease, GLFW_KEY_KP_3 }, { user_command::trainbrakedecrease, GLFW_KEY_KP_9 }, // trainbrakeset, @@ -64,6 +67,9 @@ driverkeyboard_input::default_bindings() { { user_command::alarmchaintoggle, GLFW_KEY_B | keymodifier::shift | keymodifier::control }, { user_command::wheelspinbrakeactivate, GLFW_KEY_KP_ENTER }, { user_command::sandboxactivate, GLFW_KEY_S | keymodifier::shift }, + // autosandboxtoggle, + // autosandboxactivate, + // autosandboxdeactivate, { user_command::reverserincrease, GLFW_KEY_D }, { user_command::reverserdecrease, GLFW_KEY_R }, // reverserforwardhigh, @@ -103,6 +109,9 @@ driverkeyboard_input::default_bindings() { // compressorenable, // compressordisable, { user_command::compressortogglelocal, GLFW_KEY_C | keymodifier::shift }, + // compressorpresetactivatenext, + // compressorpresetactivateprevious, + // compressorpresetactivatedefault, { user_command::motoroverloadrelaythresholdtoggle, GLFW_KEY_F | keymodifier::control }, // motoroverloadrelaythresholdsetlow, // motoroverloadrelaythresholdsethigh, @@ -229,15 +238,16 @@ driverkeyboard_input::default_bindings() { { user_command::motorblowerstogglefront, GLFW_KEY_N | keymodifier::shift }, { user_command::motorblowerstogglerear, GLFW_KEY_M | keymodifier::shift }, { user_command::motorblowersdisableall, GLFW_KEY_M | keymodifier::control } - // coolingfanstoggle - // tempomattoggle - // springbraketoggle - // springbrakeenable - // springbrakedisable - // springbrakeshutofftoggle - // springbrakeshutoffenable - // springbrakeshutoffdisable - // springbrakerelease + // coolingfanstoggle, + // tempomattoggle, + // springbraketoggle, + // springbrakeenable, + // springbrakedisable, + // springbrakeshutofftoggle, + // springbrakeshutoffenable, + // springbrakeshutoffdisable, + // springbrakerelease, + // distancecounteractivate }; } diff --git a/drivermouseinput.cpp b/drivermouseinput.cpp index 39b500a3..0e872f5d 100644 --- a/drivermouseinput.cpp +++ b/drivermouseinput.cpp @@ -774,6 +774,9 @@ drivermouse_input::default_bindings() { { "nextcurrent_sw:", { user_command::mucurrentindicatorothersourceactivate, user_command::none } }, + { "distancecounter_sw:", { + user_command::distancecounteractivate, + user_command::none } }, { "instrumentlight_sw:", { user_command::instrumentlighttoggle, user_command::none } }, diff --git a/translation.cpp b/translation.cpp index 0465e7b7..2bc83509 100644 --- a/translation.cpp +++ b/translation.cpp @@ -85,6 +85,7 @@ init() { "second controller", "shunt mode power", "tempomat", + "distance counter", "reverser", "train brake", "independent brake", @@ -202,7 +203,7 @@ init() { " Cisnienie: %.2f kPa (przewod glowny: %.2f kPa)", "!CZUWAK! ", "!SHP!", - " Wsiadanie/wysiadanie pasazerow (do zakonczenia %d s)", + " Wymiana pasazerska (do zakonczenia %d s)", " Inny pojazd na drodze (odleglosc: %.1f m)", "Scenariusz", @@ -252,6 +253,7 @@ init() { "nastawnik dodatkowy", "sterowanie analogowe", "tempomat", + "miernik odleglosci", "nastawnik kierunku", "hamulec zespolony", "hamulec pomocniczy", @@ -372,6 +374,7 @@ init() { "scndctrl:", "shuntmodepower:", "tempomat_sw:", + "distancecounter_sw:", "dirkey:", "brakectrl:", "localbrake:", diff --git a/translation.h b/translation.h index cb64123b..b8511290 100644 --- a/translation.h +++ b/translation.h @@ -74,6 +74,7 @@ enum string { cab_scndctrl, cab_shuntmodepower, cab_tempomat, + cab_distancecounter, cab_dirkey, cab_brakectrl, cab_localbrake, diff --git a/version.h b/version.h index e4cf28bb..0a6ea607 100644 --- a/version.h +++ b/version.h @@ -1,5 +1,5 @@ #pragma once #define VERSION_MAJOR 19 -#define VERSION_MINOR 906 +#define VERSION_MINOR 916 #define VERSION_REVISION 0