mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-09-01 18:39:19 +02:00
refactor: moving Train to separate directory
This commit is contained in:
5190
vehicle/train/Train.cpp
Normal file
5190
vehicle/train/Train.cpp
Normal file
File diff suppressed because it is too large
Load Diff
955
vehicle/train/Train.h
Normal file
955
vehicle/train/Train.h
Normal file
@@ -0,0 +1,955 @@
|
||||
/*
|
||||
This Source Code Form is subject to the
|
||||
terms of the Mozilla Public License, v.
|
||||
2.0. If a copy of the MPL was not
|
||||
distributed with this file, You can
|
||||
obtain one at
|
||||
http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include "vehicle/DynObj.h"
|
||||
#include "vehicle/Driver.h"
|
||||
#include "vehicle/Button.h"
|
||||
#include "vehicle/Gauge.h"
|
||||
#include "audio/sound.h"
|
||||
#include "scripting/PyInt.h"
|
||||
#include "input/command.h"
|
||||
#include "scripting/pythonscreenviewer.h"
|
||||
#include "utilities/dictionary.h"
|
||||
|
||||
#undef snprintf // pyint.h->python
|
||||
|
||||
// typedef enum {st_Off, st_Starting, st_On, st_ShuttingDown} T4State;
|
||||
|
||||
const double fCzuwakBlink = 0.15;
|
||||
const float fConverterPrzekaznik = 1.5f; // hunter-261211: do przekaznika nadmiarowego przetwornicy
|
||||
// 0.33f
|
||||
// const double fBuzzerTime= 5.0f;
|
||||
const float fHaslerTime = 1.2f;
|
||||
|
||||
class TCab {
|
||||
|
||||
public:
|
||||
// methods
|
||||
void Load(cParser &Parser);
|
||||
void Update( bool const Power );
|
||||
TGauge &Gauge( int n = -1 ); // pobranie adresu obiektu
|
||||
TButton &Button( int n = -1 ); // pobranie adresu obiektu
|
||||
// members
|
||||
glm::vec3 CabPos1{0, 1, 1};
|
||||
glm::vec3 CabPos2{0, 1, -1};
|
||||
bool bEnabled { false };
|
||||
bool bOccupied { true };
|
||||
/*
|
||||
glm::vec3 dimm; // McZapkie-120503: tlumienie swiatla
|
||||
glm::vec3 intlit; // McZapkie-120503: oswietlenie kabiny
|
||||
glm::vec3 intlitlow; // McZapkie-120503: przyciemnione oswietlenie kabiny
|
||||
*/
|
||||
bool bLight { false }; // hunter-091012: czy swiatlo jest zapalone?
|
||||
bool bLightDim { false }; // hunter-091012: czy przyciemnienie kabiny jest zapalone?
|
||||
float LightLevel{ 0.f }; // last calculated interior light level
|
||||
|
||||
private:
|
||||
// members
|
||||
std::deque<TGauge> ggList; // need a container which doesn't invalidate references
|
||||
std::vector<TButton> btList;
|
||||
};
|
||||
|
||||
class control_mapper {
|
||||
typedef std::unordered_map< TSubModel const *, std::string> submodelstring_map;
|
||||
submodelstring_map m_controlnames;
|
||||
using stringset = std::unordered_set<std::string>;
|
||||
stringset m_names; // names of registered controls
|
||||
public:
|
||||
void
|
||||
clear();
|
||||
void
|
||||
insert( TGauge const &Gauge, std::string const &Label );
|
||||
std::string
|
||||
find( TSubModel const *Control ) const;
|
||||
bool
|
||||
contains( std::string const Control ) const;
|
||||
};
|
||||
|
||||
class TTrain {
|
||||
|
||||
friend class drivingaid_panel;
|
||||
|
||||
public:
|
||||
// types
|
||||
struct state_t {
|
||||
std::uint8_t shp;
|
||||
std::uint8_t alerter;
|
||||
std::uint8_t radio_stop;
|
||||
std::uint8_t motor_resistors;
|
||||
std::uint8_t line_breaker;
|
||||
std::uint8_t ground_relay;
|
||||
std::uint8_t motor_overload;
|
||||
std::uint8_t motor_connectors;
|
||||
std::uint8_t wheelslip;
|
||||
std::uint8_t converter_overload;
|
||||
std::uint8_t converter_off;
|
||||
std::uint8_t compressor_overload;
|
||||
std::uint8_t ventilator_overload;
|
||||
std::uint8_t motor_overload_threshold;
|
||||
std::uint8_t train_heating;
|
||||
std::uint8_t cab;
|
||||
std::uint8_t recorder_braking;
|
||||
std::uint8_t recorder_power;
|
||||
std::uint8_t alerter_sound;
|
||||
std::uint8_t coupled_hv_voltage_relays;
|
||||
float velocity;
|
||||
float reservoir_pressure;
|
||||
float pipe_pressure;
|
||||
float brake_pressure;
|
||||
float pantograph_pressure;
|
||||
float hv_voltage;
|
||||
std::array<float, 3> hv_current;
|
||||
float lv_voltage;
|
||||
double distance;
|
||||
std::uint8_t radio_channel;
|
||||
std::uint8_t springbrake_active;
|
||||
std::uint8_t epbrake_enabled;
|
||||
std::uint8_t dir_forward;
|
||||
std::uint8_t dir_backward;
|
||||
std::uint8_t doorleftallowed;
|
||||
std::uint8_t doorleftopened;
|
||||
std::uint8_t doorrightallowed;
|
||||
std::uint8_t doorrightopened;
|
||||
std::uint8_t doorstepallowed;
|
||||
std::uint8_t battery;
|
||||
std::uint8_t emergencybrake;
|
||||
std::uint8_t lockpipe;
|
||||
bool radiomessageindicator;
|
||||
};
|
||||
|
||||
struct screen_entry {
|
||||
|
||||
std::string script;
|
||||
std::string target;
|
||||
double updatetime = 0;
|
||||
double updatetimecounter = 0;
|
||||
std::shared_ptr<python_rt> rt;
|
||||
std::shared_ptr<python_screen_viewer> viewer;
|
||||
std::shared_ptr<std::vector<glm::vec2>> touch_list;
|
||||
|
||||
dictionary_source parameters; // cached pre-processed optional per-screen parameters
|
||||
|
||||
void deserialize( cParser &Input );
|
||||
bool deserialize_mapping( cParser &Input );
|
||||
};
|
||||
|
||||
typedef std::vector<screen_entry> screenentry_sequence;
|
||||
|
||||
// methods
|
||||
bool CabChange(int iDirection);
|
||||
bool ShowNextCurrent; // pokaz przd w podlaczonej lokomotywie (ET41)
|
||||
bool InitializeCab(int NewCabNo, std::string const &asFileName);
|
||||
TTrain();
|
||||
~TTrain();
|
||||
// McZapkie-010302
|
||||
bool Init(TDynamicObject *NewDynamicObject, bool e3d = false);
|
||||
|
||||
inline glm::dvec3 GetDirection() const
|
||||
{
|
||||
return DynamicObject->VectorFront(); };
|
||||
inline glm::dvec3 GetUp() const
|
||||
{
|
||||
return DynamicObject->VectorUp(); };
|
||||
inline
|
||||
std::string GetLabel( TSubModel const *Control ) const {
|
||||
return m_controlmapper.find( Control ); }
|
||||
void UpdateCab();
|
||||
bool Update( double const Deltatime );
|
||||
void UpdateDirectionRelays();
|
||||
void SetupDirectionRelays();
|
||||
bool prevBatState = false;
|
||||
int prevDirection = 0;
|
||||
void add_distance( double const Distance );
|
||||
// McZapkie-310302: ladowanie parametrow z pliku
|
||||
bool LoadMMediaFile(std::string const &asFileName);
|
||||
std::shared_ptr<dictionary_source> GetTrainState( dictionary_source const &Extraparameters );
|
||||
state_t get_state() const;
|
||||
inline float get_radiovolume() const { return m_radiovolume; }
|
||||
// basic_table interface
|
||||
inline
|
||||
std::string name() const {
|
||||
return Dynamic()->name(); }
|
||||
|
||||
private:
|
||||
// types
|
||||
typedef void( *command_handler )( TTrain *Train, command_data const &Command );
|
||||
typedef std::unordered_map<user_command, command_handler> commandhandler_map;
|
||||
// methods
|
||||
// clears state of all cabin controls
|
||||
void clear_cab_controls();
|
||||
// sets cabin controls based on current state of the vehicle
|
||||
// NOTE: we can get rid of this function once we have per-cab persistent state
|
||||
void set_cab_controls( int const Cab );
|
||||
// initializes a gauge matching provided label. returns: true if the label was found, false otherwise
|
||||
bool initialize_gauge(cParser &Parser, std::string const &Label, int const Cabindex);
|
||||
// initializes a button matching provided label. returns: true if the label was found, false otherwise
|
||||
bool initialize_button(cParser &Parser, std::string const &Label, int const Cabindex);
|
||||
// helper, returns true for EMU with oerlikon brake
|
||||
bool is_eztoer() const;
|
||||
// locates nearest vehicle belonging to the consist
|
||||
TDynamicObject *find_nearest_consist_vehicle(bool freefly, glm::vec3 pos) const;
|
||||
// mover master controller to specified position
|
||||
void set_master_controller( double const Position );
|
||||
// moves train brake lever to specified position, potentially emits switch sound if conditions are met
|
||||
void set_train_brake( double const Position );
|
||||
// potentially moves train brake lever to neutral position
|
||||
void zero_charging_train_brake();
|
||||
// sets specified brake acting speed for specified vehicle, potentially updating state of cab controls to match
|
||||
void set_train_brake_speed( TDynamicObject *Vehicle, int const Speed );
|
||||
// sets the motor connector button in paired unit to specified state
|
||||
void set_paired_open_motor_connectors_button( bool const State );
|
||||
// helper, common part of pantograph selection methods
|
||||
void change_pantograph_selection( int const Change );
|
||||
// helper, common part of pantograh valves state update methods
|
||||
void update_pantograph_valves();
|
||||
// update function subroutines
|
||||
void update_sounds( double const Deltatime );
|
||||
void update_sounds_runningnoise( sound_source &Sound );
|
||||
void update_sounds_resonancenoise( sound_source &Sound );
|
||||
void update_sounds_radio();
|
||||
inline
|
||||
end cab_to_end( int const End ) const {
|
||||
return End == 2 ? end::rear : end::front; }
|
||||
inline
|
||||
end cab_to_end() const {
|
||||
return cab_to_end( iCabn ); }
|
||||
void update_screens(double dt);
|
||||
|
||||
// command handlers
|
||||
// NOTE: we're currently using universal handlers and static handler map but it may be beneficial to have these implemented on individual class instance basis
|
||||
// TBD, TODO: consider this approach if we ever want to have customized consist behaviour to received commands, based on the consist/vehicle type or whatever
|
||||
static void OnCommand_lightsset(TTrain *Train, command_data const &Command);
|
||||
static void OnCommand_wiperswitchincrease(TTrain *Train, command_data const &Command);
|
||||
static void OnCommand_wiperswitchdecrease(TTrain *Train, command_data const &Command);
|
||||
static void OnCommand_aidriverenable( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_aidriverdisable( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_jointcontrollerset( TTrain *Train, command_data const &Command );
|
||||
|
||||
static void OnCommand_mastercontrollerincrease( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_mastercontrollerincreasefast( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_mastercontrollerdecrease( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_mastercontrollerdecreasefast( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_mastercontrollerset( TTrain *Train, command_data const &Command );
|
||||
|
||||
static void OnCommand_DynamicBrakeControllerIncrease( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_DynamicBrakeControllerIncreaseFast( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_DynamicBrakeControllerDecrease( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_DynamicBrakeControllerDecreaseFast( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_DynamicBrakeControllerSet( TTrain *Train, command_data const &Command );
|
||||
|
||||
static void OnCommand_secondcontrollerincrease( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_secondcontrollerincreasefast( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_secondcontrollerdecrease( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_secondcontrollerdecreasefast( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_secondcontrollerset( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_notchingrelaytoggle( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_tempomattoggle( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_mucurrentindicatorothersourceactivate( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_independentbrakeincrease( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_independentbrakeincreasefast( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_independentbrakedecrease( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_independentbrakedecreasefast( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_independentbrakeset( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_independentbrakebailoff( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_universalbrakebutton1(TTrain *Train, command_data const &Command);
|
||||
static void OnCommand_universalbrakebutton2(TTrain *Train, command_data const &Command);
|
||||
static void OnCommand_universalbrakebutton3(TTrain *Train, command_data const &Command);
|
||||
static void OnCommand_trainbrakeincrease( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_trainbrakedecrease( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_trainbrakeset( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_trainbrakecharging( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_trainbrakerelease( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_trainbrakefirstservice( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_trainbrakeservice( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_trainbrakefullservice( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_trainbrakehandleoff( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_trainbrakeemergency( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_trainbrakebasepressureincrease( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_trainbrakebasepressuredecrease( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_trainbrakebasepressurereset( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_trainbrakeoperationtoggle( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_manualbrakeincrease( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_manualbrakedecrease( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_alarmchaintoggle( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_alarmchainenable(TTrain *Train, command_data const &Command);
|
||||
static void OnCommand_alarmchaindisable(TTrain *Train, command_data const &Command);
|
||||
static void OnCommand_wheelspinbrakeactivate( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_sandboxactivate( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_autosandboxtoggle(TTrain *Train, command_data const &Command);
|
||||
static void OnCommand_autosandboxactivate(TTrain *Train, command_data const &Command);
|
||||
static void OnCommand_autosandboxdeactivate(TTrain *Train, command_data const &Command);
|
||||
static void OnCommand_epbrakecontroltoggle( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_epbrakecontrolenable( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_epbrakecontroldisable( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_trainbrakeoperationmodeincrease(TTrain *Train, command_data const &Command);
|
||||
static void OnCommand_trainbrakeoperationmodedecrease(TTrain *Train, command_data const &Command);
|
||||
static void OnCommand_brakeactingspeedincrease( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_brakeactingspeeddecrease( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_brakeactingspeedsetcargo( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_brakeactingspeedsetpassenger( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_brakeactingspeedsetrapid( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_brakeloadcompensationincrease( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_brakeloadcompensationdecrease( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_mubrakingindicatortoggle( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_reverserincrease( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_reverserdecrease( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_reverserforwardhigh( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_reverserforward( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_reverserneutral( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_reverserbackward( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_alerteracknowledge( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_cabsignalacknowledge( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_batterytoggle( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_batteryenable( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_batterydisable( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_cabactivationtoggle(TTrain *Train, command_data const &Command);
|
||||
static void OnCommand_cabactivationenable(TTrain *Train, command_data const &Command);
|
||||
static void OnCommand_cabactivationdisable(TTrain *Train, command_data const &Command);
|
||||
static void OnCommand_pantographcompressorvalvetoggle( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_pantographcompressorvalveenable( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_pantographcompressorvalvedisable( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_pantographcompressoractivate( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_pantographtogglefront( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_pantographtogglerear( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_pantographraisefront( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_pantographraiserear( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_pantographlowerfront( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_pantographlowerrear( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_pantographlowerall( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_pantographselectnext( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_pantographselectprevious( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_pantographtoggleselected( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_pantographraiseselected( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_pantographlowerselected( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_pantographvalvesupdate( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_pantographvalvesoff( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_linebreakertoggle( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_linebreakeropen( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_linebreakerclose( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_fuelpumptoggle( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_fuelpumpenable( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_fuelpumpdisable( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_oilpumptoggle( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_oilpumpenable( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_oilpumpdisable( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_waterheaterbreakertoggle( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_waterheaterbreakerclose( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_waterheaterbreakeropen( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_waterheatertoggle( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_waterheaterenable( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_waterheaterdisable( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_waterpumpbreakertoggle( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_waterpumpbreakerclose( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_waterpumpbreakeropen( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_waterpumptoggle( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_waterpumpenable( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_waterpumpdisable( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_watercircuitslinktoggle( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_watercircuitslinkenable( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_watercircuitslinkdisable( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_convertertoggle( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_converterenable( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_converterdisable( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_convertertogglelocal( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_converteroverloadrelayreset( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_compressortoggle( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_compressorenable( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_compressordisable( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_compressortogglelocal( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_compressorpresetactivatenext( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_compressorpresetactivateprevious( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_compressorpresetactivatedefault(TTrain *Train, command_data const &Command);
|
||||
static void OnCommand_motorblowerstogglefront( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_motorblowersenablefront( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_motorblowersdisablefront( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_motorblowerstogglerear( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_motorblowersenablerear( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_motorblowersdisablerear( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_motorblowersdisableall( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_coolingfanstoggle( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_motorconnectorsopen( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_motorconnectorsclose( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_motordisconnect( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_motoroverloadrelaythresholdtoggle( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_motoroverloadrelaythresholdsetlow( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_motoroverloadrelaythresholdsethigh( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_motoroverloadrelayreset( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_universalrelayreset( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_heatingtoggle( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_heatingenable( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_heatingdisable( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_lightspresetactivatenext( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_lightspresetactivateprevious( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_headlighttoggleleft( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_headlightenableleft( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_headlightdisableleft( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_headlighttoggleright( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_headlightenableright( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_headlightdisableright( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_headlighttoggleupper( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_headlightenableupper( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_headlightdisableupper( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_redmarkertoggleleft( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_redmarkerenableleft( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_redmarkerdisableleft( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_redmarkertoggleright( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_redmarkerenableright( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_redmarkerdisableright( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_headlighttogglerearleft( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_headlightenablerearleft( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_headlightdisablerearleft( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_headlighttogglerearright( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_headlightenablerearright( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_headlightdisablerearright( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_headlighttogglerearupper( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_headlightenablerearupper( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_headlightdisablerearupper( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_modernlightdimmerincrease(TTrain *Train, command_data const &Command);
|
||||
static void OnCommand_modernlightdimmerdecrease(TTrain *Train, command_data const &Command);
|
||||
static void OnCommand_redmarkertogglerearleft( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_redmarkerenablerearleft( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_redmarkerdisablerearleft( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_redmarkertogglerearright( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_redmarkerenablerearright( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_redmarkerdisablerearright( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_redmarkerstoggle( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_endsignalstoggle( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_headlightsdimtoggle( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_headlightsdimenable( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_headlightsdimdisable( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_interiorlighttoggle( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_interiorlightenable( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_interiorlightdisable( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_interiorlightdimtoggle( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_interiorlightdimenable( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_interiorlightdimdisable( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_compartmentlightstoggle( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_compartmentlightsenable( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_compartmentlightsdisable( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_instrumentlighttoggle( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_instrumentlightenable( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_instrumentlightdisable( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_dashboardlighttoggle( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_dashboardlightenable( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_dashboardlightdisable( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_timetablelighttoggle( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_timetablelightenable( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_timetablelightdisable( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_doorlocktoggle( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_doortoggleleft( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_doortoggleright( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_doorpermitleft( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_doorpermitright( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_doorpermitpresetactivatenext( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_doorpermitpresetactivateprevious( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_dooropenleft( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_dooropenright( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_doorcloseleft( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_doorcloseright( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_dooropenall( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_doorcloseall( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_doorsteptoggle( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_doormodetoggle( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_mirrorstoggle( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_nearestcarcouplingincrease( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_nearestcarcouplingdisconnect( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_nearestcarcoupleradapterattach( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_nearestcarcoupleradapterremove( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_occupiedcarcouplingdisconnect( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_occupiedcarcouplingdisconnectback( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_departureannounce( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_hornlowactivate( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_hornhighactivate( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_whistleactivate( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_radiotoggle( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_radioenable( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_radiodisable( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_radiochannelincrease( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_radiochanneldecrease( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_radiochannelset( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_radiostopsend( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_radiostopenable( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_radiostopdisable( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_radiostoptest( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_radiocall1send( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_radiocall3send( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_radiovolumeincrease(TTrain *Train, command_data const &Command);
|
||||
static void OnCommand_radiovolumedecrease(TTrain *Train, command_data const &Command);
|
||||
static void OnCommand_radiovolumeset(TTrain *Train, command_data const &Command);
|
||||
static void OnCommand_cabchangeforward( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_cabchangebackward( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_generictoggle( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_vehiclemoveforwards( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_vehiclemovebackwards( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_vehicleboost( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_springbraketoggle(TTrain *Train, command_data const &Command);
|
||||
static void OnCommand_springbrakeenable(TTrain *Train, command_data const &Command);
|
||||
static void OnCommand_springbrakedisable(TTrain *Train, command_data const &Command);
|
||||
static void OnCommand_springbrakeshutofftoggle(TTrain *Train, command_data const &Command);
|
||||
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 );
|
||||
static void OnCommand_speedcontrolincrease(TTrain *Train, command_data const &Command);
|
||||
static void OnCommand_speedcontroldecrease(TTrain *Train, command_data const &Command);
|
||||
static void OnCommand_speedcontrolpowerincrease(TTrain *Train, command_data const &Command);
|
||||
static void OnCommand_speedcontrolpowerdecrease(TTrain *Train, command_data const &Command);
|
||||
static void OnCommand_speedcontrolbutton(TTrain *Train, command_data const &Command);
|
||||
static void OnCommand_inverterenable(TTrain *Train, command_data const &Command);
|
||||
static void OnCommand_inverterdisable(TTrain *Train, command_data const &Command);
|
||||
static void OnCommand_invertertoggle(TTrain *Train, command_data const &Command);
|
||||
|
||||
|
||||
// members
|
||||
TDynamicObject *DynamicObject { nullptr }; // przestawia zmiana pojazdu [F5]
|
||||
TMoverParameters *mvControlled { nullptr }; // człon, w którym sterujemy silnikiem
|
||||
TMoverParameters *mvOccupied { nullptr }; // człon, w którym sterujemy hamulcem
|
||||
TMoverParameters *mvSecond { nullptr }; // drugi człon (ET40, ET41, ET42, ukrotnienia)
|
||||
TMoverParameters *mvThird { nullptr }; // trzeci człon (SN61)
|
||||
TMoverParameters *mvPantographUnit { nullptr }; // nearest pantograph equipped unit
|
||||
// helper variable, to prevent immediate switch between closing and opening line breaker circuit
|
||||
int m_linebreakerstate { 0 }; // 0: open, 1: closed, 2: freshly closed (and yes this is awful way to go about it)
|
||||
static const commandhandler_map m_commandhandlers;
|
||||
control_mapper m_controlmapper;
|
||||
|
||||
public: // reszta może by?publiczna
|
||||
|
||||
// McZapkie: definicje wskaźników
|
||||
// Ra 2014-08: częsciowo przeniesione do tablicy w TCab
|
||||
TGauge ggClockSInd;
|
||||
TGauge ggClockMInd;
|
||||
TGauge ggClockHInd;
|
||||
TGauge ggLVoltage;
|
||||
TGauge ggMainGearStatus;
|
||||
|
||||
TGauge ggEngineVoltage;
|
||||
TGauge ggI1B; // drugi człon w postaci jawnej
|
||||
TGauge ggI2B;
|
||||
TGauge ggI3B;
|
||||
TGauge ggItotalB;
|
||||
|
||||
TGauge ggOilPressB; // other unit oil pressure indicator
|
||||
TGauge ggWater1TempB;
|
||||
|
||||
// McZapkie: definicje regulatorow
|
||||
TGauge ggJointCtrl;
|
||||
TGauge ggMainCtrl;
|
||||
TGauge ggMainCtrlAct;
|
||||
TGauge ggScndCtrl;
|
||||
TGauge ggScndCtrlButton;
|
||||
TGauge ggScndCtrlOffButton;
|
||||
TGauge ggDirKey;
|
||||
TGauge ggDirForwardButton;
|
||||
TGauge ggDirNeutralButton;
|
||||
TGauge ggDirBackwardButton;
|
||||
TGauge ggBrakeCtrl;
|
||||
TGauge ggLocalBrake;
|
||||
TGauge ggAlarmChain;
|
||||
TGauge ggBrakeProfileCtrl; // nastawiacz GPR - przelacznik obrotowy
|
||||
TGauge ggBrakeProfileG; // nastawiacz GP - hebelek towarowy
|
||||
TGauge ggBrakeProfileR; // nastawiacz PR - hamowanie dwustopniowe
|
||||
TGauge ggBrakeOperationModeCtrl; //przełącznik trybu pracy PS/PN/EP/MED
|
||||
|
||||
TGauge ggWiperSw; // przelacznik wycieraczek
|
||||
|
||||
TGauge ggMaxCurrentCtrl;
|
||||
|
||||
TGauge ggMainOffButton;
|
||||
TGauge ggMainOnButton;
|
||||
TGauge ggMainButton; // EZT
|
||||
TGauge ggSecurityResetButton;
|
||||
TGauge ggSHPResetButton;
|
||||
TGauge ggReleaserButton;
|
||||
TGauge ggSpringBrakeOnButton;
|
||||
TGauge ggSpringBrakeOffButton;
|
||||
TGauge ggUniveralBrakeButton1;
|
||||
TGauge ggUniveralBrakeButton2;
|
||||
TGauge ggUniveralBrakeButton3;
|
||||
TGauge ggEPFuseButton;
|
||||
TGauge ggSandButton; // guzik piasecznicy
|
||||
TGauge ggAutoSandButton; // przełącznik piasecznicy
|
||||
TGauge ggAntiSlipButton;
|
||||
TGauge ggFuseButton;
|
||||
TGauge ggConverterFuseButton; // hunter-261211: przycisk odblokowania nadmiarowego przetwornic i ogrzewania
|
||||
TGauge ggStLinOffButton;
|
||||
TGauge ggRadioChannelSelector;
|
||||
TGauge ggRadioChannelPrevious;
|
||||
TGauge ggRadioChannelNext;
|
||||
TGauge ggRadioTest;
|
||||
TGauge ggRadioStop;
|
||||
TGauge ggRadioCall1;
|
||||
TGauge ggRadioCall3;
|
||||
TGauge ggRadioVolumeSelector;
|
||||
TGauge ggRadioVolumePrevious;
|
||||
TGauge ggRadioVolumeNext;
|
||||
TGauge ggUpperLightButton;
|
||||
TGauge ggLeftLightButton;
|
||||
TGauge ggRightLightButton;
|
||||
TGauge ggLeftEndLightButton;
|
||||
TGauge ggRightEndLightButton;
|
||||
TGauge ggLightsButton; // przelacznik reflektorow (wszystkich)
|
||||
TGauge ggDimHeadlightsButton; // headlights dimming switch
|
||||
TGauge ggModernLightDimSw; // modern lights dimmer
|
||||
|
||||
// hunter-230112: przelacznik swiatel tylnich
|
||||
TGauge ggRearUpperLightButton;
|
||||
TGauge ggRearLeftLightButton;
|
||||
TGauge ggRearRightLightButton;
|
||||
TGauge ggRearLeftEndLightButton;
|
||||
TGauge ggRearRightEndLightButton;
|
||||
|
||||
TGauge ggIgnitionKey;
|
||||
|
||||
TGauge ggCompressorButton;
|
||||
TGauge ggCompressorLocalButton; // controls only compressor of its own unit (et42-specific)
|
||||
TGauge ggCompressorListButton; // controls compressors with various settings
|
||||
TGauge ggConverterButton;
|
||||
TGauge ggConverterLocalButton; // controls only converter of its own unit (et42-specific)
|
||||
TGauge ggConverterOffButton;
|
||||
|
||||
// ABu 090305 - syrena i prad nastepnego czlonu
|
||||
TGauge ggHornButton;
|
||||
TGauge ggHornLowButton;
|
||||
TGauge ggHornHighButton;
|
||||
TGauge ggWhistleButton;
|
||||
TGauge ggHelperButton;
|
||||
TGauge ggNextCurrentButton;
|
||||
|
||||
// yB 191005 - tempomat
|
||||
TGauge ggSpeedControlIncreaseButton;
|
||||
TGauge ggSpeedControlDecreaseButton;
|
||||
TGauge ggSpeedControlPowerIncreaseButton;
|
||||
TGauge ggSpeedControlPowerDecreaseButton;
|
||||
std::array<TGauge, 10> ggSpeedCtrlButtons; // NOTE: temporary arrangement until we have dynamically built control table
|
||||
|
||||
std::array<TGauge, 30> ggUniversals; // NOTE: temporary arrangement until we have dynamically built control table
|
||||
std::array<TGauge, 3> ggRelayResetButtons; // NOTE: temporary arrangement until we have dynamically built control table
|
||||
std::array<TGauge, 12> ggInverterEnableButtons; // NOTE: temporary arrangement until we have dynamically built control table
|
||||
std::array<TGauge, 12> ggInverterDisableButtons; // NOTE: temporary arrangement until we have dynamically built control table
|
||||
std::array<TGauge, 12> ggInverterToggleButtons; // NOTE: temporary arrangement until we have dynamically built control table
|
||||
|
||||
TGauge ggInstrumentLightButton;
|
||||
TGauge ggDashboardLightButton;
|
||||
TGauge ggTimetableLightButton;
|
||||
// TGauge ggCabLightButton; // hunter-091012: przelacznik oswietlania kabiny
|
||||
TGauge ggCabLightDimButton; // hunter-091012: przelacznik przyciemnienia
|
||||
// oswietlenia kabiny
|
||||
TGauge ggCompartmentLightsButton;
|
||||
TGauge ggCompartmentLightsOnButton;
|
||||
TGauge ggCompartmentLightsOffButton;
|
||||
TGauge ggBatteryButton; // Stele 161228 hebelek baterii
|
||||
TGauge ggBatteryOnButton;
|
||||
TGauge ggBatteryOffButton;
|
||||
TGauge ggCabActivationButton; // Stele 161228 hebelek baterii
|
||||
|
||||
// NBMX wrzesien 2003 - obsluga drzwi
|
||||
TGauge ggDoorLeftPermitButton;
|
||||
TGauge ggDoorRightPermitButton;
|
||||
TGauge ggDoorPermitPresetButton;
|
||||
TGauge ggDoorLeftButton;
|
||||
TGauge ggDoorRightButton;
|
||||
TGauge ggDoorLeftOnButton;
|
||||
TGauge ggDoorRightOnButton;
|
||||
TGauge ggDoorLeftOffButton;
|
||||
TGauge ggDoorRightOffButton;
|
||||
TGauge ggDoorAllOnButton;
|
||||
TGauge ggDoorAllOffButton;
|
||||
TGauge ggDepartureSignalButton;
|
||||
TGauge ggDoorStepButton;
|
||||
|
||||
// Winger 160204 - obsluga pantografow - ZROBIC
|
||||
/*
|
||||
TGauge ggPantFrontButton;
|
||||
TGauge ggPantRearButton;
|
||||
TGauge ggPantFrontButtonOff; // EZT
|
||||
TGauge ggPantRearButtonOff;
|
||||
*/
|
||||
TGauge ggPantAllDownButton;
|
||||
TGauge ggPantSelectedButton;
|
||||
TGauge ggPantSelectedDownButton;
|
||||
TGauge ggPantValvesButton;
|
||||
TGauge ggPantCompressorButton;
|
||||
TGauge ggPantCompressorValve;
|
||||
TGauge ggPantValvesUpdate;
|
||||
TGauge ggPantValvesOff;
|
||||
// Winger 020304 - wlacznik ogrzewania
|
||||
TGauge ggTrainHeatingButton;
|
||||
TGauge ggSignallingButton;
|
||||
TGauge ggDoorSignallingButton;
|
||||
|
||||
TGauge ggWaterPumpBreakerButton; // water pump breaker switch
|
||||
TGauge ggWaterPumpButton; // water pump switch
|
||||
TGauge ggWaterHeaterBreakerButton; // water heater breaker switch
|
||||
TGauge ggWaterHeaterButton; // water heater switch
|
||||
TGauge ggWaterCircuitsLinkButton;
|
||||
TGauge ggFuelPumpButton; // fuel pump switch
|
||||
TGauge ggOilPumpButton; // fuel pump switch
|
||||
TGauge ggMotorBlowersFrontButton; // front traction motor fan switch
|
||||
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;
|
||||
TButton btLampkaPrzetw;
|
||||
TButton btLampkaPrzetwOff;
|
||||
TButton btLampkaPrzekRozn; // TODO: implement
|
||||
TButton btLampkaPrzekRoznPom; // TODO: implement
|
||||
TButton btLampkaNadmSil;
|
||||
TButton btLampkaWylSzybki;
|
||||
TButton btLampkaWylSzybkiOff;
|
||||
TButton btLampkaMainBreakerReady;
|
||||
TButton btLampkaMainBreakerBlinkingIfReady;
|
||||
TButton btLampkaNadmWent;
|
||||
TButton btLampkaNadmSpr; // TODO: implement
|
||||
// yB: drugie lampki dla EP05 i ET42
|
||||
TButton btLampkaOporyB;
|
||||
TButton btLampkaStycznB;
|
||||
TButton btLampkaWylSzybkiB;
|
||||
TButton btLampkaWylSzybkiBOff;
|
||||
TButton btLampkaNadmPrzetwB;
|
||||
TButton btLampkaPrzetwB;
|
||||
TButton btLampkaPrzetwBOff;
|
||||
TButton btLampkaHVoltageB; // TODO: implement
|
||||
// KURS90 lampki jazdy bezoporowej dla EU04
|
||||
TButton btLampkaBezoporowaB;
|
||||
TButton btLampkaBezoporowa;
|
||||
TButton btLampkaUkrotnienie;
|
||||
TButton btLampkaHamPosp;
|
||||
TButton btLampkaRadio;
|
||||
TButton btLampkaRadioMessage;
|
||||
TButton btLampkaRadioStop;
|
||||
TButton btLampkaHamowanie1zes;
|
||||
TButton btLampkaHamowanie2zes;
|
||||
TButton btLampkaOpory;
|
||||
TButton btLampkaWysRozr;
|
||||
std::array<TButton, 10> btUniversals; // NOTE: temporary arrangement until we have dynamically built control table
|
||||
TButton btInstrumentLight;
|
||||
TButton btDashboardLight;
|
||||
TButton btTimetableLight;
|
||||
int InstrumentLightType{ 0 }; // ABu 030405 - swiecenie uzaleznione od: 0-nic, 1-obw.gl, 2-przetw., 3-rozrzad, 4-external lights
|
||||
bool InstrumentLightActive{ false };
|
||||
bool DashboardLightActive{ false };
|
||||
bool TimetableLightActive{ false };
|
||||
TButton btLampkaWentZaluzje; // ET22 // TODO: implement
|
||||
TButton btLampkaOgrzewanieSkladu;
|
||||
TButton btLampkaSHP;
|
||||
TButton btLampkaCzuwaka; // McZapkie-141102
|
||||
TButton btLampkaCzuwakaSHP;
|
||||
TButton btLampkaRezerwa;
|
||||
// youBy - jakies dodatkowe lampki
|
||||
TButton btLampkaNapNastHam;
|
||||
TButton btLampkaSprezarka;
|
||||
TButton btLampkaSprezarkaB;
|
||||
TButton btLampkaSprezarkaOff;
|
||||
TButton btLampkaSprezarkaBOff;
|
||||
TButton btLampkaFuelPumpOff;
|
||||
TButton btLampkaBocznik1;
|
||||
TButton btLampkaBocznik2;
|
||||
TButton btLampkaBocznik3;
|
||||
TButton btLampkaBocznik4;
|
||||
TButton btLampkaGear1;
|
||||
TButton btLampkaGear2;
|
||||
TButton btLampkaHydroLockup;
|
||||
TButton btLampkaRadiotelefon; // TODO: implement
|
||||
TButton btLampkaHamienie;
|
||||
TButton btLampkaBrakingOff;
|
||||
TButton btLampkaED; // Stele 161228 hamowanie elektrodynamiczne
|
||||
TButton btLampkaBrakeProfileG; // cargo train brake acting speed
|
||||
TButton btLampkaBrakeProfileP; // passenger train brake acting speed
|
||||
TButton btLampkaBrakeProfileR; // rapid brake acting speed
|
||||
TButton btLampkaSpringBrakeActive;
|
||||
TButton btLampkaSpringBrakeInactive;
|
||||
// overheat indicator lamps
|
||||
TButton btLampkaOilOverheat;
|
||||
TButton btLampkaWaterOverheat;
|
||||
TButton btLampkaWaterAuxOverheat;
|
||||
TButton btLampkaEngineOverheat;
|
||||
// KURS90
|
||||
TButton btLampkaBoczniki;
|
||||
TButton btLampkaMaxSila;
|
||||
TButton btLampkaPrzekrMaxSila;
|
||||
TButton btLampkaDoorLeft;
|
||||
TButton btLampkaDoorRight;
|
||||
TButton btLampkaDepartureSignal;
|
||||
TButton btLampkaBlokadaDrzwi;
|
||||
TButton btLampkaDoorLockOff;
|
||||
TButton btLampkaHamulecReczny;
|
||||
TButton btLampkaForward; // Ra: lampki w przód i w ty?dla komputerowych kabin
|
||||
TButton btLampkaNeutral; // Kierunek neutralny
|
||||
TButton btLampkaBackward;
|
||||
// light indicators
|
||||
TButton btLampkaUpperLight;
|
||||
TButton btLampkaLeftLight;
|
||||
TButton btLampkaRightLight;
|
||||
TButton btLampkaLeftEndLight;
|
||||
TButton btLampkaRightEndLight;
|
||||
TButton btLampkaRearUpperLight;
|
||||
TButton btLampkaRearLeftLight;
|
||||
TButton btLampkaRearRightLight;
|
||||
TButton btLampkaRearLeftEndLight;
|
||||
TButton btLampkaRearRightEndLight;
|
||||
TButton btCabActived;
|
||||
TButton btAKLVents;
|
||||
TButton btCompressors; // lampka pracy jakiejkolwiek sprezarki
|
||||
TButton btEDenabled; // czy wlaczony jest hamulec ED (czy dostepny)
|
||||
// other
|
||||
TButton btLampkaMalfunction;
|
||||
TButton btLampkaMalfunctionB;
|
||||
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
|
||||
TButton btHaslerBrakes; // ciśnienie w cylindrach
|
||||
TButton btHaslerCurrent; // prąd na silnikach
|
||||
|
||||
std::optional<sound_source>
|
||||
dsbNastawnikJazdy,
|
||||
dsbNastawnikBocz,
|
||||
dsbReverserKey,
|
||||
dsbBuzzer, dsbBuzzerShp,
|
||||
m_radiostop,
|
||||
dsbSlipAlarm,
|
||||
m_distancecounterclear,
|
||||
dsbHasler,
|
||||
dsbSwitch,
|
||||
dsbPneumaticSwitch,
|
||||
rsHiss,
|
||||
rsHissU,
|
||||
rsHissE,
|
||||
rsHissX,
|
||||
rsHissT,
|
||||
rsSBHiss,
|
||||
rsSBHissU,
|
||||
rsBrake,
|
||||
rsFadeSound,
|
||||
rsRunningNoise,
|
||||
rsResonanceNoise,
|
||||
rsWindSound,
|
||||
rsHuntingNoise,
|
||||
m_rainsound;
|
||||
sound_source m_radiosound { sound_placement::internal, 2 * EU07_SOUND_CABCONTROLSCUTOFFRANGE }; // cached template for radio messages
|
||||
std::vector<std::pair<int, std::shared_ptr<sound_source>>> m_radiomessages; // list of currently played radio messages
|
||||
std::vector<std::pair<std::reference_wrapper<std::optional<sound_source>>, glm::vec3>> CabSoundLocations; // list of offsets for manually located sounds;
|
||||
float m_lastlocalbrakepressure { -1.f }; // helper, cached level of pressure in local brake cylinder
|
||||
float m_localbrakepressurechange { 0.f }; // recent change of pressure in local brake cylinder
|
||||
/*
|
||||
int iCabLightFlag; // McZapkie:120503: oswietlenie kabiny (0: wyl, 1: przyciemnione, 2: pelne)
|
||||
bool bCabLight; // hunter-091012: czy swiatlo jest zapalone?
|
||||
bool bCabLightDim; // hunter-091012: czy przyciemnienie kabiny jest zapalone?
|
||||
*/
|
||||
// McZapkie: opis kabiny - obszar poruszania sie mechanika oraz zajetosc
|
||||
std::array<TCab, 3> Cabine; // przedzial maszynowy, kabina 1 (A), kabina 2 (B)
|
||||
int iCabn { 0 }; // 0: mid, 1: front, 2: rear
|
||||
bool is_cab_initialized { false };
|
||||
// McZapkie: do poruszania sie po kabinie
|
||||
glm::dvec3 pMechSittingPosition; // ABu 180404
|
||||
glm::dvec3 MirrorPosition(bool lewe);
|
||||
glm::dvec3 pMechOffset; // base position of the driver in the cab
|
||||
glm::vec2 pMechViewAngle { 0.0, 0.0 }; // camera pitch and yaw values, preserved while in external view
|
||||
|
||||
private:
|
||||
double fBlinkTimer;
|
||||
float fHaslerTimer;
|
||||
float fConverterTimer; // hunter-261211: dla przekaznika
|
||||
float fMainRelayTimer; // hunter-141211: zalaczanie WSa z opoznieniem
|
||||
float fBatteryTimer = {-1.f}; // Hirek: zalaczanie baterii z opoznieniem (tylko gdy zdefiniowano takie zachowanie w fiz)
|
||||
bool allowBatteryToggle = true; // Hirek: zabezpieczenie przed przelaczaniem bateri on/off
|
||||
int ScreenUpdateRate { 0 }; // vehicle specific python screen update rate override
|
||||
|
||||
// McZapkie-240302 - przyda sie do tachometru
|
||||
float fTachoVelocity{ 0.0f };
|
||||
float fTachoVelocityJump{ 0.0f }; // ze skakaniem
|
||||
float fTachoTimer{ 0.0f };
|
||||
float fTachoCount{ 0.0f };
|
||||
float fHVoltage{ 0.0f }; // napi?cie dla dynamicznych ga?ek
|
||||
float fHCurrent[ 4 ] = { 0.0f, 0.0f, 0.0f, 0.0f }; // pr?dy: suma i amperomierze 1,2,3
|
||||
float fEngine[ 4 ] = { 0.0f, 0.0f, 0.0f, 0.0f }; // obroty te? trzeba pobra?
|
||||
int iCarNo, iPowerNo, iUnitNo; // liczba pojazdow, czlonow napednych i jednostek spiętych ze sobą
|
||||
bool bDoors[20][5]; // drzwi dla wszystkich czlonow; left+right, left, right, step_left, step_right
|
||||
int iUnits[20]; // numer jednostki
|
||||
int iDoorNo[20]; // liczba drzwi
|
||||
char cCode[20]; // kod pojazdu
|
||||
bool bSlip[20]; // poślizg kół pojazdu
|
||||
std::string asCarName[20]; // nazwa czlonu
|
||||
bool bMains[8]; // WSy
|
||||
float fCntVol[8]; // napiecie NN
|
||||
bool bPants[8][2]; // podniesienie pantografow
|
||||
bool bFuse[8]; // nadmiarowe
|
||||
bool bBatt[8]; // baterie
|
||||
bool bConv[8]; // przetwornice
|
||||
bool bComp[8][2]; // sprezarki
|
||||
std::vector<std::tuple<bool, bool, int>> bCompressors;
|
||||
bool bHeat[8]; // grzanie
|
||||
// McZapkie: do syczenia
|
||||
float fPPress, fNPress;
|
||||
bool m_mastercontrollerinuse { false };
|
||||
float m_mastercontrollerreturndelay { 0.f };
|
||||
screenentry_sequence m_screens;
|
||||
uint16_t vid { 0 }; // train network recipient id
|
||||
float m_distancecounter { -1.f }; // distance traveled since meter was activated or -1 if inactive
|
||||
double m_brakehandlecp{ 0.0 };
|
||||
bool m_doors{ false }; // helper, true if any door is open
|
||||
bool m_doorspermitleft{ false }; // helper, true if door is open, blinking if door is pemitted
|
||||
bool m_doorspermitright{ false }; // helper, true if door is open, blinking if door is pemitted
|
||||
bool m_dirforward{ false }; // helper, true if direction set to forward
|
||||
bool m_dirneutral{ false }; // helper, true if direction set to neutral
|
||||
bool m_dirbackward{ false }; // helper, true if direction set to backward
|
||||
bool m_doorpermits{ false }; // helper, true if any door permit is active
|
||||
float m_doorpermittimers[2] = { -1.f, -1.f };
|
||||
float trainLenghtMeasureTimer = { -1.f };
|
||||
// ld substitute
|
||||
bool m_couplingdisconnect { false };
|
||||
bool m_couplingdisconnectback { false };
|
||||
float m_radiovolume { Global.DefaultRadioVolume };
|
||||
|
||||
public:
|
||||
float fPress[20][7]; // cisnienia dla wszystkich czlonow
|
||||
bool bBrakes[20][2]; // zalaczenie i dzialanie hamulcow
|
||||
static std::vector<std::string> const fPress_labels;
|
||||
float fEIMParams[9][10]; // parametry dla silnikow asynchronicznych
|
||||
float fDieselParams[9][10]; // parametry dla silnikow asynchronicznych
|
||||
// plays provided sound from position of the radio
|
||||
bool radio_message_played;
|
||||
void radio_message( sound_source *Message, int const Channel );
|
||||
inline auto const RadioChannel() const { return Dynamic()->Mechanik ? Dynamic()->Mechanik->iRadioChannel : 1; }
|
||||
inline auto &RadioChannel() { return Dynamic()->Mechanik->iRadioChannel; }
|
||||
inline TDynamicObject *Dynamic() { return DynamicObject; };
|
||||
inline TDynamicObject const *Dynamic() const { return DynamicObject; };
|
||||
inline TMoverParameters *Controlled() { return mvControlled; };
|
||||
inline TMoverParameters const *Controlled() const { return mvControlled; };
|
||||
inline TMoverParameters *Occupied() { return mvOccupied; };
|
||||
inline TMoverParameters const *Occupied() const { return mvOccupied; };
|
||||
void DynamicSet(TDynamicObject *d);
|
||||
void MoveToVehicle( TDynamicObject *target );
|
||||
// checks whether specified point is within boundaries of the active cab
|
||||
bool point_inside(glm::dvec3 const Point) const;
|
||||
glm::dvec3 clamp_inside(glm::dvec3 const &Point) const;
|
||||
const screenentry_sequence & get_screens();
|
||||
|
||||
uint16_t id();
|
||||
bool pending_delete = false;
|
||||
};
|
||||
|
||||
class train_table : public basic_table<TTrain> {
|
||||
public:
|
||||
void update( double dt );
|
||||
void updateAsync( double dt );
|
||||
TTrain *find_id( std::uint16_t const Id ) const;
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
586
vehicle/train/TrainCommandsAuxiliary.cpp
Normal file
586
vehicle/train/TrainCommandsAuxiliary.cpp
Normal file
@@ -0,0 +1,586 @@
|
||||
/*
|
||||
This Source Code Form is subject to the
|
||||
terms of the Mozilla Public License, v.
|
||||
2.0. If a copy of the MPL was not
|
||||
distributed with this file, You can
|
||||
obtain one at
|
||||
http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "vehicle/Train.h"
|
||||
|
||||
#include "world/Event.h"
|
||||
#include "simulation/simulationtime.h"
|
||||
#include "utilities/Logs.h"
|
||||
#include "model/Model3d.h"
|
||||
#include "vehicle/Driver.h"
|
||||
#include <future>
|
||||
|
||||
void TTrain::OnCommand_fuelpumptoggle(TTrain *Train, command_data const &Command)
|
||||
{
|
||||
|
||||
if (Command.action == GLFW_REPEAT)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (Train->ggFuelPumpButton.type() == TGaugeType::push)
|
||||
{
|
||||
// impulse switch
|
||||
// currently there's no off button so we always try to turn it on
|
||||
OnCommand_fuelpumpenable(Train, Command);
|
||||
}
|
||||
else
|
||||
{
|
||||
// two-state switch
|
||||
if (Command.action == GLFW_RELEASE)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (false == Train->mvControlled->FuelPump.is_enabled)
|
||||
{
|
||||
// turn on
|
||||
OnCommand_fuelpumpenable(Train, Command);
|
||||
}
|
||||
else
|
||||
{
|
||||
// turn off
|
||||
OnCommand_fuelpumpdisable(Train, Command);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_fuelpumpenable(TTrain *Train, command_data const &Command)
|
||||
{
|
||||
|
||||
if (Command.action == GLFW_REPEAT)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (Train->ggFuelPumpButton.type() == TGaugeType::push)
|
||||
{
|
||||
// impulse switch
|
||||
if (Command.action == GLFW_PRESS)
|
||||
{
|
||||
// visual feedback
|
||||
Train->ggFuelPumpButton.UpdateValue(1.0, Train->dsbSwitch);
|
||||
Train->mvControlled->FuelPumpSwitch(true);
|
||||
}
|
||||
else if (Command.action == GLFW_RELEASE)
|
||||
{
|
||||
// visual feedback
|
||||
Train->ggFuelPumpButton.UpdateValue(0.0, Train->dsbSwitch);
|
||||
Train->mvControlled->FuelPumpSwitch(false);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// two-state switch, only cares about press events
|
||||
if (Command.action == GLFW_PRESS)
|
||||
{
|
||||
// visual feedback
|
||||
Train->ggFuelPumpButton.UpdateValue(1.0, Train->dsbSwitch);
|
||||
Train->mvControlled->FuelPumpSwitch(true);
|
||||
Train->mvControlled->FuelPumpSwitchOff(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_fuelpumpdisable(TTrain *Train, command_data const &Command)
|
||||
{
|
||||
|
||||
if (Command.action == GLFW_REPEAT)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (Train->ggFuelPumpButton.type() == TGaugeType::push)
|
||||
{
|
||||
// impulse switch
|
||||
// currently there's no disable return type switch
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
// two-state switch, only cares about press events
|
||||
if (Command.action == GLFW_PRESS)
|
||||
{
|
||||
// visual feedback
|
||||
Train->ggFuelPumpButton.UpdateValue(0.0, Train->dsbSwitch);
|
||||
Train->mvControlled->FuelPumpSwitch(false);
|
||||
Train->mvControlled->FuelPumpSwitchOff(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_oilpumptoggle(TTrain *Train, command_data const &Command)
|
||||
{
|
||||
|
||||
if (Command.action == GLFW_REPEAT)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (Train->ggOilPumpButton.type() == TGaugeType::push)
|
||||
{
|
||||
// impulse switch
|
||||
// currently there's no off button so we always try to turn it on
|
||||
OnCommand_oilpumpenable(Train, Command);
|
||||
}
|
||||
else
|
||||
{
|
||||
// two-state switch
|
||||
if (Command.action == GLFW_RELEASE)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (false == Train->mvControlled->OilPump.is_enabled)
|
||||
{
|
||||
// turn on
|
||||
OnCommand_oilpumpenable(Train, Command);
|
||||
}
|
||||
else
|
||||
{
|
||||
// turn off
|
||||
OnCommand_oilpumpdisable(Train, Command);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_oilpumpenable(TTrain *Train, command_data const &Command)
|
||||
{
|
||||
|
||||
if (Command.action == GLFW_REPEAT)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (Train->ggOilPumpButton.type() == TGaugeType::push)
|
||||
{
|
||||
// impulse switch
|
||||
if (Command.action == GLFW_PRESS)
|
||||
{
|
||||
// visual feedback
|
||||
Train->ggOilPumpButton.UpdateValue(1.0, Train->dsbSwitch);
|
||||
Train->mvControlled->OilPumpSwitch(true);
|
||||
}
|
||||
else if (Command.action == GLFW_RELEASE)
|
||||
{
|
||||
// visual feedback
|
||||
Train->ggOilPumpButton.UpdateValue(0.0, Train->dsbSwitch);
|
||||
Train->mvControlled->OilPumpSwitch(false);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// two-state switch, only cares about press events
|
||||
if (Command.action == GLFW_PRESS)
|
||||
{
|
||||
// visual feedback
|
||||
Train->ggOilPumpButton.UpdateValue(1.0, Train->dsbSwitch);
|
||||
Train->mvControlled->OilPumpSwitch(true);
|
||||
Train->mvControlled->OilPumpSwitchOff(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_oilpumpdisable(TTrain *Train, command_data const &Command)
|
||||
{
|
||||
|
||||
if (Command.action == GLFW_REPEAT)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (Train->ggOilPumpButton.type() == TGaugeType::push)
|
||||
{
|
||||
// impulse switch
|
||||
// currently there's no disable return type switch
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
// two-state switch, only cares about press events
|
||||
if (Command.action == GLFW_PRESS)
|
||||
{
|
||||
// visual feedback
|
||||
Train->ggOilPumpButton.UpdateValue(0.0, Train->dsbSwitch);
|
||||
Train->mvControlled->OilPumpSwitch(false);
|
||||
Train->mvControlled->OilPumpSwitchOff(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_waterheaterbreakertoggle(TTrain *Train, command_data const &Command)
|
||||
{
|
||||
|
||||
if (Command.action == GLFW_PRESS)
|
||||
{
|
||||
// only reacting to press, so the switch doesn't flip back and forth if key is held down
|
||||
if (false == Train->mvControlled->WaterHeater.breaker)
|
||||
{
|
||||
// turn on
|
||||
OnCommand_waterheaterbreakerclose(Train, Command);
|
||||
}
|
||||
else
|
||||
{
|
||||
// turn off
|
||||
OnCommand_waterheaterbreakeropen(Train, Command);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_waterheaterbreakerclose(TTrain *Train, command_data const &Command)
|
||||
{
|
||||
|
||||
if (Command.action == GLFW_PRESS)
|
||||
{
|
||||
// visual feedback
|
||||
Train->ggWaterHeaterBreakerButton.UpdateValue(1.0, Train->dsbSwitch);
|
||||
|
||||
if (true == Train->mvControlled->WaterHeater.breaker)
|
||||
{
|
||||
return;
|
||||
} // already enabled
|
||||
|
||||
Train->mvControlled->WaterHeaterBreakerSwitch(true);
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_waterheaterbreakeropen(TTrain *Train, command_data const &Command)
|
||||
{
|
||||
|
||||
if (Command.action == GLFW_PRESS)
|
||||
{
|
||||
// visual feedback
|
||||
Train->ggWaterHeaterBreakerButton.UpdateValue(0.0, Train->dsbSwitch);
|
||||
|
||||
if (false == Train->mvControlled->WaterHeater.breaker)
|
||||
{
|
||||
return;
|
||||
} // already enabled
|
||||
|
||||
Train->mvControlled->WaterHeaterBreakerSwitch(false);
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_waterheatertoggle(TTrain *Train, command_data const &Command)
|
||||
{
|
||||
|
||||
if (Command.action == GLFW_PRESS)
|
||||
{
|
||||
// only reacting to press, so the switch doesn't flip back and forth if key is held down
|
||||
if (false == Train->mvControlled->WaterHeater.is_enabled)
|
||||
{
|
||||
// turn on
|
||||
OnCommand_waterheaterenable(Train, Command);
|
||||
}
|
||||
else
|
||||
{
|
||||
// turn off
|
||||
OnCommand_waterheaterdisable(Train, Command);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_waterheaterenable(TTrain *Train, command_data const &Command)
|
||||
{
|
||||
|
||||
if (Command.action == GLFW_PRESS)
|
||||
{
|
||||
// visual feedback
|
||||
Train->ggWaterHeaterButton.UpdateValue(1.0, Train->dsbSwitch);
|
||||
|
||||
if (true == Train->mvControlled->WaterHeater.is_enabled)
|
||||
{
|
||||
return;
|
||||
} // already enabled
|
||||
|
||||
Train->mvControlled->WaterHeaterSwitch(true);
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_waterheaterdisable(TTrain *Train, command_data const &Command)
|
||||
{
|
||||
|
||||
if (Command.action == GLFW_PRESS)
|
||||
{
|
||||
// visual feedback
|
||||
Train->ggWaterHeaterButton.UpdateValue(0.0, Train->dsbSwitch);
|
||||
|
||||
if (false == Train->mvControlled->WaterHeater.is_enabled)
|
||||
{
|
||||
return;
|
||||
} // already disabled
|
||||
|
||||
Train->mvControlled->WaterHeaterSwitch(false);
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_waterpumpbreakertoggle(TTrain *Train, command_data const &Command)
|
||||
{
|
||||
|
||||
if (Command.action == GLFW_PRESS)
|
||||
{
|
||||
// only reacting to press, so the switch doesn't flip back and forth if key is held down
|
||||
if (false == Train->mvControlled->WaterPump.breaker)
|
||||
{
|
||||
// turn on
|
||||
OnCommand_waterpumpbreakerclose(Train, Command);
|
||||
}
|
||||
else
|
||||
{
|
||||
// turn off
|
||||
OnCommand_waterpumpbreakeropen(Train, Command);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_waterpumpbreakerclose(TTrain *Train, command_data const &Command)
|
||||
{
|
||||
|
||||
if (Command.action == GLFW_PRESS)
|
||||
{
|
||||
// visual feedback
|
||||
Train->ggWaterPumpBreakerButton.UpdateValue(1.0, Train->dsbSwitch);
|
||||
|
||||
if (true == Train->mvControlled->WaterPump.breaker)
|
||||
{
|
||||
return;
|
||||
} // already enabled
|
||||
|
||||
Train->mvControlled->WaterPumpBreakerSwitch(true);
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_waterpumpbreakeropen(TTrain *Train, command_data const &Command)
|
||||
{
|
||||
|
||||
if (Command.action == GLFW_PRESS)
|
||||
{
|
||||
// visual feedback
|
||||
Train->ggWaterPumpBreakerButton.UpdateValue(0.0, Train->dsbSwitch);
|
||||
|
||||
if (false == Train->mvControlled->WaterPump.breaker)
|
||||
{
|
||||
return;
|
||||
} // already enabled
|
||||
|
||||
Train->mvControlled->WaterPumpBreakerSwitch(false);
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_waterpumptoggle(TTrain *Train, command_data const &Command)
|
||||
{
|
||||
|
||||
if (Command.action == GLFW_REPEAT)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (Train->ggWaterPumpButton.type() == TGaugeType::push)
|
||||
{
|
||||
// impulse switch
|
||||
// currently there's no off button so we always try to turn it on
|
||||
OnCommand_waterpumpenable(Train, Command);
|
||||
}
|
||||
else
|
||||
{
|
||||
// two-state switch
|
||||
if (Command.action == GLFW_RELEASE)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (false == Train->mvControlled->WaterPump.is_enabled)
|
||||
{
|
||||
// turn on
|
||||
OnCommand_waterpumpenable(Train, Command);
|
||||
}
|
||||
else
|
||||
{
|
||||
// turn off
|
||||
OnCommand_waterpumpdisable(Train, Command);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_waterpumpenable(TTrain *Train, command_data const &Command)
|
||||
{
|
||||
|
||||
if (Command.action == GLFW_REPEAT)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (Train->ggWaterPumpButton.type() == TGaugeType::push)
|
||||
{
|
||||
// impulse switch
|
||||
if (Command.action == GLFW_PRESS)
|
||||
{
|
||||
// visual feedback
|
||||
Train->ggWaterPumpButton.UpdateValue(1.0, Train->dsbSwitch);
|
||||
Train->mvControlled->WaterPumpSwitch(true);
|
||||
}
|
||||
else if (Command.action == GLFW_RELEASE)
|
||||
{
|
||||
// visual feedback
|
||||
Train->ggWaterPumpButton.UpdateValue(0.0, Train->dsbSwitch);
|
||||
Train->mvControlled->WaterPumpSwitch(false);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// two-state switch, only cares about press events
|
||||
if (Command.action == GLFW_PRESS)
|
||||
{
|
||||
// visual feedback
|
||||
Train->ggWaterPumpButton.UpdateValue(1.0, Train->dsbSwitch);
|
||||
Train->mvControlled->WaterPumpSwitch(true);
|
||||
Train->mvControlled->WaterPumpSwitchOff(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_waterpumpdisable(TTrain *Train, command_data const &Command)
|
||||
{
|
||||
|
||||
if (Command.action == GLFW_REPEAT)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (Train->ggWaterPumpButton.type() == TGaugeType::push)
|
||||
{
|
||||
// impulse switch
|
||||
// currently there's no disable return type switch
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
// two-state switch, only cares about press events
|
||||
if (Command.action == GLFW_PRESS)
|
||||
{
|
||||
// visual feedback
|
||||
Train->ggWaterPumpButton.UpdateValue(0.0, Train->dsbSwitch);
|
||||
Train->mvControlled->WaterPumpSwitch(false);
|
||||
Train->mvControlled->WaterPumpSwitchOff(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_watercircuitslinktoggle(TTrain *Train, command_data const &Command)
|
||||
{
|
||||
|
||||
if (Command.action == GLFW_PRESS)
|
||||
{
|
||||
// only reacting to press, so the switch doesn't flip back and forth if key is held down
|
||||
if (false == Train->mvControlled->WaterCircuitsLink)
|
||||
{
|
||||
// turn on
|
||||
OnCommand_watercircuitslinkenable(Train, Command);
|
||||
}
|
||||
else
|
||||
{
|
||||
// turn off
|
||||
OnCommand_watercircuitslinkdisable(Train, Command);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_watercircuitslinkenable(TTrain *Train, command_data const &Command)
|
||||
{
|
||||
|
||||
if (Command.action == GLFW_PRESS)
|
||||
{
|
||||
// visual feedback
|
||||
Train->ggWaterCircuitsLinkButton.UpdateValue(1.0, Train->dsbSwitch);
|
||||
|
||||
if (true == Train->mvControlled->WaterCircuitsLink)
|
||||
{
|
||||
return;
|
||||
} // already enabled
|
||||
|
||||
Train->mvControlled->WaterCircuitsLinkSwitch(true);
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_watercircuitslinkdisable(TTrain *Train, command_data const &Command)
|
||||
{
|
||||
|
||||
if (Command.action == GLFW_PRESS)
|
||||
{
|
||||
// visual feedback
|
||||
Train->ggWaterCircuitsLinkButton.UpdateValue(0.0, Train->dsbSwitch);
|
||||
|
||||
if (false == Train->mvControlled->WaterCircuitsLink)
|
||||
{
|
||||
return;
|
||||
} // already disabled
|
||||
|
||||
Train->mvControlled->WaterCircuitsLinkSwitch(false);
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_heatingtoggle(TTrain *Train, command_data const &Command)
|
||||
{
|
||||
|
||||
if (Train->ggTrainHeatingButton.SubModel == nullptr)
|
||||
{
|
||||
if (Command.action == GLFW_PRESS)
|
||||
{
|
||||
WriteLog("Train Heating switch is missing, or wasn't defined");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (Command.action == GLFW_PRESS)
|
||||
{
|
||||
// ignore repeats so the switch doesn't flip back and forth if key is held down
|
||||
if (false == Train->mvControlled->HeatingAllow)
|
||||
{
|
||||
// turn on
|
||||
OnCommand_heatingenable(Train, Command);
|
||||
}
|
||||
else
|
||||
{
|
||||
// turn off
|
||||
OnCommand_heatingdisable(Train, Command);
|
||||
}
|
||||
}
|
||||
else if (Command.action == GLFW_RELEASE && Train->ggTrainHeatingButton.type() == TGaugeType::push)
|
||||
{
|
||||
|
||||
// impulse switch
|
||||
// visual feedback
|
||||
Train->ggTrainHeatingButton.UpdateValue(0.0, Train->dsbSwitch);
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_heatingenable(TTrain *Train, command_data const &Command)
|
||||
{
|
||||
|
||||
if (Command.action == GLFW_PRESS)
|
||||
{
|
||||
|
||||
Train->mvOccupied->HeatingSwitch(true);
|
||||
// visual feedback
|
||||
Train->ggTrainHeatingButton.UpdateValue(1.0, Train->dsbSwitch);
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_heatingdisable(TTrain *Train, command_data const &Command)
|
||||
{
|
||||
|
||||
if (Command.action == GLFW_PRESS)
|
||||
{
|
||||
|
||||
Train->mvOccupied->HeatingSwitch(false);
|
||||
// visual feedback
|
||||
Train->ggTrainHeatingButton.UpdateValue(Train->ggTrainHeatingButton.type() == TGaugeType::push ? 1.0 : 0.0, Train->dsbSwitch);
|
||||
}
|
||||
}
|
||||
1108
vehicle/train/TrainCommandsBrakes.cpp
Normal file
1108
vehicle/train/TrainCommandsBrakes.cpp
Normal file
File diff suppressed because it is too large
Load Diff
838
vehicle/train/TrainCommandsControls.cpp
Normal file
838
vehicle/train/TrainCommandsControls.cpp
Normal file
@@ -0,0 +1,838 @@
|
||||
/*
|
||||
This Source Code Form is subject to the
|
||||
terms of the Mozilla Public License, v.
|
||||
2.0. If a copy of the MPL was not
|
||||
distributed with this file, You can
|
||||
obtain one at
|
||||
http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "vehicle/Train.h"
|
||||
|
||||
#include "world/Event.h"
|
||||
#include "simulation/simulationtime.h"
|
||||
#include "utilities/Logs.h"
|
||||
#include "model/Model3d.h"
|
||||
#include "vehicle/Driver.h"
|
||||
#include "vehicle/DynObj.h"
|
||||
#include <future>
|
||||
#include <algorithm>
|
||||
|
||||
auto const EU07_CONTROLLER_BASERETURNDELAY{0.5f};
|
||||
auto const EU07_CONTROLLER_KEYBOARDETURNDELAY{1.5f};
|
||||
|
||||
void TTrain::OnCommand_aidriverenable(TTrain *Train, command_data const &Command)
|
||||
{
|
||||
|
||||
if (Command.action == GLFW_PRESS)
|
||||
{
|
||||
// on press
|
||||
if (Train->DynamicObject->Mechanik == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (true == Train->DynamicObject->Mechanik->AIControllFlag)
|
||||
{
|
||||
// żeby nie trzeba było rozłączać dla zresetowania
|
||||
Train->DynamicObject->Mechanik->TakeControl(false);
|
||||
}
|
||||
Train->DynamicObject->Mechanik->TakeControl(true);
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_aidriverdisable(TTrain *Train, command_data const &Command)
|
||||
{
|
||||
|
||||
if (Command.action == GLFW_PRESS && Train->DynamicObject->Mechanik)
|
||||
{
|
||||
// on press
|
||||
Train->DynamicObject->Mechanik->TakeControl(false);
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_jointcontrollerset(TTrain *Train, command_data const &Command)
|
||||
{
|
||||
|
||||
if (Command.action != GLFW_RELEASE)
|
||||
{
|
||||
// on press or hold
|
||||
// value controls brake in range 0-0.5, master controller in range 0.5-1.0
|
||||
if (Command.param1 >= 0.5)
|
||||
{
|
||||
Train->set_master_controller((Command.param1 * 2 - 1) *
|
||||
(Train->mvControlled->CoupledCtrl ? Train->mvControlled->MainCtrlPosNo + Train->mvControlled->ScndCtrlPosNo : Train->mvControlled->MainCtrlPosNo));
|
||||
Train->m_mastercontrollerinuse = true;
|
||||
// when SplitEDPneumaticBrake is active the joint controller's negative range
|
||||
// commands the dedicated dynamic-brake lever instead of the local pneumatic brake
|
||||
if (Train->mvControlled->SplitEDPneumaticBrake)
|
||||
{
|
||||
Train->mvControlled->DynamicBrakeLevelSet(0.0);
|
||||
}
|
||||
else
|
||||
{
|
||||
Train->mvOccupied->LocalBrakePosA = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
auto const negativeRange{std::clamp(1.0 - Command.param1 * 2, 0.0, 1.0)};
|
||||
if (Train->mvControlled->SplitEDPneumaticBrake)
|
||||
{
|
||||
// negative range of jointctrl drives only ED braking, local pneumatic brake stays untouched.
|
||||
// snap to DBPN discrete stops so the lever animates step-by-step
|
||||
auto const stepCount{std::max(1, Train->mvControlled->DynamicBrakeCtrlPosNo)};
|
||||
auto const snapped{std::round(negativeRange * stepCount) / stepCount};
|
||||
Train->mvControlled->DynamicBrakeLevelSet(snapped);
|
||||
}
|
||||
else
|
||||
{
|
||||
Train->mvOccupied->LocalBrakePosA = negativeRange;
|
||||
}
|
||||
if (Train->mvControlled->MainCtrlPowerPos() > 0)
|
||||
{
|
||||
Train->set_master_controller(Train->mvControlled->MainCtrlNoPowerPos());
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// release
|
||||
Train->m_mastercontrollerinuse = false;
|
||||
Train->m_mastercontrollerreturndelay = EU07_CONTROLLER_BASERETURNDELAY; // NOTE: keyboard return delay is omitted for other input sources
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_mastercontrollerincrease(TTrain *Train, command_data const &Command)
|
||||
{
|
||||
|
||||
if (Command.action != GLFW_RELEASE)
|
||||
{
|
||||
// on press or hold
|
||||
auto const splitMode{Train->mvControlled->SplitEDPneumaticBrake};
|
||||
// when SplitEDPneumaticBrake is true the joint controller's negative range maps
|
||||
// to the dedicated dynamic-brake lever (DynamicBrakeCtrl) rather than to LocalBrake
|
||||
auto const negativeRangeActive{splitMode ? Train->mvControlled->DynamicBrakeCtrlPos > 0.0 : Train->mvOccupied->LocalBrakePosA > 0.0};
|
||||
if (Train->ggJointCtrl.SubModel != nullptr && negativeRangeActive)
|
||||
{
|
||||
if (splitMode)
|
||||
{
|
||||
OnCommand_DynamicBrakeControllerDecrease(Train, Command);
|
||||
Train->m_mastercontrollerinuse = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
OnCommand_independentbrakedecrease(Train, Command);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Train->mvControlled->IncMainCtrl(1);
|
||||
Train->m_mastercontrollerinuse = true;
|
||||
}
|
||||
}
|
||||
else if (Command.action == GLFW_RELEASE)
|
||||
{
|
||||
// release
|
||||
Train->m_mastercontrollerinuse = false;
|
||||
Train->m_mastercontrollerreturndelay = EU07_CONTROLLER_KEYBOARDETURNDELAY + EU07_CONTROLLER_BASERETURNDELAY;
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_mastercontrollerincreasefast(TTrain *Train, command_data const &Command)
|
||||
{
|
||||
|
||||
if (Command.action != GLFW_RELEASE)
|
||||
{
|
||||
// on press or hold
|
||||
auto const splitMode{Train->mvControlled->SplitEDPneumaticBrake};
|
||||
auto const negativeRangeActive{splitMode ? Train->mvControlled->DynamicBrakeCtrlPos > 0.0 : Train->mvOccupied->LocalBrakePosA > 0.0};
|
||||
if (Train->ggJointCtrl.SubModel != nullptr && negativeRangeActive)
|
||||
{
|
||||
if (splitMode)
|
||||
{
|
||||
OnCommand_DynamicBrakeControllerDecreaseFast(Train, Command);
|
||||
Train->m_mastercontrollerinuse = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
OnCommand_independentbrakedecreasefast(Train, Command);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Train->mvControlled->IncMainCtrl(Train->mvControlled->MainCtrlPosNo);
|
||||
Train->m_mastercontrollerinuse = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// release
|
||||
Train->m_mastercontrollerinuse = false;
|
||||
Train->m_mastercontrollerreturndelay = EU07_CONTROLLER_KEYBOARDETURNDELAY + EU07_CONTROLLER_BASERETURNDELAY;
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_mastercontrollerdecrease(TTrain *Train, command_data const &Command)
|
||||
{
|
||||
|
||||
if (Command.action != GLFW_RELEASE)
|
||||
{
|
||||
// on press or hold
|
||||
auto const splitMode{Train->mvControlled->SplitEDPneumaticBrake};
|
||||
if (Train->ggJointCtrl.SubModel != nullptr && Train->mvControlled->IsMainCtrlNoPowerPos())
|
||||
{
|
||||
// negative range of jointctrl: ED brake when split, otherwise pneumatic local brake
|
||||
if (splitMode)
|
||||
{
|
||||
OnCommand_DynamicBrakeControllerIncrease(Train, Command);
|
||||
Train->m_mastercontrollerinuse = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
OnCommand_independentbrakeincrease(Train, Command);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Train->mvControlled->DecMainCtrl(1);
|
||||
Train->m_mastercontrollerinuse = true;
|
||||
}
|
||||
}
|
||||
else if (Command.action == GLFW_RELEASE)
|
||||
{
|
||||
// release
|
||||
Train->m_mastercontrollerinuse = false;
|
||||
Train->m_mastercontrollerreturndelay = EU07_CONTROLLER_KEYBOARDETURNDELAY + EU07_CONTROLLER_BASERETURNDELAY;
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_mastercontrollerdecreasefast(TTrain *Train, command_data const &Command)
|
||||
{
|
||||
|
||||
if (Command.action != GLFW_RELEASE)
|
||||
{
|
||||
// on press or hold
|
||||
auto const splitMode{Train->mvControlled->SplitEDPneumaticBrake};
|
||||
if (Train->ggJointCtrl.SubModel != nullptr && Train->mvControlled->IsMainCtrlNoPowerPos())
|
||||
{
|
||||
if (splitMode)
|
||||
{
|
||||
OnCommand_DynamicBrakeControllerIncreaseFast(Train, Command);
|
||||
Train->m_mastercontrollerinuse = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
OnCommand_independentbrakeincreasefast(Train, Command);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Train->mvControlled->DecMainCtrl(Train->mvControlled->MainCtrlPowerPos());
|
||||
Train->m_mastercontrollerinuse = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// release
|
||||
Train->m_mastercontrollerinuse = false;
|
||||
Train->m_mastercontrollerreturndelay = EU07_CONTROLLER_KEYBOARDETURNDELAY + EU07_CONTROLLER_BASERETURNDELAY;
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_mastercontrollerset(TTrain *Train, command_data const &Command)
|
||||
{
|
||||
|
||||
if (Command.action != GLFW_RELEASE)
|
||||
{
|
||||
// on press or hold
|
||||
Train->set_master_controller(Command.param1);
|
||||
Train->m_mastercontrollerinuse = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// release
|
||||
Train->m_mastercontrollerinuse = false;
|
||||
Train->m_mastercontrollerreturndelay = EU07_CONTROLLER_BASERETURNDELAY; // NOTE: keyboard return delay is omitted for other input sources
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_secondcontrollerincrease(TTrain *Train, command_data const &Command)
|
||||
{
|
||||
|
||||
if (Train->mvControlled->EngineType == TEngineType::DieselElectric && true == Train->mvControlled->ShuntModeAllow && true == Train->mvControlled->ShuntMode)
|
||||
{
|
||||
if (Command.action != GLFW_RELEASE)
|
||||
{
|
||||
Train->mvControlled->AnPos = std::clamp(Train->mvControlled->AnPos + 0.025, 0.0, 1.0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// regular mode
|
||||
// push or pushtoggle control type
|
||||
if (Train->ggScndCtrl.is_push())
|
||||
{
|
||||
if (Command.action == GLFW_PRESS)
|
||||
{
|
||||
// activate on press
|
||||
Train->mvControlled->IncScndCtrl(1);
|
||||
}
|
||||
}
|
||||
// toggle control type
|
||||
else
|
||||
{
|
||||
if (Command.action != GLFW_RELEASE)
|
||||
{
|
||||
Train->mvControlled->IncScndCtrl(1);
|
||||
}
|
||||
}
|
||||
// HACK: potentially animate push or pushtoggle control
|
||||
if (Train->ggScndCtrl.is_push())
|
||||
{
|
||||
auto const activeposition{Train->ggScndCtrl.is_toggle() ? 1.f : 1.f};
|
||||
auto const neutralposition{Train->ggScndCtrl.is_toggle() ? 0.5f : 0.f};
|
||||
Train->ggScndCtrl.UpdateValue(Command.action == GLFW_RELEASE ? neutralposition : activeposition, Train->dsbSwitch);
|
||||
}
|
||||
// potentially animate tempomat button
|
||||
if (Train->ggScndCtrlButton.is_push() && Train->mvControlled->ScndCtrlPos <= 1)
|
||||
{
|
||||
Train->ggScndCtrlButton.UpdateValue(Command.action == GLFW_RELEASE ? 0.f : 1.f, Train->dsbSwitch);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_secondcontrollerincreasefast(TTrain *Train, command_data const &Command)
|
||||
{
|
||||
|
||||
if (Command.action != GLFW_RELEASE)
|
||||
{
|
||||
// on press or hold
|
||||
if (Train->mvControlled->EngineType == TEngineType::DieselElectric && true == Train->mvControlled->ShuntMode)
|
||||
{
|
||||
Train->mvControlled->AnPos = 1.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
Train->mvControlled->IncScndCtrl(2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_notchingrelaytoggle(TTrain *Train, command_data const &Command)
|
||||
{
|
||||
|
||||
if (Command.action == GLFW_PRESS)
|
||||
{
|
||||
// only reacting to press, so the switch doesn't flip back and forth if key is held down
|
||||
if (false == Train->mvOccupied->AutoRelayFlag)
|
||||
{
|
||||
// turn on
|
||||
Train->mvOccupied->AutoRelaySwitch(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
// turn off
|
||||
Train->mvOccupied->AutoRelaySwitch(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_tempomattoggle(TTrain *Train, command_data const &Command)
|
||||
{
|
||||
|
||||
if (Command.action == GLFW_REPEAT)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (Train->ggScndCtrlButton.is_push())
|
||||
{
|
||||
// impulse switch
|
||||
if (Command.action == GLFW_RELEASE)
|
||||
{
|
||||
// just move the button(s) back to default position
|
||||
// visual feedback
|
||||
Train->ggScndCtrlButton.UpdateValue(0.0, Train->dsbSwitch);
|
||||
Train->ggScndCtrlOffButton.UpdateValue(0.0, Train->dsbSwitch);
|
||||
return;
|
||||
}
|
||||
// glfw_press
|
||||
if (Train->mvControlled->ScndCtrlPos == 0)
|
||||
{
|
||||
// turn on if it's not active
|
||||
Train->mvControlled->IncScndCtrl(1);
|
||||
// visual feedback
|
||||
Train->ggScndCtrlButton.UpdateValue(1.0, Train->dsbSwitch);
|
||||
}
|
||||
else
|
||||
{
|
||||
// otherwise turn off
|
||||
Train->mvControlled->DecScndCtrl(2);
|
||||
// visual feedback
|
||||
if (Train->m_controlmapper.contains("tempomatoff_sw:"))
|
||||
{
|
||||
Train->ggScndCtrlOffButton.UpdateValue(1.0, Train->dsbSwitch);
|
||||
}
|
||||
else
|
||||
{
|
||||
Train->ggScndCtrlButton.UpdateValue(1.0, Train->dsbSwitch);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// two-state switch
|
||||
if (Command.action == GLFW_RELEASE)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (Train->mvControlled->ScndCtrlPos == 0)
|
||||
{
|
||||
// turn on
|
||||
Train->mvControlled->IncScndCtrl(1);
|
||||
// visual feedback
|
||||
Train->ggScndCtrlButton.UpdateValue(1.0, Train->dsbSwitch);
|
||||
}
|
||||
else
|
||||
{
|
||||
// turn off
|
||||
Train->mvControlled->DecScndCtrl(2);
|
||||
// visual feedback
|
||||
Train->ggScndCtrlButton.UpdateValue(0.0, Train->dsbSwitch);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
if (Train->mvOccupied->isDoubleClickForMeasureNeeded)
|
||||
{
|
||||
// handler tempomatu dla podwojnego kliku
|
||||
if (Train->trainLenghtMeasureTimer >= 0.f) // jesli zdazylismy w czasie sekundy
|
||||
Train->m_distancecounter = 0.f; // rozpoczynamy pomiar
|
||||
else
|
||||
Train->trainLenghtMeasureTimer = Train->mvOccupied->DistanceCounterDoublePressPeriod; // odpalamy zegarek od nowa
|
||||
}
|
||||
else
|
||||
{
|
||||
// dla pojedynczego kliku
|
||||
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)
|
||||
{
|
||||
if (Command.action == GLFW_PRESS)
|
||||
{
|
||||
WriteLog("Current Indicator Source switch is missing, or wasn't defined");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (Command.action == GLFW_PRESS)
|
||||
{
|
||||
// turn on
|
||||
Train->ShowNextCurrent = true;
|
||||
// visual feedback
|
||||
Train->ggNextCurrentButton.UpdateValue(1.0, Train->dsbSwitch);
|
||||
}
|
||||
else if (Command.action == GLFW_RELEASE)
|
||||
{
|
||||
// turn off
|
||||
Train->ShowNextCurrent = false;
|
||||
// visual feedback
|
||||
Train->ggNextCurrentButton.UpdateValue(0.0, Train->dsbSwitch);
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_secondcontrollerdecrease(TTrain *Train, command_data const &Command)
|
||||
{
|
||||
|
||||
if (Train->mvControlled->EngineType == TEngineType::DieselElectric && true == Train->mvControlled->ShuntMode)
|
||||
{
|
||||
if (Command.action != GLFW_RELEASE)
|
||||
{
|
||||
Train->mvControlled->AnPos = std::clamp(Train->mvControlled->AnPos - 0.025, 0.0, 1.0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// regular mode
|
||||
// push or pushtoggle control type
|
||||
if (Train->ggScndCtrl.is_push())
|
||||
{
|
||||
// basic push control can't decrease state, but pushtoggle can
|
||||
if (true == Train->ggScndCtrl.is_toggle() && Command.action == GLFW_PRESS)
|
||||
{
|
||||
// activate on press
|
||||
Train->mvControlled->DecScndCtrl(1);
|
||||
}
|
||||
}
|
||||
// toggle control type
|
||||
else
|
||||
{
|
||||
if (Command.action != GLFW_RELEASE)
|
||||
{
|
||||
Train->mvControlled->DecScndCtrl(1);
|
||||
}
|
||||
}
|
||||
// HACK: potentially animate push or pushtoggle control
|
||||
if (Train->ggScndCtrl.is_push())
|
||||
{
|
||||
auto const activeposition{Train->ggScndCtrl.is_toggle() ? 0.f : 1.f};
|
||||
auto const neutralposition{Train->ggScndCtrl.is_toggle() ? 0.5f : 0.f};
|
||||
Train->ggScndCtrl.UpdateValue(Command.action == GLFW_RELEASE ? neutralposition : activeposition, Train->dsbSwitch);
|
||||
}
|
||||
// potentially animate tempomat button
|
||||
if (Train->ggScndCtrlButton.is_push() && Train->mvControlled->ScndCtrlPos <= 1)
|
||||
{
|
||||
if (Train->m_controlmapper.contains("tempomatoff_sw:"))
|
||||
{
|
||||
Train->ggScndCtrlOffButton.UpdateValue(Command.action == GLFW_RELEASE ? 0.f : 1.f, Train->dsbSwitch);
|
||||
}
|
||||
else
|
||||
{
|
||||
Train->ggScndCtrlButton.UpdateValue(Command.action == GLFW_RELEASE ? 0.f : 1.f, Train->dsbSwitch);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_secondcontrollerdecreasefast(TTrain *Train, command_data const &Command)
|
||||
{
|
||||
|
||||
if (Command.action != GLFW_RELEASE)
|
||||
{
|
||||
// on press or hold
|
||||
if (Train->mvControlled->EngineType == TEngineType::DieselElectric && true == Train->mvControlled->ShuntMode)
|
||||
{
|
||||
Train->mvControlled->AnPos = 0.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
Train->mvControlled->DecScndCtrl(2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_secondcontrollerset(TTrain *Train, command_data const &Command)
|
||||
{
|
||||
|
||||
auto const targetposition{std::min<int>(Command.param1, Train->mvControlled->ScndCtrlPosNo)};
|
||||
// HACK: potentially animate push or pushtoggle control
|
||||
if (Train->ggScndCtrl.is_push())
|
||||
{
|
||||
auto const activeposition{Train->ggScndCtrl.is_toggle() ?
|
||||
(targetposition < Train->mvControlled->ScndCtrlPos ? 0.f :
|
||||
targetposition > Train->mvControlled->ScndCtrlPos ? 1.f :
|
||||
Train->ggScndCtrl.GetDesiredValue()) : // leave the control in its current position if it hits the limit
|
||||
targetposition == 0 ? 0.f :
|
||||
1.f};
|
||||
auto const neutralposition{Train->ggScndCtrl.is_toggle() ? 0.5f : 0.f};
|
||||
Train->ggScndCtrl.UpdateValue(Command.action == GLFW_RELEASE ? neutralposition : activeposition, Train->dsbSwitch);
|
||||
}
|
||||
// update control value
|
||||
if (Command.action != GLFW_RELEASE)
|
||||
{
|
||||
// on press or hold
|
||||
while (targetposition < Train->mvControlled->GetVirtualScndPos() && true == Train->mvControlled->DecScndCtrl(1))
|
||||
{
|
||||
// all work is done in the header
|
||||
}
|
||||
while (targetposition > Train->mvControlled->GetVirtualScndPos() && true == Train->mvControlled->IncScndCtrl(1))
|
||||
{
|
||||
// all work is done in the header
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_reverserincrease(TTrain *Train, command_data const &Command)
|
||||
{
|
||||
|
||||
if (Command.action == GLFW_PRESS)
|
||||
{
|
||||
|
||||
// HACK: master controller position isn't set in occupied vehicle in E(D)MUs
|
||||
// so we do a manual check in relevant vehicle here
|
||||
if (false == Train->mvControlled->EIMDirectionChangeAllow())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (Train->mvOccupied->DirectionForward() && Train->mvOccupied->DirActive && Train->DynamicObject->Mechanik)
|
||||
{
|
||||
// aktualizacja skrajnych pojazdów w składzie
|
||||
Train->DynamicObject->Mechanik->DirectionChange();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_reverserdecrease(TTrain *Train, command_data const &Command)
|
||||
{
|
||||
|
||||
if (Command.action == GLFW_PRESS)
|
||||
{
|
||||
|
||||
// HACK: master controller position isn't set in occupied vehicle in E(D)MUs
|
||||
// so we do a manual check in relevant vehicle here
|
||||
if (false == Train->mvControlled->EIMDirectionChangeAllow())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (Train->mvOccupied->DirectionBackward() && Train->mvOccupied->DirActive && Train->DynamicObject->Mechanik)
|
||||
{
|
||||
// aktualizacja skrajnych pojazdów w składzie
|
||||
Train->DynamicObject->Mechanik->DirectionChange();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_reverserforwardhigh(TTrain *Train, command_data const &Command)
|
||||
{
|
||||
|
||||
if (Command.action == GLFW_PRESS)
|
||||
{
|
||||
|
||||
// HACK: master controller position isn't set in occupied vehicle in E(D)MUs
|
||||
// so we do a manual check in relevant vehicle here
|
||||
if (false == Train->mvControlled->EIMDirectionChangeAllow())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// HACK: try to move the reverser one position back, in case it's set to "high forward"
|
||||
OnCommand_reverserdecrease(Train, Command);
|
||||
|
||||
if (Train->mvOccupied->DirActive < 1)
|
||||
{
|
||||
|
||||
while (Train->mvOccupied->DirActive < 1 && true == Train->mvOccupied->DirectionForward())
|
||||
{
|
||||
// all work is done in the header
|
||||
}
|
||||
// aktualizacja skrajnych pojazdów w składzie
|
||||
if (Train->mvOccupied->DirActive == 1 && Train->DynamicObject->Mechanik)
|
||||
{
|
||||
|
||||
Train->DynamicObject->Mechanik->DirectionChange();
|
||||
}
|
||||
}
|
||||
OnCommand_reverserincrease(Train, Command);
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_reverserforward(TTrain *Train, command_data const &Command)
|
||||
{
|
||||
|
||||
if (Command.action == GLFW_PRESS)
|
||||
{
|
||||
|
||||
// HACK: master controller position isn't set in occupied vehicle in E(D)MUs
|
||||
// so we do a manual check in relevant vehicle here
|
||||
if (false == Train->mvControlled->EIMDirectionChangeAllow())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// HACK: try to move the reverser one position back, in case it's set to "high forward"
|
||||
// OnCommand_reverserdecrease( Train, Command );
|
||||
// visual feedback
|
||||
Train->ggDirForwardButton.UpdateValue(1.0, Train->dsbSwitch);
|
||||
|
||||
if (Train->mvOccupied->DirActive == 0)
|
||||
{
|
||||
|
||||
while (Train->mvOccupied->DirActive < 1 && true == Train->mvOccupied->DirectionForward())
|
||||
{
|
||||
// all work is done in the header
|
||||
}
|
||||
// aktualizacja skrajnych pojazdów w składzie
|
||||
if (Train->mvOccupied->DirActive == 1 && Train->DynamicObject->Mechanik)
|
||||
{
|
||||
|
||||
Train->DynamicObject->Mechanik->DirectionChange();
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (Command.action == GLFW_RELEASE)
|
||||
{
|
||||
// release
|
||||
// visual feedback
|
||||
Train->ggDirForwardButton.UpdateValue(0.0, Train->dsbSwitch);
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_reverserneutral(TTrain *Train, command_data const &Command)
|
||||
{
|
||||
|
||||
if (Command.action == GLFW_PRESS)
|
||||
{
|
||||
|
||||
// HACK: master controller position isn't set in occupied vehicle in E(D)MUs
|
||||
// so we do a manual check in relevant vehicle here
|
||||
if (false == Train->mvControlled->EIMDirectionChangeAllow())
|
||||
{
|
||||
return;
|
||||
}
|
||||
// visual feedback
|
||||
Train->ggDirNeutralButton.UpdateValue(1.0, Train->dsbSwitch);
|
||||
while (Train->mvOccupied->DirActive < 0 && true == Train->mvOccupied->DirectionForward())
|
||||
{
|
||||
// all work is done in the header
|
||||
}
|
||||
while (Train->mvOccupied->DirActive > 0 && true == Train->mvOccupied->DirectionBackward())
|
||||
{
|
||||
// all work is done in the header
|
||||
}
|
||||
}
|
||||
else if (Command.action == GLFW_RELEASE)
|
||||
{
|
||||
// release
|
||||
// visual feedback
|
||||
Train->ggDirNeutralButton.UpdateValue(0.0, Train->dsbSwitch);
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_reverserbackward(TTrain *Train, command_data const &Command)
|
||||
{
|
||||
|
||||
if (Command.action == GLFW_PRESS)
|
||||
{
|
||||
|
||||
// HACK: master controller position isn't set in occupied vehicle in E(D)MUs
|
||||
// so we do a manual check in relevant vehicle here
|
||||
if (false == Train->mvControlled->EIMDirectionChangeAllow())
|
||||
{
|
||||
return;
|
||||
}
|
||||
Train->ggDirBackwardButton.UpdateValue(1.0, Train->dsbSwitch);
|
||||
if (Train->mvOccupied->DirActive == 0)
|
||||
{
|
||||
|
||||
while (Train->mvOccupied->DirActive > -1 && true == Train->mvOccupied->DirectionBackward())
|
||||
{
|
||||
// all work is done in the header
|
||||
}
|
||||
// aktualizacja skrajnych pojazdów w składzie
|
||||
if (Train->mvOccupied->DirActive == -1 && Train->DynamicObject->Mechanik)
|
||||
{
|
||||
|
||||
Train->DynamicObject->Mechanik->DirectionChange();
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (Command.action == GLFW_RELEASE)
|
||||
{
|
||||
// release
|
||||
// visual feedback
|
||||
Train->ggDirBackwardButton.UpdateValue(0.0, Train->dsbSwitch);
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_speedcontrolincrease(TTrain *Train, command_data const &Command)
|
||||
{
|
||||
if (Command.action == GLFW_PRESS)
|
||||
{
|
||||
// only reacting to press, so the switch doesn't flip back and forth if key is held down
|
||||
Train->mvOccupied->SpeedCtrlInc();
|
||||
// visual feedback
|
||||
Train->ggSpeedControlIncreaseButton.UpdateValue(1.0, Train->dsbSwitch);
|
||||
}
|
||||
else if (Command.action == GLFW_RELEASE)
|
||||
{
|
||||
// release
|
||||
// visual feedback
|
||||
Train->ggSpeedControlIncreaseButton.UpdateValue(0.0, Train->dsbSwitch);
|
||||
}
|
||||
};
|
||||
|
||||
void TTrain::OnCommand_speedcontroldecrease(TTrain *Train, command_data const &Command)
|
||||
{
|
||||
if (Command.action == GLFW_PRESS)
|
||||
{
|
||||
// only reacting to press, so the switch doesn't flip back and forth if key is held down
|
||||
Train->mvOccupied->SpeedCtrlDec();
|
||||
// visual feedback
|
||||
Train->ggSpeedControlDecreaseButton.UpdateValue(1.0, Train->dsbSwitch);
|
||||
}
|
||||
else if (Command.action == GLFW_RELEASE)
|
||||
{
|
||||
// release
|
||||
// visual feedback
|
||||
Train->ggSpeedControlDecreaseButton.UpdateValue(0.0, Train->dsbSwitch);
|
||||
}
|
||||
};
|
||||
|
||||
void TTrain::OnCommand_speedcontrolpowerincrease(TTrain *Train, command_data const &Command)
|
||||
{
|
||||
if (Command.action == GLFW_PRESS)
|
||||
{
|
||||
// only reacting to press, so the switch doesn't flip back and forth if key is held down
|
||||
Train->mvOccupied->SpeedCtrlPowerInc();
|
||||
// visual feedback
|
||||
Train->ggSpeedControlPowerIncreaseButton.UpdateValue(1.0, Train->dsbSwitch);
|
||||
}
|
||||
else if (Command.action == GLFW_RELEASE)
|
||||
{
|
||||
// release
|
||||
// visual feedback
|
||||
Train->ggSpeedControlPowerIncreaseButton.UpdateValue(0.0, Train->dsbSwitch);
|
||||
}
|
||||
};
|
||||
|
||||
void TTrain::OnCommand_speedcontrolpowerdecrease(TTrain *Train, command_data const &Command)
|
||||
{
|
||||
if (Command.action == GLFW_PRESS)
|
||||
{
|
||||
// only reacting to press, so the switch doesn't flip back and forth if key is held down
|
||||
Train->mvOccupied->SpeedCtrlPowerDec();
|
||||
// visual feedback
|
||||
Train->ggSpeedControlPowerDecreaseButton.UpdateValue(1.0, Train->dsbSwitch);
|
||||
}
|
||||
else if (Command.action == GLFW_RELEASE)
|
||||
{
|
||||
// release
|
||||
// visual feedback
|
||||
Train->ggSpeedControlPowerDecreaseButton.UpdateValue(0.0, Train->dsbSwitch);
|
||||
}
|
||||
};
|
||||
|
||||
void TTrain::OnCommand_speedcontrolbutton(TTrain *Train, command_data const &Command)
|
||||
{
|
||||
|
||||
auto const itemindex = static_cast<int>(Command.command) - static_cast<int>(user_command::speedcontrolbutton0);
|
||||
auto &item = Train->ggSpeedCtrlButtons[itemindex];
|
||||
|
||||
if (Command.action == GLFW_PRESS)
|
||||
{
|
||||
// only reacting to press, so the switch doesn't flip back and forth if key is held down
|
||||
Train->mvOccupied->SpeedCtrlButton(itemindex);
|
||||
// visual feedback
|
||||
Train->ggSpeedCtrlButtons[itemindex].UpdateValue(1.0, Train->dsbSwitch);
|
||||
}
|
||||
else if (Command.action == GLFW_RELEASE)
|
||||
{
|
||||
// release
|
||||
// visual feedback
|
||||
Train->ggSpeedCtrlButtons[itemindex].UpdateValue(0.0, Train->dsbSwitch);
|
||||
}
|
||||
};
|
||||
851
vehicle/train/TrainCommandsDoors.cpp
Normal file
851
vehicle/train/TrainCommandsDoors.cpp
Normal file
@@ -0,0 +1,851 @@
|
||||
/*
|
||||
This Source Code Form is subject to the
|
||||
terms of the Mozilla Public License, v.
|
||||
2.0. If a copy of the MPL was not
|
||||
distributed with this file, You can
|
||||
obtain one at
|
||||
http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "vehicle/Train.h"
|
||||
|
||||
#include "simulation/simulation.h"
|
||||
#include "world/Event.h"
|
||||
#include "simulation/simulationtime.h"
|
||||
#include "utilities/Logs.h"
|
||||
#include "model/Model3d.h"
|
||||
#include "vehicle/Driver.h"
|
||||
#include "vehicle/DynObj.h"
|
||||
#include "rendering/renderer.h"
|
||||
#include <future>
|
||||
|
||||
void TTrain::OnCommand_doorlocktoggle(TTrain *Train, command_data const &Command)
|
||||
{
|
||||
|
||||
if (Train->ggDoorSignallingButton.SubModel == nullptr)
|
||||
{
|
||||
if (Command.action == GLFW_PRESS)
|
||||
{
|
||||
WriteLog("Door Lock switch is missing, or wasn't defined");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (Command.action == GLFW_PRESS)
|
||||
{
|
||||
// only reacting to press, so the sound can loop uninterrupted
|
||||
if (false == Train->mvOccupied->Doors.lock_enabled)
|
||||
{
|
||||
// turn on
|
||||
// TODO: door lock command to send through consist
|
||||
Train->mvOccupied->LockDoors(true);
|
||||
// visual feedback
|
||||
Train->ggDoorSignallingButton.UpdateValue(1.0, Train->dsbSwitch);
|
||||
}
|
||||
else
|
||||
{
|
||||
// turn off
|
||||
// TODO: door lock command to send through consist
|
||||
Train->mvOccupied->LockDoors(false);
|
||||
// visual feedback
|
||||
Train->ggDoorSignallingButton.UpdateValue(0.0, Train->dsbSwitch);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_doortoggleleft(TTrain *Train, command_data const &Command)
|
||||
{
|
||||
|
||||
if (Command.action == GLFW_PRESS)
|
||||
{
|
||||
// NOTE: test how the door state check works with consists where the occupied vehicle doesn't have opening doors
|
||||
if (false == (Train->ggDoorLeftButton.GetDesiredValue() > 0.5 || Train->ggDoorLeftOnButton.GetDesiredValue() > 0.5))
|
||||
{
|
||||
// open
|
||||
OnCommand_dooropenleft(Train, Command);
|
||||
}
|
||||
else
|
||||
{
|
||||
// close
|
||||
if (Train->ggDoorAllOffButton.SubModel != nullptr && Train->ggDoorLeftOffButton.SubModel == nullptr)
|
||||
{
|
||||
// OnCommand_doorcloseall( Train, Command );
|
||||
// if two-button setup lacks dedicated closing button require the user to press appropriate button manually
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
OnCommand_doorcloseleft(Train, Command);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (Command.action == GLFW_RELEASE)
|
||||
{
|
||||
|
||||
if (true == (Train->ggDoorLeftButton.GetDesiredValue() > 0.5 || Train->ggDoorLeftOnButton.GetDesiredValue() > 0.5))
|
||||
{
|
||||
// open
|
||||
if (Train->mvOccupied->Doors.has_autowarning && Train->mvOccupied->DepartureSignal)
|
||||
{
|
||||
// complete closing the doors
|
||||
if (Train->ggDoorAllOffButton.SubModel != nullptr && Train->ggDoorLeftOffButton.SubModel == nullptr)
|
||||
{
|
||||
// OnCommand_doorcloseall( Train, Command );
|
||||
// if two-button setup lacks dedicated closing button require the user to press appropriate button manually
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
OnCommand_doorcloseleft(Train, Command);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
OnCommand_dooropenleft(Train, Command);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// close
|
||||
if (Train->ggDoorAllOffButton.SubModel != nullptr && Train->ggDoorLeftOffButton.SubModel == nullptr)
|
||||
{
|
||||
// OnCommand_doorcloseall( Train, Command );
|
||||
// if two-button setup lacks dedicated closing button require the user to press appropriate button manually
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
OnCommand_doorcloseleft(Train, Command);
|
||||
}
|
||||
}
|
||||
// visual feedback
|
||||
// dedicated closing buttons are presumed to be impulse switches and return automatically to neutral position
|
||||
// NOTE: temporary arrangement, can be removed when LD system is in place
|
||||
if (Train->ggDoorLeftOffButton.SubModel)
|
||||
Train->ggDoorLeftOffButton.UpdateValue(0.0, Train->dsbSwitch);
|
||||
if (Train->ggDoorLeftOnButton.SubModel)
|
||||
Train->ggDoorLeftOnButton.UpdateValue(0.0, Train->dsbSwitch);
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_doorpermitleft(TTrain *Train, command_data const &Command)
|
||||
{
|
||||
|
||||
if (Command.action == GLFW_REPEAT)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (false == Train->mvOccupied->Doors.permit_presets.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
auto const side{(Train->cab_to_end() == end::front ? side::left : side::right)};
|
||||
|
||||
if (Command.action == GLFW_PRESS)
|
||||
{
|
||||
|
||||
if (Train->ggDoorLeftPermitButton.is_push())
|
||||
{
|
||||
// impulse switch
|
||||
Train->mvOccupied->PermitDoors(side);
|
||||
// visual feedback
|
||||
Train->ggDoorLeftPermitButton.UpdateValue(1.0, Train->dsbSwitch);
|
||||
// start potential timer for remote door control
|
||||
Train->m_doorpermittimers[side] = Train->mvOccupied->DoorsOpenWithPermitAfter;
|
||||
}
|
||||
else
|
||||
{
|
||||
// two-state switch
|
||||
auto const newstate{!(Train->ggDoorLeftPermitButton.GetDesiredValue() > 0.5)};
|
||||
|
||||
Train->mvOccupied->PermitDoors(side, newstate);
|
||||
// visual feedback
|
||||
Train->ggDoorLeftPermitButton.UpdateValue(newstate ? 1.0 : 0.0, Train->dsbSwitch);
|
||||
}
|
||||
}
|
||||
else if (Command.action == GLFW_RELEASE && Train->ggDoorLeftPermitButton.is_push())
|
||||
{
|
||||
|
||||
// impulse switch
|
||||
// visual feedback
|
||||
Train->ggDoorLeftPermitButton.UpdateValue(0.0, Train->dsbSwitch);
|
||||
// reset potential remote door control timer
|
||||
Train->m_doorpermittimers[side] = -1.f;
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_doorpermitright(TTrain *Train, command_data const &Command)
|
||||
{
|
||||
|
||||
if (Command.action == GLFW_REPEAT)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (false == Train->mvOccupied->Doors.permit_presets.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
auto const side{(Train->cab_to_end() == end::front ? side::right : side::left)};
|
||||
|
||||
if (Command.action == GLFW_PRESS)
|
||||
{
|
||||
|
||||
if (Train->ggDoorRightPermitButton.type() == TGaugeType::push)
|
||||
{
|
||||
// impulse switch
|
||||
Train->mvOccupied->PermitDoors(side);
|
||||
// visual feedback
|
||||
Train->ggDoorRightPermitButton.UpdateValue(1.0, Train->dsbSwitch);
|
||||
// start potential timer for remote door control
|
||||
Train->m_doorpermittimers[side] = Train->mvOccupied->DoorsOpenWithPermitAfter;
|
||||
}
|
||||
else
|
||||
{
|
||||
// two-state switch
|
||||
auto const newstate{!(Train->ggDoorRightPermitButton.GetDesiredValue() > 0.5)};
|
||||
|
||||
Train->mvOccupied->PermitDoors(side, newstate);
|
||||
// visual feedback
|
||||
Train->ggDoorRightPermitButton.UpdateValue(newstate ? 1.0 : 0.0, Train->dsbSwitch);
|
||||
}
|
||||
}
|
||||
else if (Command.action == GLFW_RELEASE && Train->ggDoorRightPermitButton.type() == TGaugeType::push)
|
||||
{
|
||||
|
||||
// impulse switch
|
||||
// visual feedback
|
||||
Train->ggDoorRightPermitButton.UpdateValue(0.0, Train->dsbSwitch);
|
||||
// reset potential remote door control timer
|
||||
Train->m_doorpermittimers[side] = -1.f;
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_doorpermitpresetactivatenext(TTrain *Train, command_data const &Command)
|
||||
{
|
||||
|
||||
if (Command.action == GLFW_PRESS)
|
||||
{
|
||||
|
||||
Train->mvOccupied->ChangeDoorPermitPreset(1);
|
||||
// visual feedback
|
||||
Train->ggDoorPermitPresetButton.UpdateValue(Train->mvOccupied->Doors.permit_preset, Train->dsbSwitch);
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_doorpermitpresetactivateprevious(TTrain *Train, command_data const &Command)
|
||||
{
|
||||
|
||||
if (Command.action == GLFW_PRESS)
|
||||
{
|
||||
|
||||
Train->mvOccupied->ChangeDoorPermitPreset(-1);
|
||||
// visual feedback
|
||||
Train->ggDoorPermitPresetButton.UpdateValue(Train->mvOccupied->Doors.permit_preset, Train->dsbSwitch);
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_dooropenleft(TTrain *Train, command_data const &Command)
|
||||
{
|
||||
|
||||
auto const remoteopencontrol{Train->mvOccupied->Doors.open_control == control_t::driver || Train->mvOccupied->Doors.open_control == control_t::mixed};
|
||||
|
||||
if (false == remoteopencontrol)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (Train->ggDoorLeftOnButton.SubModel == nullptr && Train->ggDoorLeftButton.SubModel == nullptr)
|
||||
{
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (Command.action == GLFW_PRESS)
|
||||
{
|
||||
Train->mvOccupied->OperateDoors(Train->cab_to_end() == end::front ? side::left : side::right, true);
|
||||
// visual feedback
|
||||
if (Train->ggDoorLeftOnButton.SubModel != nullptr)
|
||||
{
|
||||
// two separate impulse switches
|
||||
Train->ggDoorLeftOnButton.UpdateValue(1.0, Train->dsbSwitch);
|
||||
}
|
||||
else
|
||||
{
|
||||
// single two-state switch
|
||||
Train->ggDoorLeftButton.UpdateValue(1.0, Train->dsbSwitch);
|
||||
}
|
||||
}
|
||||
else if (Command.action == GLFW_RELEASE && Train->ggDoorLeftOnButton.SubModel != nullptr)
|
||||
{
|
||||
// visual feedback
|
||||
// two separate impulse switches
|
||||
Train->ggDoorLeftOnButton.UpdateValue(0.0, Train->dsbSwitch);
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_doorcloseleft(TTrain *Train, command_data const &Command)
|
||||
{
|
||||
|
||||
auto const remoteclosecontrol{Train->mvOccupied->Doors.close_control == control_t::driver || Train->mvOccupied->Doors.close_control == control_t::mixed};
|
||||
|
||||
if (false == remoteclosecontrol)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (Train->ggDoorLeftOffButton.SubModel == nullptr && Train->ggDoorLeftButton.SubModel == nullptr)
|
||||
{
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (Command.action == GLFW_PRESS)
|
||||
{
|
||||
|
||||
if (Train->mvOccupied->Doors.has_autowarning)
|
||||
{
|
||||
// automatic departure signal delays actual door closing until the button is released
|
||||
Train->mvOccupied->signal_departure(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO: move door opening/closing to the update, so the switch animation doesn't hinge on door working
|
||||
Train->mvOccupied->OperateDoors(Train->cab_to_end() == end::front ? side::left : side::right, false);
|
||||
}
|
||||
// visual feedback
|
||||
if (Train->ggDoorLeftOffButton.SubModel != nullptr)
|
||||
{
|
||||
// two separate switches to open and close the door
|
||||
Train->ggDoorLeftOffButton.UpdateValue(1.0, Train->dsbSwitch);
|
||||
}
|
||||
else
|
||||
{
|
||||
// single two-state switch
|
||||
Train->ggDoorLeftButton.UpdateValue(0.0, Train->dsbSwitch);
|
||||
}
|
||||
}
|
||||
else if (Command.action == GLFW_RELEASE)
|
||||
{
|
||||
|
||||
if (Train->mvOccupied->Doors.has_autowarning)
|
||||
{
|
||||
// automatic departure signal delays actual door closing until the button is released
|
||||
Train->mvOccupied->signal_departure(false);
|
||||
// now we can actually close the door
|
||||
Train->mvOccupied->OperateDoors(Train->cab_to_end() == end::front ? side::left : side::right, false);
|
||||
}
|
||||
// visual feedback
|
||||
// dedicated closing buttons are presumed to be impulse switches and return automatically to neutral position
|
||||
if (Train->ggDoorLeftOffButton.SubModel)
|
||||
Train->ggDoorLeftOffButton.UpdateValue(0.0, Train->dsbSwitch);
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_doortoggleright(TTrain *Train, command_data const &Command)
|
||||
{
|
||||
|
||||
if (Command.action == GLFW_PRESS)
|
||||
{
|
||||
// NOTE: test how the door state check works with consists where the occupied vehicle doesn't have opening doors
|
||||
if (false == (Train->ggDoorRightButton.GetDesiredValue() > 0.5 || Train->ggDoorRightOnButton.GetDesiredValue() > 0.5))
|
||||
{
|
||||
// open
|
||||
OnCommand_dooropenright(Train, Command);
|
||||
}
|
||||
else
|
||||
{
|
||||
// close
|
||||
if (Train->ggDoorAllOffButton.SubModel != nullptr && Train->ggDoorRightOffButton.SubModel == nullptr)
|
||||
{
|
||||
// OnCommand_doorcloseall( Train, Command );
|
||||
// if two-button setup lacks dedicated closing button require the user to press appropriate button manually
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
OnCommand_doorcloseright(Train, Command);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (Command.action == GLFW_RELEASE)
|
||||
{
|
||||
|
||||
if (true == (Train->ggDoorRightButton.GetDesiredValue() > 0.5 || Train->ggDoorRightOnButton.GetDesiredValue() > 0.5))
|
||||
{
|
||||
// open
|
||||
if (Train->mvOccupied->Doors.has_autowarning && Train->mvOccupied->DepartureSignal)
|
||||
{
|
||||
// complete closing the doors
|
||||
if (Train->ggDoorAllOffButton.SubModel != nullptr && Train->ggDoorRightOffButton.SubModel == nullptr)
|
||||
{
|
||||
// OnCommand_doorcloseall( Train, Command );
|
||||
// if two-button setup lacks dedicated closing button require the user to press appropriate button manually
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
OnCommand_doorcloseright(Train, Command);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
OnCommand_dooropenright(Train, Command);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// close
|
||||
if (Train->ggDoorAllOffButton.SubModel != nullptr && Train->ggDoorRightOffButton.SubModel == nullptr)
|
||||
{
|
||||
// OnCommand_doorcloseall( Train, Command );
|
||||
// if two-button setup lacks dedicated closing button require the user to press appropriate button manually
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
OnCommand_doorcloseright(Train, Command);
|
||||
}
|
||||
}
|
||||
// visual feedback
|
||||
// dedicated closing buttons are presumed to be impulse switches and return automatically to neutral position
|
||||
// NOTE: temporary arrangement, can be removed when LD system is in place
|
||||
if (Train->ggDoorRightOffButton.SubModel)
|
||||
Train->ggDoorRightOffButton.UpdateValue(0.0, Train->dsbSwitch);
|
||||
if (Train->ggDoorRightOnButton.SubModel)
|
||||
Train->ggDoorRightOnButton.UpdateValue(0.0, Train->dsbSwitch);
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_dooropenright(TTrain *Train, command_data const &Command)
|
||||
{
|
||||
|
||||
auto const remoteopencontrol{Train->mvOccupied->Doors.open_control == control_t::driver || Train->mvOccupied->Doors.open_control == control_t::mixed};
|
||||
|
||||
if (false == remoteopencontrol)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (Train->ggDoorRightOnButton.SubModel == nullptr && Train->ggDoorRightButton.SubModel == nullptr)
|
||||
{
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (Command.action == GLFW_PRESS)
|
||||
{
|
||||
|
||||
Train->mvOccupied->OperateDoors(Train->cab_to_end() == end::front ? side::right : side::left, true);
|
||||
// visual feedback
|
||||
if (Train->ggDoorRightOnButton.SubModel != nullptr)
|
||||
{
|
||||
// two separate impulse switches
|
||||
Train->ggDoorRightOnButton.UpdateValue(1.0, Train->dsbSwitch);
|
||||
}
|
||||
else
|
||||
{
|
||||
// single two-state switch
|
||||
Train->ggDoorRightButton.UpdateValue(1.0, Train->dsbSwitch);
|
||||
}
|
||||
}
|
||||
else if (Command.action == GLFW_RELEASE && Train->ggDoorRightOnButton.SubModel != nullptr)
|
||||
{
|
||||
// visual feedback
|
||||
// two separate impulse switches
|
||||
Train->ggDoorRightOnButton.UpdateValue(0.0, Train->dsbSwitch);
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_doorcloseright(TTrain *Train, command_data const &Command)
|
||||
{
|
||||
|
||||
auto const remoteclosecontrol{Train->mvOccupied->Doors.close_control == control_t::driver || Train->mvOccupied->Doors.close_control == control_t::mixed};
|
||||
|
||||
if (false == remoteclosecontrol)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (Train->ggDoorRightOffButton.SubModel == nullptr && Train->ggDoorRightButton.SubModel == nullptr)
|
||||
{
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (Command.action == GLFW_PRESS)
|
||||
{
|
||||
|
||||
if (Train->mvOccupied->Doors.has_autowarning)
|
||||
{
|
||||
// automatic departure signal delays actual door closing until the button is released
|
||||
Train->mvOccupied->signal_departure(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
Train->mvOccupied->OperateDoors(Train->cab_to_end() == end::front ? side::right : side::left, false);
|
||||
}
|
||||
// visual feedback
|
||||
if (Train->ggDoorRightOffButton.SubModel != nullptr)
|
||||
{
|
||||
// two separate switches to open and close the door
|
||||
Train->ggDoorRightOffButton.UpdateValue(1.0, Train->dsbSwitch);
|
||||
}
|
||||
else
|
||||
{
|
||||
// single two-state switch
|
||||
Train->ggDoorRightButton.UpdateValue(0.0, Train->dsbSwitch);
|
||||
}
|
||||
}
|
||||
else if (Command.action == GLFW_RELEASE)
|
||||
{
|
||||
|
||||
if (Train->mvOccupied->Doors.has_autowarning)
|
||||
{
|
||||
// automatic departure signal delays actual door closing until the button is released
|
||||
Train->mvOccupied->signal_departure(false);
|
||||
// now we can actually close the door
|
||||
Train->mvOccupied->OperateDoors(Train->cab_to_end() == end::front ? side::right : side::left, false);
|
||||
}
|
||||
// visual feedback
|
||||
// dedicated closing buttons are presumed to be impulse switches and return automatically to neutral position
|
||||
if (Train->ggDoorRightOffButton.SubModel)
|
||||
Train->ggDoorRightOffButton.UpdateValue(0.0, Train->dsbSwitch);
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_dooropenall(TTrain *Train, command_data const &Command)
|
||||
{
|
||||
|
||||
auto const remoteopencontrol{Train->mvOccupied->Doors.open_control == control_t::driver || Train->mvOccupied->Doors.open_control == control_t::mixed};
|
||||
|
||||
if (false == remoteopencontrol)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (Train->ggDoorAllOnButton.SubModel == nullptr)
|
||||
{
|
||||
// TODO: expand definition of cab controls so we can know if the control is present without testing for presence of 3d switch
|
||||
if (Command.action == GLFW_PRESS)
|
||||
{
|
||||
WriteLog("Open All Doors switch is missing, or wasn't defined");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (Command.action == GLFW_PRESS)
|
||||
{
|
||||
|
||||
Train->mvOccupied->OperateDoors(side::right, true);
|
||||
Train->mvOccupied->OperateDoors(side::left, true);
|
||||
// visual feedback
|
||||
Train->ggDoorAllOnButton.UpdateValue(1.0, Train->dsbSwitch);
|
||||
}
|
||||
else if (Command.action == GLFW_RELEASE)
|
||||
{
|
||||
// visual feedback
|
||||
Train->ggDoorAllOnButton.UpdateValue(0.0);
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_doorcloseall(TTrain *Train, command_data const &Command)
|
||||
{
|
||||
|
||||
auto const remoteclosecontrol{Train->mvOccupied->Doors.close_control == control_t::driver || Train->mvOccupied->Doors.close_control == control_t::mixed};
|
||||
|
||||
if (false == remoteclosecontrol)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (Train->ggDoorAllOffButton.SubModel == nullptr)
|
||||
{
|
||||
// TODO: expand definition of cab controls so we can know if the control is present without testing for presence of 3d switch
|
||||
if (Command.action == GLFW_PRESS)
|
||||
{
|
||||
WriteLog("Close All Doors switch is missing, or wasn't defined");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (Command.action == GLFW_PRESS)
|
||||
{
|
||||
|
||||
if (Train->mvOccupied->Doors.has_autowarning)
|
||||
{
|
||||
Train->mvOccupied->signal_departure(true);
|
||||
}
|
||||
if (Train->ggDoorAllOffButton.type() != TGaugeType::push_delayed)
|
||||
{
|
||||
// delays the action until the button is released
|
||||
Train->mvOccupied->OperateDoors(side::right, false);
|
||||
Train->mvOccupied->OperateDoors(side::left, false);
|
||||
}
|
||||
// visual feedback
|
||||
Train->ggDoorLeftButton.UpdateValue(0.0, Train->dsbSwitch);
|
||||
Train->ggDoorRightButton.UpdateValue(0.0, Train->dsbSwitch);
|
||||
if (Train->ggDoorAllOffButton.SubModel)
|
||||
Train->ggDoorAllOffButton.UpdateValue(1.0, Train->dsbSwitch);
|
||||
}
|
||||
else if (Command.action == GLFW_RELEASE)
|
||||
{
|
||||
if (Train->mvOccupied->Doors.has_autowarning)
|
||||
{
|
||||
Train->mvOccupied->signal_departure(false);
|
||||
}
|
||||
if (Train->ggDoorAllOffButton.type() == TGaugeType::push_delayed)
|
||||
{
|
||||
// now we can actually close the door
|
||||
Train->mvOccupied->OperateDoors(side::right, false);
|
||||
Train->mvOccupied->OperateDoors(side::left, false);
|
||||
}
|
||||
// visual feedback
|
||||
if (Train->ggDoorAllOffButton.SubModel)
|
||||
Train->ggDoorAllOffButton.UpdateValue(0.0);
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_doorsteptoggle(TTrain *Train, command_data const &Command)
|
||||
{
|
||||
// TODO: move logic/visualization code to the gauge, on_command() should return hint whether it should invoke a reaction
|
||||
if (Command.action == GLFW_PRESS)
|
||||
{
|
||||
// effect
|
||||
if (false == Train->ggDoorStepButton.is_delayed())
|
||||
{
|
||||
Train->mvOccupied->PermitDoorStep(false == Train->mvOccupied->Doors.step_enabled);
|
||||
}
|
||||
// visual feedback
|
||||
auto const isactive{(Train->ggDoorStepButton.is_push() // always press push button
|
||||
|| Train->mvOccupied->Doors.step_enabled)}; // for toggle buttons indicate item state
|
||||
Train->ggDoorStepButton.UpdateValue(isactive ? 1 : 0);
|
||||
}
|
||||
else if (Command.action == GLFW_RELEASE)
|
||||
{
|
||||
// effect
|
||||
if (Train->ggDoorStepButton.is_delayed())
|
||||
{
|
||||
Train->mvOccupied->PermitDoorStep(false == Train->mvOccupied->Doors.step_enabled);
|
||||
}
|
||||
// visual feedback
|
||||
if (Train->ggDoorStepButton.is_push())
|
||||
{
|
||||
Train->ggDoorStepButton.UpdateValue(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_doormodetoggle(TTrain *Train, command_data const &Command)
|
||||
{
|
||||
|
||||
if (Command.action == GLFW_PRESS)
|
||||
{
|
||||
Train->mvOccupied->ChangeDoorControlMode(false == Train->mvOccupied->Doors.remote_only);
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_mirrorstoggle(TTrain *Train, command_data const &Command)
|
||||
{
|
||||
|
||||
if (Command.action != GLFW_PRESS)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// only reacting to press, so the sound can loop uninterrupted
|
||||
if (false == Train->mvOccupied->MirrorForbidden)
|
||||
{
|
||||
// turn on
|
||||
Train->mvOccupied->MirrorForbidden = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// turn off
|
||||
Train->mvOccupied->MirrorForbidden = false;
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_nearestcarcouplingincrease(TTrain *Train, command_data const &Command)
|
||||
{
|
||||
|
||||
if (true == Command.freefly && Command.action == GLFW_PRESS)
|
||||
{
|
||||
// tryb freefly, press only
|
||||
auto coupler{-1};
|
||||
auto *vehicle{Train->DynamicObject->ABuScanNearestObject(Command.location, Train->DynamicObject->GetTrack(), 1, 1500, coupler)};
|
||||
if (vehicle == nullptr)
|
||||
vehicle = Train->DynamicObject->ABuScanNearestObject(Command.location, Train->DynamicObject->GetTrack(), -1, 1500, coupler);
|
||||
|
||||
if (coupler != -1 && vehicle != nullptr)
|
||||
{
|
||||
|
||||
vehicle->couple(coupler);
|
||||
}
|
||||
if (Train->DynamicObject->Mechanik)
|
||||
{
|
||||
// aktualizacja flag kierunku w składzie
|
||||
Train->DynamicObject->Mechanik->CheckVehicles(Connect);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_nearestcarcouplingdisconnect(TTrain *Train, command_data const &Command)
|
||||
{
|
||||
|
||||
if (true == Command.freefly && Command.action == GLFW_PRESS)
|
||||
{
|
||||
// tryb freefly, press only
|
||||
auto coupler{-1};
|
||||
auto *vehicle{Train->DynamicObject->ABuScanNearestObject(Command.location, Train->DynamicObject->GetTrack(), 1, 1500, coupler)};
|
||||
if (vehicle == nullptr)
|
||||
vehicle = Train->DynamicObject->ABuScanNearestObject(Command.location, Train->DynamicObject->GetTrack(), -1, 1500, coupler);
|
||||
|
||||
if (coupler != -1 && vehicle != nullptr)
|
||||
{
|
||||
|
||||
vehicle->uncouple(coupler);
|
||||
}
|
||||
if (Train->DynamicObject->Mechanik)
|
||||
{
|
||||
// aktualizacja flag kierunku w składzie
|
||||
Train->DynamicObject->Mechanik->CheckVehicles(Disconnect);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_nearestcarcoupleradapterattach(TTrain *Train, command_data const &Command)
|
||||
{
|
||||
|
||||
if (true == Command.freefly && Command.action == GLFW_PRESS)
|
||||
{
|
||||
// tryb freefly, press only
|
||||
auto *vehicle{std::get<TDynamicObject *>(simulation::Region->find_vehicle(Command.location, 50, false, true))};
|
||||
if (vehicle == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
auto const coupler =
|
||||
glm::length2(glm::vec3{vehicle->CouplerPosition(end::front)} - Command.location) < glm::length2(glm::vec3{vehicle->CouplerPosition(end::rear)} - Command.location) ? end::front : end::rear;
|
||||
|
||||
vehicle->attach_coupler_adapter(coupler);
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_nearestcarcoupleradapterremove(TTrain *Train, command_data const &Command)
|
||||
{
|
||||
|
||||
if (true == Command.freefly && Command.action == GLFW_PRESS)
|
||||
{
|
||||
// tryb freefly, press only
|
||||
auto *vehicle{std::get<TDynamicObject *>(simulation::Region->find_vehicle(Command.location, 50, false, true))};
|
||||
if (vehicle == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
auto const coupler =
|
||||
glm::length2(glm::vec3{vehicle->CouplerPosition(end::front)} - Command.location) < glm::length2(glm::vec3{vehicle->CouplerPosition(end::rear)} - Command.location) ? end::front : end::rear;
|
||||
|
||||
vehicle->remove_coupler_adapter(coupler);
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_occupiedcarcouplingdisconnect(TTrain *Train, command_data const &Command)
|
||||
{
|
||||
|
||||
// if( false == Train->m_controlmapper.contains( "couplingdisconnect_sw:" ) ) { return; }
|
||||
|
||||
if (Command.action == GLFW_PRESS)
|
||||
{
|
||||
// visual feedback
|
||||
Train->m_couplingdisconnect = true;
|
||||
|
||||
if (Train->iCabn == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (Train->DynamicObject)
|
||||
{
|
||||
Train->DynamicObject->uncouple(Train->cab_to_end());
|
||||
if (Train->DynamicObject->Mechanik)
|
||||
{
|
||||
// aktualizacja flag kierunku w składzie
|
||||
Train->DynamicObject->Mechanik->CheckVehicles(Disconnect);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (Command.action == GLFW_RELEASE)
|
||||
{
|
||||
// visual feedback
|
||||
Train->m_couplingdisconnect = false;
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_occupiedcarcouplingdisconnectback(TTrain *Train, command_data const &Command)
|
||||
{
|
||||
|
||||
// if( false == Train->m_controlmapper.contains( "couplingdisconnect_sw:" ) ) { return; }
|
||||
|
||||
if (Command.action == GLFW_PRESS)
|
||||
{
|
||||
// visual feedback
|
||||
Train->m_couplingdisconnectback = true;
|
||||
|
||||
if (Train->iCabn == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (Train->DynamicObject)
|
||||
{
|
||||
Train->DynamicObject->uncouple(1 - Train->cab_to_end());
|
||||
if (Train->DynamicObject->Mechanik)
|
||||
{
|
||||
// aktualizacja flag kierunku w składzie
|
||||
Train->DynamicObject->Mechanik->CheckVehicles(Disconnect);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (Command.action == GLFW_RELEASE)
|
||||
{
|
||||
// visual feedback
|
||||
Train->m_couplingdisconnectback = false;
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_departureannounce(TTrain *Train, command_data const &Command)
|
||||
{
|
||||
|
||||
if (Train->ggDepartureSignalButton.SubModel == nullptr)
|
||||
{
|
||||
if (Command.action == GLFW_PRESS)
|
||||
{
|
||||
WriteLog("Departure Signal button is missing, or wasn't defined");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (Command.action == GLFW_PRESS)
|
||||
{
|
||||
// only reacting to press, so the sound can loop uninterrupted
|
||||
if (false == Train->mvOccupied->DepartureSignal)
|
||||
{
|
||||
// turn on
|
||||
Train->mvOccupied->signal_departure(true);
|
||||
// visual feedback
|
||||
Train->ggDepartureSignalButton.UpdateValue(1.0, Train->dsbSwitch);
|
||||
}
|
||||
}
|
||||
else if (Command.action == GLFW_RELEASE)
|
||||
{
|
||||
// turn off
|
||||
Train->mvOccupied->signal_departure(false);
|
||||
// visual feedback
|
||||
Train->ggDepartureSignalButton.UpdateValue(0.0, Train->dsbSwitch);
|
||||
}
|
||||
}
|
||||
1890
vehicle/train/TrainCommandsElectrical.cpp
Normal file
1890
vehicle/train/TrainCommandsElectrical.cpp
Normal file
File diff suppressed because it is too large
Load Diff
1508
vehicle/train/TrainCommandsLights.cpp
Normal file
1508
vehicle/train/TrainCommandsLights.cpp
Normal file
File diff suppressed because it is too large
Load Diff
211
vehicle/train/TrainCommandsMisc.cpp
Normal file
211
vehicle/train/TrainCommandsMisc.cpp
Normal file
@@ -0,0 +1,211 @@
|
||||
/*
|
||||
This Source Code Form is subject to the
|
||||
terms of the Mozilla Public License, v.
|
||||
2.0. If a copy of the MPL was not
|
||||
distributed with this file, You can
|
||||
obtain one at
|
||||
http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "vehicle/Train.h"
|
||||
|
||||
#include "world/Event.h"
|
||||
#include "simulation/simulationtime.h"
|
||||
#include "model/Model3d.h"
|
||||
#include "vehicle/Driver.h"
|
||||
#include "vehicle/DynObj.h"
|
||||
#include <future>
|
||||
|
||||
void TTrain::OnCommand_alerteracknowledge(TTrain *Train, command_data const &Command)
|
||||
{
|
||||
if (Command.action == GLFW_PRESS)
|
||||
{
|
||||
// visual feedback
|
||||
Train->ggSecurityResetButton.UpdateValue(1.0, Train->dsbSwitch);
|
||||
|
||||
if (Train->mvOccupied->TrainType == dt_EZT || Train->mvOccupied->DirActive != 0)
|
||||
Train->mvOccupied->SecuritySystem.acknowledge_press();
|
||||
}
|
||||
else if (Command.action == GLFW_RELEASE)
|
||||
{
|
||||
// visual feedback
|
||||
Train->ggSecurityResetButton.UpdateValue(0.0);
|
||||
|
||||
if (Train->mvOccupied->TrainType == dt_EZT || Train->mvOccupied->DirActive != 0)
|
||||
Train->mvOccupied->SecuritySystem.acknowledge_release();
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_cabsignalacknowledge(TTrain *Train, command_data const &Command)
|
||||
{
|
||||
// TODO: visual feedback
|
||||
if (Command.action == GLFW_PRESS)
|
||||
{
|
||||
if (Train->mvOccupied->SecuritySystem.has_separate_acknowledge())
|
||||
{
|
||||
Train->mvOccupied->SecuritySystem.cabsignal_reset();
|
||||
Train->ggSHPResetButton.UpdateValue(1.0, Train->dsbSwitch);
|
||||
}
|
||||
}
|
||||
else if (Command.action == GLFW_RELEASE)
|
||||
{
|
||||
Train->ggSHPResetButton.UpdateValue(0.0);
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_generictoggle(TTrain *Train, command_data const &Command)
|
||||
{
|
||||
|
||||
auto const itemindex = static_cast<int>(Command.command) - static_cast<int>(user_command::generictoggle0);
|
||||
auto &item = Train->ggUniversals[itemindex];
|
||||
/*
|
||||
if( item.SubModel == nullptr ) {
|
||||
if( Command.action == GLFW_PRESS ) {
|
||||
WriteLog( "Train generic item " + std::to_string( itemindex ) + " is missing, or wasn't defined" );
|
||||
}
|
||||
return;
|
||||
}
|
||||
*/
|
||||
|
||||
if (Command.action == GLFW_PRESS)
|
||||
{
|
||||
|
||||
if (item.type() == TGaugeType::push)
|
||||
{
|
||||
// impulse switch
|
||||
// turn on
|
||||
// visual feedback
|
||||
item.UpdateValue(1.0);
|
||||
}
|
||||
else
|
||||
{
|
||||
// two-state switch
|
||||
if (item.GetDesiredValue() < 0.5)
|
||||
{
|
||||
// turn on
|
||||
// visual feedback
|
||||
item.UpdateValue(1.0);
|
||||
}
|
||||
else
|
||||
{
|
||||
// turn off
|
||||
// visual feedback
|
||||
item.UpdateValue(0.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (Command.action == GLFW_RELEASE && item.type() == TGaugeType::push)
|
||||
{
|
||||
|
||||
// impulse switch
|
||||
// turn off
|
||||
// visual feedback
|
||||
item.UpdateValue(0.0);
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_cabchangeforward(TTrain *Train, command_data const &Command)
|
||||
{
|
||||
|
||||
if (Command.action == GLFW_PRESS)
|
||||
{
|
||||
auto const *owner{(Train->DynamicObject->ctOwner != nullptr ? Train->DynamicObject->ctOwner : Train->DynamicObject->Mechanik)};
|
||||
auto const movedirection{1};
|
||||
if (false == Train->CabChange(movedirection))
|
||||
{
|
||||
auto const exitdirection{(movedirection > 0 ? end::front : end::rear)};
|
||||
if (TestFlag(Train->mvOccupied->Couplers[exitdirection].CouplingFlag, coupling::gangway))
|
||||
{
|
||||
// przejscie do nastepnego pojazdu
|
||||
auto *targetvehicle = exitdirection == end::front ? Train->DynamicObject->PrevConnected() : Train->DynamicObject->NextConnected();
|
||||
targetvehicle->MoverParameters->CabOccupied = Train->mvOccupied->Neighbours[exitdirection].vehicle_end ? -1 : 1;
|
||||
Train->MoveToVehicle(targetvehicle);
|
||||
}
|
||||
}
|
||||
// HACK: match consist door permit state with the preset in the active cab
|
||||
if (Train->ggDoorPermitPresetButton.SubModel != nullptr)
|
||||
{
|
||||
Train->mvOccupied->ChangeDoorPermitPreset(0);
|
||||
}
|
||||
// HACK: update lights state
|
||||
if (Train->mvOccupied->LightsPosNo > 0)
|
||||
{
|
||||
Train->DynamicObject->SetLights();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_cabchangebackward(TTrain *Train, command_data const &Command)
|
||||
{
|
||||
|
||||
if (Command.action == GLFW_PRESS)
|
||||
{
|
||||
auto const *owner{(Train->DynamicObject->ctOwner != nullptr ? Train->DynamicObject->ctOwner : Train->DynamicObject->Mechanik)};
|
||||
auto const movedirection{-1};
|
||||
if (false == Train->CabChange(movedirection))
|
||||
{
|
||||
// current vehicle doesn't extend any farther in this direction, check if we there's one connected we can move to
|
||||
auto const exitdirection{(movedirection > 0 ? end::front : end::rear)};
|
||||
if (TestFlag(Train->mvOccupied->Couplers[exitdirection].CouplingFlag, coupling::gangway))
|
||||
{
|
||||
// przejscie do nastepnego pojazdu
|
||||
auto *targetvehicle = exitdirection == end::front ? Train->DynamicObject->PrevConnected() : Train->DynamicObject->NextConnected();
|
||||
targetvehicle->MoverParameters->CabOccupied = Train->mvOccupied->Neighbours[exitdirection].vehicle_end ? -1 : 1;
|
||||
Train->MoveToVehicle(targetvehicle);
|
||||
}
|
||||
}
|
||||
// HACK: match consist door permit state with the preset in the active cab
|
||||
if (Train->ggDoorPermitPresetButton.SubModel != nullptr)
|
||||
{
|
||||
Train->mvOccupied->ChangeDoorPermitPreset(0);
|
||||
}
|
||||
// HACK: update lights state
|
||||
if (Train->mvOccupied->LightsPosNo > 0)
|
||||
{
|
||||
Train->DynamicObject->SetLights();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_vehiclemoveforwards(TTrain *Train, const command_data &Command)
|
||||
{
|
||||
if (Command.action == GLFW_RELEASE || !DebugModeFlag)
|
||||
return;
|
||||
|
||||
Train->DynamicObject->move_set(100.0);
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_vehiclemovebackwards(TTrain *Train, const command_data &Command)
|
||||
{
|
||||
if (Command.action == GLFW_RELEASE || !DebugModeFlag)
|
||||
return;
|
||||
|
||||
Train->DynamicObject->move_set(-100.0);
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_vehicleboost(TTrain *Train, const command_data &Command)
|
||||
{
|
||||
if (Command.action == GLFW_RELEASE || !DebugModeFlag)
|
||||
return;
|
||||
|
||||
double boost = Command.param1 != 0.0 ? Command.param1 : 2.78;
|
||||
|
||||
if (Train->DynamicObject == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
auto *vehicle{Train->DynamicObject};
|
||||
while (vehicle)
|
||||
{
|
||||
vehicle->MoverParameters->V += vehicle->DirectionGet() * boost;
|
||||
vehicle = vehicle->Next(); // pozostałe też
|
||||
}
|
||||
vehicle = Train->DynamicObject->Prev();
|
||||
while (vehicle)
|
||||
{
|
||||
vehicle->MoverParameters->V += vehicle->DirectionGet() * boost;
|
||||
vehicle = vehicle->Prev(); // w drugą stronę też
|
||||
}
|
||||
}
|
||||
382
vehicle/train/TrainCommandsRadio.cpp
Normal file
382
vehicle/train/TrainCommandsRadio.cpp
Normal file
@@ -0,0 +1,382 @@
|
||||
/*
|
||||
This Source Code Form is subject to the
|
||||
terms of the Mozilla Public License, v.
|
||||
2.0. If a copy of the MPL was not
|
||||
distributed with this file, You can
|
||||
obtain one at
|
||||
http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "vehicle/Train.h"
|
||||
|
||||
#include "simulation/simulation.h"
|
||||
#include "world/Event.h"
|
||||
#include "simulation/simulationtime.h"
|
||||
#include "utilities/Logs.h"
|
||||
#include "model/Model3d.h"
|
||||
#include "vehicle/Driver.h"
|
||||
#include "vehicle/DynObj.h"
|
||||
#include "rendering/renderer.h"
|
||||
#include <future>
|
||||
#include <algorithm>
|
||||
|
||||
void TTrain::OnCommand_hornlowactivate(TTrain *Train, command_data const &Command)
|
||||
{
|
||||
|
||||
if (Train->ggHornButton.SubModel == nullptr && Train->ggHornLowButton.SubModel == nullptr)
|
||||
{
|
||||
if (Command.action == GLFW_PRESS)
|
||||
{
|
||||
WriteLog("Horn button is missing, or wasn't defined");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (Command.action == GLFW_PRESS)
|
||||
{
|
||||
// only need to react to press, sound will continue until stopped
|
||||
if (false == TestFlag(Train->mvOccupied->WarningSignal, 1))
|
||||
{
|
||||
// turn on
|
||||
Train->mvOccupied->WarningSignal |= 1;
|
||||
/*
|
||||
if( true == TestFlag( Train->mvOccupied->WarningSignal, 2 ) ) {
|
||||
low and high horn are treated as mutually exclusive
|
||||
Train->mvControlled->WarningSignal &= ~2;
|
||||
}
|
||||
*/
|
||||
// visual feedback
|
||||
Train->ggHornButton.UpdateValue(-1.0);
|
||||
Train->ggHornLowButton.UpdateValue(1.0);
|
||||
}
|
||||
}
|
||||
else if (Command.action == GLFW_RELEASE)
|
||||
{
|
||||
// turn off
|
||||
/*
|
||||
NOTE: we turn off both low and high horn, due to unreliability of release event when shift key is involved
|
||||
Train->mvOccupied->WarningSignal &= ~( 1 | 2 );
|
||||
*/
|
||||
Train->mvOccupied->WarningSignal &= ~1;
|
||||
// visual feedback
|
||||
Train->ggHornButton.UpdateValue(0.0);
|
||||
Train->ggHornLowButton.UpdateValue(0.0);
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_hornhighactivate(TTrain *Train, command_data const &Command)
|
||||
{
|
||||
|
||||
if (Train->ggHornButton.SubModel == nullptr && Train->ggHornHighButton.SubModel == nullptr)
|
||||
{
|
||||
if (Command.action == GLFW_PRESS)
|
||||
{
|
||||
WriteLog("Horn button is missing, or wasn't defined");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (Command.action == GLFW_PRESS)
|
||||
{
|
||||
// only need to react to press, sound will continue until stopped
|
||||
if (false == TestFlag(Train->mvOccupied->WarningSignal, 2))
|
||||
{
|
||||
// turn on
|
||||
Train->mvOccupied->WarningSignal |= 2;
|
||||
/*
|
||||
if( true == TestFlag( Train->mvOccupied->WarningSignal, 1 ) ) {
|
||||
low and high horn are treated as mutually exclusive
|
||||
Train->mvControlled->WarningSignal &= ~1;
|
||||
}
|
||||
*/
|
||||
// visual feedback
|
||||
Train->ggHornButton.UpdateValue(1.0);
|
||||
Train->ggHornHighButton.UpdateValue(1.0);
|
||||
}
|
||||
}
|
||||
else if (Command.action == GLFW_RELEASE)
|
||||
{
|
||||
// turn off
|
||||
/*
|
||||
NOTE: we turn off both low and high horn, due to unreliability of release event when shift key is involved
|
||||
Train->mvOccupied->WarningSignal &= ~( 1 | 2 );
|
||||
*/
|
||||
Train->mvOccupied->WarningSignal &= ~2;
|
||||
// visual feedback
|
||||
Train->ggHornButton.UpdateValue(0.0);
|
||||
Train->ggHornHighButton.UpdateValue(0.0);
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_whistleactivate(TTrain *Train, command_data const &Command)
|
||||
{
|
||||
|
||||
if (Train->ggWhistleButton.SubModel == nullptr)
|
||||
{
|
||||
if (Command.action == GLFW_PRESS)
|
||||
{
|
||||
WriteLog("Whistle button is missing, or wasn't defined");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (Command.action == GLFW_PRESS)
|
||||
{
|
||||
// only need to react to press, sound will continue until stopped
|
||||
if (false == TestFlag(Train->mvOccupied->WarningSignal, 4))
|
||||
{
|
||||
// turn on
|
||||
Train->mvOccupied->WarningSignal |= 4;
|
||||
// visual feedback
|
||||
Train->ggWhistleButton.UpdateValue(1.0);
|
||||
}
|
||||
}
|
||||
else if (Command.action == GLFW_RELEASE)
|
||||
{
|
||||
// turn off
|
||||
Train->mvOccupied->WarningSignal &= ~4;
|
||||
// visual feedback
|
||||
Train->ggWhistleButton.UpdateValue(0.0);
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_radiotoggle(TTrain *Train, command_data const &Command)
|
||||
{
|
||||
if (Command.action != GLFW_PRESS)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// NOTE: we ignore the lack of 3d model to allow system reset after receiving radio-stop signal
|
||||
/*
|
||||
if( false == Train->m_controlmapper.contains( "radio_sw:" ) ) {
|
||||
return;
|
||||
}
|
||||
*/
|
||||
// only reacting to press, so the sound can loop uninterrupted
|
||||
if (false == Train->mvOccupied->Radio)
|
||||
{
|
||||
// turn on
|
||||
OnCommand_radioenable(Train, Command);
|
||||
}
|
||||
else
|
||||
{
|
||||
// turn off
|
||||
OnCommand_radiodisable(Train, Command);
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_radioenable(TTrain *Train, command_data const &Command)
|
||||
{
|
||||
if (Command.action != GLFW_PRESS)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (false == Train->mvOccupied->Radio)
|
||||
{
|
||||
Train->mvOccupied->Radio = true;
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_radiodisable(TTrain *Train, command_data const &Command)
|
||||
{
|
||||
if (Command.action != GLFW_PRESS)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (Train->mvOccupied->Radio)
|
||||
{
|
||||
Train->mvOccupied->Radio = false;
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_radiochannelincrease(TTrain *Train, command_data const &Command)
|
||||
{
|
||||
|
||||
if (Command.action == GLFW_PRESS)
|
||||
{
|
||||
command_data newCommand = Command;
|
||||
newCommand.param1 = Train->RadioChannel() + 1;
|
||||
OnCommand_radiochannelset(Train, newCommand);
|
||||
|
||||
Train->ggRadioChannelNext.UpdateValue(1.0);
|
||||
}
|
||||
else if (Command.action == GLFW_RELEASE)
|
||||
{
|
||||
// visual feedback
|
||||
Train->ggRadioChannelNext.UpdateValue(0.0);
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_radiochanneldecrease(TTrain *Train, command_data const &Command)
|
||||
{
|
||||
|
||||
if (Command.action == GLFW_PRESS)
|
||||
{
|
||||
command_data newCommand = Command;
|
||||
newCommand.param1 = Train->RadioChannel() - 1;
|
||||
OnCommand_radiochannelset(Train, newCommand);
|
||||
|
||||
Train->ggRadioChannelPrevious.UpdateValue(1.0);
|
||||
}
|
||||
else if (Command.action == GLFW_RELEASE)
|
||||
{
|
||||
// visual feedback
|
||||
Train->ggRadioChannelPrevious.UpdateValue(0.0);
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_radiochannelset(TTrain *Train, command_data const &Command)
|
||||
{
|
||||
if (Command.action != GLFW_RELEASE)
|
||||
{
|
||||
// on press or hold
|
||||
Train->RadioChannel() = std::clamp((int)Command.param1, 1, 10);
|
||||
Train->ggRadioChannelSelector.UpdateValue(Train->RadioChannel() - 1);
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_radiostopsend(TTrain *Train, command_data const &Command)
|
||||
{
|
||||
|
||||
if (Command.action == GLFW_PRESS)
|
||||
{
|
||||
if (true == Train->mvOccupied->Radio && (Train->mvOccupied->Power24vIsAvailable || Train->mvOccupied->Power110vIsAvailable))
|
||||
{
|
||||
simulation::Region->RadioStop(Train->Dynamic()->GetPosition());
|
||||
}
|
||||
// visual feedback
|
||||
Train->ggRadioStop.UpdateValue(1.0);
|
||||
}
|
||||
else if (Command.action == GLFW_RELEASE)
|
||||
{
|
||||
// visual feedback
|
||||
Train->ggRadioStop.UpdateValue(0.0);
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_radiostopenable(TTrain *Train, command_data const &Command)
|
||||
{
|
||||
if (Command.action == GLFW_PRESS && Train->ggRadioStop.GetValue() == 0)
|
||||
{
|
||||
if (true == Train->mvOccupied->Radio && (Train->mvOccupied->Power24vIsAvailable || Train->mvOccupied->Power110vIsAvailable))
|
||||
{
|
||||
simulation::Region->RadioStop(Train->Dynamic()->GetPosition());
|
||||
}
|
||||
// visual feedback
|
||||
Train->ggRadioStop.UpdateValue(1.0);
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_radiostopdisable(TTrain *Train, command_data const &Command)
|
||||
{
|
||||
if (Command.action == GLFW_PRESS && Train->ggRadioStop.GetValue() > 0)
|
||||
{
|
||||
// visual feedback
|
||||
Train->ggRadioStop.UpdateValue(0.0);
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_radiostoptest(TTrain *Train, command_data const &Command)
|
||||
{
|
||||
|
||||
if (Command.action == GLFW_PRESS)
|
||||
{
|
||||
if (Train->RadioChannel() == 10 && true == Train->mvOccupied->Radio && (Train->mvOccupied->Power24vIsAvailable || Train->mvOccupied->Power110vIsAvailable))
|
||||
{
|
||||
Train->Dynamic()->RadioStop();
|
||||
}
|
||||
// visual feedback
|
||||
Train->ggRadioTest.UpdateValue(1.0);
|
||||
}
|
||||
else if (Command.action == GLFW_RELEASE)
|
||||
{
|
||||
// visual feedback
|
||||
Train->ggRadioTest.UpdateValue(0.0);
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_radiocall1send(TTrain *Train, command_data const &Command)
|
||||
{
|
||||
if (Command.action == GLFW_PRESS)
|
||||
{
|
||||
if (Train->RadioChannel() != 10 && true == Train->mvOccupied->Radio && (Train->mvOccupied->Power24vIsAvailable || Train->mvOccupied->Power110vIsAvailable))
|
||||
{
|
||||
simulation::Events.queue_receivers(radio_message::call1, Train->Dynamic()->GetPosition());
|
||||
}
|
||||
// visual feedback
|
||||
Train->ggRadioCall1.UpdateValue(1.0);
|
||||
}
|
||||
else if (Command.action == GLFW_RELEASE)
|
||||
{
|
||||
// visual feedback
|
||||
Train->ggRadioCall1.UpdateValue(0.0);
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_radiocall3send(TTrain *Train, command_data const &Command)
|
||||
{
|
||||
|
||||
if (Command.action == GLFW_PRESS)
|
||||
{
|
||||
if (Train->RadioChannel() != 10 && true == Train->mvOccupied->Radio && (Train->mvOccupied->Power24vIsAvailable || Train->mvOccupied->Power110vIsAvailable))
|
||||
{
|
||||
simulation::Events.queue_receivers(radio_message::call3, Train->Dynamic()->GetPosition());
|
||||
}
|
||||
// visual feedback
|
||||
Train->ggRadioCall3.UpdateValue(1.0);
|
||||
}
|
||||
else if (Command.action == GLFW_RELEASE)
|
||||
{
|
||||
// visual feedback
|
||||
Train->ggRadioCall3.UpdateValue(0.0);
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_radiovolumeincrease(TTrain *Train, command_data const &Command)
|
||||
{
|
||||
|
||||
if (Command.action == GLFW_PRESS)
|
||||
{
|
||||
command_data newCommand = Command;
|
||||
newCommand.param1 = Train->m_radiovolume + 0.125;
|
||||
OnCommand_radiovolumeset(Train, newCommand);
|
||||
Train->ggRadioVolumeNext.UpdateValue(1.0);
|
||||
}
|
||||
else if (Command.action == GLFW_RELEASE)
|
||||
{
|
||||
// visual feedback
|
||||
Train->ggRadioVolumeNext.UpdateValue(0.0);
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_radiovolumedecrease(TTrain *Train, command_data const &Command)
|
||||
{
|
||||
|
||||
if (Command.action == GLFW_PRESS)
|
||||
{
|
||||
command_data newCommand = Command;
|
||||
newCommand.param1 = Train->m_radiovolume - 0.125;
|
||||
OnCommand_radiovolumeset(Train, newCommand);
|
||||
Train->ggRadioVolumePrevious.UpdateValue(1.0);
|
||||
}
|
||||
else if (Command.action == GLFW_RELEASE)
|
||||
{
|
||||
// visual feedback
|
||||
Train->ggRadioVolumePrevious.UpdateValue(0.0);
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_radiovolumeset(TTrain *Train, command_data const &Command)
|
||||
{
|
||||
if (Command.action != GLFW_RELEASE)
|
||||
{
|
||||
// on press or hold
|
||||
Train->m_radiovolume = std::clamp(Command.param1, 0.0, 1.0);
|
||||
Train->ggRadioVolumeSelector.UpdateValue(Train->m_radiovolume);
|
||||
audio::event_volume_change = true;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user