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

Merge branch 'gfx-work' into sim

This commit is contained in:
milek7
2019-03-16 02:28:42 +01:00
35 changed files with 2358 additions and 1764 deletions

View File

@@ -123,12 +123,13 @@ TButton::Turn( bool const State ) {
}
}
void TButton::Update() {
void TButton::Update( bool const Power ) {
if( ( bData != nullptr )
&& ( *bData != m_state ) ) {
auto const state { Power && ( bData ? *bData : m_state ) };
m_state = ( *bData );
if( state != m_state ) {
m_state = state;
play();
}

View File

@@ -30,7 +30,7 @@ public:
bool Active() {
return ( ( pModelOn != nullptr )
|| ( pModelOff != nullptr ) ); }
void Update();
void Update( bool const Power = true );
bool Init( std::string const &asName, TModel3d const *pModel, bool bNewOn = false );
void Load( cParser &Parser, TDynamicObject const *Owner );
void AssignBool(bool const *bValue);

File diff suppressed because it is too large Load Diff

View File

@@ -19,15 +19,18 @@ enum TOrders
{ // rozkazy dla AI
Wait_for_orders = 0, // czekanie na dostarczenie następnych rozkazów
// operacje tymczasowe
Prepare_engine = 1, // włączenie silnika
Release_engine = 2, // wyłączenie silnika
Change_direction = 4, // zmiana kierunku (bez skanowania sygnalizacji)
Connect = 8, // podłączanie wagonów (z częściowym skanowaniem sygnalizacji)
Disconnect = 0x10, // odłączanie wagonów (bez skanowania sygnalizacji)
Prepare_engine = 1 << 0, // włączenie silnika
Release_engine = 1 << 1, // wyłączenie silnika
Change_direction = 1 << 2, // zmiana kierunku (bez skanowania sygnalizacji)
Connect = 1 << 3, // podłączanie wagonów (z częściowym skanowaniem sygnalizacji)
Disconnect = 1 << 4, // odłączanie wagonów (bez skanowania sygnalizacji)
// jazda
Shunt = 0x20, // tryb manewrowy
Obey_train = 0x40, // tryb pociągowy
Jump_to_first_order = 0x60 // zapęlenie do pierwszej pozycji (po co?)
Shunt = 1 << 5, // tryb manewrowy
Loose_shunt = 1 << 6, // coupling-free shunting mode
Obey_train = 1 << 7, // tryb pociągowy
Bank = 1 << 8, // assist mode
// others
Jump_to_first_order = 1 << 9 // zapęlenie do pierwszej pozycji (po co?)
};
enum TMovementStatus
@@ -193,6 +196,7 @@ public:
TMoverParameters const *Controlling() const {
return mvControlling; }
void DirectionInitial();
void DirectionChange();
inline
int Direction() const {
return iDirection; }
@@ -207,6 +211,10 @@ private:
bool DecBrake();
bool IncSpeed();
bool DecSpeed(bool force = false);
bool IncBrakeEIM();
bool DecBrakeEIM();
bool IncSpeedEIM();
bool DecSpeedEIM();
void SpeedSet();
void SpeedCntrl(double DesiredSpeed);
double ESMVelocity(bool Main);
@@ -308,21 +316,25 @@ private:
public:
void PutCommand(std::string NewCommand, double NewValue1, double NewValue2, const TLocation &NewLocation, TStopReason reason = stopComm);
bool PutCommand( std::string NewCommand, double NewValue1, double NewValue2, glm::dvec3 const *NewLocation, TStopReason reason = stopComm );
// defines assignment data
inline auto assignment() -> std::string & { return m_assignment; }
inline auto assignment() const -> std::string const & { return m_assignment; }
std::string OrderCurrent() const;
private:
void RecognizeCommand(); // odczytuje komende przekazana lokomotywie
void JumpToNextOrder();
void JumpToFirstOrder();
void OrderPush(TOrders NewOrder);
void OrderNext(TOrders NewOrder);
inline TOrders OrderCurrentGet();
inline TOrders OrderNextGet();
inline TOrders OrderCurrentGet() const;
inline TOrders OrderNextGet() const;
void OrderCheck();
void OrdersInit(double fVel);
void OrdersClear();
void OrdersDump();
std::string OrderCurrent() const;
std::string Order2Str(TOrders Order) const;
// members
std::string m_assignment;
Math3D::vector3 vCommandLocation; // polozenie wskaznika, sygnalizatora lub innego obiektu do ktorego odnosi sie komenda // NOTE: not used
TOrders OrderList[ maxorders ]; // lista rozkazów
int OrderPos = 0,
@@ -376,6 +388,7 @@ private:
std::size_t SemNextStopIndex{ std::size_t( -1 ) };
double dMoveLen = 0.0; // odległość przejechana od ostatniego sprawdzenia tabelki
basic_event *eSignNext = nullptr; // sygnał zmieniający prędkość, do pokazania na [F2]
neighbour_data Obstacle; // nearest vehicle detected ahead on current route
// timetable
// methods
@@ -448,3 +461,11 @@ private:
*/
};
inline TOrders TController::OrderCurrentGet() const {
return OrderList[ OrderPos ];
}
inline TOrders TController::OrderNextGet() const {
return OrderList[ OrderPos + 1 ];
}

File diff suppressed because it is too large Load Diff

View File

@@ -187,12 +187,13 @@ public:
std::string asDestination; // dokąd pojazd ma być kierowany "(stacja):(tor)"
Math3D::matrix4x4 mMatrix; // macierz przekształcenia do renderowania modeli
TMoverParameters *MoverParameters; // parametry fizyki ruchu oraz przeliczanie
TDynamicObject *NextConnected; // pojazd podłączony od strony sprzęgu 1 (kabina -1)
TDynamicObject *PrevConnected; // pojazd podłączony od strony sprzęgu 0 (kabina 1)
int NextConnectedNo; // numer sprzęgu podłączonego z tyłu
int PrevConnectedNo; // numer sprzęgu podłączonego z przodu
double fScanDist; // odległość skanowania torów na obecność innych pojazdów
double fTrackBlock; // odległość do przeszkody do dalszego ruchu (wykrywanie kolizji z innym pojazdem)
inline TDynamicObject *NextConnected() { return MoverParameters->Neighbours[ end::rear ].vehicle; }; // pojazd podłączony od strony sprzęgu 1 (kabina -1)
inline TDynamicObject *PrevConnected() { return MoverParameters->Neighbours[ end::front ].vehicle; }; // pojazd podłączony od strony sprzęgu 0 (kabina 1)
inline TDynamicObject *NextConnected() const { return MoverParameters->Neighbours[ end::rear ].vehicle; }; // pojazd podłączony od strony sprzęgu 1 (kabina -1)
inline TDynamicObject *PrevConnected() const { return MoverParameters->Neighbours[ end::front ].vehicle; }; // pojazd podłączony od strony sprzęgu 0 (kabina 1)
inline int NextConnectedNo() const { return MoverParameters->Neighbours[ end::rear ].vehicle_end; }
inline int PrevConnectedNo() const { return MoverParameters->Neighbours[ end::front ].vehicle_end; }
// double fTrackBlock; // odległość do przeszkody do dalszego ruchu (wykrywanie kolizji z innym pojazdem)
TPowerSource ConnectedEnginePowerSource( TDynamicObject const *Caller ) const;
@@ -458,11 +459,8 @@ private:
int iNumAxles; // ilość osi
std::string asModel;
public:
void ABuScanObjects(int ScanDir, double ScanDist);
private:
TDynamicObject *ABuFindObject( int &Foundcoupler, double &Distance, TTrack const *Track, int const Direction, int const Mycoupler );
TDynamicObject *ABuFindObject( int &Foundcoupler, double &Distance, TTrack const *Track, int const Direction, int const Mycoupler ) const;
void ABuCheckMyTrack();
public:
@@ -471,7 +469,6 @@ private:
TDynamicObject * PrevAny() const;
TDynamicObject * Prev(int C = -1) const;
TDynamicObject * Next(int C = -1) const;
double NextDistance(double d = -1.0);
void SetdMoveLen(double dMoveLen) {
MoverParameters->dMoveLen = dMoveLen; }
void ResetdMoveLen() {
@@ -486,6 +483,7 @@ private:
return this ?
asName :
std::string(); };
std::string asBaseDir;
// std::ofstream PneuLogFile; //zapis parametrow pneumatycznych
// youBy - dym
@@ -507,7 +505,6 @@ private:
bool bDisplayCab; // czy wyswietlac kabine w train.cpp
int iCabs; // maski bitowe modeli kabin
TTrack *MyTrack; // McZapkie-030303: tor na ktorym stoi, ABu
std::string asBaseDir;
int iOverheadMask; // maska przydzielana przez AI pojazdom posiadającym pantograf, aby wymuszały jazdę bezprądową
TTractionParam tmpTraction;
double fAdjustment; // korekcja - docelowo przenieść do TrkFoll.cpp wraz z odległością od poprzedniego
@@ -522,7 +519,7 @@ private:
int init_sections( TModel3d const *Model, std::string const &Nameprefix );
void create_controller( std::string const Type, bool const Trainset );
void AttachPrev(TDynamicObject *Object, int iType = 1);
bool UpdateForce(double dt, double dt1, bool FullVer);
bool UpdateForce(double dt);
// initiates load change by specified amounts, with a platform on specified side
void LoadExchange( int const Disembark, int const Embark, int const Platform );
// calculates time needed to complete current load change
@@ -606,14 +603,13 @@ private:
Axle1.GetTranslation() :
Axle0.GetTranslation(); };
// zwraca tor z aktywną osią
inline TTrack * RaTrackGet() {
inline TTrack * RaTrackGet() const {
return iAxleFirst ?
Axle1.GetTrack() :
Axle0.GetTrack(); };
void couple( int const Side );
int uncouple( int const Side );
void CouplersDettach(double MinDist, int MyScanDir);
void RadioStop();
void Damage(char flag);
void RaLightsSet(int head, int rear);
@@ -627,8 +623,11 @@ private:
return iDirection + iDirection - 1; };
int DettachStatus(int dir);
int Dettach(int dir);
TDynamicObject * Neightbour(int &dir);
void CoupleDist();
TDynamicObject * Neighbour(int &dir);
// updates potential collision sources
void update_neighbours();
// locates potential collision source within specified range, scanning its route in specified direction
auto find_vehicle( int const Direction, double const Range ) const -> std::tuple<TDynamicObject *, int, double, bool>;
TDynamicObject * ControlledFind();
void ParamSet(int what, int into);
// zapytanie do AI, po którym segmencie skrzyżowania jechać

View File

@@ -960,7 +960,11 @@ whois_event::run_() {
1 :
0, // 1, gdy ma tu zatrzymanie
m_input.flags );
WriteLog( "Train detected: " + m_activator->Mechanik->TrainName() );
WriteLog(
"Type: WhoIs (" + to_string( m_input.flags ) + ") - "
+ "[train: " + m_activator->Mechanik->TrainName() + "], "
+ "[stations left: " + to_string( m_activator->Mechanik->StationCount() - m_activator->Mechanik->StationIndex() ) + "], "
+ "[stop at next: " + ( m_activator->Mechanik->IsStop() ? "yes" : "no") + "]" );
}
}
}

View File

@@ -360,22 +360,36 @@ void TGauge::AssignInt(int *iValue)
iData = iValue;
};
void TGauge::AssignBool(bool *bValue)
{
m_datatype = 'b';
bData = bValue;
};
void TGauge::UpdateValue()
{ // ustawienie wartości docelowej z parametru
switch (m_datatype)
{ // to nie jest zbyt optymalne, można by zrobić osobne funkcje
case 'f':
case 'f': {
UpdateValue( *fData );
break;
case 'd':
}
case 'd': {
UpdateValue( *dData );
break;
case 'i':
}
case 'i': {
UpdateValue( *iData );
break;
default:
}
case 'b': {
UpdateValue( ( *bData ? 1.f : 0.f ) );
break;
}
default: {
break;
}
}
};
float TGauge::GetScaledValue() const {

View File

@@ -48,6 +48,7 @@ public:
void AssignFloat(float *fValue);
void AssignDouble(double *dValue);
void AssignInt(int *iValue);
void AssignBool(bool *bValue);
void UpdateValue();
// returns offset of submodel associated with the button from the model centre
glm::vec3 model_offset() const;
@@ -82,6 +83,7 @@ private:
float *fData;
double *dData { nullptr };
int *iData;
bool *bData;
};
int m_soundtype { 0 }; // toggle between exclusive and multiple sound generation
sound_source m_soundtemplate { sound_placement::internal, EU07_SOUND_CABCONTROLSCUTOFFRANGE }; // shared properties for control's sounds

View File

@@ -141,7 +141,7 @@ static int const ctrain_depot = 128; //nie rozłączalny podczas zwykłyc
// vehicle sides; exclusive
enum end {
front = 0,
rear
rear = 1
};
enum side {
@@ -359,7 +359,7 @@ enum class TBrakeSystem { Individual, Pneumatic, ElectroPneumatic };
/*podtypy hamulcow zespolonych*/
enum class TBrakeSubSystem { ss_None, ss_W, ss_K, ss_KK, ss_Hik, ss_ESt, ss_KE, ss_LSt, ss_MT, ss_Dako };
enum class TBrakeValve { NoValve, W, W_Lu_VI, W_Lu_L, W_Lu_XR, K, Kg, Kp, Kss, Kkg, Kkp, Kks, Hikg1, Hikss, Hikp1, KE, SW, EStED, NESt3, ESt3, LSt, ESt4, ESt3AL2, EP1, EP2, M483, CV1_L_TR, CV1, CV1_R, Other };
enum class TBrakeHandle { NoHandle, West, FV4a, M394, M254, FVel1, FVel6, D2, Knorr, FD1, BS2, testH, St113, MHZ_P, MHZ_T, MHZ_EN57, MHZ_K5P, MHZ_K8P };
enum class TBrakeHandle { NoHandle, West, FV4a, M394, M254, FVE408, FVel6, D2, Knorr, FD1, BS2, testH, St113, MHZ_P, MHZ_T, MHZ_EN57, MHZ_K5P, MHZ_K8P };
/*typy hamulcow indywidualnych*/
enum class TLocalBrake { NoBrake, ManualBrake, PneumaticBrake, HydraulicBrake };
/*dla osob/towar: opoznienie hamowania/odhamowania*/
@@ -619,18 +619,16 @@ struct power_coupling {
struct TCoupling {
/*parametry*/
double SpringKB = 1.0; /*stala sprezystosci zderzaka/sprzegu, %tlumiennosci */
double SpringKC = 1.0;
double beta = 0.0;
double DmaxB = 0.1; /*tolerancja scisku/rozciagania, sila rozerwania*/
double FmaxB = 1000.0;
double SpringKC = 1.0;
double DmaxC = 0.1;
double FmaxC = 1000.0;
double beta = 0.0;
TCouplerType CouplerType = TCouplerType::NoCoupler; /*typ sprzegu*/
int AllowedFlag = 3; //Ra: maska dostępnych
/*zmienne*/
int CouplingFlag = 0; /*0 - wirtualnie, 1 - sprzegi, 2 - pneumatycznie, 4 - sterowanie, 8 - kabel mocy*/
int AllowedFlag = 3; //Ra: znaczenie jak wyżej, maska dostępnych
bool Render = false; /*ABu: czy rysowac jak zaczepiony sprzeg*/
double CoupleDist = 0.0; /*ABu: optymalizacja - liczenie odleglosci raz na klatkę, bez iteracji*/
class TMoverParameters *Connected = nullptr; /*co jest podlaczone*/
int ConnectedNr = 0; //Ra: od której strony podłączony do (Connected): 0=przód, 1=tył
double CForce = 0.0; /*sila z jaka dzialal*/
@@ -638,16 +636,26 @@ struct TCoupling {
bool CheckCollision = false; /*czy sprawdzac sile czy pedy*/
power_coupling power_high;
power_coupling power_low; // TODO: implement this
// power_coupling power_low; // TODO: implement this
int sounds { 0 }; // sounds emitted by the coupling devices
bool Render = false; /*ABu: czy rysowac jak zaczepiony sprzeg*/
};
class TDynamicObject;
struct neighbour_data {
TDynamicObject *vehicle { nullptr }; // detected obstacle
int vehicle_end { -1 }; // facing end of the obstacle
float distance { 10000.f }; // distance to the obstacle // NOTE: legacy value. TBD, TODO: use standard -1 instead?
};
class TMoverParameters
{ // Ra: wrapper na kod pascalowy, przejmujący jego funkcje Q: 20160824 - juz nie wrapper a klasa bazowa :)
private:
// types
/* TODO: implement
// communication cable, exchanging control signals with adjacent vehicle
struct jumper_cable {
// types
@@ -661,7 +669,7 @@ private:
// integers
// std::array<int, 1> values {};
};
*/
// basic approximation of a generic device
// TBD: inheritance or composition?
struct basic_device {
@@ -726,6 +734,8 @@ private:
bool is_closing { false }; // the door is currently closing
bool is_opening { false }; // the door is currently opening
bool is_open { false }; // the door is fully open
bool step_folding { false }; // the doorstep is currently closing
bool step_unfolding { false }; // the doorstep is currently opening
};
struct door_data {
@@ -751,6 +761,7 @@ private:
std::vector<int> permit_presets; // permit presets selectable with preset switch
// ld inputs
bool lock_enabled { true };
bool step_enabled { true };
// internal data
int permit_preset { -1 }; // curent position of preset selection switch
// vehicle parts
@@ -828,14 +839,12 @@ private:
public:
double dMoveLen = 0.0;
std::string filename;
/*---opis lokomotywy, wagonu itp*/
/*--opis serii--*/
int CategoryFlag = 1; /*1 - pociag, 2 - samochod, 4 - statek, 8 - samolot*/
/*--sekcja stalych typowych parametrow*/
std::string TypeName; /*nazwa serii/typu*/
//TrainType: string; {typ: EZT/elektrowoz - Winger 040304}
int TrainType = 0; /*Ra: powinno być szybciej niż string*/
int TrainType = 0; /*typ: EZT/elektrowoz - Winger 040304 Ra: powinno być szybciej niż string*/
TEngineType EngineType = TEngineType::None; /*typ napedu*/
TPowerParameters EnginePowerSource; /*zrodlo mocy dla silnikow*/
TPowerParameters SystemPowerSource; /*zrodlo mocy dla systemow sterowania/przetwornic/sprezarek*/
@@ -968,16 +977,23 @@ public:
int DynamicBrakeType = 0; /*patrz dbrake_**/
int DynamicBrakeAmpmeters = 2; /*liczba amperomierzy przy hamowaniu ED*/
double DynamicBrakeRes = 5.8; /*rezystancja oporników przy hamowaniu ED*/
double TUHEX_Sum = 750; /*nastawa sterownika hamowania ED*/
double DynamicBrakeRes1 = 5.8; /*rezystancja oporników przy hamowaniu ED - 1 tryb*/
double DynamicBrakeRes2 = 5.8; /*rezystancja oporników przy hamowaniu ED - 2 tryb*/
double TUHEX_Sum = 750; /*nastawa sterownika hamowania ED - aktualna*/
double TUHEX_Diff = 10; /*histereza działania sterownika hamowania ED*/
double TUHEX_MinIw = 60; /*minimalny prąd wzbudzenia przy hamowaniu ED - wynika z chk silnika*/
double TUHEX_MaxIw = 400; /*maksymalny prąd wzbudzenia przy hamowaniu ED - ograniczenie max siły*/
double TUHEX_Sum1 = 750; /*nastawa1 sterownika hamowania ED*/
double TUHEX_Sum2 = 750; /*nastawa2 sterownika hamowania ED*/
double TUHEX_Sum3 = 750; /*nastawa3 sterownika hamowania ED*/
int TUHEX_Stages = 0; /*liczba stopni hamowania ED*/
// TODO: wrap resistor fans variables and state into a device
int RVentType = 0; /*0 - brak, 1 - jest, 2 - automatycznie wlaczany*/
double RVentnmax = 1.0; /*maks. obroty wentylatorow oporow rozruchowych*/
double RVentCutOff = 0.0; /*rezystancja wylaczania wentylatorow dla RVentType=2*/
double RVentSpeed { 0.5 }; //rozpedzanie sie wentylatora obr/s^2}
double RVentMinI { 50.0 }; //przy jakim pradzie sie wylaczaja}
bool RVentForceOn { false }; // forced activation switch
int CompressorPower = 1; // 0: main circuit, 1: z przetwornicy, reczne, 2: w przetwornicy, stale, 3: diesel engine, 4: converter of unit in front, 5: converter of unit behind
int SmallCompressorPower = 0; /*Winger ZROBIC*/
bool Trafo = false; /*pojazd wyposażony w transformator*/
@@ -1051,6 +1067,12 @@ public:
bool MED_EPVC = 0; // czy korekcja sily hamowania EP, gdy nie ma dostepnego ED
double MED_EPVC_Time = 7; // czas korekcji sily hamowania EP, gdy nie ma dostepnego ED
bool MED_Ncor = 0; // czy korekcja sily hamowania z uwzglednieniem nacisku
int DCEMUED_CC; //na którym sprzęgu sprawdzać działanie ED
double DCEMUED_EP_max_Vel; //maksymalna prędkość, przy której działa EP przy włączonym ED w jednostce (dla tocznych)
double DCEMUED_EP_min_Im; //minimalny prąd, przy którym EP nie działa przy włączonym ED w członie (dla silnikowych)
double DCEMUED_EP_delay; //opóźnienie włączenia hamulca EP przy hamowaniu ED - zwłoka wstępna
/*-dla wagonow*/
struct load_attributes {
std::string name; // name of the cargo
@@ -1087,6 +1109,7 @@ public:
TRotation Rot { 0.0, 0.0, 0.0 };
std::string Name; /*nazwa wlasna*/
TCoupling Couplers[2]; //urzadzenia zderzno-sprzegowe, polaczenia miedzy wagonami
std::array<neighbour_data, 2> Neighbours; // potential collision sources
bool EventFlag = false; /*!o true jesli cos nietypowego sie wydarzy*/
int SoundFlag = 0; /*!o patrz stale sound_ */
double DistCounter = 0.0; /*! licznik kilometrow */
@@ -1159,6 +1182,10 @@ public:
int BrakeOpModeFlag = 0; /*nastawa trybu pracy PS/PN/EP/MED 1/2/4/8*/
int BrakeOpModes = 0; /*nastawy mozliwe do uzyskania*/
bool DynamicBrakeFlag = false; /*czy wlaczony hamulec elektrodymiczny*/
bool DynamicBrakeEMUStatus = true; /*czy hamulec ED dziala w ezt*/
int TUHEX_StageActual = 0; /*aktualny stopien tuhexa*/
bool TUHEX_ResChange = false; /*czy zmiana rezystancji hamowania ED - odwzbudzanie*/
bool TUHEX_Active = false; /*czy hamowanie ED wywołane z zewnątrz*/
// NapUdWsp: integer;
double LimPipePress = 0.0; /*stabilizator cisnienia*/
double ActFlowSpeed = 0.0; /*szybkosc stabilizatora*/
@@ -1265,9 +1292,14 @@ public:
double hydro_R_n = 0.0; /*predkosc obrotowa retardera*/
/*- zmienne dla lokomotyw z silnikami indukcyjnymi -*/
double eimic = 0; /*aktualna pozycja zintegrowanego sterowania jazda i hamowaniem*/
double eimic_real = 0; /*faktycznie uzywana pozycja zintegrowanego sterowania jazda i hamowaniem*/
int EIMCtrlType = 0; /*rodzaj wariantu zadajnika jazdy*/
double eimv_pr = 0; /*realizowany procent dostepnej sily rozruchu/hamowania*/
double eimv[21];
static std::vector<std::string> const eimv_labels;
double SpeedCtrlTimer = 0; /*zegar dzialania tempomatu z wybieralna predkoscia*/
double eimicSpeedCtrl = 0; /*pozycja sugerowana przez tempomat*/
double NewSpeed = 0; /*nowa predkosc do zadania*/
double MED_EPVC_CurrentTime = 0; /*aktualny czas licznika czasu korekcji siły EP*/
@@ -1317,24 +1349,19 @@ public:
double FrictConst2d= 0.0;
double TotalMassxg = 0.0; /*TotalMass*g*/
Math3D::vector3 vCoulpler[2]; // powtórzenie współrzędnych sprzęgów z DynObj :/
double fBrakeCtrlPos = -2.0; // płynna nastawa hamulca zespolonego
bool bPantKurek3 = true; // kurek trójdrogowy (pantografu): true=połączenie z ZG, false=połączenie z małą sprężarką // domyślnie zbiornik pantografu połączony jest ze zbiornikiem głównym
int iProblem = 0; // flagi problemów z taborem, aby AI nie musiało porównywać; 0=może jechać
int iLights[2]; // bity zapalonych świateł tutaj, żeby dało się liczyć pobór prądu
private:
double CouplerDist(int Coupler);
public:
TMoverParameters(double VelInitial, std::string TypeNameInit, std::string NameInit, int Cab);
// obsługa sprzęgów
double Distance(const TLocation &Loc1, const TLocation &Loc2, const TDimension &Dim1, const TDimension &Dim2);
/* double Distance(const vector3 &Loc1, const vector3 &Loc2, const vector3 &Dim1, const vector3 &Dim2);
*/ //bool AttachA(int ConnectNo, int ConnectToNr, TMoverParameters *ConnectTo, int CouplingType, bool Forced = false);
static double CouplerDist( TMoverParameters const *Left, TMoverParameters const *Right );
static double Distance(const TLocation &Loc1, const TLocation &Loc2, const TDimension &Dim1, const TDimension &Dim2);
bool Attach(int ConnectNo, int ConnectToNr, TMoverParameters *ConnectTo, int CouplingType, bool Forced = false, bool Audible = true);
int DettachStatus(int ConnectNo);
bool Dettach(int ConnectNo);
void SetCoupleDist();
bool DirectionForward();
void BrakeLevelSet(double b);
bool BrakeLevelAdd(double b);
@@ -1350,7 +1377,7 @@ public:
// Q *******************************************************************************************
double GetTrainsetVoltage(void);
bool Physic_ReActivation(void);
bool switch_physics(bool const State);
double LocalBrakeRatio(void);
double ManualBrakeRatio(void);
double PipeRatio(void);/*ile napelniac*/
@@ -1421,17 +1448,17 @@ public:
/*funkcje obliczajace sily*/
void ComputeConstans(void);//ABu: wczesniejsze wyznaczenie stalych dla liczenia sil
double ComputeMass(void);
void ComputeTotalForce(double dt, double dt1, bool FullVer);
void ComputeTotalForce(double dt);
double Adhesive(double staticfriction) const;
double TractionForce(double dt);
double FrictionForce(double R, int TDamage);
double BrakeForceR(double ratio, double velocity);
double BrakeForceP(double press, double velocity);
double BrakeForce(const TTrackParam &Track);
double CouplerForce(int CouplerN, double dt);
double CouplerForce(int const End, double dt);
void CollisionDetect(int CouplerN, double dt);
/*obrot kol uwzgledniajacy poslizg*/
double ComputeRotatingWheel(double WForce, double dt, double n);
double ComputeRotatingWheel(double WForce, double dt, double n) const;
/*--funkcje dla lokomotyw*/
bool DirectionBackward(void);/*! kierunek ruchu*/
@@ -1485,6 +1512,9 @@ public:
bool PantFront( bool const State, range_t const Notify = range_t::consist ); //obsluga pantografou przedniego
bool PantRear( bool const State, range_t const Notify = range_t::consist ); //obsluga pantografu tylnego
void CheckEIMIC(double dt); //sprawdzenie i zmiana nastawy zintegrowanego nastawnika jazdy/hamowania
void CheckSpeedCtrl();
/*-funkcje typowe dla lokomotywy spalinowej z przekladnia mechaniczna*/
bool dizel_EngageSwitch(double state);
bool dizel_EngageChange(double dt);
@@ -1501,6 +1531,7 @@ public:
bool LoadingDone(double LSpeed, std::string const &Loadname);
bool PermitDoors( side const Door, bool const State = true, range_t const Notify = range_t::consist );
bool ChangeDoorPermitPreset( int const Change, range_t const Notify = range_t::consist );
bool PermitDoorStep( bool const State, range_t const Notify = range_t::consist );
bool OperateDoors( side const Door, bool const State, range_t const Notify = range_t::consist );
bool LockDoors( bool const State, range_t const Notify = range_t::consist );
bool signal_departure( bool const State, range_t const Notify = range_t::consist ); // toggles departure warning
@@ -1524,6 +1555,7 @@ private:
void LoadFIZ_TurboPos( std::string const &line );
void LoadFIZ_Cntrl( std::string const &line );
void LoadFIZ_Blending(std::string const &line);
void LoadFIZ_DCEMUED(std::string const &line);
void LoadFIZ_Light( std::string const &line );
void LoadFIZ_Clima( std::string const &line );
void LoadFIZ_Power( std::string const &Line );

File diff suppressed because it is too large Load Diff

View File

@@ -31,6 +31,7 @@ double const TSt113::BPT_K[6][2] = {{10, 0}, {4, 1}, {0, 1}, {4, 0}, {4, -1}, {1
double const TSt113::BEP_K[7] = {0, -1, 1, 0, 0, 0, 0};
double const TSt113::pos_table[11] = {-1, 5, -1, 0, 2, 3, 4, 5, 0, 0, 1};
double const TFVel6::pos_table[11] = {-1, 6, -1, 0, 6, 4, 4.7, 5, -1, 0, 1};
double const TFVE408::pos_table[11] = { 0, 10, 0, 0, 10, 7, 8, 9, 0, 1, 5 };
double PR(double P1, double P2)
{
@@ -133,6 +134,11 @@ double PFVd( double PH, double PL, double const S, double LIM, double const DP )
return 0;
}
bool is_EQ(double pos, double i_pos)
{
return (pos <= i_pos + 0.5) && (pos > i_pos - 0.5);
}
//---ZBIORNIKI---
double TReservoir::pa()
@@ -863,10 +869,7 @@ double TEStEP2::GetPF( double const PP, double const dt, double const Vel )
dV1 = dV1 - 0.96 * dv;
// hamulec EP
temp = BVP * int(EPS > 0);
dv = PF(temp, LBP, 0.00053 + 0.00060 * int(EPS < 0)) * dt * EPS * EPS *
int(LBP * EPS < MaxBP * LoadC);
LBP = LBP - dv;
EPCalc(dt);
// luzowanie KI
if ((BrakeStatus & b_hld) == b_off)
@@ -936,6 +939,24 @@ void TEStEP2::SetLP( double const TM, double const LM, double const TBP )
TareBP = TBP;
}
void TEStEP2::EPCalc(double dt)
{
double temp = BrakeRes->P() * int(EPS > 0);
double dv = PF(temp, LBP, 0.00053 + 0.00060 * int(EPS < 0)) * dt * EPS * EPS *
int(LBP * EPS < MaxBP * LoadC);
LBP = LBP - dv;
}
void TEStEP1::EPCalc(double dt)
{
double temp = EPS - std::floor(EPS); //część ułamkowa jest hamulcem EP
double LBPLim = Min0R(MaxBP * LoadC * temp, BrakeRes->P()); //do czego dążymy
double S = 10 * clamp(LBPLim - LBP, -0.1, 0.1); //przymykanie zaworku
double dv = PF(( S > 0 ? BrakeRes->P() : 0 ), LBP, abs(S)*(0.00053 + 0.00060 * int(S < 0))) * dt; //przepływ
LBP = LBP - dv;
}
//---EST3--
double TESt3::GetPF( double const PP, double const dt, double const Vel )
@@ -3133,4 +3154,71 @@ void TFVel6::Init(double Press)
TimeEP = true;
}
//---FVE408---
double TFVE408::GetPF(double i_bcp, double PP, double HP, double dt, double ep)
{
static int const LBDelay = 100;
double LimPP;
double dpMainValve;
double ActFlowSpeed;
LimPP = Min0R(5 * int(i_bcp < 6.5), HP);
if ((i_bcp >= 6.5) && ((i_bcp < 7.5) || (i_bcp > 9.5)))
ActFlowSpeed = 0;
else if ((i_bcp > 7.5) && (i_bcp < 8.5))
ActFlowSpeed = 2; // konsultacje wawa1 - bylo 8;
else if ((i_bcp < 6.5))
ActFlowSpeed = 2;
else
ActFlowSpeed = 4;
dpMainValve = PF(LimPP, PP, ActFlowSpeed / LBDelay) * dt;
Sounds[s_fv4a_e] = 0;
Sounds[s_fv4a_u] = 0;
Sounds[s_fv4a_b] = 0;
if ((i_bcp < 6.5))
Sounds[s_fv4a_u] = -dpMainValve;
else if ((i_bcp < 8.5))
Sounds[s_fv4a_b] = dpMainValve;
else if ((i_bcp < 9.5))
Sounds[s_fv4a_e] = dpMainValve;
if (is_EQ(i_bcp, 1)) EPS = 1.15; else
if (is_EQ(i_bcp, 2)) EPS = 1.40; else
if (is_EQ(i_bcp, 3)) EPS = 2.64; else
if (is_EQ(i_bcp, 4)) EPS = 3.84; else
if (is_EQ(i_bcp, 5)) EPS = 3.99; else
EPS = 0;
return dpMainValve;
}
double TFVE408::GetCP()
{
return EPS;
}
double TFVE408::GetPos(int i)
{
return pos_table[i];
}
double TFVE408::GetSound(int i)
{
if (i > 2)
return 0;
else
return Sounds[i];
}
void TFVE408::Init(double Press)
{
Time = true;
TimeEP = false;
}
// END

View File

@@ -381,7 +381,7 @@ class TEStED : public TLSt { //zawor z EP09 - Est4 z oddzielnym przekladnikiem,
class TEStEP2 : public TLSt {
private:
protected:
double TareM = 0.0; //masa proznego
double LoadM = 0.0; //masa pelnego
double TareBP = 0.0; //cisnienie dla proznego
@@ -394,12 +394,23 @@ public:
void PLC( double const mass ); //wspolczynnik cisnienia przystawki wazacej
void SetEPS( double const nEPS )/*override*/; //stan hamulca EP
void SetLP( double const TM, double const LM, double const TBP ); //parametry przystawki wazacej
void virtual EPCalc(double dt);
inline TEStEP2(double i_mbp, double i_bcr, double i_bcd, double i_brc, int i_bcn, int i_BD, int i_mat, int i_ba, int i_nbpa) :
TLSt( i_mbp, i_bcr, i_bcd, i_brc, i_bcn, i_BD, i_mat, i_ba, i_nbpa)
{}
};
class TEStEP1 : public TEStEP2 {
public:
void EPCalc(double dt);
inline TEStEP1(double i_mbp, double i_bcr, double i_bcd, double i_brc, int i_bcn, int i_BD, int i_mat, int i_ba, int i_nbpa) :
TEStEP2(i_mbp, i_bcr, i_bcd, i_brc, i_bcn, i_BD, i_mat, i_ba, i_nbpa)
{}
};
class TCV1 : public TBrake {
private:
@@ -775,6 +786,24 @@ class TFVel6 : public TDriverHandle {
{}
};
class TFVE408 : public TDriverHandle {
private:
double EPS = 0.0;
static double const pos_table[11]; // = {-1, 6, -1, 0, 6, 4, 4.7, 5, -1, 0, 1};
public:
double GetPF(double i_bcp, double PP, double HP, double dt, double ep)/*override*/;
double GetCP()/*override*/;
double GetPos(int i)/*override*/;
double GetSound(int i)/*override*/;
void Init(double Press)/*override*/;
inline TFVE408(void) :
TDriverHandle()
{}
};
extern double PF( double const P1, double const P2, double const S, double const DP = 0.25 );
extern double PF1( double const P1, double const P2, double const S );

326
Train.cpp
View File

@@ -138,28 +138,17 @@ TButton &TCab::Button(int n)
}
};
void TCab::Update()
void TCab::Update( bool const Power )
{ // odczyt parametrów i ustawienie animacji submodelom
/*
int i;
for (i = 0; i < iGauges; ++i)
{ // animacje izometryczne
ggList[i].UpdateValue(); // odczyt parametru i przeliczenie na kąt
ggList[i].Update(); // ustawienie animacji
}
for (i = 0; i < iButtons; ++i)
{ // animacje dwustanowe
btList[i].Update(); // odczyt parametru i wybór submodelu
}
*/
for( auto &gauge : ggList ) {
// animacje izometryczne
gauge.UpdateValue(); // odczyt parametru i przeliczenie na kąt
gauge.Update(); // ustawienie animacji
}
for( auto &button : btList ) {
// animacje dwustanowe
button.Update(); // odczyt parametru i wybór submodelu
button.Update( Power ); // odczyt parametru i wybór submodelu
}
};
@@ -169,6 +158,7 @@ TTrain::commandhandler_map const TTrain::m_commandhandlers = {
{ user_command::aidriverenable, &TTrain::OnCommand_aidriverenable },
{ user_command::aidriverdisable, &TTrain::OnCommand_aidriverdisable },
{ user_command::jointcontrollerset, &TTrain::OnCommand_jointcontrollerset },
{ user_command::mastercontrollerincrease, &TTrain::OnCommand_mastercontrollerincrease },
{ user_command::mastercontrollerincreasefast, &TTrain::OnCommand_mastercontrollerincreasefast },
{ user_command::mastercontrollerdecrease, &TTrain::OnCommand_mastercontrollerdecrease },
@@ -180,6 +170,7 @@ TTrain::commandhandler_map const TTrain::m_commandhandlers = {
{ user_command::secondcontrollerdecreasefast, &TTrain::OnCommand_secondcontrollerdecreasefast },
{ user_command::secondcontrollerset, &TTrain::OnCommand_secondcontrollerset },
{ user_command::notchingrelaytoggle, &TTrain::OnCommand_notchingrelaytoggle },
{ user_command::tempomattoggle, &TTrain::OnCommand_tempomattoggle },
{ user_command::mucurrentindicatorothersourceactivate, &TTrain::OnCommand_mucurrentindicatorothersourceactivate },
{ user_command::independentbrakeincrease, &TTrain::OnCommand_independentbrakeincrease },
{ user_command::independentbrakeincreasefast, &TTrain::OnCommand_independentbrakeincreasefast },
@@ -272,6 +263,7 @@ TTrain::commandhandler_map const TTrain::m_commandhandlers = {
{ user_command::motorblowerstogglefront, &TTrain::OnCommand_motorblowerstogglefront },
{ user_command::motorblowerstogglerear, &TTrain::OnCommand_motorblowerstogglerear },
{ user_command::motorblowersdisableall, &TTrain::OnCommand_motorblowersdisableall },
{ user_command::coolingfanstoggle, &TTrain::OnCommand_coolingfanstoggle },
{ user_command::motorconnectorsopen, &TTrain::OnCommand_motorconnectorsopen },
{ user_command::motorconnectorsclose, &TTrain::OnCommand_motorconnectorsclose },
{ user_command::motordisconnect, &TTrain::OnCommand_motordisconnect },
@@ -333,6 +325,7 @@ TTrain::commandhandler_map const TTrain::m_commandhandlers = {
{ user_command::doorcloseright, &TTrain::OnCommand_doorcloseright },
{ user_command::dooropenall, &TTrain::OnCommand_dooropenall },
{ user_command::doorcloseall, &TTrain::OnCommand_doorcloseall },
{ user_command::doorsteptoggle, &TTrain::OnCommand_doorsteptoggle },
{ user_command::carcouplingincrease, &TTrain::OnCommand_carcouplingincrease },
{ user_command::carcouplingdisconnect, &TTrain::OnCommand_carcouplingdisconnect },
{ user_command::departureannounce, &TTrain::OnCommand_departureannounce },
@@ -536,13 +529,16 @@ dictionary_source *TTrain::GetTrainState() {
dict->insert( "unit_no", iUnitNo );
for( int i = 0; i < 20; i++ ) {
dict->insert( ( "doors_" + std::to_string( i + 1 ) ), bDoors[ i ][ 0 ] );
dict->insert( ( "doors_r_" + std::to_string( i + 1 ) ), bDoors[ i ][ 1 ] );
dict->insert( ( "doors_l_" + std::to_string( i + 1 ) ), bDoors[ i ][ 2 ] );
dict->insert( ( "doors_no_" + std::to_string( i + 1 ) ), iDoorNo[ i ] );
dict->insert( ( "code_" + std::to_string( i + 1 ) ), ( std::to_string( iUnits[ i ] ) + cCode[ i ] ) );
dict->insert( ( "car_name" + std::to_string( i + 1 ) ), asCarName[ i ] );
dict->insert( ( "slip_" + std::to_string( i + 1 ) ), bSlip[ i ] );
auto const caridx { std::to_string( i + 1 ) };
dict->insert( ( "doors_" + caridx ), bDoors[ i ][ 0 ] );
dict->insert( ( "doors_l_" + caridx ), bDoors[ i ][ 1 ] );
dict->insert( ( "doors_r_" + caridx ), bDoors[ i ][ 2 ] );
dict->insert( ( "doorstep_l_" + caridx ), bDoors[ i ][ 3 ] );
dict->insert( ( "doorstep_r_" + caridx ), bDoors[ i ][ 4 ] );
dict->insert( ( "doors_no_" + caridx ), iDoorNo[ i ] );
dict->insert( ( "code_" + caridx ), ( std::to_string( iUnits[ i ] ) + cCode[ i ] ) );
dict->insert( ( "car_name" + caridx ), asCarName[ i ] );
dict->insert( ( "slip_" + caridx ), bSlip[ i ] );
}
// ai state data
auto const *driver = DynamicObject->Mechanik;
@@ -774,13 +770,50 @@ void TTrain::OnCommand_aidriverdisable( TTrain *Train, command_data const &Comma
auto const EU07_CONTROLLER_BASERETURNDELAY { 0.5f };
auto const EU07_CONTROLLER_KEYBOARDETURNDELAY { 1.5f };
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;
Train->mvOccupied->LocalBrakePosA = 0;
}
else {
Train->mvOccupied->LocalBrakePosA = (
clamp(
1.0 - ( Command.param1 * 2 ),
0.0, 1.0 ) );
if( Train->mvControlled->MainCtrlPos > 0 ) {
Train->set_master_controller( 0 );
}
}
}
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
if( ( Train->ggJointCtrl.SubModel != nullptr )
&& ( Train->mvControlled->LocalBrakePosA > 0.0 ) ) {
OnCommand_independentbrakedecrease( Train, Command );
}
else {
Train->mvControlled->IncMainCtrl( 1 );
Train->m_mastercontrollerinuse = true;
}
}
else if (Command.action == GLFW_RELEASE) {
// release
Train->m_mastercontrollerinuse = false;
@@ -792,7 +825,19 @@ void TTrain::OnCommand_mastercontrollerincreasefast( TTrain *Train, command_data
if( Command.action != GLFW_RELEASE ) {
// on press or hold
if( ( Train->ggJointCtrl.SubModel != nullptr )
&& ( Train->mvControlled->LocalBrakePosA > 0.0 ) ) {
OnCommand_independentbrakedecreasefast( Train, Command );
}
else {
Train->mvControlled->IncMainCtrl( 2 );
Train->m_mastercontrollerinuse = true;
}
}
else {
// release
Train->m_mastercontrollerinuse = false;
Train->m_mastercontrollerreturndelay = EU07_CONTROLLER_KEYBOARDETURNDELAY + EU07_CONTROLLER_BASERETURNDELAY;
}
}
@@ -800,9 +845,15 @@ void TTrain::OnCommand_mastercontrollerdecrease( TTrain *Train, command_data con
if( Command.action != GLFW_RELEASE ) {
// on press or hold
if( ( Train->ggJointCtrl.SubModel != nullptr )
&& ( Train->mvControlled->MainCtrlPos == 0 ) ) {
OnCommand_independentbrakeincrease( Train, Command );
}
else {
Train->mvControlled->DecMainCtrl( 1 );
Train->m_mastercontrollerinuse = true;
}
}
else if (Command.action == GLFW_RELEASE) {
// release
Train->m_mastercontrollerinuse = false;
@@ -814,7 +865,19 @@ void TTrain::OnCommand_mastercontrollerdecreasefast( TTrain *Train, command_data
if( Command.action != GLFW_RELEASE ) {
// on press or hold
if( ( Train->ggJointCtrl.SubModel != nullptr )
&& ( Train->mvControlled->MainCtrlPos == 0 ) ) {
OnCommand_independentbrakeincreasefast( Train, Command );
}
else {
Train->mvControlled->DecMainCtrl( 2 );
Train->m_mastercontrollerinuse = true;
}
}
else {
// release
Train->m_mastercontrollerinuse = false;
Train->m_mastercontrollerreturndelay = EU07_CONTROLLER_KEYBOARDETURNDELAY + EU07_CONTROLLER_BASERETURNDELAY;
}
}
@@ -877,6 +940,45 @@ void TTrain::OnCommand_notchingrelaytoggle( TTrain *Train, command_data const &C
}
}
void TTrain::OnCommand_tempomattoggle( TTrain *Train, command_data const &Command ) {
if( Command.action == GLFW_REPEAT ) { return; }
if( Train->ggScndCtrlButton.type() == TGaugeType::push ) {
// impulse switch
if( Command.action == GLFW_RELEASE ) {
// just move the button back to default position
// visual feedback
Train->ggScndCtrlButton.UpdateValue( 0.0, Train->dsbSwitch );
return;
}
// glfw_press
if( Train->mvControlled->ScndCtrlPos == 0 ) {
// turn on if needed
Train->mvControlled->IncScndCtrl( 1 );
}
// visual feedback
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_mucurrentindicatorothersourceactivate( TTrain *Train, command_data const &Command ) {
if( Train->ggNextCurrentButton.SubModel == nullptr ) {
@@ -997,7 +1099,7 @@ void TTrain::OnCommand_independentbrakeset( TTrain *Train, command_data const &C
if( Command.action != GLFW_RELEASE ) {
Train->mvControlled->LocalBrakePosA = (
Train->mvOccupied->LocalBrakePosA = (
clamp(
Command.param1,
0.0, 1.0 ) );
@@ -1524,7 +1626,7 @@ void TTrain::OnCommand_reverserincrease( TTrain *Train, command_data const &Comm
if( ( Train->mvOccupied->ActiveDir )
&& ( Train->DynamicObject->Mechanik ) ) {
Train->DynamicObject->Mechanik->CheckVehicles( Change_direction );
Train->DynamicObject->Mechanik->DirectionChange();
}
}
}
@@ -1539,7 +1641,7 @@ void TTrain::OnCommand_reverserdecrease( TTrain *Train, command_data const &Comm
if( ( Train->mvOccupied->ActiveDir )
&& ( Train->DynamicObject->Mechanik ) ) {
Train->DynamicObject->Mechanik->CheckVehicles( Change_direction );
Train->DynamicObject->Mechanik->DirectionChange();;
}
}
}
@@ -1570,7 +1672,7 @@ void TTrain::OnCommand_reverserforward( TTrain *Train, command_data const &Comma
if( ( Train->mvOccupied->ActiveDir == 1 )
&& ( Train->DynamicObject->Mechanik ) ) {
Train->DynamicObject->Mechanik->CheckVehicles( Change_direction );
Train->DynamicObject->Mechanik->DirectionChange();
}
}
}
@@ -1605,7 +1707,7 @@ void TTrain::OnCommand_reverserbackward( TTrain *Train, command_data const &Comm
if( ( Train->mvOccupied->ActiveDir == -1 )
&& ( Train->DynamicObject->Mechanik ) ) {
Train->DynamicObject->Mechanik->CheckVehicles( Change_direction );
Train->DynamicObject->Mechanik->DirectionChange();
}
}
}
@@ -2985,6 +3087,13 @@ void TTrain::OnCommand_motorblowersdisableall( TTrain *Train, command_data const
}
}
void TTrain::OnCommand_coolingfanstoggle( TTrain *Train, command_data const &Command ) {
if( Command.action != GLFW_PRESS ) { return; }
Train->mvControlled->RVentForceOn = ( !Train->mvControlled->RVentForceOn );
}
void TTrain::OnCommand_motorconnectorsopen( TTrain *Train, command_data const &Command ) {
// TODO: don't rely on presense of 3d model to determine presence of the switch
@@ -4088,12 +4197,12 @@ void TTrain::OnCommand_generictoggle( TTrain *Train, command_data const &Command
if( item.GetDesiredValue() < 0.5 ) {
// turn on
// visual feedback
item.UpdateValue( 1.0, Train->dsbSwitch );
item.UpdateValue( 1.0 );
}
else {
// turn off
// visual feedback
item.UpdateValue( 0.0, Train->dsbSwitch );
item.UpdateValue( 0.0 );
}
}
}
@@ -4591,6 +4700,13 @@ void TTrain::OnCommand_doorcloseall( TTrain *Train, command_data const &Command
}
}
void TTrain::OnCommand_doorsteptoggle( TTrain *Train, command_data const &Command ) {
if( Command.action == GLFW_PRESS ) {
Train->mvOccupied->PermitDoorStep( false == Train->mvOccupied->Doors.step_enabled );
}
}
void TTrain::OnCommand_carcouplingincrease( TTrain *Train, command_data const &Command ) {
if( ( true == Command.freefly )
@@ -4860,9 +4976,9 @@ void TTrain::OnCommand_cabchangeforward( TTrain *Train, command_data const &Comm
if( false == Train->CabChange( 1 ) ) {
if( TestFlag( Train->DynamicObject->MoverParameters->Couplers[ end::front ].CouplingFlag, coupling::gangway ) ) {
// przejscie do nastepnego pojazdu
TDynamicObject *dynobj = Train->DynamicObject->PrevConnected;
TDynamicObject *dynobj = Train->DynamicObject->PrevConnected();
dynobj->MoverParameters->ActiveCab = (
Train->DynamicObject->PrevConnectedNo ?
Train->DynamicObject->MoverParameters->Neighbours[end::front].vehicle_end ?
-1 :
1 );
Train->MoveToVehicle(dynobj);
@@ -4877,9 +4993,9 @@ void TTrain::OnCommand_cabchangebackward( TTrain *Train, command_data const &Com
if( false == Train->CabChange( -1 ) ) {
if( TestFlag( Train->DynamicObject->MoverParameters->Couplers[ end::rear ].CouplingFlag, coupling::gangway ) ) {
// przejscie do nastepnego pojazdu
TDynamicObject *dynobj = Train->DynamicObject->NextConnected;
TDynamicObject *dynobj = Train->DynamicObject->NextConnected();
dynobj->MoverParameters->ActiveCab = (
Train->DynamicObject->NextConnectedNo ?
Train->DynamicObject->MoverParameters->Neighbours[end::rear].vehicle_end ?
-1 :
1 );
Train->MoveToVehicle(dynobj);
@@ -5147,8 +5263,10 @@ bool TTrain::Update( double const Deltatime )
fPress[i][0] = p->MoverParameters->BrakePress;
fPress[i][1] = p->MoverParameters->PipePress;
fPress[i][2] = p->MoverParameters->ScndPipePress;
bDoors[i][1] = ( false == p->MoverParameters->Doors.instances[ side::right ].is_closed );
bDoors[i][2] = ( false == p->MoverParameters->Doors.instances[ side::left ].is_closed );
bDoors[i][1] = ( p->MoverParameters->Doors.instances[ side::left ].position > 0.f );
bDoors[i][2] = ( p->MoverParameters->Doors.instances[ side::right ].position > 0.f );
bDoors[i][3] = ( p->MoverParameters->Doors.instances[ side::left ].step_position > 0.f );
bDoors[i][4] = ( p->MoverParameters->Doors.instances[ side::right ].step_position > 0.f );
bDoors[i][0] = ( bDoors[i][1] || bDoors[i][2] );
iDoorNo[i] = p->iAnimType[ANIM_DOORS];
iUnits[i] = iUnitNo;
@@ -5195,12 +5313,16 @@ bool TTrain::Update( double const Deltatime )
}
else
{
fPress[i][0] = 0;
fPress[i][1] = 0;
fPress[i][2] = 0;
bDoors[i][0] = false;
bDoors[i][1] = false;
bDoors[i][2] = false;
fPress[i][0]
= fPress[i][1]
= fPress[i][2]
= 0;
bDoors[i][0]
= bDoors[i][1]
= bDoors[i][2]
= bDoors[i][3]
= bDoors[i][4]
= false;
bSlip[i] = false;
iUnits[i] = 0;
cCode[i] = 0; //'0';
@@ -5208,11 +5330,12 @@ bool TTrain::Update( double const Deltatime )
}
}
if (mvControlled == mvOccupied)
fEIMParams[0][3] = mvControlled->eimv[eimv_Fzad]; // procent zadany
else
fEIMParams[0][3] =
mvControlled->eimv[eimv_Fzad] - mvOccupied->LocalBrakeRatio(); // procent zadany
// if (mvControlled == mvOccupied)
// fEIMParams[0][3] = mvControlled->eimv[eimv_Fzad]; // procent zadany
// else
// fEIMParams[0][3] =
// mvControlled->eimv[eimv_Fzad] - mvOccupied->LocalBrakeRatio(); // procent zadany
fEIMParams[0][3] = mvOccupied->eimic_real;
fEIMParams[0][4] = Max0R(fEIMParams[0][3], 0);
fEIMParams[0][5] = -Min0R(fEIMParams[0][3], 0);
fEIMParams[0][1] = fEIMParams[0][4] * mvControlled->eimv[eimv_Fful];
@@ -5286,14 +5409,14 @@ bool TTrain::Update( double const Deltatime )
{
TDynamicObject *tmp;
tmp = NULL;
if (DynamicObject->NextConnected)
if (DynamicObject->NextConnected())
if ((TestFlag(mvControlled->Couplers[1].CouplingFlag, ctrain_controll)) &&
(mvOccupied->ActiveCab == 1))
tmp = DynamicObject->NextConnected;
if (DynamicObject->PrevConnected)
tmp = DynamicObject->NextConnected();
if (DynamicObject->PrevConnected())
if ((TestFlag(mvControlled->Couplers[0].CouplingFlag, ctrain_controll)) &&
(mvOccupied->ActiveCab == -1))
tmp = DynamicObject->PrevConnected;
tmp = DynamicObject->PrevConnected();
if( tmp ) {
if( tmp->MoverParameters->Power > 0 ) {
if( ggI1B.SubModel ) {
@@ -5334,7 +5457,7 @@ bool TTrain::Update( double const Deltatime )
ggClockHInd.Update();
}
Cabine[iCabn].Update(); // nowy sposób ustawienia animacji
Cabine[iCabn].Update( mvControlled->Battery || mvControlled->ConverterFlag ); // nowy sposób ustawienia animacji
if (ggZbS.SubModel)
{
ggZbS.UpdateValue(mvOccupied->Handle->GetCP());
@@ -5681,10 +5804,10 @@ bool TTrain::Update( double const Deltatime )
tmp = NULL;
if ((TestFlag(mvControlled->Couplers[1].CouplingFlag, ctrain_controll)) &&
(mvOccupied->ActiveCab > 0))
tmp = DynamicObject->NextConnected;
tmp = DynamicObject->NextConnected();
if ((TestFlag(mvControlled->Couplers[0].CouplingFlag, ctrain_controll)) &&
(mvOccupied->ActiveCab < 0))
tmp = DynamicObject->PrevConnected;
tmp = DynamicObject->PrevConnected();
if (tmp)
if ( mvControlled->Battery || mvControlled->ConverterFlag ) {
@@ -5751,7 +5874,21 @@ bool TTrain::Update( double const Deltatime )
}
}
// McZapkie-080602: obroty (albo translacje) regulatorow
if (ggMainCtrl.SubModel) {
if( ggJointCtrl.SubModel != nullptr ) {
// joint master controller moves forward to adjust power and backward to adjust brakes
auto const brakerangemultiplier {
( mvControlled->CoupledCtrl ?
mvControlled->MainCtrlPosNo + mvControlled->ScndCtrlPosNo :
mvControlled->MainCtrlPosNo )
/ static_cast<double>(LocalBrakePosNo) };
ggJointCtrl.UpdateValue(
( mvOccupied->LocalBrakePosA > 0.0 ? mvOccupied->LocalBrakePosA * LocalBrakePosNo * -1 * brakerangemultiplier :
mvControlled->CoupledCtrl ? double( mvControlled->MainCtrlPos + mvControlled->ScndCtrlPos ) :
double( mvControlled->MainCtrlPos ) ),
dsbNastawnikJazdy );
ggJointCtrl.Update();
}
if ( ggMainCtrl.SubModel != nullptr ) {
#ifdef _WIN32
if( ( DynamicObject->Mechanik != nullptr )
@@ -5792,6 +5929,7 @@ bool TTrain::Update( double const Deltatime )
dsbNastawnikBocz );
ggScndCtrl.Update();
}
ggScndCtrlButton.Update();
if (ggDirKey.SubModel) {
if (mvControlled->TrainType != dt_EZT)
ggDirKey.UpdateValue(
@@ -5837,7 +5975,8 @@ bool TTrain::Update( double const Deltatime )
ggBrakeCtrl.UpdateValue(mvOccupied->fBrakeCtrlPos);
ggBrakeCtrl.Update();
}
if( ggLocalBrake.SubModel ) {
if( ggLocalBrake.SubModel != nullptr ) {
#ifdef _WIN32
if( ( DynamicObject->Mechanik != nullptr )
&& ( false == DynamicObject->Mechanik->AIControllFlag ) // nie blokujemy AI
@@ -6424,7 +6563,7 @@ bool TTrain::CabChange(int iDirection)
DynamicObject->asBaseDir + DynamicObject->MoverParameters->TypeName + ".mmd" ) ) {
// zmiana kabiny w ramach tego samego pojazdu
DynamicObject->MoverParameters->CabActivisation(); // załączenie rozrządu (wirtualne kabiny)
DynamicObject->Mechanik->CheckVehicles( Change_direction );
DynamicObject->Mechanik->DirectionChange();
return true; // udało się zmienić kabinę
}
}
@@ -6889,6 +7028,9 @@ bool TTrain::InitializeCab(int NewCabNo, std::string const &asFileName)
if( dsbReverserKey.offset() == nullvector ) {
dsbReverserKey.offset( ggDirKey.model_offset() );
}
if( dsbNastawnikJazdy.offset() == nullvector ) {
dsbNastawnikJazdy.offset( ggJointCtrl.model_offset() );
}
if( dsbNastawnikJazdy.offset() == nullvector ) {
dsbNastawnikJazdy.offset( ggMainCtrl.model_offset() );
}
@@ -6987,25 +7129,24 @@ void TTrain::DynamicSet(TDynamicObject *d)
mvOccupied = mvControlled = d ? DynamicObject->MoverParameters : NULL; // albo silnikowy w EZT
if (!DynamicObject)
return;
if (mvControlled->TrainType & dt_EZT) // na razie dotyczy to EZT
if (DynamicObject->NextConnected ? mvControlled->Couplers[1].AllowedFlag & ctrain_depot :
false)
{ // gdy jest człon od sprzęgu 1, a sprzęg łączony
// warsztatowo (powiedzmy)
if ((mvControlled->Power < 1.0) && (mvControlled->Couplers[1].Connected->Power >
1.0)) // my nie mamy mocy, ale ten drugi ma
mvControlled =
DynamicObject->NextConnected->MoverParameters; // będziemy sterować tym z mocą
// TODO: leverage code already present in TDynamicObject::ControlledFind()
if( ( d->MoverParameters->TrainType == dt_EZT )
|| ( d->MoverParameters->TrainType == dt_DMU ) ) {
if( ( d->NextConnected() != nullptr )
&& ( true == TestFlag( d->MoverParameters->Couplers[ end::rear ].AllowedFlag, coupling::permanent ) ) ) {
if( ( mvControlled->Power < 1.0 ) && ( mvControlled->Couplers[ 1 ].Connected->Power > 1.0 ) ) {
// my nie mamy mocy, ale ten drugi ma
mvControlled = DynamicObject->NextConnected()->MoverParameters; // będziemy sterować tym z mocą
}
}
else if( ( d->PrevConnected() != nullptr )
&& ( true == TestFlag( d->MoverParameters->Couplers[ end::front ].AllowedFlag, coupling::permanent ) ) ) {
if( ( mvControlled->Power < 1.0 ) && ( mvControlled->Couplers[ 0 ].Connected->Power > 1.0 ) ) {
// my nie mamy mocy, ale ten drugi ma
mvControlled = DynamicObject->PrevConnected()->MoverParameters; // będziemy sterować tym z mocą
}
}
else if (DynamicObject->PrevConnected ?
mvControlled->Couplers[0].AllowedFlag & ctrain_depot :
false)
{ // gdy jest człon od sprzęgu 0, a sprzęg łączony
// warsztatowo (powiedzmy)
if ((mvControlled->Power < 1.0) && (mvControlled->Couplers[0].Connected->Power >
1.0)) // my nie mamy mocy, ale ten drugi ma
mvControlled =
DynamicObject->PrevConnected->MoverParameters; // będziemy sterować tym z mocą
}
mvSecond = NULL; // gdyby się nic nie znalazło
if (mvOccupied->Power > 1.0) // dwuczłonowe lub ukrotnienia, żeby nie szukać każdorazowo
@@ -7226,9 +7367,11 @@ void TTrain::clear_cab_controls()
// other cab controls
// TODO: arrange in more readable manner, and eventually refactor
ggJointCtrl.Clear();
ggMainCtrl.Clear();
ggMainCtrlAct.Clear();
ggScndCtrl.Clear();
ggScndCtrlButton.Clear();
ggDirKey.Clear();
ggBrakeCtrl.Clear();
ggLocalBrake.Clear();
@@ -7697,6 +7840,13 @@ void TTrain::set_cab_controls( int const Cab ) {
1.f :
0.f );
}
// tempomat
if( ggScndCtrlButton.type() != TGaugeType::push ) {
ggScndCtrlButton.PutValue(
( mvControlled->ScndCtrlPos > 0 ) ?
1.f :
0.f );
}
// we reset all indicators, as they're set during the update pass
// TODO: when cleaning up break setting indicator state into a separate function, so we can reuse it
@@ -7807,7 +7957,8 @@ bool TTrain::initialize_button(cParser &Parser, std::string const &Label, int co
// TODO: move viable dedicated lights to the automatic light array
std::unordered_map<std::string, bool *> const autolights = {
{ "i-doorpermit_left:", &mvOccupied->Doors.instances[side::left].open_permit },
{ "i-doorpermit_right:", &mvOccupied->Doors.instances[ side::right ].open_permit }
{ "i-doorpermit_right:", &mvOccupied->Doors.instances[ side::right ].open_permit },
{ "i-doorstep:", &mvOccupied->Doors.step_enabled }
};
{
auto lookup = autolights.find( Label );
@@ -7860,6 +8011,7 @@ bool TTrain::initialize_button(cParser &Parser, std::string const &Label, int co
bool TTrain::initialize_gauge(cParser &Parser, std::string const &Label, int const Cabindex) {
std::unordered_map<std::string, TGauge &> const gauges = {
{ "jointctrl:", ggJointCtrl },
{ "mainctrl:", ggMainCtrl },
{ "scndctrl:", ggScndCtrl },
{ "dirkey:" , ggDirKey },
@@ -7953,6 +8105,7 @@ bool TTrain::initialize_gauge(cParser &Parser, std::string const &Label, int con
{ "cablight_sw:", ggCabLightButton },
{ "cablightdim_sw:", ggCabLightDimButton },
{ "battery_sw:", ggBatteryButton },
{ "tempomat_sw:", ggScndCtrlButton },
{ "universal0:", ggUniversals[ 0 ] },
{ "universal1:", ggUniversals[ 1 ] },
{ "universal2:", ggUniversals[ 2 ] },
@@ -7964,14 +8117,32 @@ bool TTrain::initialize_gauge(cParser &Parser, std::string const &Label, int con
{ "universal8:", ggUniversals[ 8 ] },
{ "universal9:", ggUniversals[ 9 ] }
};
{
auto lookup = gauges.find( Label );
if( lookup != gauges.end() ) {
lookup->second.Load( Parser, DynamicObject );
m_controlmapper.insert( lookup->second, lookup->first );
return true;
}
}
// TODO: move viable dedicated gauges to the automatic array
std::unordered_map<std::string, bool *> const autoboolgauges = {
{ "doorstep_sw:", &mvOccupied->Doors.step_enabled },
{ "coolingfans_sw:", &mvControlled->RVentForceOn }
};
{
auto lookup = autoboolgauges.find( Label );
if( lookup != autoboolgauges.end() ) {
auto &gauge = Cabine[ Cabindex ].Gauge( -1 ); // pierwsza wolna lampka
gauge.Load( Parser, DynamicObject );
gauge.AssignBool( lookup->second );
m_controlmapper.insert( gauge, lookup->first );
return true;
}
}
// ABu 090305: uniwersalne przyciski lub inne rzeczy
else if( Label == "mainctrlact:" ) {
if( Label == "mainctrlact:" ) {
ggMainCtrlAct.Load( Parser, DynamicObject);
}
// SEKCJA WSKAZNIKOW
@@ -8053,7 +8224,7 @@ bool TTrain::initialize_gauge(cParser &Parser, std::string const &Label, int con
Parser.getTokens(2, false);
Parser >> i >> j;
auto &gauge = Cabine[Cabindex].Gauge(-1); // pierwsza wolna gałka
gauge.Load(Parser, DynamicObject);
gauge.Load(Parser, DynamicObject, 0.1);
gauge.AssignFloat(&fPress[i - 1][j]);
}
else if ((Label == "brakepress:") || (Label == "brakepressb:"))
@@ -8161,6 +8332,9 @@ bool TTrain::initialize_gauge(cParser &Parser, std::string const &Label, int con
}
}
}
else if( Label == "clock_seconds:" ) {
ggClockSInd.Load( Parser, DynamicObject );
}
else if (Label == "evoltage:")
{
// woltomierz napiecia silnikow

15
Train.h
View File

@@ -18,6 +18,8 @@ http://mozilla.org/MPL/2.0/.
#include "command.h"
#include "pythonscreenviewer.h"
#undef snprintf // pyint.h->python
// typedef enum {st_Off, st_Starting, st_On, st_ShuttingDown} T4State;
const int maxcab = 2;
@@ -33,7 +35,7 @@ class TCab {
public:
// methods
void Load(cParser &Parser);
void Update();
void Update( bool const Power );
TGauge &Gauge( int n = -1 ); // pobranie adresu obiektu
TButton &Button( int n = -1 ); // pobranie adresu obiektu
// members
@@ -52,7 +54,7 @@ public:
private:
// members
std::vector<TGauge> ggList;
std::deque<TGauge> ggList; // need a container which doesn't invalidate references
std::vector<TButton> btList;
};
@@ -160,6 +162,7 @@ class TTrain
// 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_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 );
@@ -171,6 +174,7 @@ class TTrain
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 );
@@ -267,6 +271,7 @@ class TTrain
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 );
@@ -328,6 +333,7 @@ class TTrain
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_carcouplingincrease( TTrain *Train, command_data const &Command );
static void OnCommand_carcouplingdisconnect( TTrain *Train, command_data const &Command );
static void OnCommand_departureannounce( TTrain *Train, command_data const &Command );
@@ -380,10 +386,11 @@ public: // reszta może by?publiczna
TGauge ggWater1TempB;
// McZapkie: definicje regulatorow
TGauge ggJointCtrl;
TGauge ggMainCtrl;
TGauge ggMainCtrlAct;
TGauge ggScndCtrl;
TGauge ggScndCtrlButton; // NOTE: not used?
TGauge ggScndCtrlButton;
TGauge ggDirKey;
TGauge ggBrakeCtrl;
TGauge ggLocalBrake;
@@ -646,7 +653,7 @@ private:
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][3]; // drzwi dla wszystkich czlonow
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

View File

@@ -23,6 +23,7 @@ commanddescription_sequence Commands_descriptions = {
{ "aidriverenable", command_target::vehicle, command_mode::oneoff },
{ "aidriverdisable", command_target::vehicle, command_mode::oneoff },
{ "jointcontrollerset", command_target::vehicle, command_mode::oneoff },
{ "mastercontrollerincrease", command_target::vehicle, command_mode::oneoff },
{ "mastercontrollerincreasefast", command_target::vehicle, command_mode::oneoff },
{ "mastercontrollerdecrease", command_target::vehicle, command_mode::oneoff },
@@ -153,6 +154,7 @@ commanddescription_sequence Commands_descriptions = {
{ "doorcloseleft", command_target::vehicle, command_mode::oneoff },
{ "doorcloseright", command_target::vehicle, command_mode::oneoff },
{ "doorcloseall", command_target::vehicle, command_mode::oneoff },
{ "doorsteptoggle", command_target::vehicle, command_mode::oneoff },
{ "departureannounce", command_target::vehicle, command_mode::oneoff },
{ "doorlocktoggle", command_target::vehicle, command_mode::oneoff },
{ "pantographcompressorvalvetoggle", command_target::vehicle, command_mode::oneoff },
@@ -224,6 +226,8 @@ commanddescription_sequence Commands_descriptions = {
{ "motorblowerstogglefront", command_target::vehicle, command_mode::oneoff },
{ "motorblowerstogglerear", command_target::vehicle, command_mode::oneoff },
{ "motorblowersdisableall", command_target::vehicle, command_mode::oneoff },
{ "coolingfanstoggle", command_target::vehicle, command_mode::oneoff },
{ "tempomattoggle", command_target::vehicle, command_mode::oneoff },
{ "timejump", command_target::simulation, command_mode::oneoff },
{ "timejumplarge", command_target::simulation, command_mode::oneoff },
{ "timejumpsmall", command_target::simulation, command_mode::oneoff },

View File

@@ -17,6 +17,7 @@ enum class user_command {
aidriverenable = 0,
aidriverdisable,
jointcontrollerset,
mastercontrollerincrease,
mastercontrollerincreasefast,
mastercontrollerdecrease,
@@ -146,6 +147,7 @@ enum class user_command {
doorcloseleft,
doorcloseright,
doorcloseall,
doorsteptoggle,
departureannounce,
doorlocktoggle,
pantographcompressorvalvetoggle,
@@ -217,6 +219,8 @@ enum class user_command {
motorblowerstogglefront,
motorblowerstogglerear,
motorblowersdisableall,
coolingfanstoggle,
tempomattoggle,
timejump,
timejumplarge,

View File

@@ -27,6 +27,7 @@ driverkeyboard_input::default_bindings() {
m_bindingsetups = {
{ user_command::aidriverenable, GLFW_KEY_Q | keymodifier::shift },
{ user_command::aidriverdisable, GLFW_KEY_Q },
// jointcontrollerset,
{ user_command::mastercontrollerincrease, GLFW_KEY_KP_ADD },
{ user_command::mastercontrollerincreasefast, GLFW_KEY_KP_ADD | keymodifier::shift },
{ user_command::mastercontrollerdecrease, GLFW_KEY_KP_SUBTRACT },
@@ -154,6 +155,7 @@ driverkeyboard_input::default_bindings() {
// doorcloseleft,
// doorcloseright,
{ user_command::doorcloseall, GLFW_KEY_SLASH | keymodifier::control },
// doorsteptoggle,
{ user_command::departureannounce, GLFW_KEY_SLASH },
{ user_command::doorlocktoggle, GLFW_KEY_S | keymodifier::control },
{ user_command::pantographcompressorvalvetoggle, GLFW_KEY_V | keymodifier::control },
@@ -225,6 +227,9 @@ driverkeyboard_input::default_bindings() {
{ user_command::motorblowerstogglefront, GLFW_KEY_N | keymodifier::shift },
{ user_command::motorblowerstogglerear, GLFW_KEY_M | keymodifier::shift },
{ user_command::motorblowersdisableall, GLFW_KEY_M | keymodifier::control },
// coolingfanstoggle
// tempomattoggle
// admin_timejump,
{ user_command::timejumplarge, GLFW_KEY_F1 | keymodifier::control },
{ user_command::timejumpsmall, GLFW_KEY_F1 | keymodifier::shift },

View File

@@ -22,6 +22,8 @@ http://mozilla.org/MPL/2.0/.
#include "uilayer.h"
#include "Logs.h"
auto const EU07_CONTROLLER_MOUSESLIDERSIZE{ 0.65 };
void
mouse_slider::bind( user_command const &Command ) {
@@ -30,6 +32,7 @@ mouse_slider::bind( user_command const &Command ) {
auto const *train { simulation::Train };
TMoverParameters const *vehicle { nullptr };
switch( m_command ) {
case user_command::jointcontrollerset:
case user_command::mastercontrollerset:
case user_command::secondcontrollerset: {
vehicle = ( train ? train->Controlled() : nullptr );
@@ -48,6 +51,29 @@ mouse_slider::bind( user_command const &Command ) {
// calculate initial value and accepted range
switch( m_command ) {
case user_command::jointcontrollerset: {
// NOTE: special case, merges two separate controls
auto const *occupied { train ? train->Occupied() : nullptr };
if( occupied == nullptr ) { return; }
auto const powerrange { static_cast<double>(
vehicle->CoupledCtrl ?
vehicle->MainCtrlPosNo + vehicle->ScndCtrlPosNo :
vehicle->MainCtrlPosNo ) };
// for simplicity upper half of the range controls power, lower controls brakes
auto const brakerangemultiplier { powerrange / LocalBrakePosNo };
m_valuerange = 1.0;
m_value =
0.5
+ 0.5 * ( vehicle->CoupledCtrl ?
vehicle->MainCtrlPos + vehicle->ScndCtrlPos :
vehicle->MainCtrlPos ) / powerrange
- 0.5 * occupied->LocalBrakePosA;
m_analogue = true;
m_invertrange = false;
break;
}
case user_command::mastercontrollerset: {
m_valuerange = (
vehicle->CoupledCtrl ?
@@ -58,24 +84,28 @@ mouse_slider::bind( user_command const &Command ) {
vehicle->MainCtrlPos + vehicle->ScndCtrlPos :
vehicle->MainCtrlPos );
m_analogue = false;
m_invertrange = false;
break;
}
case user_command::secondcontrollerset: {
m_valuerange = vehicle->ScndCtrlPosNo;
m_value = vehicle->ScndCtrlPos;
m_analogue = false;
m_invertrange = true;
break;
}
case user_command::trainbrakeset: {
m_valuerange = 1.0;
m_value = ( vehicle->fBrakeCtrlPos - vehicle->Handle->GetPos( bh_MIN ) ) / ( vehicle->Handle->GetPos( bh_MAX ) - vehicle->Handle->GetPos( bh_MIN ) );
m_analogue = true;
m_invertrange = true;
break;
}
case user_command::independentbrakeset: {
m_valuerange = 1.0;
m_value = vehicle->LocalBrakePosA;
m_analogue = true;
m_invertrange = true;
break;
}
default: {
@@ -87,14 +117,18 @@ mouse_slider::bind( user_command const &Command ) {
Application.get_cursor_pos( m_cursorposition.x, m_cursorposition.y );
Application.set_cursor( GLFW_CURSOR_DISABLED );
auto const controlsize { Global.iWindowHeight * 0.75 };
auto const controlsize { Global.iWindowHeight * EU07_CONTROLLER_MOUSESLIDERSIZE };
auto const controledge { Global.iWindowHeight * 0.5 + controlsize * 0.5 };
auto const stepsize { controlsize / m_valuerange };
if( m_invertrange ) {
m_value = ( m_analogue ? 1.0 : m_valuerange ) - m_value;
}
Application.set_cursor_pos(
Global.iWindowWidth * 0.5,
( m_analogue ?
controledge - ( 1.0 - m_value ) * controlsize :
controledge - m_value * controlsize :
controledge - m_value * stepsize - 0.5 * stepsize ) );
}
@@ -109,15 +143,17 @@ mouse_slider::release() {
void
mouse_slider::on_move( double const Mousex, double const Mousey ) {
auto const controlsize { Global.iWindowHeight * 0.75 };
auto const controlsize { Global.iWindowHeight * EU07_CONTROLLER_MOUSESLIDERSIZE };
auto const controledge { Global.iWindowHeight * 0.5 + controlsize * 0.5 };
auto const stepsize { controlsize / m_valuerange };
auto mousey = clamp( Mousey, controledge - controlsize, controledge );
m_value = (
m_analogue ?
1.0 - ( ( controledge - mousey ) / controlsize ) :
( controledge - mousey ) / controlsize :
std::floor( ( controledge - mousey ) / stepsize ) );
if( m_invertrange ) {
m_value = ( m_analogue ? 1.0 : m_valuerange ) - m_value; }
}
@@ -374,6 +410,7 @@ drivermouse_input::button( int const Button, int const Action ) {
m_varyingpollrate = true;
break;
}
case user_command::jointcontrollerset:
case user_command::mastercontrollerset:
case user_command::secondcontrollerset:
case user_command::trainbrakeset:
@@ -386,6 +423,7 @@ drivermouse_input::button( int const Button, int const Action ) {
break;
}
}
// NOTE: basic keyboard controls don't have any parameters
// NOTE: as we haven't yet implemented either item id system or multiplayer, the 'local' controlled vehicle and entity have temporary ids of 0
// TODO: pass correct entity id once the missing systems are in place
@@ -452,6 +490,9 @@ void
drivermouse_input::default_bindings() {
m_buttonbindings = {
{ "jointctrl:", {
user_command::jointcontrollerset,
user_command::none } },
{ "mainctrl:", {
user_command::mastercontrollerset,
user_command::none } },
@@ -461,6 +502,9 @@ drivermouse_input::default_bindings() {
{ "shuntmodepower:", {
user_command::secondcontrollerincrease,
user_command::secondcontrollerdecrease } },
{ "tempomat_sw:", {
user_command::tempomattoggle,
user_command::none } },
{ "dirkey:", {
user_command::reverserincrease,
user_command::reverserdecrease } },
@@ -519,6 +563,9 @@ drivermouse_input::default_bindings() {
{ "motorblowersalloff_sw:", {
user_command::motorblowersdisableall,
user_command::none } },
{ "coolingfans_sw:", {
user_command::coolingfanstoggle,
user_command::none } },
{ "main_off_bt:", {
user_command::linebreakeropen,
user_command::none } },
@@ -591,6 +638,9 @@ drivermouse_input::default_bindings() {
{ "dooralloff_sw:", {
user_command::doorcloseall,
user_command::none } },
{ "doorstep_sw:", {
user_command::doorsteptoggle,
user_command::none } },
{ "departure_signal_bt:", {
user_command::departureannounce,
user_command::none } },

View File

@@ -39,6 +39,7 @@ private:
double m_value { 0.0 };
double m_valuerange { 0.0 };
bool m_analogue { false };
bool m_invertrange { false };
glm::dvec2 m_cursorposition { 0.0 };
};

View File

@@ -23,6 +23,7 @@ driver_ui::driver_ui() {
clear_panels();
// bind the panels with ui object. maybe not the best place for this but, eh
push_back( &m_aidpanel );
push_back( &m_scenariopanel );
push_back( &m_timetablepanel );
push_back( &m_debugpanel );
push_back( &m_transcriptspanel );
@@ -36,6 +37,10 @@ driver_ui::driver_ui() {
m_aidpanel.title = locale::strings[ locale::string::driver_aid_header ];
m_scenariopanel.title = locale::strings[ locale::string::driver_scenario_header ];
m_scenariopanel.size_min = { 435, 85 };
m_scenariopanel.size_max = { Global.iWindowWidth * 0.95, Global.iWindowHeight * 0.95 };
m_timetablepanel.title = locale::strings[ locale::string::driver_timetable_header ];
m_timetablepanel.size_min = { 435, 110 };
m_timetablepanel.size_max = { 435, Global.iWindowHeight * 0.95 };
@@ -51,7 +56,7 @@ void driver_ui::render_menu_contents() {
if (ImGui::BeginMenu(locale::strings[locale::string::ui_mode_windows].c_str()))
{
ImGui::MenuItem(m_aidpanel.title.c_str(), "F1", &m_aidpanel.is_open);
ImGui::MenuItem(m_timetablepanel.title.c_str(), "F2", &m_timetablepanel.is_open);
ImGui::MenuItem(locale::strings[locale::string::driver_timetable_name].c_str(), "F2", &m_timetablepanel.is_open);
ImGui::MenuItem(m_debugpanel.get_name().c_str(), "F12", &m_debugpanel.is_open);
ImGui::MenuItem(m_mappanel.get_name().c_str(), "Tab", &m_mappanel.is_open);
@@ -75,6 +80,7 @@ driver_ui::on_key( int const Key, int const Action ) {
case GLFW_KEY_TAB:
case GLFW_KEY_F1:
case GLFW_KEY_F2:
case GLFW_KEY_F3:
case GLFW_KEY_F10:
case GLFW_KEY_F12: { // ui mode selectors
@@ -128,6 +134,12 @@ driver_ui::on_key( int const Key, int const Action ) {
return true;
}
case GLFW_KEY_F3: {
// debug panel
m_scenariopanel.is_open = !m_scenariopanel.is_open;
return true;
}
case GLFW_KEY_F12: {
// debug panel
m_debugpanel.is_open = !m_debugpanel.is_open;

View File

@@ -51,6 +51,7 @@ private:
// members
drivingaid_panel m_aidpanel { "Driving Aid", true };
scenario_panel m_scenariopanel { "Scenario", true };
timetable_panel m_timetablepanel { "Timetable", false };
debug_panel m_debugpanel { "Debug Data", false };
transcripts_panel m_transcriptspanel { "Transcripts", true }; // voice transcripts

View File

@@ -27,8 +27,6 @@ http://mozilla.org/MPL/2.0/.
#include "utilities.h"
#include "Logs.h"
#undef snprintf // defined by train.h->pyint.h->python
void
drivingaid_panel::update() {
@@ -149,6 +147,79 @@ drivingaid_panel::update() {
}
}
void
scenario_panel::update() {
if( false == is_open ) { return; }
text_lines.clear();
auto const *train { simulation::Train };
auto const *controlled { ( train ? train->Dynamic() : nullptr ) };
auto const &camera { Global.pCamera };
m_nearest = (
false == FreeFlyModeFlag ? controlled :
camera.m_owner != nullptr ? camera.m_owner :
std::get<TDynamicObject *>( simulation::Region->find_vehicle( camera.Pos, 20, false, false ) ) ); // w trybie latania lokalizujemy wg mapy
if( m_nearest == nullptr ) { return; }
auto const *owner { (
( ( m_nearest->Mechanik != nullptr ) && ( m_nearest->Mechanik->Primary() ) ) ?
m_nearest->Mechanik :
m_nearest->ctOwner ) };
if( owner == nullptr ) { return; }
std::string textline =
locale::strings[ locale::string::driver_scenario_currenttask ] + "\n "
+ owner->OrderCurrent();
text_lines.emplace_back( textline, Global.UITextColor );
}
void
scenario_panel::render() {
if( false == is_open ) { return; }
if( true == text_lines.empty() ) { return; }
if( m_nearest == nullptr ) { return; } // possibly superfluous given the above but, eh
auto flags =
ImGuiWindowFlags_NoFocusOnAppearing
| ImGuiWindowFlags_NoCollapse
| ( size.x > 0 ? ImGuiWindowFlags_NoResize : 0 );
if( size.x > 0 ) {
ImGui::SetNextWindowSize( ImVec2( size.x, size.y ) );
}
if( size_min.x > 0 ) {
ImGui::SetNextWindowSizeConstraints( ImVec2( size_min.x, size_min.y ), ImVec2( size_max.x, size_max.y ) );
}
auto const panelname { (
title.empty() ?
name :
title )
+ "###" + name };
if( true == ImGui::Begin( panelname.c_str(), &is_open, flags ) ) {
// potential assignment section
auto const *owner { (
( ( m_nearest->Mechanik != nullptr ) && ( m_nearest->Mechanik->Primary() ) ) ?
m_nearest->Mechanik :
m_nearest->ctOwner ) };
if( owner != nullptr ) {
auto const assignmentheader { locale::strings[ locale::string::driver_scenario_assignment ] };
if( ( false == owner->assignment().empty() )
&& ( true == ImGui::CollapsingHeader( assignmentheader.c_str() ) ) ) {
ImGui::TextWrapped( owner->assignment().c_str() );
ImGui::Separator();
}
}
// current task
for( auto const &line : text_lines ) {
ImGui::TextColored( ImVec4( line.color.r, line.color.g, line.color.b, line.color.a ), line.data.c_str() );
}
}
ImGui::End();
}
void
timetable_panel::update() {
@@ -164,12 +235,14 @@ timetable_panel::update() {
{ // current time
std::snprintf(
m_buffer.data(), m_buffer.size(),
locale::strings[ locale::string::driver_timetable_time ].c_str(),
locale::strings[ locale::string::driver_timetable_header ].c_str(),
40, 40,
locale::strings[ locale::string::driver_timetable_name ].c_str(),
time.wHour,
time.wMinute,
time.wSecond );
text_lines.emplace_back( m_buffer.data(), Global.UITextColor );
title = m_buffer.data();
}
auto *vehicle { (
@@ -215,8 +288,7 @@ timetable_panel::update() {
auto consistmass { owner->fMass };
auto consistlength { owner->fLength };
if( ( owner->mvControlling->TrainType != dt_DMU )
&& ( owner->mvControlling->TrainType != dt_EZT )
&& ( owner->pVehicles[end::front] != owner->pVehicles[end::rear] ) ) {
&& ( owner->mvControlling->TrainType != dt_EZT ) ) {
//odejmij lokomotywy czynne, a przynajmniej aktualną
consistmass -= owner->pVehicle->MoverParameters->TotalMass;
// subtract potential other half of a two-part vehicle
@@ -224,7 +296,6 @@ timetable_panel::update() {
if( previous != nullptr ) { consistmass -= previous->MoverParameters->TotalMass; }
auto const *next { owner->pVehicle->Next( coupling::permanent ) };
if( next != nullptr ) { consistmass -= next->MoverParameters->TotalMass; }
// consistlength -= owner->pVehicle->MoverParameters->Dim.L;
}
std::snprintf(
m_buffer.data(), m_buffer.size(),
@@ -369,7 +440,12 @@ debug_panel::render() {
if( size_min.x > 0 ) {
ImGui::SetNextWindowSizeConstraints( ImVec2( size_min.x, size_min.y ), ImVec2( size_max.x, size_max.y ) );
}
if( true == ImGui::Begin( name.c_str(), &is_open, flags ) ) {
auto const panelname { (
title.empty() ?
name :
title )
+ "###" + name };
if( true == ImGui::Begin( panelname.c_str(), &is_open, flags ) ) {
// header section
for( auto const &line : text_lines ) {
ImGui::TextColored( ImVec4( line.color.r, line.color.g, line.color.b, line.color.a ), line.data.c_str() );
@@ -568,10 +644,7 @@ debug_panel::update_vehicle_coupler( int const Side ) {
// NOTE: mover and vehicle are guaranteed to be valid by the caller
std::string couplerstatus { locale::strings[ locale::string::debug_vehicle_none ] };
auto const *connected { (
Side == end::front ?
m_input.vehicle->PrevConnected :
m_input.vehicle->NextConnected ) };
auto const *connected { m_input.vehicle->MoverParameters->Neighbours[ Side ].vehicle };
if( connected == nullptr ) { return couplerstatus; }
@@ -579,10 +652,10 @@ debug_panel::update_vehicle_coupler( int const Side ) {
std::snprintf(
m_buffer.data(), m_buffer.size(),
"%s [%d]%s",
"%s [%d] (%.1f m)",
connected->name().c_str(),
mover.Couplers[ Side ].CouplingFlag,
std::string( mover.Couplers[ Side ].CouplingFlag == 0 ? " (" + to_string( mover.Couplers[ Side ].CoupleDist, 1 ) + " m)" : "" ).c_str() );
mover.Neighbours[ Side ].distance );
return { m_buffer.data() };
}
@@ -686,7 +759,9 @@ debug_panel::update_section_ai( std::vector<text_line> &Output ) {
auto const &mechanik{ *m_input.mechanik };
// biezaca komenda dla AI
auto textline = "Current order: " + mechanik.OrderCurrent();
auto textline =
"Current order: [" + std::to_string( mechanik.OrderPos ) + "] "
+ mechanik.OrderCurrent();
if( mechanik.fStopTime < 0.0 ) {
textline += "\n stop time: " + to_string( std::abs( mechanik.fStopTime ), 1 );
@@ -705,6 +780,12 @@ debug_panel::update_section_ai( std::vector<text_line> &Output ) {
"Distances:\n proximity: " + to_string( mechanik.ActualProximityDist, 0 )
+ ", braking: " + to_string( mechanik.fBrakeDist, 0 );
if( mechanik.Obstacle.distance < 5000 ) {
textline +=
"\n obstacle: " + to_string( mechanik.Obstacle.distance, 0 )
+ " (" + mechanik.Obstacle.vehicle->asName + ")";
}
Output.emplace_back( textline, Global.UITextColor );
// velocity factors

View File

@@ -39,6 +39,21 @@ private:
std::array<char, 256> m_buffer;
};
class scenario_panel : public ui_panel {
public:
scenario_panel( std::string const &Name, bool const Isopen )
: ui_panel( Name, Isopen ) {}
void update() override;
void render() override;
private:
// members
// std::array<char, 256> m_buffer;
TDynamicObject const *m_nearest { nullptr };
};
class debug_panel : public ui_panel {
public:

View File

@@ -53,6 +53,7 @@ struct scratch_data {
std::vector<int> couplings;
TDynamicObject * driver { nullptr };
bool is_open { false };
std::unordered_map<std::string, std::string> assignment;
} trainset;
std::string name;

View File

@@ -46,10 +46,12 @@ bounding_area::serialize( std::ostream &Output ) const {
// restores content of the struct from provided input stream
void
bounding_area::deserialize( std::istream &Input ) {
bounding_area::deserialize( std::istream &Input, bool const Preserveradius ) {
center = sn_utils::d_dvec3( Input );
radius = std::max(radius, sn_utils::ld_float32( Input ));
radius = ( Preserveradius ?
std::max( radius, sn_utils::ld_float32( Input ) ) :
sn_utils::ld_float32( Input ) );
}

View File

@@ -59,9 +59,9 @@ struct bounding_area {
// stores content of the struct in provided output stream
void
serialize( std::ostream &Output ) const;
// restores content of the struct from provided input stream
// restores content of the struct from provided input stream.
void
deserialize( std::istream &Input );
deserialize( std::istream &Input, bool const Preserveradius = true );
};
//using group_handle = std::size_t;

View File

@@ -56,6 +56,7 @@ state_serializer::deserialize_begin( std::string const &Scenariofile ) {
std::string,
deserializefunction> > functionlist = {
{ "area", &state_serializer::deserialize_area },
{ "assignment", &state_serializer::deserialize_assignment },
{ "atmo", &state_serializer::deserialize_atmo },
{ "camera", &state_serializer::deserialize_camera },
{ "config", &state_serializer::deserialize_config },
@@ -143,6 +144,20 @@ state_serializer::deserialize_area( cParser &Input, scene::scratch_data &Scratch
}
}
void
state_serializer::deserialize_assignment( cParser &Input, scene::scratch_data &Scratchpad ) {
std::string token { Input.getToken<std::string>() };
while( ( false == token.empty() )
&& ( token != "endassignment" ) ) {
// assignment is expected to come as string pairs: language id and the actual assignment enclosed in quotes to form a single token
auto assignment{ Input.getToken<std::string>() };
win1250_to_ascii( assignment );
Scratchpad.trainset.assignment.emplace( token, assignment );
token = Input.getToken<std::string>();
}
}
void
state_serializer::deserialize_atmo( cParser &Input, scene::scratch_data &Scratchpad ) {
@@ -640,6 +655,11 @@ state_serializer::deserialize_endtrainset( cParser &Input, scene::scratch_data &
&& ( vehicle->Mechanik->Primary() ) ) {
// primary driver will receive the timetable for this trainset
Scratchpad.trainset.driver = vehicle;
// they'll also receive assignment data if there's any
auto const lookup { Scratchpad.trainset.assignment.find( Global.asLang ) };
if( lookup != Scratchpad.trainset.assignment.end() ) {
vehicle->Mechanik->assignment() = lookup->second;
}
}
if( vehicleindex > 0 ) {
// from second vehicle on couple it with the previous one

View File

@@ -48,6 +48,7 @@ private:
// methods
// restores class data from provided stream
void deserialize_area( cParser &Input, scene::scratch_data &Scratchpad );
void deserialize_assignment( cParser &Input, scene::scratch_data &Scratchpad );
void deserialize_atmo( cParser &Input, scene::scratch_data &Scratchpad );
void deserialize_camera( cParser &Input, scene::scratch_data &Scratchpad );
void deserialize_config( cParser &Input, scene::scratch_data &Scratchpad );

View File

@@ -114,7 +114,7 @@ scenario_time::update( double const Deltatime ) {
}
m_time.wHour -= 24;
}
int leap { ( m_time.wYear % 4 == 0 ) && ( m_time.wYear % 100 != 0 ) || ( m_time.wYear % 400 == 0 ) };
int leap { is_leap( m_time.wYear ) };
while( m_time.wDay > m_monthdaycounts[ leap ][ m_time.wMonth ] ) {
m_time.wDay -= m_monthdaycounts[ leap ][ m_time.wMonth ];
@@ -123,7 +123,7 @@ scenario_time::update( double const Deltatime ) {
if( m_time.wMonth > 12 ) {
++m_time.wYear;
leap = ( m_time.wYear % 4 == 0 ) && ( m_time.wYear % 100 != 0 ) || ( m_time.wYear % 400 == 0 );
leap = is_leap( m_time.wYear );
m_time.wMonth -= 12;
}
}
@@ -137,7 +137,7 @@ scenario_time::year_day( int Day, const int Month, const int Year ) const {
{ 0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
};
int const leap { ( Year % 4 == 0 ) && ( Year % 100 != 0 ) || ( Year % 400 == 0 ) };
int const leap { is_leap( Year ) };
for( int i = 1; i < Month; ++i )
Day += daytab[ leap ][ i ];
@@ -152,7 +152,7 @@ scenario_time::daymonth( WORD &Day, WORD &Month, WORD const Year, WORD const Yea
{ 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 }
};
int const leap { ( Year % 4 == 0 ) && ( Year % 100 != 0 ) || ( Year % 400 == 0 ) };
int const leap { is_leap( Year ) };
WORD idx = 1;
while( ( idx < 13 ) && ( Yearday >= daytab[ leap ][ idx ] ) ) {
@@ -221,7 +221,7 @@ scenario_time::day_of_month( int const Week, int const Weekday, int const Month,
{ 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
{ 0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
};
int const leap { ( Year % 4 == 0 ) && ( Year % 100 != 0 ) || ( Year % 400 == 0 ) };
int const leap { is_leap( Year ) };
while( day > daytab[ leap ][ Month ] ) {
day -= 7;
@@ -246,3 +246,11 @@ scenario_time::convert_transition_time( SYSTEMTIME &Time ) const {
// NOTE: windows uses 0-6 range for days of week numbering, our methods use 1-7
Time.wDay = day_of_month( Time.wDay, Time.wDayOfWeek + 1, Time.wMonth, m_time.wYear );
}
bool
scenario_time::is_leap( int const Year ) const {
return ( ( Year % 4 == 0 ) && ( ( Year % 100 != 0 ) || ( Year % 400 == 0 ) ) );
}
//---------------------------------------------------------------------------

View File

@@ -69,6 +69,9 @@ private:
// returns number of days between specified days of week
int
weekdays( int const First, int const Second ) const;
// returns true if specified year is a leap year, false otherwise
bool
is_leap( int const Year ) const;
SYSTEMTIME m_time;
double m_milliseconds{ 0.0 };

14
sun.cpp
View File

@@ -173,17 +173,11 @@ void cSun::move() {
m_body.rascen = clamp_circular( radtodeg * std::atan2( top, bottom ) );
// Greenwich mean sidereal time
m_observer.gmst = 6.697375 + 0.0657098242 * daynumber + m_observer.utime;
// Greenwich mean sidereal time (hours)
m_observer.gmst = clamp_circular( 6.697375 + 0.0657098242 * daynumber + m_observer.utime, 24.0 );
m_observer.gmst -= 24.0 * (int)( m_observer.gmst / 24.0 );
if( m_observer.gmst < 0.0 ) m_observer.gmst += 24.0;
// local mean sidereal time
m_observer.lmst = m_observer.gmst * 15.0 + m_observer.longitude;
m_observer.lmst -= 360.0 * (int)( m_observer.lmst / 360.0 );
if( m_observer.lmst < 0.0 ) m_observer.lmst += 360.0;
// local mean sidereal time (deg)
m_observer.lmst = clamp_circular( m_observer.gmst * 15.0 + m_observer.longitude );
// hour angle
m_body.hrang = m_observer.lmst - m_body.rascen;

View File

@@ -38,8 +38,26 @@ init() {
" Loading/unloading in progress (%d s left)",
" Another vehicle ahead (distance: %.1f m)",
"Scenario",
"Assignment",
"Current task:",
"Wait for orders",
"Start the engine",
"Shut down the engine",
"Change direction",
"Couple to consist ahead",
"Uncouple %s",
"the engine",
"the engine plus the next vehicle",
"the engine plus %d next vehicles",
"the engine plus %d next vehicles",
"Shunt according to signals",
"Loose shunt according to signals",
"Drive according to signals and timetable",
"Bank consist ahead",
"%-*.*s Time: %d:%02d:%02d", // HACK: some manual padding to account for longer 'time' equivalent in polish version
"Timetable",
"Time: %d:%02d:%02d",
"(no timetable)",
"Consist weight: %d t (specified) %d t (actual)\nConsist length: %d m",
@@ -93,9 +111,11 @@ init() {
"Vehicle parameters",
"master controller",
"master controller",
"second controller",
"shunt mode power",
"tempomat",
"reverser",
"train brake",
"independent brake",
@@ -116,6 +136,7 @@ init() {
"motor blowers A",
"motor blowers B",
"all motor blowers",
"cooling fans",
"line breaker",
"line breaker",
"alerter",
@@ -140,6 +161,7 @@ init() {
"right door (close)",
"all doors (open)",
"all doors (close)",
"doorstep",
"departure signal",
"upper headlight",
"left headlight",
@@ -212,8 +234,26 @@ init() {
u8" Wsiadanie/wysiadanie pasażerów (do zakończenia %d s)",
u8" Inny pojazd na drodze (odległość: %.1f m)",
u8"Scenariusz",
u8"Zlecenie",
u8"Bieżace zadanie:",
u8"Oczekiwać dalszych poleceń",
u8"Przygotować pojazd do jazdy",
u8"Wyłączyc pojazd",
u8"Zmienić kierunek jazdy",
u8"Sprząc się ze składem z przodu",
u8"Odpiąć %s",
u8"pojazd prowadzący",
u8"pojazd prowadzący plus kolejny",
u8"pojazd prowadzący plus %d kolejne",
u8"pojazd prowadzący plus %d kolejnych",
u8"Prowadzić manewry według sygnałów",
u8"Prowadzić manewry przetaczania odrzutem",
u8"Prowadzić skład według sygnałów i rozkładu",
u8"Popychać skład z przodu",
u8"%-*.*s Godzina: %d:%02d:%02d",
u8"Rozkład jazdy",
u8"Godzina: %d:%02d:%02d",
u8"(brak rozkładu)",
u8"Brutto: %d t (rozkładowe) %d t (rzeczywiste)\nDługość pociągu: %d m",
@@ -267,9 +307,11 @@ init() {
u8"Parametry pojazdu",
u8"nastawnik jazdy",
u8"nastawnik jazdy",
u8"nastawnik dodatkowy",
u8"sterowanie analogowe",
u8"tempomat",
u8"nastawnik kierunku",
u8"hamulec zespolony",
u8"hamulec pomocniczy",
@@ -290,6 +332,7 @@ init() {
u8"wentylatory silników trakcyjnych A",
u8"wentylatory silników trakcyjnych B",
u8"wszystkie wentylatory silników trakcyjnych",
u8"wentylatory oporów rozruchowych",
u8"wyłącznik szybki",
u8"wyłącznik szybki",
u8"czuwak",
@@ -314,6 +357,7 @@ init() {
u8"drzwi prawe (zamknij)",
u8"drzwi (otwórz)",
u8"drzwi (zamknij)",
u8"stopień drzwi",
u8"sygnal odjazdu",
u8"reflektor gorny",
u8"reflektor lewy",
@@ -382,8 +426,10 @@ init() {
{
std::vector<std::string> cabcontrols = {
"mainctrl:",
"jointctrl:",
"scndctrl:",
"shuntmodepower:",
"tempomat_sw:",
"dirkey:",
"brakectrl:",
"localbrake:",
@@ -404,6 +450,7 @@ init() {
"motorblowersfront_sw:",
"motorblowersrear_sw:",
"motorblowersalloff_sw:",
"coolingfans_sw:",
"main_off_bt:",
"main_on_bt:",
"security_reset_bt:",
@@ -428,6 +475,7 @@ init() {
"doorrightoff_sw:",
"doorallon_sw:",
"dooralloff_sw:",
"doorstep_sw:",
"departure_signal_bt:",
"upperlight_sw:",
"leftlight_sw:",

View File

@@ -27,8 +27,26 @@ enum string {
driver_aid_loadinginprogress,
driver_aid_vehicleahead,
driver_scenario_header,
driver_scenario_assignment,
driver_scenario_currenttask,
driver_scenario_waitfororders,
driver_scenario_prepareengine,
driver_scenario_releaseengine,
driver_scenario_changedirection,
driver_scenario_connect,
driver_scenario_disconnect,
driver_scenario_allvehicles,
driver_scenario_onevehicle,
driver_scenario_fewvehicles,
driver_scenario_somevehicles,
driver_scenario_shunt,
driver_scenario_looseshunt,
driver_scenario_obeytrain,
driver_scenario_bank,
driver_timetable_header,
driver_timetable_time,
driver_timetable_name,
driver_timetable_notimetable,
driver_timetable_consistdata,
@@ -83,8 +101,10 @@ enum string {
vehicleparams_window,
cab_mainctrl,
cab_jointctrl,
cab_scndctrl,
cab_shuntmodepower,
cab_tempomat,
cab_dirkey,
cab_brakectrl,
cab_localbrake,
@@ -105,6 +125,7 @@ enum string {
cab_motorblowersfront_sw,
cab_motorblowersrear_sw,
cab_motorblowersalloff_sw,
cab_coolingfans_sw,
cab_main_off_bt,
cab_main_on_bt,
cab_security_reset_bt,
@@ -129,6 +150,7 @@ enum string {
cab_doorrightoff_sw,
cab_doorallon_sw,
cab_dooralloff_sw,
cab_doorstep_sw,
cab_departure_signal_bt,
cab_upperlight_sw,
cab_leftlight_sw,

View File

@@ -1 +1 @@
#define VERSION_INFO "M7 (GL3 NET) 21.02.2018, based on milek-267c4472a, tmj-bc60b5ac6"
#define VERSION_INFO "M7 (GL3 NET) 16.03.2019, based on tmj-8d67338"